grimoire-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1174) hide show
  1. package/.claude/CLAUDE.md +318 -0
  2. package/.claude/hooks/README.md +170 -0
  3. package/.claude/hooks/enforce-architecture-first.py +198 -0
  4. package/.claude/hooks/install-hooks.sh +43 -0
  5. package/.claude/hooks/mind-clone-governance.py +192 -0
  6. package/.claude/hooks/pre-commit-version-check.sh +157 -0
  7. package/.claude/hooks/precompact-session-digest.js +47 -0
  8. package/.claude/hooks/read-protection.py +153 -0
  9. package/.claude/hooks/slug-validation.py +176 -0
  10. package/.claude/hooks/sql-governance.py +182 -0
  11. package/.claude/hooks/synapse-engine.js +77 -0
  12. package/.claude/hooks/write-path-validation.py +196 -0
  13. package/.claude/rules/mcp-usage.md +177 -0
  14. package/.grimoire/cli/commands/config/index.js +609 -0
  15. package/.grimoire/cli/commands/generate/index.js +222 -0
  16. package/.grimoire/cli/commands/manifest/index.js +47 -0
  17. package/.grimoire/cli/commands/manifest/regenerate.js +97 -0
  18. package/.grimoire/cli/commands/manifest/validate.js +66 -0
  19. package/.grimoire/cli/commands/mcp/add.js +235 -0
  20. package/.grimoire/cli/commands/mcp/index.js +77 -0
  21. package/.grimoire/cli/commands/mcp/link.js +218 -0
  22. package/.grimoire/cli/commands/mcp/setup.js +165 -0
  23. package/.grimoire/cli/commands/mcp/status.js +184 -0
  24. package/.grimoire/cli/commands/metrics/cleanup.js +91 -0
  25. package/.grimoire/cli/commands/metrics/index.js +66 -0
  26. package/.grimoire/cli/commands/metrics/record.js +154 -0
  27. package/.grimoire/cli/commands/metrics/seed.js +127 -0
  28. package/.grimoire/cli/commands/metrics/show.js +209 -0
  29. package/.grimoire/cli/commands/migrate/analyze.js +355 -0
  30. package/.grimoire/cli/commands/migrate/backup.js +354 -0
  31. package/.grimoire/cli/commands/migrate/execute.js +294 -0
  32. package/.grimoire/cli/commands/migrate/index.js +443 -0
  33. package/.grimoire/cli/commands/migrate/rollback.js +325 -0
  34. package/.grimoire/cli/commands/migrate/update-imports.js +398 -0
  35. package/.grimoire/cli/commands/migrate/validate.js +454 -0
  36. package/.grimoire/cli/commands/pro/index.js +705 -0
  37. package/.grimoire/cli/commands/qa/index.js +57 -0
  38. package/.grimoire/cli/commands/qa/run.js +163 -0
  39. package/.grimoire/cli/commands/qa/status.js +195 -0
  40. package/.grimoire/cli/commands/validate/index.js +431 -0
  41. package/.grimoire/cli/commands/workers/formatters/info-formatter.js +275 -0
  42. package/.grimoire/cli/commands/workers/formatters/list-table.js +265 -0
  43. package/.grimoire/cli/commands/workers/formatters/list-tree.js +160 -0
  44. package/.grimoire/cli/commands/workers/index.js +57 -0
  45. package/.grimoire/cli/commands/workers/info.js +195 -0
  46. package/.grimoire/cli/commands/workers/list.js +215 -0
  47. package/.grimoire/cli/commands/workers/search-filters.js +185 -0
  48. package/.grimoire/cli/commands/workers/search-keyword.js +310 -0
  49. package/.grimoire/cli/commands/workers/search-semantic.js +294 -0
  50. package/.grimoire/cli/commands/workers/search.js +155 -0
  51. package/.grimoire/cli/commands/workers/utils/pagination.js +102 -0
  52. package/.grimoire/cli/index.js +150 -0
  53. package/.grimoire/cli/utils/output-formatter-cli.js +233 -0
  54. package/.grimoire/cli/utils/score-calculator.js +221 -0
  55. package/.grimoire/constitution.md +172 -0
  56. package/.grimoire/core/README.md +231 -0
  57. package/.grimoire/core/code-intel/code-intel-client.js +280 -0
  58. package/.grimoire/core/code-intel/code-intel-enricher.js +160 -0
  59. package/.grimoire/core/code-intel/index.js +137 -0
  60. package/.grimoire/core/code-intel/providers/code-graph-provider.js +201 -0
  61. package/.grimoire/core/code-intel/providers/provider-interface.js +108 -0
  62. package/.grimoire/core/config/config-cache.js +233 -0
  63. package/.grimoire/core/config/config-loader.js +281 -0
  64. package/.grimoire/core/config/config-resolver.js +609 -0
  65. package/.grimoire/core/config/env-interpolator.js +122 -0
  66. package/.grimoire/core/config/merge-utils.js +101 -0
  67. package/.grimoire/core/config/migrate-config.js +293 -0
  68. package/.grimoire/core/config/schemas/framework-config.schema.json +19 -0
  69. package/.grimoire/core/config/schemas/local-config.schema.json +20 -0
  70. package/.grimoire/core/config/schemas/project-config.schema.json +32 -0
  71. package/.grimoire/core/config/schemas/user-config.schema.json +33 -0
  72. package/.grimoire/core/config/templates/user-config.yaml +24 -0
  73. package/.grimoire/core/docs/SHARD-TRANSLATION-GUIDE.md +337 -0
  74. package/.grimoire/core/docs/component-creation-guide.md +459 -0
  75. package/.grimoire/core/docs/session-update-pattern.md +316 -0
  76. package/.grimoire/core/docs/template-syntax.md +267 -0
  77. package/.grimoire/core/docs/troubleshooting-guide.md +626 -0
  78. package/.grimoire/core/elicitation/agent-elicitation.js +272 -0
  79. package/.grimoire/core/elicitation/elicitation-engine.js +486 -0
  80. package/.grimoire/core/elicitation/session-manager.js +322 -0
  81. package/.grimoire/core/elicitation/task-elicitation.js +281 -0
  82. package/.grimoire/core/elicitation/workflow-elicitation.js +349 -0
  83. package/.grimoire/core/events/dashboard-emitter.js +369 -0
  84. package/.grimoire/core/events/index.js +17 -0
  85. package/.grimoire/core/events/types.js +52 -0
  86. package/.grimoire/core/execution/autonomous-build-loop.js +1068 -0
  87. package/.grimoire/core/execution/build-orchestrator.js +1055 -0
  88. package/.grimoire/core/execution/build-state-manager.js +1530 -0
  89. package/.grimoire/core/execution/context-injector.js +537 -0
  90. package/.grimoire/core/execution/parallel-executor.js +292 -0
  91. package/.grimoire/core/execution/parallel-monitor.js +429 -0
  92. package/.grimoire/core/execution/rate-limit-manager.js +314 -0
  93. package/.grimoire/core/execution/result-aggregator.js +486 -0
  94. package/.grimoire/core/execution/semantic-merge-engine.js +1736 -0
  95. package/.grimoire/core/execution/subagent-dispatcher.js +848 -0
  96. package/.grimoire/core/execution/wave-executor.js +397 -0
  97. package/.grimoire/core/health-check/base-check.js +224 -0
  98. package/.grimoire/core/health-check/check-registry.js +253 -0
  99. package/.grimoire/core/health-check/checks/deployment/build-config.js +111 -0
  100. package/.grimoire/core/health-check/checks/deployment/ci-config.js +125 -0
  101. package/.grimoire/core/health-check/checks/deployment/deployment-readiness.js +152 -0
  102. package/.grimoire/core/health-check/checks/deployment/docker-config.js +122 -0
  103. package/.grimoire/core/health-check/checks/deployment/env-file.js +111 -0
  104. package/.grimoire/core/health-check/checks/deployment/index.js +29 -0
  105. package/.grimoire/core/health-check/checks/index.js +56 -0
  106. package/.grimoire/core/health-check/checks/local/disk-space.js +214 -0
  107. package/.grimoire/core/health-check/checks/local/environment-vars.js +136 -0
  108. package/.grimoire/core/health-check/checks/local/git-install.js +158 -0
  109. package/.grimoire/core/health-check/checks/local/ide-detection.js +148 -0
  110. package/.grimoire/core/health-check/checks/local/index.js +35 -0
  111. package/.grimoire/core/health-check/checks/local/memory.js +138 -0
  112. package/.grimoire/core/health-check/checks/local/network.js +170 -0
  113. package/.grimoire/core/health-check/checks/local/npm-install.js +149 -0
  114. package/.grimoire/core/health-check/checks/local/shell-environment.js +120 -0
  115. package/.grimoire/core/health-check/checks/project/agent-config.js +167 -0
  116. package/.grimoire/core/health-check/checks/project/dependencies.js +150 -0
  117. package/.grimoire/core/health-check/checks/project/framework-config.js +133 -0
  118. package/.grimoire/core/health-check/checks/project/grimoire-directory.js +143 -0
  119. package/.grimoire/core/health-check/checks/project/index.js +35 -0
  120. package/.grimoire/core/health-check/checks/project/node-version.js +163 -0
  121. package/.grimoire/core/health-check/checks/project/package-json.js +107 -0
  122. package/.grimoire/core/health-check/checks/project/task-definitions.js +192 -0
  123. package/.grimoire/core/health-check/checks/project/workflow-dependencies.js +214 -0
  124. package/.grimoire/core/health-check/checks/repository/branch-protection.js +107 -0
  125. package/.grimoire/core/health-check/checks/repository/commit-history.js +144 -0
  126. package/.grimoire/core/health-check/checks/repository/conflicts.js +152 -0
  127. package/.grimoire/core/health-check/checks/repository/git-repo.js +159 -0
  128. package/.grimoire/core/health-check/checks/repository/git-status.js +149 -0
  129. package/.grimoire/core/health-check/checks/repository/gitignore.js +194 -0
  130. package/.grimoire/core/health-check/checks/repository/index.js +35 -0
  131. package/.grimoire/core/health-check/checks/repository/large-files.js +183 -0
  132. package/.grimoire/core/health-check/checks/repository/lockfile-integrity.js +144 -0
  133. package/.grimoire/core/health-check/checks/services/api-endpoints.js +168 -0
  134. package/.grimoire/core/health-check/checks/services/claude-code.js +139 -0
  135. package/.grimoire/core/health-check/checks/services/gemini-cli.js +241 -0
  136. package/.grimoire/core/health-check/checks/services/github-cli.js +117 -0
  137. package/.grimoire/core/health-check/checks/services/index.js +29 -0
  138. package/.grimoire/core/health-check/checks/services/mcp-integration.js +125 -0
  139. package/.grimoire/core/health-check/engine.js +407 -0
  140. package/.grimoire/core/health-check/healers/backup-manager.js +340 -0
  141. package/.grimoire/core/health-check/healers/index.js +330 -0
  142. package/.grimoire/core/health-check/index.js +370 -0
  143. package/.grimoire/core/health-check/reporters/console.js +331 -0
  144. package/.grimoire/core/health-check/reporters/index.js +117 -0
  145. package/.grimoire/core/health-check/reporters/json.js +301 -0
  146. package/.grimoire/core/health-check/reporters/markdown.js +323 -0
  147. package/.grimoire/core/ideation/ideation-engine.js +834 -0
  148. package/.grimoire/core/ids/README.md +123 -0
  149. package/.grimoire/core/ids/circuit-breaker.js +156 -0
  150. package/.grimoire/core/ids/framework-governor.js +567 -0
  151. package/.grimoire/core/ids/gates/g1-epic-creation.js +101 -0
  152. package/.grimoire/core/ids/gates/g2-story-creation.js +133 -0
  153. package/.grimoire/core/ids/gates/g3-story-validation.js +166 -0
  154. package/.grimoire/core/ids/gates/g4-dev-context.js +155 -0
  155. package/.grimoire/core/ids/incremental-decision-engine.js +651 -0
  156. package/.grimoire/core/ids/index.js +157 -0
  157. package/.grimoire/core/ids/registry-healer.js +868 -0
  158. package/.grimoire/core/ids/registry-loader.js +281 -0
  159. package/.grimoire/core/ids/registry-updater.js +703 -0
  160. package/.grimoire/core/ids/verification-gate.js +306 -0
  161. package/.grimoire/core/index.esm.js +44 -0
  162. package/.grimoire/core/index.js +90 -0
  163. package/.grimoire/core/manifest/manifest-generator.js +388 -0
  164. package/.grimoire/core/manifest/manifest-validator.js +431 -0
  165. package/.grimoire/core/mcp/config-migrator.js +341 -0
  166. package/.grimoire/core/mcp/global-config-manager.js +370 -0
  167. package/.grimoire/core/mcp/index.js +34 -0
  168. package/.grimoire/core/mcp/os-detector.js +189 -0
  169. package/.grimoire/core/mcp/symlink-manager.js +415 -0
  170. package/.grimoire/core/memory/__tests__/active-modules.verify.js +254 -0
  171. package/.grimoire/core/memory/gotchas-memory.js +1154 -0
  172. package/.grimoire/core/migration/migration-config.yaml +85 -0
  173. package/.grimoire/core/migration/module-mapping.yaml +91 -0
  174. package/.grimoire/core/orchestration/agent-invoker.js +612 -0
  175. package/.grimoire/core/orchestration/bob-orchestrator.js +1032 -0
  176. package/.grimoire/core/orchestration/bob-status-writer.js +482 -0
  177. package/.grimoire/core/orchestration/bob-surface-criteria.yaml +272 -0
  178. package/.grimoire/core/orchestration/brownfield-handler.js +741 -0
  179. package/.grimoire/core/orchestration/checklist-runner.js +328 -0
  180. package/.grimoire/core/orchestration/cli-commands.js +581 -0
  181. package/.grimoire/core/orchestration/condition-evaluator.js +379 -0
  182. package/.grimoire/core/orchestration/context-manager.js +616 -0
  183. package/.grimoire/core/orchestration/dashboard-integration.js +520 -0
  184. package/.grimoire/core/orchestration/data-lifecycle-manager.js +357 -0
  185. package/.grimoire/core/orchestration/epic-context-accumulator.js +396 -0
  186. package/.grimoire/core/orchestration/execution-profile-resolver.js +107 -0
  187. package/.grimoire/core/orchestration/executor-assignment.js +413 -0
  188. package/.grimoire/core/orchestration/executors/epic-3-executor.js +223 -0
  189. package/.grimoire/core/orchestration/executors/epic-4-executor.js +269 -0
  190. package/.grimoire/core/orchestration/executors/epic-5-executor.js +329 -0
  191. package/.grimoire/core/orchestration/executors/epic-6-executor.js +265 -0
  192. package/.grimoire/core/orchestration/executors/epic-executor.js +237 -0
  193. package/.grimoire/core/orchestration/executors/index.js +86 -0
  194. package/.grimoire/core/orchestration/gate-evaluator.js +495 -0
  195. package/.grimoire/core/orchestration/gemini-model-selector.js +161 -0
  196. package/.grimoire/core/orchestration/greenfield-handler.js +890 -0
  197. package/.grimoire/core/orchestration/index.js +323 -0
  198. package/.grimoire/core/orchestration/lock-manager.js +327 -0
  199. package/.grimoire/core/orchestration/master-orchestrator.js +1544 -0
  200. package/.grimoire/core/orchestration/message-formatter.js +279 -0
  201. package/.grimoire/core/orchestration/parallel-executor.js +225 -0
  202. package/.grimoire/core/orchestration/recovery-handler.js +721 -0
  203. package/.grimoire/core/orchestration/session-state.js +876 -0
  204. package/.grimoire/core/orchestration/skill-dispatcher.js +364 -0
  205. package/.grimoire/core/orchestration/subagent-prompt-builder.js +370 -0
  206. package/.grimoire/core/orchestration/surface-checker.js +403 -0
  207. package/.grimoire/core/orchestration/task-complexity-classifier.js +123 -0
  208. package/.grimoire/core/orchestration/tech-stack-detector.js +599 -0
  209. package/.grimoire/core/orchestration/terminal-spawner.js +1044 -0
  210. package/.grimoire/core/orchestration/workflow-executor.js +1182 -0
  211. package/.grimoire/core/orchestration/workflow-orchestrator.js +907 -0
  212. package/.grimoire/core/permissions/__tests__/permission-mode.test.js +293 -0
  213. package/.grimoire/core/permissions/index.js +140 -0
  214. package/.grimoire/core/permissions/operation-guard.js +395 -0
  215. package/.grimoire/core/permissions/permission-mode.js +271 -0
  216. package/.grimoire/core/quality-gates/base-layer.js +134 -0
  217. package/.grimoire/core/quality-gates/checklist-generator.js +329 -0
  218. package/.grimoire/core/quality-gates/focus-area-recommender.js +361 -0
  219. package/.grimoire/core/quality-gates/human-review-orchestrator.js +530 -0
  220. package/.grimoire/core/quality-gates/layer1-precommit.js +336 -0
  221. package/.grimoire/core/quality-gates/layer2-pr-automation.js +331 -0
  222. package/.grimoire/core/quality-gates/layer3-human-review.js +350 -0
  223. package/.grimoire/core/quality-gates/notification-manager.js +551 -0
  224. package/.grimoire/core/quality-gates/quality-gate-config.yaml +87 -0
  225. package/.grimoire/core/quality-gates/quality-gate-manager.js +603 -0
  226. package/.grimoire/core/registry/README.md +181 -0
  227. package/.grimoire/core/registry/build-registry.js +454 -0
  228. package/.grimoire/core/registry/registry-loader.js +331 -0
  229. package/.grimoire/core/registry/registry-schema.json +168 -0
  230. package/.grimoire/core/registry/service-registry.json +6468 -0
  231. package/.grimoire/core/registry/validate-registry.js +341 -0
  232. package/.grimoire/core/session/context-detector.js +233 -0
  233. package/.grimoire/core/session/context-loader.js +443 -0
  234. package/.grimoire/core/synapse/context/context-builder.js +34 -0
  235. package/.grimoire/core/synapse/context/context-tracker.js +190 -0
  236. package/.grimoire/core/synapse/diagnostics/collectors/consistency-collector.js +168 -0
  237. package/.grimoire/core/synapse/diagnostics/collectors/hook-collector.js +129 -0
  238. package/.grimoire/core/synapse/diagnostics/collectors/manifest-collector.js +82 -0
  239. package/.grimoire/core/synapse/diagnostics/collectors/output-analyzer.js +134 -0
  240. package/.grimoire/core/synapse/diagnostics/collectors/pipeline-collector.js +75 -0
  241. package/.grimoire/core/synapse/diagnostics/collectors/quality-collector.js +252 -0
  242. package/.grimoire/core/synapse/diagnostics/collectors/relevance-matrix.js +174 -0
  243. package/.grimoire/core/synapse/diagnostics/collectors/safe-read-json.js +31 -0
  244. package/.grimoire/core/synapse/diagnostics/collectors/session-collector.js +102 -0
  245. package/.grimoire/core/synapse/diagnostics/collectors/timing-collector.js +126 -0
  246. package/.grimoire/core/synapse/diagnostics/collectors/uap-collector.js +83 -0
  247. package/.grimoire/core/synapse/diagnostics/report-formatter.js +485 -0
  248. package/.grimoire/core/synapse/diagnostics/synapse-diagnostics.js +95 -0
  249. package/.grimoire/core/synapse/domain/domain-loader.js +322 -0
  250. package/.grimoire/core/synapse/engine.js +380 -0
  251. package/.grimoire/core/synapse/layers/l0-constitution.js +80 -0
  252. package/.grimoire/core/synapse/layers/l1-global.js +102 -0
  253. package/.grimoire/core/synapse/layers/l2-agent.js +94 -0
  254. package/.grimoire/core/synapse/layers/l3-workflow.js +94 -0
  255. package/.grimoire/core/synapse/layers/l4-task.js +83 -0
  256. package/.grimoire/core/synapse/layers/l5-squad.js +244 -0
  257. package/.grimoire/core/synapse/layers/l6-keyword.js +154 -0
  258. package/.grimoire/core/synapse/layers/l7-star-command.js +169 -0
  259. package/.grimoire/core/synapse/layers/layer-processor.js +82 -0
  260. package/.grimoire/core/synapse/memory/memory-bridge.js +246 -0
  261. package/.grimoire/core/synapse/output/formatter.js +561 -0
  262. package/.grimoire/core/synapse/runtime/hook-runtime.js +61 -0
  263. package/.grimoire/core/synapse/scripts/generate-constitution.js +205 -0
  264. package/.grimoire/core/synapse/session/session-manager.js +403 -0
  265. package/.grimoire/core/synapse/utils/paths.js +57 -0
  266. package/.grimoire/core/synapse/utils/tokens.js +25 -0
  267. package/.grimoire/core/ui/index.js +43 -0
  268. package/.grimoire/core/ui/observability-panel.js +394 -0
  269. package/.grimoire/core/ui/panel-renderer.js +337 -0
  270. package/.grimoire/core/utils/output-formatter.js +299 -0
  271. package/.grimoire/core/utils/security-utils.js +336 -0
  272. package/.grimoire/core/utils/yaml-validator.js +416 -0
  273. package/.grimoire/core-config.yaml +357 -0
  274. package/.grimoire/data/agent-config-requirements.yaml +409 -0
  275. package/.grimoire/data/entity-registry.yaml +9219 -0
  276. package/.grimoire/data/grimoire-kb.md +918 -0
  277. package/.grimoire/data/learned-patterns.yaml +3 -0
  278. package/.grimoire/data/tech-presets/_template.md +259 -0
  279. package/.grimoire/data/tech-presets/nextjs-react.md +933 -0
  280. package/.grimoire/data/technical-preferences.md +85 -0
  281. package/.grimoire/data/workflow-patterns.yaml +836 -0
  282. package/.grimoire/data/workflow-state-schema.yaml +203 -0
  283. package/.grimoire/development/README.md +143 -0
  284. package/.grimoire/development/agent-teams/team-all.yaml +16 -0
  285. package/.grimoire/development/agent-teams/team-fullstack.yaml +19 -0
  286. package/.grimoire/development/agent-teams/team-ide-minimal.yaml +10 -0
  287. package/.grimoire/development/agent-teams/team-no-ui.yaml +14 -0
  288. package/.grimoire/development/agent-teams/team-qa-focused.yaml +155 -0
  289. package/.grimoire/development/agents/analyst.md +261 -0
  290. package/.grimoire/development/agents/architect.md +461 -0
  291. package/.grimoire/development/agents/caravaggio.md +31 -0
  292. package/.grimoire/development/agents/data-engineer.md +482 -0
  293. package/.grimoire/development/agents/dev.md +548 -0
  294. package/.grimoire/development/agents/devops.md +500 -0
  295. package/.grimoire/development/agents/frida.md +31 -0
  296. package/.grimoire/development/agents/grimoire-master.md +447 -0
  297. package/.grimoire/development/agents/picasso.md +31 -0
  298. package/.grimoire/development/agents/pm.md +365 -0
  299. package/.grimoire/development/agents/po.md +323 -0
  300. package/.grimoire/development/agents/qa.md +437 -0
  301. package/.grimoire/development/agents/salvador.md +31 -0
  302. package/.grimoire/development/agents/sm.md +275 -0
  303. package/.grimoire/development/agents/squad-creator.md +330 -0
  304. package/.grimoire/development/agents/tarsila.md +31 -0
  305. package/.grimoire/development/agents/ux-design-expert.md +482 -0
  306. package/.grimoire/development/agents/van-gogh.md +31 -0
  307. package/.grimoire/development/agents/warhol.md +31 -0
  308. package/.grimoire/development/checklists/agent-quality-gate.md +560 -0
  309. package/.grimoire/development/checklists/brownfield-compatibility-checklist.md +116 -0
  310. package/.grimoire/development/checklists/self-critique-checklist.md +274 -0
  311. package/.grimoire/development/data/decision-heuristics-framework.md +622 -0
  312. package/.grimoire/development/data/quality-dimensions-framework.md +427 -0
  313. package/.grimoire/development/data/tier-system-framework.md +476 -0
  314. package/.grimoire/development/scripts/activation-runtime.js +64 -0
  315. package/.grimoire/development/scripts/agent-assignment-resolver.js +231 -0
  316. package/.grimoire/development/scripts/agent-config-loader.js +628 -0
  317. package/.grimoire/development/scripts/agent-exit-hooks.js +97 -0
  318. package/.grimoire/development/scripts/apply-inline-greeting-all-agents.js +147 -0
  319. package/.grimoire/development/scripts/approval-workflow.js +643 -0
  320. package/.grimoire/development/scripts/audit-agent-config.js +382 -0
  321. package/.grimoire/development/scripts/backlog-manager.js +409 -0
  322. package/.grimoire/development/scripts/backup-manager.js +607 -0
  323. package/.grimoire/development/scripts/batch-update-agents-session-context.js +97 -0
  324. package/.grimoire/development/scripts/branch-manager.js +390 -0
  325. package/.grimoire/development/scripts/code-quality-improver.js +1312 -0
  326. package/.grimoire/development/scripts/commit-message-generator.js +850 -0
  327. package/.grimoire/development/scripts/conflict-resolver.js +675 -0
  328. package/.grimoire/development/scripts/decision-context.js +229 -0
  329. package/.grimoire/development/scripts/decision-log-generator.js +294 -0
  330. package/.grimoire/development/scripts/decision-log-indexer.js +285 -0
  331. package/.grimoire/development/scripts/decision-recorder.js +169 -0
  332. package/.grimoire/development/scripts/dependency-analyzer.js +639 -0
  333. package/.grimoire/development/scripts/dev-context-loader.js +298 -0
  334. package/.grimoire/development/scripts/diff-generator.js +352 -0
  335. package/.grimoire/development/scripts/elicitation-engine.js +385 -0
  336. package/.grimoire/development/scripts/elicitation-session-manager.js +300 -0
  337. package/.grimoire/development/scripts/generate-greeting.js +109 -0
  338. package/.grimoire/development/scripts/git-wrapper.js +462 -0
  339. package/.grimoire/development/scripts/greeting-builder.js +1406 -0
  340. package/.grimoire/development/scripts/greeting-config-cli.js +86 -0
  341. package/.grimoire/development/scripts/greeting-preference-manager.js +170 -0
  342. package/.grimoire/development/scripts/manifest-preview.js +245 -0
  343. package/.grimoire/development/scripts/metrics-tracker.js +776 -0
  344. package/.grimoire/development/scripts/migrate-task-to-v2.js +379 -0
  345. package/.grimoire/development/scripts/modification-validator.js +555 -0
  346. package/.grimoire/development/scripts/pattern-learner.js +1225 -0
  347. package/.grimoire/development/scripts/performance-analyzer.js +758 -0
  348. package/.grimoire/development/scripts/populate-entity-registry.js +281 -0
  349. package/.grimoire/development/scripts/refactoring-suggester.js +1139 -0
  350. package/.grimoire/development/scripts/rollback-handler.js +532 -0
  351. package/.grimoire/development/scripts/security-checker.js +359 -0
  352. package/.grimoire/development/scripts/skill-validator.js +343 -0
  353. package/.grimoire/development/scripts/squad/README.md +114 -0
  354. package/.grimoire/development/scripts/squad/index.js +124 -0
  355. package/.grimoire/development/scripts/squad/squad-analyzer.js +638 -0
  356. package/.grimoire/development/scripts/squad/squad-designer.js +1010 -0
  357. package/.grimoire/development/scripts/squad/squad-downloader.js +511 -0
  358. package/.grimoire/development/scripts/squad/squad-extender.js +872 -0
  359. package/.grimoire/development/scripts/squad/squad-generator.js +1406 -0
  360. package/.grimoire/development/scripts/squad/squad-loader.js +359 -0
  361. package/.grimoire/development/scripts/squad/squad-migrator.js +628 -0
  362. package/.grimoire/development/scripts/squad/squad-publisher.js +630 -0
  363. package/.grimoire/development/scripts/squad/squad-validator.js +857 -0
  364. package/.grimoire/development/scripts/story-index-generator.js +339 -0
  365. package/.grimoire/development/scripts/story-manager.js +375 -0
  366. package/.grimoire/development/scripts/story-update-hook.js +259 -0
  367. package/.grimoire/development/scripts/task-identifier-resolver.js +145 -0
  368. package/.grimoire/development/scripts/template-engine.js +240 -0
  369. package/.grimoire/development/scripts/template-validator.js +279 -0
  370. package/.grimoire/development/scripts/test-generator.js +844 -0
  371. package/.grimoire/development/scripts/test-greeting-system.js +143 -0
  372. package/.grimoire/development/scripts/transaction-manager.js +591 -0
  373. package/.grimoire/development/scripts/unified-activation-pipeline.js +796 -0
  374. package/.grimoire/development/scripts/usage-tracker.js +675 -0
  375. package/.grimoire/development/scripts/validate-filenames.js +228 -0
  376. package/.grimoire/development/scripts/validate-task-v2.js +320 -0
  377. package/.grimoire/development/scripts/verify-workflow-gaps.js +1034 -0
  378. package/.grimoire/development/scripts/version-tracker.js +527 -0
  379. package/.grimoire/development/scripts/workflow-navigator.js +328 -0
  380. package/.grimoire/development/scripts/workflow-state-manager.js +652 -0
  381. package/.grimoire/development/scripts/workflow-validator.js +697 -0
  382. package/.grimoire/development/scripts/yaml-validator.js +397 -0
  383. package/.grimoire/development/tasks/add-mcp.md +437 -0
  384. package/.grimoire/development/tasks/advanced-elicitation.md +320 -0
  385. package/.grimoire/development/tasks/analyst-facilitate-brainstorming.md +343 -0
  386. package/.grimoire/development/tasks/analyze-brownfield.md +458 -0
  387. package/.grimoire/development/tasks/analyze-cross-artifact.md +358 -0
  388. package/.grimoire/development/tasks/analyze-framework.md +698 -0
  389. package/.grimoire/development/tasks/analyze-performance.md +639 -0
  390. package/.grimoire/development/tasks/analyze-project-structure.md +623 -0
  391. package/.grimoire/development/tasks/apply-qa-fixes.md +342 -0
  392. package/.grimoire/development/tasks/architect-analyze-impact.md +828 -0
  393. package/.grimoire/development/tasks/audit-codebase.md +431 -0
  394. package/.grimoire/development/tasks/audit-tailwind-config.md +272 -0
  395. package/.grimoire/development/tasks/audit-utilities.md +360 -0
  396. package/.grimoire/development/tasks/blocks/README.md +180 -0
  397. package/.grimoire/development/tasks/blocks/agent-prompt-template.md +117 -0
  398. package/.grimoire/development/tasks/blocks/context-loading.md +110 -0
  399. package/.grimoire/development/tasks/blocks/execution-pattern.md +122 -0
  400. package/.grimoire/development/tasks/blocks/finalization.md +123 -0
  401. package/.grimoire/development/tasks/bootstrap-shadcn-library.md +288 -0
  402. package/.grimoire/development/tasks/brownfield-create-epic.md +533 -0
  403. package/.grimoire/development/tasks/brownfield-create-story.md +358 -0
  404. package/.grimoire/development/tasks/build-autonomous.md +186 -0
  405. package/.grimoire/development/tasks/build-component.md +480 -0
  406. package/.grimoire/development/tasks/build-resume.md +125 -0
  407. package/.grimoire/development/tasks/build-status.md +155 -0
  408. package/.grimoire/development/tasks/build.md +142 -0
  409. package/.grimoire/development/tasks/calculate-roi.md +457 -0
  410. package/.grimoire/development/tasks/check-docs-links.md +114 -0
  411. package/.grimoire/development/tasks/ci-cd-configuration.md +766 -0
  412. package/.grimoire/development/tasks/cleanup-utilities.md +672 -0
  413. package/.grimoire/development/tasks/cleanup-worktrees.md +39 -0
  414. package/.grimoire/development/tasks/collaborative-edit.md +1110 -0
  415. package/.grimoire/development/tasks/compose-molecule.md +286 -0
  416. package/.grimoire/development/tasks/consolidate-patterns.md +416 -0
  417. package/.grimoire/development/tasks/correct-course.md +281 -0
  418. package/.grimoire/development/tasks/create-agent.md +1199 -0
  419. package/.grimoire/development/tasks/create-brownfield-story.md +728 -0
  420. package/.grimoire/development/tasks/create-deep-research-prompt.md +500 -0
  421. package/.grimoire/development/tasks/create-doc.md +318 -0
  422. package/.grimoire/development/tasks/create-next-story.md +776 -0
  423. package/.grimoire/development/tasks/create-service.md +393 -0
  424. package/.grimoire/development/tasks/create-suite.md +285 -0
  425. package/.grimoire/development/tasks/create-task.md +391 -0
  426. package/.grimoire/development/tasks/create-workflow.md +429 -0
  427. package/.grimoire/development/tasks/create-worktree.md +439 -0
  428. package/.grimoire/development/tasks/db-analyze-hotpaths.md +574 -0
  429. package/.grimoire/development/tasks/db-apply-migration.md +383 -0
  430. package/.grimoire/development/tasks/db-bootstrap.md +644 -0
  431. package/.grimoire/development/tasks/db-domain-modeling.md +695 -0
  432. package/.grimoire/development/tasks/db-dry-run.md +295 -0
  433. package/.grimoire/development/tasks/db-env-check.md +262 -0
  434. package/.grimoire/development/tasks/db-explain.md +633 -0
  435. package/.grimoire/development/tasks/db-impersonate.md +497 -0
  436. package/.grimoire/development/tasks/db-load-csv.md +595 -0
  437. package/.grimoire/development/tasks/db-policy-apply.md +655 -0
  438. package/.grimoire/development/tasks/db-rls-audit.md +413 -0
  439. package/.grimoire/development/tasks/db-rollback.md +741 -0
  440. package/.grimoire/development/tasks/db-run-sql.md +615 -0
  441. package/.grimoire/development/tasks/db-schema-audit.md +1013 -0
  442. package/.grimoire/development/tasks/db-seed.md +392 -0
  443. package/.grimoire/development/tasks/db-smoke-test.md +353 -0
  444. package/.grimoire/development/tasks/db-snapshot.md +571 -0
  445. package/.grimoire/development/tasks/db-squad-integration.md +665 -0
  446. package/.grimoire/development/tasks/db-supabase-setup.md +714 -0
  447. package/.grimoire/development/tasks/db-verify-order.md +517 -0
  448. package/.grimoire/development/tasks/deprecate-component.md +958 -0
  449. package/.grimoire/development/tasks/dev-apply-qa-fixes.md +320 -0
  450. package/.grimoire/development/tasks/dev-backlog-debt.md +471 -0
  451. package/.grimoire/development/tasks/dev-develop-story.md +912 -0
  452. package/.grimoire/development/tasks/dev-improve-code-quality.md +874 -0
  453. package/.grimoire/development/tasks/dev-optimize-performance.md +1035 -0
  454. package/.grimoire/development/tasks/dev-suggest-refactoring.md +872 -0
  455. package/.grimoire/development/tasks/dev-validate-next-story.md +350 -0
  456. package/.grimoire/development/tasks/document-gotchas.md +479 -0
  457. package/.grimoire/development/tasks/document-project.md +554 -0
  458. package/.grimoire/development/tasks/environment-bootstrap.md +1391 -0
  459. package/.grimoire/development/tasks/execute-checklist.md +303 -0
  460. package/.grimoire/development/tasks/execute-epic-plan.md +887 -0
  461. package/.grimoire/development/tasks/export-design-tokens-dtcg.md +276 -0
  462. package/.grimoire/development/tasks/extend-pattern.md +271 -0
  463. package/.grimoire/development/tasks/extract-patterns.md +399 -0
  464. package/.grimoire/development/tasks/extract-tokens.md +469 -0
  465. package/.grimoire/development/tasks/facilitate-brainstorming-session.md +520 -0
  466. package/.grimoire/development/tasks/generate-ai-frontend-prompt.md +262 -0
  467. package/.grimoire/development/tasks/generate-documentation.md +286 -0
  468. package/.grimoire/development/tasks/generate-migration-strategy.md +524 -0
  469. package/.grimoire/development/tasks/generate-shock-report.md +503 -0
  470. package/.grimoire/development/tasks/github-devops-github-pr-automation.md +666 -0
  471. package/.grimoire/development/tasks/github-devops-pre-push-quality-gate.md +791 -0
  472. package/.grimoire/development/tasks/github-devops-repository-cleanup.md +376 -0
  473. package/.grimoire/development/tasks/github-devops-version-management.md +485 -0
  474. package/.grimoire/development/tasks/gotcha.md +138 -0
  475. package/.grimoire/development/tasks/gotchas.md +155 -0
  476. package/.grimoire/development/tasks/health-check.yaml +227 -0
  477. package/.grimoire/development/tasks/ids-governor.md +96 -0
  478. package/.grimoire/development/tasks/ids-health.md +91 -0
  479. package/.grimoire/development/tasks/ids-query.md +156 -0
  480. package/.grimoire/development/tasks/improve-self.md +824 -0
  481. package/.grimoire/development/tasks/index-docs.md +389 -0
  482. package/.grimoire/development/tasks/init-project-status.md +508 -0
  483. package/.grimoire/development/tasks/integrate-squad.md +316 -0
  484. package/.grimoire/development/tasks/kb-mode-interaction.md +285 -0
  485. package/.grimoire/development/tasks/learn-patterns.md +902 -0
  486. package/.grimoire/development/tasks/list-mcps.md +33 -0
  487. package/.grimoire/development/tasks/list-worktrees.md +344 -0
  488. package/.grimoire/development/tasks/mcp-workflow.md +438 -0
  489. package/.grimoire/development/tasks/merge-worktree.md +42 -0
  490. package/.grimoire/development/tasks/modify-agent.md +399 -0
  491. package/.grimoire/development/tasks/modify-task.md +442 -0
  492. package/.grimoire/development/tasks/modify-workflow.md +511 -0
  493. package/.grimoire/development/tasks/next.md +327 -0
  494. package/.grimoire/development/tasks/orchestrate-resume.md +60 -0
  495. package/.grimoire/development/tasks/orchestrate-status.md +64 -0
  496. package/.grimoire/development/tasks/orchestrate-stop.md +55 -0
  497. package/.grimoire/development/tasks/orchestrate.md +66 -0
  498. package/.grimoire/development/tasks/patterns.md +336 -0
  499. package/.grimoire/development/tasks/plan-create-context.md +812 -0
  500. package/.grimoire/development/tasks/plan-create-implementation.md +797 -0
  501. package/.grimoire/development/tasks/plan-execute-subtask.md +962 -0
  502. package/.grimoire/development/tasks/po-backlog-add.md +372 -0
  503. package/.grimoire/development/tasks/po-close-story.md +428 -0
  504. package/.grimoire/development/tasks/po-manage-story-backlog.md +525 -0
  505. package/.grimoire/development/tasks/po-pull-story-from-clickup.md +542 -0
  506. package/.grimoire/development/tasks/po-pull-story.md +318 -0
  507. package/.grimoire/development/tasks/po-stories-index.md +353 -0
  508. package/.grimoire/development/tasks/po-sync-story-to-clickup.md +459 -0
  509. package/.grimoire/development/tasks/po-sync-story.md +305 -0
  510. package/.grimoire/development/tasks/pr-automation.md +703 -0
  511. package/.grimoire/development/tasks/propose-modification.md +844 -0
  512. package/.grimoire/development/tasks/publish-npm.md +259 -0
  513. package/.grimoire/development/tasks/qa-after-creation.md +519 -0
  514. package/.grimoire/development/tasks/qa-backlog-add-followup.md +427 -0
  515. package/.grimoire/development/tasks/qa-browser-console-check.md +343 -0
  516. package/.grimoire/development/tasks/qa-create-fix-request.md +625 -0
  517. package/.grimoire/development/tasks/qa-evidence-requirements.md +314 -0
  518. package/.grimoire/development/tasks/qa-false-positive-detection.md +374 -0
  519. package/.grimoire/development/tasks/qa-fix-issues.md +686 -0
  520. package/.grimoire/development/tasks/qa-gate.md +375 -0
  521. package/.grimoire/development/tasks/qa-generate-tests.md +1176 -0
  522. package/.grimoire/development/tasks/qa-library-validation.md +497 -0
  523. package/.grimoire/development/tasks/qa-migration-validation.md +584 -0
  524. package/.grimoire/development/tasks/qa-nfr-assess.md +559 -0
  525. package/.grimoire/development/tasks/qa-review-build.md +1225 -0
  526. package/.grimoire/development/tasks/qa-review-proposal.md +1159 -0
  527. package/.grimoire/development/tasks/qa-review-story.md +684 -0
  528. package/.grimoire/development/tasks/qa-risk-profile.md +568 -0
  529. package/.grimoire/development/tasks/qa-run-tests.md +279 -0
  530. package/.grimoire/development/tasks/qa-security-checklist.md +552 -0
  531. package/.grimoire/development/tasks/qa-test-design.md +389 -0
  532. package/.grimoire/development/tasks/qa-trace-requirements.md +478 -0
  533. package/.grimoire/development/tasks/release-management.md +754 -0
  534. package/.grimoire/development/tasks/remove-mcp.md +35 -0
  535. package/.grimoire/development/tasks/remove-worktree.md +435 -0
  536. package/.grimoire/development/tasks/run-design-system-pipeline.md +642 -0
  537. package/.grimoire/development/tasks/run-workflow-engine.md +861 -0
  538. package/.grimoire/development/tasks/run-workflow.md +389 -0
  539. package/.grimoire/development/tasks/search-mcp.md +309 -0
  540. package/.grimoire/development/tasks/security-audit.md +556 -0
  541. package/.grimoire/development/tasks/security-scan.md +792 -0
  542. package/.grimoire/development/tasks/session-resume.md +193 -0
  543. package/.grimoire/development/tasks/setup-database.md +743 -0
  544. package/.grimoire/development/tasks/setup-design-system.md +464 -0
  545. package/.grimoire/development/tasks/setup-github.md +876 -0
  546. package/.grimoire/development/tasks/setup-llm-routing.md +231 -0
  547. package/.grimoire/development/tasks/setup-mcp-docker.md +628 -0
  548. package/.grimoire/development/tasks/setup-project-docs.md +442 -0
  549. package/.grimoire/development/tasks/shard-doc.md +539 -0
  550. package/.grimoire/development/tasks/sm-create-next-story.md +482 -0
  551. package/.grimoire/development/tasks/spec-assess-complexity.md +461 -0
  552. package/.grimoire/development/tasks/spec-critique.md +595 -0
  553. package/.grimoire/development/tasks/spec-gather-requirements.md +545 -0
  554. package/.grimoire/development/tasks/spec-research-dependencies.md +446 -0
  555. package/.grimoire/development/tasks/spec-write-spec.md +531 -0
  556. package/.grimoire/development/tasks/squad-creator-analyze.md +318 -0
  557. package/.grimoire/development/tasks/squad-creator-create.md +314 -0
  558. package/.grimoire/development/tasks/squad-creator-design.md +335 -0
  559. package/.grimoire/development/tasks/squad-creator-download.md +169 -0
  560. package/.grimoire/development/tasks/squad-creator-extend.md +413 -0
  561. package/.grimoire/development/tasks/squad-creator-list.md +226 -0
  562. package/.grimoire/development/tasks/squad-creator-migrate.md +245 -0
  563. package/.grimoire/development/tasks/squad-creator-publish.md +231 -0
  564. package/.grimoire/development/tasks/squad-creator-sync-grimoire.md +317 -0
  565. package/.grimoire/development/tasks/squad-creator-sync-ide-command.md +403 -0
  566. package/.grimoire/development/tasks/squad-creator-validate.md +160 -0
  567. package/.grimoire/development/tasks/story-checkpoint.md +361 -0
  568. package/.grimoire/development/tasks/sync-documentation.md +866 -0
  569. package/.grimoire/development/tasks/tailwind-upgrade.md +296 -0
  570. package/.grimoire/development/tasks/test-as-user.md +623 -0
  571. package/.grimoire/development/tasks/test-validation-task.md +172 -0
  572. package/.grimoire/development/tasks/undo-last.md +348 -0
  573. package/.grimoire/development/tasks/update-grimoire.md +153 -0
  574. package/.grimoire/development/tasks/update-manifest.md +411 -0
  575. package/.grimoire/development/tasks/update-source-tree.md +138 -0
  576. package/.grimoire/development/tasks/ux-create-wireframe.md +619 -0
  577. package/.grimoire/development/tasks/ux-ds-scan-artifact.md +674 -0
  578. package/.grimoire/development/tasks/ux-user-research.md +561 -0
  579. package/.grimoire/development/tasks/validate-agents.md +117 -0
  580. package/.grimoire/development/tasks/validate-next-story.md +456 -0
  581. package/.grimoire/development/tasks/validate-tech-preset.md +187 -0
  582. package/.grimoire/development/tasks/validate-workflow.md +323 -0
  583. package/.grimoire/development/tasks/verify-subtask.md +237 -0
  584. package/.grimoire/development/tasks/waves.md +206 -0
  585. package/.grimoire/development/tasks/yolo-toggle.md +115 -0
  586. package/.grimoire/development/templates/grimoire-doc-template.md +496 -0
  587. package/.grimoire/development/templates/research-prompt-tmpl.md +486 -0
  588. package/.grimoire/development/templates/service-template/README.md.hbs +159 -0
  589. package/.grimoire/development/templates/service-template/__tests__/index.test.ts.hbs +238 -0
  590. package/.grimoire/development/templates/service-template/client.ts.hbs +404 -0
  591. package/.grimoire/development/templates/service-template/errors.ts.hbs +183 -0
  592. package/.grimoire/development/templates/service-template/index.ts.hbs +121 -0
  593. package/.grimoire/development/templates/service-template/jest.config.js +89 -0
  594. package/.grimoire/development/templates/service-template/package.json.hbs +88 -0
  595. package/.grimoire/development/templates/service-template/tsconfig.json +45 -0
  596. package/.grimoire/development/templates/service-template/types.ts.hbs +146 -0
  597. package/.grimoire/development/templates/squad/agent-template.md +69 -0
  598. package/.grimoire/development/templates/squad/checklist-template.md +82 -0
  599. package/.grimoire/development/templates/squad/data-template.yaml +105 -0
  600. package/.grimoire/development/templates/squad/script-template.js +179 -0
  601. package/.grimoire/development/templates/squad/task-template.md +125 -0
  602. package/.grimoire/development/templates/squad/template-template.md +98 -0
  603. package/.grimoire/development/templates/squad/tool-template.js +103 -0
  604. package/.grimoire/development/templates/squad/workflow-template.yaml +108 -0
  605. package/.grimoire/development/templates/squad-template/LICENSE +21 -0
  606. package/.grimoire/development/templates/squad-template/README.md +37 -0
  607. package/.grimoire/development/templates/squad-template/agents/example-agent.yaml +36 -0
  608. package/.grimoire/development/templates/squad-template/package.json +20 -0
  609. package/.grimoire/development/templates/squad-template/squad.yaml +26 -0
  610. package/.grimoire/development/templates/squad-template/tasks/example-task.yaml +46 -0
  611. package/.grimoire/development/templates/squad-template/templates/example-template.md +24 -0
  612. package/.grimoire/development/templates/squad-template/tests/example-agent.test.js +54 -0
  613. package/.grimoire/development/templates/squad-template/workflows/example-workflow.yaml +54 -0
  614. package/.grimoire/development/templates/subagent-step-prompt.md +122 -0
  615. package/.grimoire/development/workflows/README.md +82 -0
  616. package/.grimoire/development/workflows/auto-worktree.yaml +423 -0
  617. package/.grimoire/development/workflows/brownfield-discovery.yaml +933 -0
  618. package/.grimoire/development/workflows/brownfield-fullstack.yaml +369 -0
  619. package/.grimoire/development/workflows/brownfield-service.yaml +246 -0
  620. package/.grimoire/development/workflows/brownfield-ui.yaml +260 -0
  621. package/.grimoire/development/workflows/design-system-build-quality.yaml +228 -0
  622. package/.grimoire/development/workflows/development-cycle.yaml +427 -0
  623. package/.grimoire/development/workflows/epic-orchestration.yaml +328 -0
  624. package/.grimoire/development/workflows/greenfield-fullstack.yaml +386 -0
  625. package/.grimoire/development/workflows/greenfield-service.yaml +278 -0
  626. package/.grimoire/development/workflows/greenfield-ui.yaml +284 -0
  627. package/.grimoire/development/workflows/qa-loop.yaml +444 -0
  628. package/.grimoire/development/workflows/spec-pipeline.yaml +577 -0
  629. package/.grimoire/development/workflows/story-development-cycle.yaml +285 -0
  630. package/.grimoire/docs/standards/AGENT-PERSONALIZATION-STANDARD-V1.md +574 -0
  631. package/.grimoire/docs/standards/EXECUTOR-DECISION-TREE.md +698 -0
  632. package/.grimoire/docs/standards/OPEN-SOURCE-VS-SERVICE-DIFFERENCES.md +513 -0
  633. package/.grimoire/docs/standards/QUALITY-GATES-SPECIFICATION.md +558 -0
  634. package/.grimoire/docs/standards/STANDARDS-INDEX.md +212 -0
  635. package/.grimoire/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +551 -0
  636. package/.grimoire/docs/standards/TASK-FORMAT-SPECIFICATION-V1.md +1415 -0
  637. package/.grimoire/docs/standards/grimoire-COLOR-PALETTE-QUICK-REFERENCE.md +186 -0
  638. package/.grimoire/docs/standards/grimoire-COLOR-PALETTE-V2.1.md +354 -0
  639. package/.grimoire/docs/standards/grimoire-LIVRO-DE-OURO-V2.1-COMPLETE.md +839 -0
  640. package/.grimoire/docs/standards/grimoire-LIVRO-DE-OURO-V2.2-SUMMARY.md +1341 -0
  641. package/.grimoire/elicitation/agent-elicitation.js +272 -0
  642. package/.grimoire/elicitation/task-elicitation.js +281 -0
  643. package/.grimoire/elicitation/workflow-elicitation.js +315 -0
  644. package/.grimoire/framework-config.yaml +152 -0
  645. package/.grimoire/hooks/gemini/after-tool.js +78 -0
  646. package/.grimoire/hooks/gemini/before-agent.js +80 -0
  647. package/.grimoire/hooks/gemini/before-tool.js +115 -0
  648. package/.grimoire/hooks/gemini/rewind-handler.js +69 -0
  649. package/.grimoire/hooks/gemini/session-end.js +91 -0
  650. package/.grimoire/hooks/gemini/session-start.js +91 -0
  651. package/.grimoire/hooks/ids-post-commit.js +118 -0
  652. package/.grimoire/hooks/ids-pre-push.js +125 -0
  653. package/.grimoire/hooks/unified/README.md +309 -0
  654. package/.grimoire/hooks/unified/hook-interface.js +161 -0
  655. package/.grimoire/hooks/unified/hook-registry.js +143 -0
  656. package/.grimoire/hooks/unified/index.js +36 -0
  657. package/.grimoire/hooks/unified/runners/precompact-runner.js +98 -0
  658. package/.grimoire/index.esm.js +17 -0
  659. package/.grimoire/index.js +17 -0
  660. package/.grimoire/infrastructure/README.md +128 -0
  661. package/.grimoire/infrastructure/contracts/compatibility/grimoire-4.0.4.yaml +46 -0
  662. package/.grimoire/infrastructure/index.js +200 -0
  663. package/.grimoire/infrastructure/integrations/ai-providers/README.md +103 -0
  664. package/.grimoire/infrastructure/integrations/ai-providers/ai-provider-factory.js +286 -0
  665. package/.grimoire/infrastructure/integrations/ai-providers/ai-provider.js +145 -0
  666. package/.grimoire/infrastructure/integrations/ai-providers/claude-provider.js +170 -0
  667. package/.grimoire/infrastructure/integrations/ai-providers/gemini-provider.js +365 -0
  668. package/.grimoire/infrastructure/integrations/ai-providers/index.js +45 -0
  669. package/.grimoire/infrastructure/integrations/gemini-extensions/cloudrun-adapter.js +129 -0
  670. package/.grimoire/infrastructure/integrations/gemini-extensions/index.js +41 -0
  671. package/.grimoire/infrastructure/integrations/gemini-extensions/policy-sync.js +74 -0
  672. package/.grimoire/infrastructure/integrations/gemini-extensions/security-adapter.js +159 -0
  673. package/.grimoire/infrastructure/integrations/gemini-extensions/supabase-adapter.js +88 -0
  674. package/.grimoire/infrastructure/integrations/gemini-extensions/workspace-adapter.js +100 -0
  675. package/.grimoire/infrastructure/integrations/pm-adapters/README.md +60 -0
  676. package/.grimoire/infrastructure/integrations/pm-adapters/clickup-adapter.js +345 -0
  677. package/.grimoire/infrastructure/integrations/pm-adapters/github-adapter.js +393 -0
  678. package/.grimoire/infrastructure/integrations/pm-adapters/jira-adapter.js +449 -0
  679. package/.grimoire/infrastructure/integrations/pm-adapters/local-adapter.js +176 -0
  680. package/.grimoire/infrastructure/schemas/agent-v3-schema.json +160 -0
  681. package/.grimoire/infrastructure/schemas/build-state.schema.json +158 -0
  682. package/.grimoire/infrastructure/schemas/task-v3-schema.json +152 -0
  683. package/.grimoire/infrastructure/scripts/approach-manager.js +1005 -0
  684. package/.grimoire/infrastructure/scripts/approval-workflow.js +644 -0
  685. package/.grimoire/infrastructure/scripts/asset-inventory.js +622 -0
  686. package/.grimoire/infrastructure/scripts/atomic-layer-classifier.js +309 -0
  687. package/.grimoire/infrastructure/scripts/backup-manager.js +607 -0
  688. package/.grimoire/infrastructure/scripts/batch-creator.js +609 -0
  689. package/.grimoire/infrastructure/scripts/branch-manager.js +391 -0
  690. package/.grimoire/infrastructure/scripts/capability-analyzer.js +535 -0
  691. package/.grimoire/infrastructure/scripts/changelog-generator.js +554 -0
  692. package/.grimoire/infrastructure/scripts/cicd-discovery.js +1269 -0
  693. package/.grimoire/infrastructure/scripts/clickup-helpers.js +227 -0
  694. package/.grimoire/infrastructure/scripts/code-quality-improver.js +1312 -0
  695. package/.grimoire/infrastructure/scripts/codebase-mapper.js +1288 -0
  696. package/.grimoire/infrastructure/scripts/codex-skills-sync/index.js +184 -0
  697. package/.grimoire/infrastructure/scripts/codex-skills-sync/validate.js +174 -0
  698. package/.grimoire/infrastructure/scripts/commit-message-generator.js +850 -0
  699. package/.grimoire/infrastructure/scripts/component-generator.js +738 -0
  700. package/.grimoire/infrastructure/scripts/component-metadata.js +628 -0
  701. package/.grimoire/infrastructure/scripts/component-search.js +278 -0
  702. package/.grimoire/infrastructure/scripts/config-cache.js +322 -0
  703. package/.grimoire/infrastructure/scripts/config-loader.js +351 -0
  704. package/.grimoire/infrastructure/scripts/conflict-resolver.js +675 -0
  705. package/.grimoire/infrastructure/scripts/coverage-analyzer.js +882 -0
  706. package/.grimoire/infrastructure/scripts/dashboard-status-writer.js +310 -0
  707. package/.grimoire/infrastructure/scripts/dependency-analyzer.js +639 -0
  708. package/.grimoire/infrastructure/scripts/dependency-impact-analyzer.js +704 -0
  709. package/.grimoire/infrastructure/scripts/diff-generator.js +129 -0
  710. package/.grimoire/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +502 -0
  711. package/.grimoire/infrastructure/scripts/documentation-integrity/config-generator.js +369 -0
  712. package/.grimoire/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +309 -0
  713. package/.grimoire/infrastructure/scripts/documentation-integrity/doc-generator.js +331 -0
  714. package/.grimoire/infrastructure/scripts/documentation-integrity/gitignore-generator.js +314 -0
  715. package/.grimoire/infrastructure/scripts/documentation-integrity/index.js +75 -0
  716. package/.grimoire/infrastructure/scripts/documentation-integrity/mode-detector.js +391 -0
  717. package/.grimoire/infrastructure/scripts/documentation-synchronizer.js +1432 -0
  718. package/.grimoire/infrastructure/scripts/framework-analyzer.js +763 -0
  719. package/.grimoire/infrastructure/scripts/git-config-detector.js +293 -0
  720. package/.grimoire/infrastructure/scripts/git-hooks/post-commit.js +75 -0
  721. package/.grimoire/infrastructure/scripts/git-wrapper.js +444 -0
  722. package/.grimoire/infrastructure/scripts/gotchas-documenter.js +1296 -0
  723. package/.grimoire/infrastructure/scripts/grimoire-validator.js +295 -0
  724. package/.grimoire/infrastructure/scripts/ide-sync/README.md +220 -0
  725. package/.grimoire/infrastructure/scripts/ide-sync/agent-parser.js +295 -0
  726. package/.grimoire/infrastructure/scripts/ide-sync/gemini-commands.js +207 -0
  727. package/.grimoire/infrastructure/scripts/ide-sync/index.js +540 -0
  728. package/.grimoire/infrastructure/scripts/ide-sync/redirect-generator.js +179 -0
  729. package/.grimoire/infrastructure/scripts/ide-sync/transformers/antigravity.js +107 -0
  730. package/.grimoire/infrastructure/scripts/ide-sync/transformers/claude-code.js +86 -0
  731. package/.grimoire/infrastructure/scripts/ide-sync/transformers/cursor.js +96 -0
  732. package/.grimoire/infrastructure/scripts/ide-sync/validator.js +273 -0
  733. package/.grimoire/infrastructure/scripts/improvement-engine.js +758 -0
  734. package/.grimoire/infrastructure/scripts/improvement-validator.js +710 -0
  735. package/.grimoire/infrastructure/scripts/llm-routing/install-llm-routing.js +282 -0
  736. package/.grimoire/infrastructure/scripts/llm-routing/templates/claude-free-tracked.cmd +129 -0
  737. package/.grimoire/infrastructure/scripts/llm-routing/templates/claude-free-tracked.sh +108 -0
  738. package/.grimoire/infrastructure/scripts/llm-routing/templates/claude-free.cmd +80 -0
  739. package/.grimoire/infrastructure/scripts/llm-routing/templates/claude-free.sh +62 -0
  740. package/.grimoire/infrastructure/scripts/llm-routing/templates/claude-max.cmd +26 -0
  741. package/.grimoire/infrastructure/scripts/llm-routing/templates/claude-max.sh +18 -0
  742. package/.grimoire/infrastructure/scripts/llm-routing/templates/deepseek-proxy.cmd +73 -0
  743. package/.grimoire/infrastructure/scripts/llm-routing/templates/deepseek-proxy.sh +65 -0
  744. package/.grimoire/infrastructure/scripts/llm-routing/templates/deepseek-usage.cmd +53 -0
  745. package/.grimoire/infrastructure/scripts/llm-routing/templates/deepseek-usage.sh +16 -0
  746. package/.grimoire/infrastructure/scripts/llm-routing/usage-tracker/index.js +551 -0
  747. package/.grimoire/infrastructure/scripts/migrate-agent.js +528 -0
  748. package/.grimoire/infrastructure/scripts/modification-risk-assessment.js +970 -0
  749. package/.grimoire/infrastructure/scripts/modification-validator.js +555 -0
  750. package/.grimoire/infrastructure/scripts/output-formatter.js +298 -0
  751. package/.grimoire/infrastructure/scripts/path-analyzer.js +476 -0
  752. package/.grimoire/infrastructure/scripts/pattern-extractor.js +1563 -0
  753. package/.grimoire/infrastructure/scripts/performance-analyzer.js +758 -0
  754. package/.grimoire/infrastructure/scripts/performance-and-error-resolver.js +258 -0
  755. package/.grimoire/infrastructure/scripts/performance-optimizer.js +1902 -0
  756. package/.grimoire/infrastructure/scripts/performance-tracker.js +454 -0
  757. package/.grimoire/infrastructure/scripts/plan-tracker.js +922 -0
  758. package/.grimoire/infrastructure/scripts/pm-adapter-factory.js +182 -0
  759. package/.grimoire/infrastructure/scripts/pm-adapter.js +134 -0
  760. package/.grimoire/infrastructure/scripts/pr-review-ai.js +1062 -0
  761. package/.grimoire/infrastructure/scripts/project-status-loader.js +850 -0
  762. package/.grimoire/infrastructure/scripts/qa-loop-orchestrator.js +1264 -0
  763. package/.grimoire/infrastructure/scripts/qa-report-generator.js +1154 -0
  764. package/.grimoire/infrastructure/scripts/recovery-tracker.js +965 -0
  765. package/.grimoire/infrastructure/scripts/refactoring-suggester.js +1139 -0
  766. package/.grimoire/infrastructure/scripts/repository-detector.js +66 -0
  767. package/.grimoire/infrastructure/scripts/rollback-manager.js +734 -0
  768. package/.grimoire/infrastructure/scripts/sandbox-tester.js +618 -0
  769. package/.grimoire/infrastructure/scripts/security-checker.js +359 -0
  770. package/.grimoire/infrastructure/scripts/spot-check-validator.js +149 -0
  771. package/.grimoire/infrastructure/scripts/status-mapper.js +116 -0
  772. package/.grimoire/infrastructure/scripts/story-worktree-hooks.js +426 -0
  773. package/.grimoire/infrastructure/scripts/stuck-detector.js +1251 -0
  774. package/.grimoire/infrastructure/scripts/subtask-verifier.js +793 -0
  775. package/.grimoire/infrastructure/scripts/template-engine.js +240 -0
  776. package/.grimoire/infrastructure/scripts/template-validator.js +279 -0
  777. package/.grimoire/infrastructure/scripts/test-discovery.js +1259 -0
  778. package/.grimoire/infrastructure/scripts/test-generator.js +845 -0
  779. package/.grimoire/infrastructure/scripts/test-quality-assessment.js +1082 -0
  780. package/.grimoire/infrastructure/scripts/test-utilities-fast.js +126 -0
  781. package/.grimoire/infrastructure/scripts/test-utilities.js +201 -0
  782. package/.grimoire/infrastructure/scripts/tool-resolver.js +362 -0
  783. package/.grimoire/infrastructure/scripts/transaction-manager.js +590 -0
  784. package/.grimoire/infrastructure/scripts/usage-analytics.js +636 -0
  785. package/.grimoire/infrastructure/scripts/validate-agents.js +527 -0
  786. package/.grimoire/infrastructure/scripts/validate-claude-integration.js +103 -0
  787. package/.grimoire/infrastructure/scripts/validate-codex-integration.js +143 -0
  788. package/.grimoire/infrastructure/scripts/validate-gemini-integration.js +153 -0
  789. package/.grimoire/infrastructure/scripts/validate-output-pattern.js +213 -0
  790. package/.grimoire/infrastructure/scripts/validate-parity.js +357 -0
  791. package/.grimoire/infrastructure/scripts/validate-paths.js +144 -0
  792. package/.grimoire/infrastructure/scripts/validate-user-profile.js +251 -0
  793. package/.grimoire/infrastructure/scripts/visual-impact-generator.js +1056 -0
  794. package/.grimoire/infrastructure/scripts/worktree-manager.js +704 -0
  795. package/.grimoire/infrastructure/scripts/yaml-validator.js +397 -0
  796. package/.grimoire/infrastructure/templates/coderabbit.yaml.template +280 -0
  797. package/.grimoire/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +177 -0
  798. package/.grimoire/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +169 -0
  799. package/.grimoire/infrastructure/templates/github-workflows/README.md +110 -0
  800. package/.grimoire/infrastructure/templates/github-workflows/ci.yml.template +170 -0
  801. package/.grimoire/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -0
  802. package/.grimoire/infrastructure/templates/github-workflows/release.yml.template +197 -0
  803. package/.grimoire/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +20 -0
  804. package/.grimoire/infrastructure/templates/gitignore/gitignore-grimoire-base.tmpl +65 -0
  805. package/.grimoire/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -0
  806. package/.grimoire/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -0
  807. package/.grimoire/infrastructure/templates/grimoire-sync.yaml.template +183 -0
  808. package/.grimoire/infrastructure/templates/project-docs/coding-standards-tmpl.md +347 -0
  809. package/.grimoire/infrastructure/templates/project-docs/source-tree-tmpl.md +179 -0
  810. package/.grimoire/infrastructure/templates/project-docs/tech-stack-tmpl.md +269 -0
  811. package/.grimoire/infrastructure/tests/project-status-loader.test.js +569 -0
  812. package/.grimoire/infrastructure/tests/regression-suite-v2.md +622 -0
  813. package/.grimoire/infrastructure/tests/validate-module.js +98 -0
  814. package/.grimoire/infrastructure/tests/worktree-manager.test.js +620 -0
  815. package/.grimoire/infrastructure/tools/README.md +224 -0
  816. package/.grimoire/infrastructure/tools/cli/github-cli.yaml +200 -0
  817. package/.grimoire/infrastructure/tools/cli/llm-routing.yaml +128 -0
  818. package/.grimoire/infrastructure/tools/cli/railway-cli.yaml +260 -0
  819. package/.grimoire/infrastructure/tools/cli/supabase-cli.yaml +224 -0
  820. package/.grimoire/infrastructure/tools/local/ffmpeg.yaml +261 -0
  821. package/.grimoire/infrastructure/tools/mcp/21st-dev-magic.yaml +127 -0
  822. package/.grimoire/infrastructure/tools/mcp/browser.yaml +103 -0
  823. package/.grimoire/infrastructure/tools/mcp/clickup.yaml +535 -0
  824. package/.grimoire/infrastructure/tools/mcp/context7.yaml +78 -0
  825. package/.grimoire/infrastructure/tools/mcp/desktop-commander.yaml +180 -0
  826. package/.grimoire/infrastructure/tools/mcp/exa.yaml +103 -0
  827. package/.grimoire/infrastructure/tools/mcp/google-workspace.yaml +930 -0
  828. package/.grimoire/infrastructure/tools/mcp/n8n.yaml +551 -0
  829. package/.grimoire/infrastructure/tools/mcp/supabase.yaml +808 -0
  830. package/.grimoire/install-manifest.yaml +4058 -0
  831. package/.grimoire/local-config.yaml.template +73 -0
  832. package/.grimoire/manifests/schema/manifest-schema.json +191 -0
  833. package/.grimoire/monitor/hooks/lib/__init__.py +2 -0
  834. package/.grimoire/monitor/hooks/lib/enrich.py +59 -0
  835. package/.grimoire/monitor/hooks/lib/send_event.py +48 -0
  836. package/.grimoire/monitor/hooks/notification.py +30 -0
  837. package/.grimoire/monitor/hooks/post_tool_use.py +46 -0
  838. package/.grimoire/monitor/hooks/pre_compact.py +30 -0
  839. package/.grimoire/monitor/hooks/pre_tool_use.py +41 -0
  840. package/.grimoire/monitor/hooks/stop.py +30 -0
  841. package/.grimoire/monitor/hooks/subagent_stop.py +30 -0
  842. package/.grimoire/monitor/hooks/user_prompt_submit.py +39 -0
  843. package/.grimoire/package.json +104 -0
  844. package/.grimoire/presets/README.md +359 -0
  845. package/.grimoire/product/README.md +57 -0
  846. package/.grimoire/product/checklists/accessibility-wcag-checklist.md +80 -0
  847. package/.grimoire/product/checklists/architect-checklist.md +444 -0
  848. package/.grimoire/product/checklists/change-checklist.md +183 -0
  849. package/.grimoire/product/checklists/component-quality-checklist.md +74 -0
  850. package/.grimoire/product/checklists/database-design-checklist.md +119 -0
  851. package/.grimoire/product/checklists/dba-predeploy-checklist.md +97 -0
  852. package/.grimoire/product/checklists/dba-rollback-checklist.md +99 -0
  853. package/.grimoire/product/checklists/migration-readiness-checklist.md +75 -0
  854. package/.grimoire/product/checklists/pattern-audit-checklist.md +88 -0
  855. package/.grimoire/product/checklists/pm-checklist.md +376 -0
  856. package/.grimoire/product/checklists/po-master-checklist.md +442 -0
  857. package/.grimoire/product/checklists/pre-push-checklist.md +108 -0
  858. package/.grimoire/product/checklists/release-checklist.md +122 -0
  859. package/.grimoire/product/checklists/self-critique-checklist.md +387 -0
  860. package/.grimoire/product/checklists/story-dod-checklist.md +102 -0
  861. package/.grimoire/product/checklists/story-draft-checklist.md +216 -0
  862. package/.grimoire/product/data/atomic-design-principles.md +108 -0
  863. package/.grimoire/product/data/brainstorming-techniques.md +37 -0
  864. package/.grimoire/product/data/consolidation-algorithms.md +142 -0
  865. package/.grimoire/product/data/database-best-practices.md +182 -0
  866. package/.grimoire/product/data/design-token-best-practices.md +107 -0
  867. package/.grimoire/product/data/elicitation-methods.md +135 -0
  868. package/.grimoire/product/data/integration-patterns.md +207 -0
  869. package/.grimoire/product/data/migration-safety-guide.md +329 -0
  870. package/.grimoire/product/data/mode-selection-best-practices.md +471 -0
  871. package/.grimoire/product/data/postgres-tuning-guide.md +300 -0
  872. package/.grimoire/product/data/rls-security-patterns.md +333 -0
  873. package/.grimoire/product/data/roi-calculation-guide.md +142 -0
  874. package/.grimoire/product/data/supabase-patterns.md +330 -0
  875. package/.grimoire/product/data/test-levels-framework.md +149 -0
  876. package/.grimoire/product/data/test-priorities-matrix.md +175 -0
  877. package/.grimoire/product/data/wcag-compliance-guide.md +267 -0
  878. package/.grimoire/product/templates/activation-instructions-inline-greeting.yaml +64 -0
  879. package/.grimoire/product/templates/activation-instructions-template.md +260 -0
  880. package/.grimoire/product/templates/adr.hbs +126 -0
  881. package/.grimoire/product/templates/agent-template.yaml +122 -0
  882. package/.grimoire/product/templates/architecture-tmpl.yaml +651 -0
  883. package/.grimoire/product/templates/brainstorming-output-tmpl.yaml +156 -0
  884. package/.grimoire/product/templates/brownfield-architecture-tmpl.yaml +476 -0
  885. package/.grimoire/product/templates/brownfield-prd-tmpl.yaml +280 -0
  886. package/.grimoire/product/templates/brownfield-risk-report-tmpl.yaml +278 -0
  887. package/.grimoire/product/templates/changelog-template.md +134 -0
  888. package/.grimoire/product/templates/command-rationalization-matrix.md +154 -0
  889. package/.grimoire/product/templates/competitor-analysis-tmpl.yaml +293 -0
  890. package/.grimoire/product/templates/component-react-tmpl.tsx +98 -0
  891. package/.grimoire/product/templates/current-approach-tmpl.md +56 -0
  892. package/.grimoire/product/templates/dbdr.hbs +242 -0
  893. package/.grimoire/product/templates/design-story-tmpl.yaml +588 -0
  894. package/.grimoire/product/templates/ds-artifact-analysis.md +70 -0
  895. package/.grimoire/product/templates/engine/elicitation.js +298 -0
  896. package/.grimoire/product/templates/engine/index.js +310 -0
  897. package/.grimoire/product/templates/engine/loader.js +232 -0
  898. package/.grimoire/product/templates/engine/renderer.js +343 -0
  899. package/.grimoire/product/templates/engine/schemas/adr.schema.json +102 -0
  900. package/.grimoire/product/templates/engine/schemas/dbdr.schema.json +205 -0
  901. package/.grimoire/product/templates/engine/schemas/epic.schema.json +175 -0
  902. package/.grimoire/product/templates/engine/schemas/pmdr.schema.json +175 -0
  903. package/.grimoire/product/templates/engine/schemas/prd-v2.schema.json +300 -0
  904. package/.grimoire/product/templates/engine/schemas/prd.schema.json +152 -0
  905. package/.grimoire/product/templates/engine/schemas/story.schema.json +222 -0
  906. package/.grimoire/product/templates/engine/schemas/task.schema.json +154 -0
  907. package/.grimoire/product/templates/engine/validator.js +295 -0
  908. package/.grimoire/product/templates/epic.hbs +213 -0
  909. package/.grimoire/product/templates/eslintrc-security.json +32 -0
  910. package/.grimoire/product/templates/front-end-architecture-tmpl.yaml +206 -0
  911. package/.grimoire/product/templates/front-end-spec-tmpl.yaml +349 -0
  912. package/.grimoire/product/templates/fullstack-architecture-tmpl.yaml +805 -0
  913. package/.grimoire/product/templates/gemini/settings.json +81 -0
  914. package/.grimoire/product/templates/github-actions-cd.yml +213 -0
  915. package/.grimoire/product/templates/github-actions-ci.yml +173 -0
  916. package/.grimoire/product/templates/github-pr-template.md +68 -0
  917. package/.grimoire/product/templates/gordon-mcp.yaml +141 -0
  918. package/.grimoire/product/templates/grimoire-ai-config.yaml +107 -0
  919. package/.grimoire/product/templates/ide-rules/antigravity-rules.md +117 -0
  920. package/.grimoire/product/templates/ide-rules/claude-rules.md +233 -0
  921. package/.grimoire/product/templates/ide-rules/codex-rules.md +67 -0
  922. package/.grimoire/product/templates/ide-rules/copilot-rules.md +94 -0
  923. package/.grimoire/product/templates/ide-rules/cursor-rules.md +116 -0
  924. package/.grimoire/product/templates/ide-rules/gemini-rules.md +89 -0
  925. package/.grimoire/product/templates/index-strategy-tmpl.yaml +53 -0
  926. package/.grimoire/product/templates/market-research-tmpl.yaml +252 -0
  927. package/.grimoire/product/templates/mcp-workflow.js +273 -0
  928. package/.grimoire/product/templates/migration-plan-tmpl.yaml +1022 -0
  929. package/.grimoire/product/templates/migration-strategy-tmpl.md +524 -0
  930. package/.grimoire/product/templates/personalized-agent-template.md +260 -0
  931. package/.grimoire/product/templates/personalized-checklist-template.md +341 -0
  932. package/.grimoire/product/templates/personalized-task-template-v2.md +907 -0
  933. package/.grimoire/product/templates/personalized-task-template.md +345 -0
  934. package/.grimoire/product/templates/personalized-template-file.yaml +323 -0
  935. package/.grimoire/product/templates/personalized-workflow-template.yaml +461 -0
  936. package/.grimoire/product/templates/pmdr.hbs +187 -0
  937. package/.grimoire/product/templates/prd-tmpl.yaml +202 -0
  938. package/.grimoire/product/templates/prd-v2.0.hbs +217 -0
  939. package/.grimoire/product/templates/prd.hbs +202 -0
  940. package/.grimoire/product/templates/project-brief-tmpl.yaml +221 -0
  941. package/.grimoire/product/templates/qa-gate-tmpl.yaml +240 -0
  942. package/.grimoire/product/templates/qa-report-tmpl.md +235 -0
  943. package/.grimoire/product/templates/rls-policies-tmpl.yaml +1203 -0
  944. package/.grimoire/product/templates/schema-design-tmpl.yaml +428 -0
  945. package/.grimoire/product/templates/shock-report-tmpl.html +502 -0
  946. package/.grimoire/product/templates/spec-tmpl.md +235 -0
  947. package/.grimoire/product/templates/state-persistence-tmpl.yaml +219 -0
  948. package/.grimoire/product/templates/statusline/statusline-script.js +190 -0
  949. package/.grimoire/product/templates/statusline/track-agent.sh +70 -0
  950. package/.grimoire/product/templates/story-tmpl.yaml +369 -0
  951. package/.grimoire/product/templates/story.hbs +264 -0
  952. package/.grimoire/product/templates/task-execution-report.md +496 -0
  953. package/.grimoire/product/templates/task-template.md +123 -0
  954. package/.grimoire/product/templates/task.hbs +171 -0
  955. package/.grimoire/product/templates/tmpl-comment-on-examples.sql +158 -0
  956. package/.grimoire/product/templates/tmpl-migration-script.sql +91 -0
  957. package/.grimoire/product/templates/tmpl-rls-granular-policies.sql +104 -0
  958. package/.grimoire/product/templates/tmpl-rls-kiss-policy.sql +10 -0
  959. package/.grimoire/product/templates/tmpl-rls-roles.sql +135 -0
  960. package/.grimoire/product/templates/tmpl-rls-simple.sql +77 -0
  961. package/.grimoire/product/templates/tmpl-rls-tenant.sql +152 -0
  962. package/.grimoire/product/templates/tmpl-rollback-script.sql +77 -0
  963. package/.grimoire/product/templates/tmpl-seed-data.sql +140 -0
  964. package/.grimoire/product/templates/tmpl-smoke-test.sql +16 -0
  965. package/.grimoire/product/templates/tmpl-staging-copy-merge.sql +139 -0
  966. package/.grimoire/product/templates/tmpl-stored-proc.sql +140 -0
  967. package/.grimoire/product/templates/tmpl-trigger.sql +152 -0
  968. package/.grimoire/product/templates/tmpl-view-materialized.sql +133 -0
  969. package/.grimoire/product/templates/tmpl-view.sql +177 -0
  970. package/.grimoire/product/templates/token-exports-css-tmpl.css +240 -0
  971. package/.grimoire/product/templates/token-exports-tailwind-tmpl.js +395 -0
  972. package/.grimoire/product/templates/tokens-schema-tmpl.yaml +305 -0
  973. package/.grimoire/product/templates/workflow-template.yaml +152 -0
  974. package/.grimoire/project-config.yaml +166 -0
  975. package/.grimoire/quality/metrics-collector.js +601 -0
  976. package/.grimoire/quality/metrics-hook.js +261 -0
  977. package/.grimoire/quality/schemas/quality-metrics.schema.json +234 -0
  978. package/.grimoire/quality/seed-metrics.js +336 -0
  979. package/.grimoire/schemas/README.md +405 -0
  980. package/.grimoire/schemas/agent-v3-schema.json +395 -0
  981. package/.grimoire/schemas/squad-design-schema.json +300 -0
  982. package/.grimoire/schemas/squad-schema.json +187 -0
  983. package/.grimoire/schemas/task-v3-schema.json +354 -0
  984. package/.grimoire/schemas/validate-v3-schema.js +431 -0
  985. package/.grimoire/scripts/README.md +124 -0
  986. package/.grimoire/scripts/batch-migrate-phase1.ps1 +37 -0
  987. package/.grimoire/scripts/batch-migrate-phase2.ps1 +89 -0
  988. package/.grimoire/scripts/batch-migrate-phase3.ps1 +46 -0
  989. package/.grimoire/scripts/command-execution-hook.js +202 -0
  990. package/.grimoire/scripts/diagnostics/diagnose-installation.js +276 -0
  991. package/.grimoire/scripts/diagnostics/diagnose-npx-issue.ps1 +98 -0
  992. package/.grimoire/scripts/diagnostics/health-dashboard/README.md +123 -0
  993. package/.grimoire/scripts/diagnostics/health-dashboard/index.html +14 -0
  994. package/.grimoire/scripts/diagnostics/health-dashboard/package-lock.json +5262 -0
  995. package/.grimoire/scripts/diagnostics/health-dashboard/package.json +25 -0
  996. package/.grimoire/scripts/diagnostics/health-dashboard/public/favicon.svg +10 -0
  997. package/.grimoire/scripts/diagnostics/health-dashboard/src/App.jsx +22 -0
  998. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/AutoFixLog.css +122 -0
  999. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/AutoFixLog.jsx +72 -0
  1000. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/DomainCard.css +121 -0
  1001. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/DomainCard.jsx +116 -0
  1002. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/HealthScore.css +80 -0
  1003. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/HealthScore.jsx +81 -0
  1004. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/IssuesList.css +184 -0
  1005. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/IssuesList.jsx +145 -0
  1006. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/TechDebtList.css +114 -0
  1007. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/TechDebtList.jsx +72 -0
  1008. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/index.js +9 -0
  1009. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/Card.css +44 -0
  1010. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/Card.jsx +25 -0
  1011. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/Chart.css +14 -0
  1012. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/Chart.jsx +138 -0
  1013. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/Header.css +54 -0
  1014. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/Header.jsx +22 -0
  1015. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/StatusBadge.css +77 -0
  1016. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/StatusBadge.jsx +45 -0
  1017. package/.grimoire/scripts/diagnostics/health-dashboard/src/components/shared/index.js +4 -0
  1018. package/.grimoire/scripts/diagnostics/health-dashboard/src/hooks/index.js +2 -0
  1019. package/.grimoire/scripts/diagnostics/health-dashboard/src/hooks/useAutoRefresh.js +89 -0
  1020. package/.grimoire/scripts/diagnostics/health-dashboard/src/hooks/useHealthData.js +308 -0
  1021. package/.grimoire/scripts/diagnostics/health-dashboard/src/main.jsx +13 -0
  1022. package/.grimoire/scripts/diagnostics/health-dashboard/src/pages/Dashboard.css +238 -0
  1023. package/.grimoire/scripts/diagnostics/health-dashboard/src/pages/Dashboard.jsx +154 -0
  1024. package/.grimoire/scripts/diagnostics/health-dashboard/src/pages/DomainDetail.css +259 -0
  1025. package/.grimoire/scripts/diagnostics/health-dashboard/src/pages/DomainDetail.jsx +164 -0
  1026. package/.grimoire/scripts/diagnostics/health-dashboard/src/pages/index.js +2 -0
  1027. package/.grimoire/scripts/diagnostics/health-dashboard/src/styles/App.css +19 -0
  1028. package/.grimoire/scripts/diagnostics/health-dashboard/src/styles/index.css +67 -0
  1029. package/.grimoire/scripts/diagnostics/health-dashboard/vite.config.js +23 -0
  1030. package/.grimoire/scripts/diagnostics/quick-diagnose.cmd +86 -0
  1031. package/.grimoire/scripts/diagnostics/quick-diagnose.ps1 +118 -0
  1032. package/.grimoire/scripts/grimoire-doc-template.md +326 -0
  1033. package/.grimoire/scripts/migrate-framework-docs.sh +302 -0
  1034. package/.grimoire/scripts/pm.sh +455 -0
  1035. package/.grimoire/scripts/session-context-loader.js +46 -0
  1036. package/.grimoire/scripts/test-template-system.js +942 -0
  1037. package/.grimoire/scripts/update-grimoire.sh +176 -0
  1038. package/.grimoire/scripts/validate-phase1.ps1 +36 -0
  1039. package/.grimoire/scripts/workflow-management.md +70 -0
  1040. package/.grimoire/user-guide.md +1411 -0
  1041. package/.grimoire/utils/format-duration.js +95 -0
  1042. package/.grimoire/utils/grimoire-validator.js +27 -0
  1043. package/.grimoire/workflow-intelligence/__tests__/confidence-scorer.test.js +334 -0
  1044. package/.grimoire/workflow-intelligence/__tests__/integration.test.js +339 -0
  1045. package/.grimoire/workflow-intelligence/__tests__/suggestion-engine.test.js +437 -0
  1046. package/.grimoire/workflow-intelligence/__tests__/wave-analyzer.test.js +447 -0
  1047. package/.grimoire/workflow-intelligence/__tests__/workflow-registry.test.js +302 -0
  1048. package/.grimoire/workflow-intelligence/engine/confidence-scorer.js +306 -0
  1049. package/.grimoire/workflow-intelligence/engine/output-formatter.js +299 -0
  1050. package/.grimoire/workflow-intelligence/engine/suggestion-engine.js +798 -0
  1051. package/.grimoire/workflow-intelligence/engine/wave-analyzer.js +683 -0
  1052. package/.grimoire/workflow-intelligence/index.js +330 -0
  1053. package/.grimoire/workflow-intelligence/learning/capture-hook.js +148 -0
  1054. package/.grimoire/workflow-intelligence/learning/gotcha-registry.js +654 -0
  1055. package/.grimoire/workflow-intelligence/learning/index.js +306 -0
  1056. package/.grimoire/workflow-intelligence/learning/pattern-capture.js +330 -0
  1057. package/.grimoire/workflow-intelligence/learning/pattern-store.js +497 -0
  1058. package/.grimoire/workflow-intelligence/learning/pattern-validator.js +310 -0
  1059. package/.grimoire/workflow-intelligence/learning/qa-feedback.js +586 -0
  1060. package/.grimoire/workflow-intelligence/learning/semantic-search.js +521 -0
  1061. package/.grimoire/workflow-intelligence/registry/workflow-registry.js +357 -0
  1062. package/.grimoire/working-in-the-brownfield.md +362 -0
  1063. package/LICENSE +25 -0
  1064. package/README.md +59 -0
  1065. package/bin/grimoire-ids.js +560 -0
  1066. package/bin/grimoire-init.js +1232 -0
  1067. package/bin/grimoire-minimal.js +40 -0
  1068. package/bin/grimoire.js +1118 -0
  1069. package/bin/modules/env-config.js +436 -0
  1070. package/bin/modules/mcp-installer.js +384 -0
  1071. package/bin/utils/install-errors.js +340 -0
  1072. package/bin/utils/install-transaction.js +447 -0
  1073. package/bin/utils/pro-detector.js +110 -0
  1074. package/package.json +158 -0
  1075. package/packages/gemini-grimoire-extension/README.md +55 -0
  1076. package/packages/gemini-grimoire-extension/commands/grimoire-agent.js +7 -0
  1077. package/packages/gemini-grimoire-extension/commands/grimoire-agents.js +51 -0
  1078. package/packages/gemini-grimoire-extension/commands/grimoire-analyst.js +6 -0
  1079. package/packages/gemini-grimoire-extension/commands/grimoire-architect.js +6 -0
  1080. package/packages/gemini-grimoire-extension/commands/grimoire-data-engineer.js +6 -0
  1081. package/packages/gemini-grimoire-extension/commands/grimoire-dev.js +6 -0
  1082. package/packages/gemini-grimoire-extension/commands/grimoire-devops.js +6 -0
  1083. package/packages/gemini-grimoire-extension/commands/grimoire-master.js +7 -0
  1084. package/packages/gemini-grimoire-extension/commands/grimoire-menu.js +6 -0
  1085. package/packages/gemini-grimoire-extension/commands/grimoire-pm.js +6 -0
  1086. package/packages/gemini-grimoire-extension/commands/grimoire-po.js +6 -0
  1087. package/packages/gemini-grimoire-extension/commands/grimoire-qa.js +6 -0
  1088. package/packages/gemini-grimoire-extension/commands/grimoire-sm.js +6 -0
  1089. package/packages/gemini-grimoire-extension/commands/grimoire-squad-creator.js +6 -0
  1090. package/packages/gemini-grimoire-extension/commands/grimoire-status.js +68 -0
  1091. package/packages/gemini-grimoire-extension/commands/grimoire-ux-design-expert.js +6 -0
  1092. package/packages/gemini-grimoire-extension/commands/grimoire-validate.js +35 -0
  1093. package/packages/gemini-grimoire-extension/commands/lib/agent-launcher.js +147 -0
  1094. package/packages/gemini-grimoire-extension/extension.json +149 -0
  1095. package/packages/gemini-grimoire-extension/gemini-extension.json +149 -0
  1096. package/packages/gemini-grimoire-extension/hooks/hooks.json +72 -0
  1097. package/packages/grimoire-install/.releaserc.json +39 -0
  1098. package/packages/grimoire-install/CHANGELOG.md +33 -0
  1099. package/packages/grimoire-install/README.md +119 -0
  1100. package/packages/grimoire-install/bin/edmcp.js +80 -0
  1101. package/packages/grimoire-install/bin/grimoire-install.js +51 -0
  1102. package/packages/grimoire-install/jest.config.js +27 -0
  1103. package/packages/grimoire-install/package.json +68 -0
  1104. package/packages/grimoire-install/src/dep-checker.js +306 -0
  1105. package/packages/grimoire-install/src/edmcp/index.js +382 -0
  1106. package/packages/grimoire-install/src/installer.js +487 -0
  1107. package/packages/grimoire-install/src/os-detector.js +280 -0
  1108. package/packages/grimoire-pro-cli/bin/grimoire-pro.js +233 -0
  1109. package/packages/grimoire-pro-cli/package.json +38 -0
  1110. package/packages/grimoire-pro-cli/src/recover.js +101 -0
  1111. package/packages/installer/package.json +40 -0
  1112. package/packages/installer/src/__tests__/performance-benchmark.js +384 -0
  1113. package/packages/installer/src/config/configure-environment.js +373 -0
  1114. package/packages/installer/src/config/ide-configs.js +161 -0
  1115. package/packages/installer/src/config/templates/core-config-template.js +199 -0
  1116. package/packages/installer/src/config/templates/env-template.js +272 -0
  1117. package/packages/installer/src/config/validation/config-validator.js +244 -0
  1118. package/packages/installer/src/detection/detect-project-type.js +83 -0
  1119. package/packages/installer/src/installer/brownfield-upgrader.js +440 -0
  1120. package/packages/installer/src/installer/dependency-installer.js +335 -0
  1121. package/packages/installer/src/installer/file-hasher.js +234 -0
  1122. package/packages/installer/src/installer/grimoire-core-installer.js +428 -0
  1123. package/packages/installer/src/installer/manifest-signature.js +380 -0
  1124. package/packages/installer/src/installer/post-install-validator.js +1524 -0
  1125. package/packages/installer/src/merger/index.js +72 -0
  1126. package/packages/installer/src/merger/parsers/env-parser.js +153 -0
  1127. package/packages/installer/src/merger/parsers/markdown-section-parser.js +199 -0
  1128. package/packages/installer/src/merger/strategies/base-merger.js +61 -0
  1129. package/packages/installer/src/merger/strategies/env-merger.js +138 -0
  1130. package/packages/installer/src/merger/strategies/index.js +105 -0
  1131. package/packages/installer/src/merger/strategies/markdown-merger.js +208 -0
  1132. package/packages/installer/src/merger/strategies/replace-merger.js +68 -0
  1133. package/packages/installer/src/merger/types.js +72 -0
  1134. package/packages/installer/src/pro/pro-scaffolder.js +387 -0
  1135. package/packages/installer/src/updater/index.js +814 -0
  1136. package/packages/installer/src/utils/grimoire-colors.js +235 -0
  1137. package/packages/installer/src/wizard/feedback.js +232 -0
  1138. package/packages/installer/src/wizard/i18n.js +230 -0
  1139. package/packages/installer/src/wizard/ide-config-generator.js +993 -0
  1140. package/packages/installer/src/wizard/ide-selector.js +86 -0
  1141. package/packages/installer/src/wizard/index.js +831 -0
  1142. package/packages/installer/src/wizard/pro-setup.js +1223 -0
  1143. package/packages/installer/src/wizard/questions.js +336 -0
  1144. package/packages/installer/src/wizard/validation/index.js +121 -0
  1145. package/packages/installer/src/wizard/validation/report-generator.js +254 -0
  1146. package/packages/installer/src/wizard/validation/troubleshooting-system.js +348 -0
  1147. package/packages/installer/src/wizard/validation/validators/config-validator.js +364 -0
  1148. package/packages/installer/src/wizard/validation/validators/dependency-validator.js +333 -0
  1149. package/packages/installer/src/wizard/validation/validators/file-structure-validator.js +175 -0
  1150. package/packages/installer/src/wizard/validation/validators/mcp-health-checker.js +310 -0
  1151. package/packages/installer/src/wizard/validators.js +274 -0
  1152. package/packages/installer/src/wizard/wizard.js +246 -0
  1153. package/packages/installer/tests/integration/environment-configuration.test.js +331 -0
  1154. package/packages/installer/tests/integration/wizard-detection.test.js +353 -0
  1155. package/packages/installer/tests/unit/config-validator.test.js +316 -0
  1156. package/packages/installer/tests/unit/detection/detect-project-type.test.js +403 -0
  1157. package/packages/installer/tests/unit/env-template.test.js +189 -0
  1158. package/packages/installer/tests/unit/merger/env-merger.test.js +192 -0
  1159. package/packages/installer/tests/unit/merger/markdown-merger.test.js +262 -0
  1160. package/packages/installer/tests/unit/merger/strategies.test.js +153 -0
  1161. package/scripts/check-markdown-links.py +353 -0
  1162. package/scripts/code-intel-health-check.js +344 -0
  1163. package/scripts/dashboard-parallel-dev.sh +184 -0
  1164. package/scripts/dashboard-parallel-phase3.sh +130 -0
  1165. package/scripts/dashboard-parallel-phase4.sh +131 -0
  1166. package/scripts/ensure-manifest.js +59 -0
  1167. package/scripts/generate-install-manifest.js +368 -0
  1168. package/scripts/install-monitor-hooks.sh +83 -0
  1169. package/scripts/package-synapse.js +325 -0
  1170. package/scripts/semantic-lint.js +191 -0
  1171. package/scripts/sign-manifest.ps1 +132 -0
  1172. package/scripts/sign-manifest.sh +122 -0
  1173. package/scripts/validate-manifest.js +267 -0
  1174. package/scripts/validate-package-completeness.js +319 -0
@@ -0,0 +1,1524 @@
1
+ /**
2
+ * Post-Installation Validator
3
+ * Validates installation integrity by comparing installed files against SIGNED manifest
4
+ *
5
+ * @module src/installer/post-install-validator
6
+ * @story 6.19 - Post-Installation Validation & Integrity Verification
7
+ * @version 2.0.0 - Security hardened
8
+ *
9
+ * SECURITY MODEL:
10
+ * - Manifest MUST be cryptographically signed before any file access
11
+ * - All paths are validated for containment before filesystem operations
12
+ * - Symlinks are explicitly rejected
13
+ * - Repair operations require source file hash verification
14
+ * - Fail closed on any security violation
15
+ *
16
+ * Features:
17
+ * - Validates all installed files against signed install-manifest.yaml
18
+ * - Verifies SHA256 hashes for integrity checking
19
+ * - Detects missing, corrupted, and extra files
20
+ * - Provides detailed reports with actionable remediation
21
+ * - Supports automatic repair of missing files (with verification)
22
+ * - Cross-platform compatible (Windows, macOS, Linux)
23
+ */
24
+
25
+ 'use strict';
26
+
27
+ const fs = require('fs-extra');
28
+ const path = require('path');
29
+ const yaml = require('js-yaml');
30
+ const { hashFile, hashesMatch } = require('./file-hasher');
31
+ const { loadAndVerifyManifest } = require('./manifest-signature');
32
+
33
+ /**
34
+ * Validation result severity levels
35
+ * @enum {string}
36
+ */
37
+ const Severity = {
38
+ CRITICAL: 'critical',
39
+ HIGH: 'high',
40
+ MEDIUM: 'medium',
41
+ LOW: 'low',
42
+ INFO: 'info',
43
+ };
44
+
45
+ /**
46
+ * Validation issue types
47
+ * @enum {string}
48
+ */
49
+ const IssueType = {
50
+ MISSING_FILE: 'MISSING_FILE',
51
+ CORRUPTED_FILE: 'CORRUPTED_FILE',
52
+ EXTRA_FILE: 'EXTRA_FILE',
53
+ MISSING_MANIFEST: 'MISSING_MANIFEST',
54
+ INVALID_MANIFEST: 'INVALID_MANIFEST',
55
+ PERMISSION_ERROR: 'PERMISSION_ERROR',
56
+ SIZE_MISMATCH: 'SIZE_MISMATCH',
57
+ INVALID_PATH: 'INVALID_PATH',
58
+ SYMLINK_REJECTED: 'SYMLINK_REJECTED',
59
+ SIGNATURE_MISSING: 'SIGNATURE_MISSING',
60
+ SIGNATURE_INVALID: 'SIGNATURE_INVALID',
61
+ HASH_ERROR: 'HASH_ERROR',
62
+ SCHEMA_VIOLATION: 'SCHEMA_VIOLATION',
63
+ };
64
+
65
+ /**
66
+ * File categories for prioritized reporting
67
+ * @enum {string}
68
+ */
69
+ const FileCategory = {
70
+ CORE: 'core',
71
+ CLI: 'cli',
72
+ DEVELOPMENT: 'development',
73
+ INFRASTRUCTURE: 'infrastructure',
74
+ PRODUCT: 'product',
75
+ WORKFLOW: 'workflow',
76
+ WORKFLOW_INTELLIGENCE: 'workflow-intelligence',
77
+ MONITOR: 'monitor',
78
+ OTHER: 'other',
79
+ };
80
+
81
+ /**
82
+ * Security limits to prevent DoS attacks
83
+ */
84
+ const SecurityLimits = {
85
+ MAX_MANIFEST_SIZE: 10 * 1024 * 1024, // 10MB
86
+ MAX_FILE_COUNT: 50000,
87
+ MAX_SCAN_DEPTH: 50,
88
+ MAX_SCAN_FILES: 100000,
89
+ MAX_PATH_LENGTH: 1024,
90
+ };
91
+
92
+ /**
93
+ * Allowed fields in manifest entries (reject unknown fields)
94
+ */
95
+ const ALLOWED_MANIFEST_FIELDS = ['path', 'hash', 'size', 'type'];
96
+
97
+ /**
98
+ * Allowed type values in manifest entries
99
+ * These represent file categories, not filesystem types
100
+ * Based on actual types used in install-manifest.yaml
101
+ */
102
+ const ALLOWED_TYPE_VALUES = [
103
+ // General types
104
+ 'file',
105
+ 'other',
106
+ // Structural categories
107
+ 'cli',
108
+ 'core',
109
+ 'development',
110
+ 'infrastructure',
111
+ 'product',
112
+ 'workflow',
113
+ 'workflow-intelligence',
114
+ 'monitor',
115
+ 'data',
116
+ 'docs',
117
+ 'documentation',
118
+ 'template',
119
+ 'script',
120
+ 'config',
121
+ // Content types
122
+ 'task',
123
+ 'agent',
124
+ 'tool',
125
+ 'checklist',
126
+ 'elicitation',
127
+ 'code',
128
+ 'manifest',
129
+ ];
130
+
131
+ /**
132
+ * Categorize a file path into its functional category
133
+ * @param {string} filePath - Relative file path
134
+ * @returns {FileCategory} - File category
135
+ */
136
+ function categorizeFile(filePath) {
137
+ const normalized = filePath.replace(/\\/g, '/').toLowerCase();
138
+
139
+ if (normalized.startsWith('core/')) return FileCategory.CORE;
140
+ if (normalized.startsWith('cli/')) return FileCategory.CLI;
141
+ if (normalized.startsWith('development/')) return FileCategory.DEVELOPMENT;
142
+ if (normalized.startsWith('infrastructure/')) return FileCategory.INFRASTRUCTURE;
143
+ if (normalized.startsWith('product/')) return FileCategory.PRODUCT;
144
+ if (normalized.startsWith('workflow-intelligence/')) return FileCategory.WORKFLOW_INTELLIGENCE;
145
+ if (normalized.startsWith('monitor/')) return FileCategory.MONITOR;
146
+ if (normalized.includes('workflow')) return FileCategory.WORKFLOW;
147
+
148
+ return FileCategory.OTHER;
149
+ }
150
+
151
+ /**
152
+ * Get severity based on file category
153
+ * @param {FileCategory} category - File category
154
+ * @returns {Severity} - Severity level
155
+ */
156
+ function getSeverityForCategory(category) {
157
+ const severityMap = {
158
+ [FileCategory.CORE]: Severity.CRITICAL,
159
+ [FileCategory.CLI]: Severity.HIGH,
160
+ [FileCategory.DEVELOPMENT]: Severity.HIGH,
161
+ [FileCategory.INFRASTRUCTURE]: Severity.MEDIUM,
162
+ [FileCategory.PRODUCT]: Severity.MEDIUM,
163
+ [FileCategory.WORKFLOW]: Severity.MEDIUM,
164
+ [FileCategory.WORKFLOW_INTELLIGENCE]: Severity.HIGH,
165
+ [FileCategory.MONITOR]: Severity.MEDIUM,
166
+ [FileCategory.OTHER]: Severity.LOW,
167
+ };
168
+
169
+ return severityMap[category] || Severity.LOW;
170
+ }
171
+
172
+ /**
173
+ * Validate that a resolved path is contained within the root directory
174
+ * Prevents path traversal attacks via malicious manifest entries
175
+ *
176
+ * SECURITY: Handles Windows case-insensitivity and alternate data streams
177
+ *
178
+ * @param {string} absolutePath - The resolved absolute path to check
179
+ * @param {string} rootDir - The root directory that should contain the path
180
+ * @returns {boolean} - True if path is safely contained within root
181
+ */
182
+ function isPathContained(absolutePath, rootDir) {
183
+ const normalizedRoot = path.resolve(rootDir);
184
+ const normalizedPath = path.resolve(absolutePath);
185
+
186
+ // SECURITY: Case-insensitive comparison on Windows
187
+ const comparableRoot =
188
+ process.platform === 'win32' ? normalizedRoot.toLowerCase() : normalizedRoot;
189
+ const comparablePath =
190
+ process.platform === 'win32' ? normalizedPath.toLowerCase() : normalizedPath;
191
+
192
+ // SECURITY: Reject alternate data streams (Windows)
193
+ // Valid format: drive letter at start only (e.g., "C:\")
194
+ // Reject any other ':' in the path (indicates ADS like "file.txt:stream")
195
+ const colonCount = (absolutePath.match(/:/g) || []).length;
196
+ if (process.platform === 'win32') {
197
+ // Windows: allow exactly one colon at position 1 (drive letter)
198
+ if (colonCount > 1 || (colonCount === 1 && !absolutePath.match(/^[a-zA-Z]:[/\\]/))) {
199
+ return false;
200
+ }
201
+ } else {
202
+ // Unix: reject any colon (could indicate ADS-like attacks)
203
+ if (colonCount > 0) {
204
+ return false;
205
+ }
206
+ }
207
+
208
+ // Path must be equal to root or start with root + separator
209
+ return comparablePath === comparableRoot || comparablePath.startsWith(comparableRoot + path.sep);
210
+ }
211
+
212
+ /**
213
+ * Validate a manifest entry against strict schema
214
+ * SECURITY: Rejects unknown fields and invalid types
215
+ *
216
+ * @param {*} entry - Manifest entry to validate
217
+ * @param {number} index - Entry index for error reporting
218
+ * @returns {{ valid: boolean, error: string|null, sanitized: Object|null }}
219
+ */
220
+ function validateManifestEntry(entry, index) {
221
+ // Must be a plain object
222
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
223
+ return { valid: false, error: `Entry ${index}: not an object`, sanitized: null };
224
+ }
225
+
226
+ // SECURITY: Reject unknown fields
227
+ for (const key of Object.keys(entry)) {
228
+ if (!ALLOWED_MANIFEST_FIELDS.includes(key)) {
229
+ return { valid: false, error: `Entry ${index}: unknown field '${key}'`, sanitized: null };
230
+ }
231
+ }
232
+
233
+ // path: required, string, non-empty
234
+ if (typeof entry.path !== 'string' || entry.path.length === 0) {
235
+ return { valid: false, error: `Entry ${index}: missing or invalid 'path'`, sanitized: null };
236
+ }
237
+
238
+ // SECURITY: Path validation
239
+ const pathVal = entry.path;
240
+
241
+ // Reject null bytes
242
+ if (pathVal.includes('\0')) {
243
+ return { valid: false, error: `Entry ${index}: path contains null byte`, sanitized: null };
244
+ }
245
+
246
+ // Reject path traversal sequences
247
+ if (pathVal.includes('..')) {
248
+ return {
249
+ valid: false,
250
+ error: `Entry ${index}: path contains '..' traversal`,
251
+ sanitized: null,
252
+ };
253
+ }
254
+
255
+ // Reject absolute paths
256
+ if (path.isAbsolute(pathVal)) {
257
+ return { valid: false, error: `Entry ${index}: absolute path not allowed`, sanitized: null };
258
+ }
259
+
260
+ // Reject excessively long paths
261
+ if (pathVal.length > SecurityLimits.MAX_PATH_LENGTH) {
262
+ return { valid: false, error: `Entry ${index}: path exceeds maximum length`, sanitized: null };
263
+ }
264
+
265
+ // SECURITY: Reject alternate data streams (Windows ADS) and colons in paths
266
+ // Colons are not valid in filenames on Windows and could indicate ADS attacks
267
+ if (pathVal.includes(':')) {
268
+ return {
269
+ valid: false,
270
+ error: `Entry ${index}: path contains ':' (potential ADS attack)`,
271
+ sanitized: null,
272
+ };
273
+ }
274
+
275
+ // hash: optional, but if present must be valid format
276
+ if (entry.hash !== undefined && entry.hash !== null) {
277
+ if (typeof entry.hash !== 'string') {
278
+ return { valid: false, error: `Entry ${index}: hash must be a string`, sanitized: null };
279
+ }
280
+ if (!entry.hash.match(/^sha256:[a-f0-9]{64}$/i)) {
281
+ return { valid: false, error: `Entry ${index}: invalid hash format`, sanitized: null };
282
+ }
283
+ }
284
+
285
+ // size: optional, but if present must be non-negative integer
286
+ if (entry.size !== undefined && entry.size !== null) {
287
+ if (typeof entry.size !== 'number' || !Number.isInteger(entry.size) || entry.size < 0) {
288
+ return {
289
+ valid: false,
290
+ error: `Entry ${index}: size must be non-negative integer`,
291
+ sanitized: null,
292
+ };
293
+ }
294
+ }
295
+
296
+ // type: optional, if present must be from allowed list
297
+ if (entry.type !== undefined && entry.type !== null) {
298
+ if (!ALLOWED_TYPE_VALUES.includes(entry.type)) {
299
+ return {
300
+ valid: false,
301
+ error: `Entry ${index}: invalid type '${entry.type}'`,
302
+ sanitized: null,
303
+ };
304
+ }
305
+ }
306
+
307
+ // Return sanitized entry with normalized path
308
+ return {
309
+ valid: true,
310
+ error: null,
311
+ sanitized: {
312
+ path: pathVal.replace(/\\/g, '/'),
313
+ hash: entry.hash ? String(entry.hash).toLowerCase() : null,
314
+ size: typeof entry.size === 'number' ? entry.size : null,
315
+ type: entry.type || 'file',
316
+ },
317
+ };
318
+ }
319
+
320
+ /**
321
+ * Post-Installation Validator Class
322
+ * Comprehensive validation of grimoire installation with security hardening
323
+ */
324
+ class PostInstallValidator {
325
+ /**
326
+ * Create a new PostInstallValidator instance
327
+ *
328
+ * @param {string} targetDir - Directory where grimoire was installed (project root)
329
+ * @param {string} [sourceDir] - Source directory for repairs (optional)
330
+ * @param {Object} [options] - Validation options
331
+ * @param {boolean} [options.verifyHashes=true] - Whether to verify file hashes
332
+ * @param {boolean} [options.detectExtras=false] - Whether to detect extra files
333
+ * @param {boolean} [options.verbose=false] - Enable verbose logging
334
+ * @param {boolean} [options.requireSignature=true] - Require manifest signature
335
+ * @param {Function} [options.onProgress] - Progress callback (current, total, file)
336
+ */
337
+ constructor(targetDir, sourceDir = null, options = {}) {
338
+ this.targetDir = path.resolve(targetDir);
339
+ this.sourceDir = sourceDir ? path.resolve(sourceDir) : null;
340
+ this.grimoireCoreTarget = path.join(this.targetDir, '.grimoire');
341
+ this.grimoireCoreSource = this.sourceDir ? path.join(this.sourceDir, '.grimoire') : null;
342
+
343
+ this.options = {
344
+ verifyHashes: options.verifyHashes !== false,
345
+ detectExtras: options.detectExtras === true,
346
+ verbose: options.verbose === true,
347
+ requireSignature: options.requireSignature !== false,
348
+ onProgress: options.onProgress || (() => {}),
349
+ };
350
+
351
+ this.manifest = null;
352
+ this.manifestVerified = false;
353
+ this.issues = [];
354
+ this.stats = {
355
+ totalFiles: 0,
356
+ validFiles: 0,
357
+ missingFiles: 0,
358
+ corruptedFiles: 0,
359
+ extraFiles: 0,
360
+ skippedFiles: 0,
361
+ };
362
+
363
+ // INS-2 Performance: Cache realpath of target directory (computed once, used for all files)
364
+ // This eliminates redundant fs.realpathSync() calls - 50% reduction in syscalls
365
+ this._realTargetDirCache = null;
366
+ }
367
+
368
+ /**
369
+ * Get the real path of the target directory (cached)
370
+ * INS-2 Performance Optimization: Reduces syscalls from 2 to 1 per file validation
371
+ * @returns {string|null} - Real path or null if resolution fails
372
+ */
373
+ _getRealTargetDir() {
374
+ if (this._realTargetDirCache === null) {
375
+ try {
376
+ this._realTargetDirCache = fs.realpathSync(this.grimoireCoreTarget);
377
+ } catch {
378
+ // Will be handled by caller
379
+ return null;
380
+ }
381
+ }
382
+ return this._realTargetDirCache;
383
+ }
384
+
385
+ /**
386
+ * Load, verify signature, and parse the install manifest
387
+ * SECURITY: Signature is verified BEFORE parsing YAML
388
+ *
389
+ * @returns {Promise<Object|null>} - Parsed manifest or null if verification fails
390
+ */
391
+ async loadManifest() {
392
+ // Determine manifest path
393
+ const sourceManifestPath = this.grimoireCoreSource
394
+ ? path.join(this.grimoireCoreSource, 'install-manifest.yaml')
395
+ : null;
396
+ const targetManifestPath = path.join(this.grimoireCoreTarget, 'install-manifest.yaml');
397
+
398
+ let manifestPath = targetManifestPath;
399
+
400
+ // Prefer source manifest (has hashes)
401
+ if (sourceManifestPath && fs.existsSync(sourceManifestPath)) {
402
+ manifestPath = sourceManifestPath;
403
+ this.log(`Using source manifest: ${sourceManifestPath}`);
404
+ } else if (!fs.existsSync(targetManifestPath)) {
405
+ this.issues.push({
406
+ type: IssueType.MISSING_MANIFEST,
407
+ severity: Severity.CRITICAL,
408
+ message: 'Install manifest not found',
409
+ details: `Expected at: ${targetManifestPath}`,
410
+ remediation: 'Re-run installation or copy manifest from source package',
411
+ relativePath: null,
412
+ });
413
+ return null;
414
+ }
415
+
416
+ // SECURITY [C1]: Verify signature BEFORE parsing
417
+ if (this.options.requireSignature) {
418
+ const verifyResult = loadAndVerifyManifest(manifestPath, {
419
+ requireSignature: true,
420
+ });
421
+
422
+ if (verifyResult.error) {
423
+ const issueType = verifyResult.error.includes('not found')
424
+ ? IssueType.SIGNATURE_MISSING
425
+ : IssueType.SIGNATURE_INVALID;
426
+
427
+ this.issues.push({
428
+ type: issueType,
429
+ severity: Severity.CRITICAL,
430
+ message: `Manifest signature verification failed: ${verifyResult.error}`,
431
+ details: 'The manifest cannot be trusted without a valid signature',
432
+ remediation: 'Obtain a properly signed manifest from the official source',
433
+ relativePath: null,
434
+ });
435
+ return null; // HARD FAIL
436
+ }
437
+
438
+ this.manifestVerified = verifyResult.verified;
439
+
440
+ // Parse verified content
441
+ try {
442
+ return this.parseManifestContent(verifyResult.content.toString('utf8'));
443
+ } catch (error) {
444
+ this.issues.push({
445
+ type: IssueType.INVALID_MANIFEST,
446
+ severity: Severity.CRITICAL,
447
+ message: 'Failed to parse verified manifest',
448
+ details: error.message,
449
+ remediation: 'Re-download manifest from trusted source',
450
+ relativePath: null,
451
+ });
452
+ return null;
453
+ }
454
+ }
455
+
456
+ // Development mode: signature not required (NOT for production)
457
+ this.log('WARNING: Signature verification disabled - development mode only');
458
+ try {
459
+ // SECURITY [DOS-3]: Check file size BEFORE reading into memory
460
+ const manifestStat = fs.statSync(manifestPath);
461
+ if (manifestStat.size > SecurityLimits.MAX_MANIFEST_SIZE) {
462
+ this.issues.push({
463
+ type: IssueType.INVALID_MANIFEST,
464
+ severity: Severity.CRITICAL,
465
+ message: 'Manifest file exceeds maximum size',
466
+ details: `Size: ${manifestStat.size} bytes, Max: ${SecurityLimits.MAX_MANIFEST_SIZE} bytes`,
467
+ remediation: 'Use a valid manifest file from the official source',
468
+ relativePath: null,
469
+ });
470
+ return null;
471
+ }
472
+
473
+ const content = fs.readFileSync(manifestPath, 'utf8');
474
+ return this.parseManifestContent(content);
475
+ } catch (error) {
476
+ this.issues.push({
477
+ type: IssueType.INVALID_MANIFEST,
478
+ severity: Severity.CRITICAL,
479
+ message: 'Failed to read manifest',
480
+ details: error.message,
481
+ remediation: 'Re-run installation',
482
+ relativePath: null,
483
+ });
484
+ return null;
485
+ }
486
+ }
487
+
488
+ /**
489
+ * Parse manifest content with strict validation
490
+ * SECURITY [C2]: Uses FAILSAFE_SCHEMA to prevent code execution
491
+ * SECURITY [H5]: Validates schema strictly
492
+ *
493
+ * @param {string} content - Raw manifest content
494
+ * @returns {Object} Parsed and validated manifest
495
+ */
496
+ parseManifestContent(content) {
497
+ // SECURITY [DOS-4]: Size limit using byte length, not character length
498
+ // String.length counts Unicode characters, not bytes. A string with multibyte
499
+ // characters (emojis, CJK) would have fewer characters than bytes.
500
+ // Example: "🔒" has length 2 but is 4 bytes in UTF-8
501
+ const byteLength = Buffer.byteLength(content, 'utf8');
502
+ if (byteLength > SecurityLimits.MAX_MANIFEST_SIZE) {
503
+ throw new Error(
504
+ `Manifest exceeds maximum size (${byteLength} bytes > ${SecurityLimits.MAX_MANIFEST_SIZE} bytes)`,
505
+ );
506
+ }
507
+
508
+ // SECURITY [C2]: Use FAILSAFE_SCHEMA - no custom types, no code execution
509
+ const parsed = yaml.load(content, { schema: yaml.FAILSAFE_SCHEMA });
510
+
511
+ // Validate root structure
512
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
513
+ throw new Error('Manifest must be a valid YAML object');
514
+ }
515
+
516
+ if (!Array.isArray(parsed.files)) {
517
+ throw new Error('Manifest missing required "files" array');
518
+ }
519
+
520
+ // SECURITY: File count limit
521
+ if (parsed.files.length > SecurityLimits.MAX_FILE_COUNT) {
522
+ throw new Error(
523
+ `Manifest contains too many files (${parsed.files.length} > ${SecurityLimits.MAX_FILE_COUNT})`,
524
+ );
525
+ }
526
+
527
+ // SECURITY [H5]: Validate and sanitize each entry
528
+ const sanitizedFiles = [];
529
+ for (let i = 0; i < parsed.files.length; i++) {
530
+ const entry = parsed.files[i];
531
+
532
+ // Handle string format (simple manifest)
533
+ if (typeof entry === 'string') {
534
+ const validation = validateManifestEntry({ path: entry }, i);
535
+ if (!validation.valid) {
536
+ throw new Error(validation.error);
537
+ }
538
+ sanitizedFiles.push(validation.sanitized);
539
+ continue;
540
+ }
541
+
542
+ // SECURITY [H5-PRE]: Reject unknown fields BEFORE normalization
543
+ // This prevents malicious fields from being silently dropped
544
+ if (typeof entry === 'object' && entry !== null) {
545
+ for (const key of Object.keys(entry)) {
546
+ if (!ALLOWED_MANIFEST_FIELDS.includes(key)) {
547
+ throw new Error(`Entry ${i}: unknown field '${key}' in manifest`);
548
+ }
549
+ }
550
+ }
551
+
552
+ // SECURITY [H5-SIZE]: Fail fast on malformed sizes instead of silently nulling
553
+ // When size is present but invalid, reject the manifest entirely
554
+ if (entry.size !== undefined && entry.size !== null) {
555
+ const sizeNum = Number(entry.size);
556
+ if (Number.isNaN(sizeNum) || !Number.isInteger(sizeNum) || sizeNum < 0) {
557
+ throw new Error(
558
+ `Entry ${i}: invalid size '${entry.size}' for path '${entry.path}' (must be non-negative integer)`,
559
+ );
560
+ }
561
+ }
562
+
563
+ // Object format - convert FAILSAFE_SCHEMA strings to proper types
564
+ const normalizedEntry = {
565
+ path: entry.path,
566
+ hash: entry.hash,
567
+ // FAILSAFE_SCHEMA returns all values as strings, convert size to number
568
+ // Size already validated above, safe to convert
569
+ size: entry.size !== undefined && entry.size !== null ? Number(entry.size) : null,
570
+ type: entry.type,
571
+ };
572
+
573
+ const validation = validateManifestEntry(normalizedEntry, i);
574
+ if (!validation.valid) {
575
+ throw new Error(validation.error);
576
+ }
577
+ sanitizedFiles.push(validation.sanitized);
578
+ }
579
+
580
+ this.manifest = {
581
+ ...parsed,
582
+ files: sanitizedFiles,
583
+ };
584
+
585
+ this.log(
586
+ `Loaded manifest v${this.manifest.version || 'unknown'} with ${this.manifest.files.length} files`,
587
+ );
588
+
589
+ return this.manifest;
590
+ }
591
+
592
+ /**
593
+ * Validate a single file against manifest entry
594
+ * SECURITY [C3]: Rejects symlinks and non-regular files
595
+ * SECURITY [H1]: Validates path containment
596
+ * SECURITY [H2]: Requires size in quick mode
597
+ * SECURITY [H3]: Treats hash errors as failures
598
+ *
599
+ * @param {Object} entry - Validated manifest entry
600
+ * @returns {Promise<Object>} - Validation result
601
+ */
602
+ async validateFile(entry) {
603
+ const relativePath = entry.path;
604
+ const absolutePath = path.resolve(this.grimoireCoreTarget, relativePath);
605
+ const category = categorizeFile(relativePath);
606
+
607
+ const result = {
608
+ path: relativePath,
609
+ category,
610
+ exists: false,
611
+ hashValid: null,
612
+ sizeValid: null,
613
+ issue: null,
614
+ };
615
+
616
+ // SECURITY [H1]: Validate path containment
617
+ if (!isPathContained(absolutePath, this.grimoireCoreTarget)) {
618
+ this.log(`SECURITY: Path traversal blocked: ${relativePath}`);
619
+ result.issue = {
620
+ type: IssueType.INVALID_PATH,
621
+ severity: Severity.CRITICAL,
622
+ message: 'Path traversal attempt blocked',
623
+ details: 'Manifest entry attempts to access outside installation directory',
624
+ category,
625
+ remediation: 'This indicates a malicious or corrupted manifest',
626
+ relativePath,
627
+ };
628
+ this.stats.skippedFiles++;
629
+ return result;
630
+ }
631
+
632
+ // Check file existence
633
+ let lstat;
634
+ try {
635
+ lstat = fs.lstatSync(absolutePath);
636
+ } catch (error) {
637
+ if (error.code === 'ENOENT') {
638
+ result.issue = {
639
+ type: IssueType.MISSING_FILE,
640
+ severity: getSeverityForCategory(category),
641
+ message: `Missing file: ${relativePath}`,
642
+ details: `Expected at: ${absolutePath}`,
643
+ category,
644
+ remediation: this.sourceDir
645
+ ? "Run 'grimoire validate --repair' to restore"
646
+ : 'Re-run installation',
647
+ relativePath,
648
+ };
649
+ this.stats.missingFiles++;
650
+ return result;
651
+ }
652
+
653
+ result.issue = {
654
+ type: IssueType.PERMISSION_ERROR,
655
+ severity: Severity.HIGH,
656
+ message: `Cannot access file: ${relativePath}`,
657
+ details: error.message,
658
+ category,
659
+ remediation: 'Check file permissions',
660
+ relativePath,
661
+ };
662
+ this.stats.skippedFiles++;
663
+ return result;
664
+ }
665
+
666
+ // SECURITY [C3]: Reject symlinks
667
+ if (lstat.isSymbolicLink()) {
668
+ result.issue = {
669
+ type: IssueType.SYMLINK_REJECTED,
670
+ severity: Severity.CRITICAL,
671
+ message: `Symlink not allowed: ${relativePath}`,
672
+ details: 'Symlinks are rejected to prevent path escape attacks',
673
+ category,
674
+ remediation: 'Replace symlink with actual file',
675
+ relativePath,
676
+ };
677
+ this.stats.skippedFiles++;
678
+ return result;
679
+ }
680
+
681
+ // SECURITY [C3]: Reject non-regular files
682
+ if (!lstat.isFile()) {
683
+ result.issue = {
684
+ type: IssueType.INVALID_PATH,
685
+ severity: Severity.HIGH,
686
+ message: `Not a regular file: ${relativePath}`,
687
+ details: `Found ${lstat.isDirectory() ? 'directory' : 'special file'} instead of file`,
688
+ category,
689
+ remediation: 'Only regular files are allowed',
690
+ relativePath,
691
+ };
692
+ this.stats.skippedFiles++;
693
+ return result;
694
+ }
695
+
696
+ // SECURITY [C3-REALPATH]: Detect symlinks in intermediate directory components
697
+ // A file may not be a symlink itself, but a parent directory could be,
698
+ // allowing path traversal attacks (e.g., /install/.grimoire/symlinked-dir/../../../etc/passwd)
699
+ //
700
+ // NOTE: On macOS, /tmp is a symlink to /private/tmp. This is a system-level
701
+ // symlink that shouldn't trigger security alerts. We handle this by resolving
702
+ // both the file path AND the target directory to their real paths, then
703
+ // comparing containment. The key security check is: does the real path of the
704
+ // file stay within the real path of the target directory?
705
+ //
706
+ // INS-2 Performance: realTargetDir is now cached via _getRealTargetDir()
707
+ // This reduces syscalls from 2 to 1 per file (50% reduction)
708
+ try {
709
+ const realPath = fs.realpathSync(absolutePath);
710
+ const realTargetDir = this._getRealTargetDir();
711
+
712
+ // Handle case where target dir resolution failed
713
+ if (realTargetDir === null) {
714
+ this.log('SECURITY: Cannot resolve realpath for target directory');
715
+ result.issue = {
716
+ type: IssueType.PERMISSION_ERROR,
717
+ severity: Severity.CRITICAL,
718
+ message: 'Cannot resolve real path for target directory',
719
+ details: 'Target directory realpath resolution failed',
720
+ category,
721
+ remediation: 'Check directory permissions',
722
+ relativePath,
723
+ };
724
+ this.stats.skippedFiles++;
725
+ return result;
726
+ }
727
+
728
+ // SECURITY: Verify realpath is still contained within REAL target directory
729
+ // This handles system symlinks like /tmp -> /private/tmp correctly
730
+ if (!isPathContained(realPath, realTargetDir)) {
731
+ this.log(`SECURITY: Realpath escapes target directory: ${relativePath}`);
732
+ result.issue = {
733
+ type: IssueType.INVALID_PATH,
734
+ severity: Severity.CRITICAL,
735
+ message: `Path escape via symlink detected: ${relativePath}`,
736
+ details: `Real path ${realPath} is outside installation directory ${realTargetDir}`,
737
+ category,
738
+ remediation: 'This indicates a path traversal attack via symlinked directories',
739
+ relativePath,
740
+ };
741
+ this.stats.skippedFiles++;
742
+ return result;
743
+ }
744
+
745
+ // SECURITY: Detect symlinks in the RELATIVE portion of the path
746
+ // Compare the relative path from target to file with the relative path
747
+ // from realTarget to realPath. If they differ, there's a symlink attack.
748
+ const expectedRelative = path.relative(this.grimoireCoreTarget, absolutePath);
749
+ const actualRelative = path.relative(realTargetDir, realPath);
750
+
751
+ // Platform-aware comparison (case-insensitive on Windows)
752
+ const comparableExpected =
753
+ process.platform === 'win32' ? expectedRelative.toLowerCase() : expectedRelative;
754
+ const comparableActual =
755
+ process.platform === 'win32' ? actualRelative.toLowerCase() : actualRelative;
756
+
757
+ if (comparableExpected !== comparableActual) {
758
+ this.log(`SECURITY: Symlinked path component detected: ${relativePath}`);
759
+ result.issue = {
760
+ type: IssueType.SYMLINK_REJECTED,
761
+ severity: Severity.CRITICAL,
762
+ message: `Symlinked path component detected: ${relativePath}`,
763
+ details: `Resolved relative path differs: expected '${expectedRelative}', got '${actualRelative}'`,
764
+ category,
765
+ remediation: 'Remove symlinks from directory structure',
766
+ relativePath,
767
+ };
768
+ this.stats.skippedFiles++;
769
+ return result;
770
+ }
771
+ } catch (error) {
772
+ // realpathSync can fail if file doesn't exist or permission denied
773
+ // File existence already checked via lstat, so this indicates permission issue
774
+ this.log(`SECURITY: Cannot resolve realpath for: ${relativePath} - ${error.message}`);
775
+ result.issue = {
776
+ type: IssueType.PERMISSION_ERROR,
777
+ severity: Severity.HIGH,
778
+ message: `Cannot resolve real path: ${relativePath}`,
779
+ details: error.message,
780
+ category,
781
+ remediation: 'Check file and directory permissions',
782
+ relativePath,
783
+ };
784
+ this.stats.skippedFiles++;
785
+ return result;
786
+ }
787
+
788
+ result.exists = true;
789
+
790
+ // SECURITY [H2]: In quick mode (no hash), size MUST be present
791
+ if (!this.options.verifyHashes) {
792
+ if (entry.size === null || entry.size === undefined) {
793
+ result.issue = {
794
+ type: IssueType.SCHEMA_VIOLATION,
795
+ severity: Severity.HIGH,
796
+ message: `Missing size in manifest: ${relativePath}`,
797
+ details: 'Size is required when hash verification is disabled',
798
+ category,
799
+ remediation: 'Use full validation mode or update manifest with size information',
800
+ relativePath,
801
+ };
802
+ this.stats.skippedFiles++;
803
+ return result;
804
+ }
805
+ }
806
+
807
+ // Verify file size
808
+ const actualSize = lstat.size;
809
+ if (entry.size !== null && entry.size !== undefined) {
810
+ result.sizeValid = actualSize === entry.size;
811
+
812
+ if (!result.sizeValid) {
813
+ this.log(`Size mismatch: ${relativePath} (expected ${entry.size}, got ${actualSize})`);
814
+
815
+ // In quick mode, size mismatch is a failure
816
+ if (!this.options.verifyHashes) {
817
+ result.issue = {
818
+ type: IssueType.SIZE_MISMATCH,
819
+ severity: getSeverityForCategory(category),
820
+ message: `File size mismatch: ${relativePath}`,
821
+ details: `Expected: ${entry.size} bytes, Got: ${actualSize} bytes`,
822
+ category,
823
+ remediation: this.sourceDir
824
+ ? "Run 'grimoire validate --repair' to restore"
825
+ : 'Re-run installation',
826
+ relativePath,
827
+ };
828
+ this.stats.corruptedFiles++;
829
+ return result;
830
+ }
831
+ }
832
+ }
833
+
834
+ // SECURITY [H7]: Missing hash when hash verification is enabled is a schema violation
835
+ // This MUST be checked BEFORE the hash verification block to prevent bypass
836
+ if (this.options.verifyHashes && !entry.hash) {
837
+ result.issue = {
838
+ type: IssueType.SCHEMA_VIOLATION,
839
+ severity: getSeverityForCategory(category),
840
+ message: `Missing hash in manifest: ${relativePath}`,
841
+ details: 'Hash verification enabled but no hash provided in manifest',
842
+ category,
843
+ remediation: 'Update manifest with file hashes or disable hash verification',
844
+ relativePath,
845
+ };
846
+ this.stats.corruptedFiles++;
847
+ return result;
848
+ }
849
+
850
+ // Verify hash (full validation)
851
+ if (this.options.verifyHashes && entry.hash) {
852
+ try {
853
+ const actualHash = `sha256:${hashFile(absolutePath)}`;
854
+ result.hashValid = hashesMatch(actualHash, entry.hash);
855
+
856
+ if (!result.hashValid) {
857
+ result.issue = {
858
+ type: IssueType.CORRUPTED_FILE,
859
+ severity: getSeverityForCategory(category),
860
+ message: `Hash mismatch: ${relativePath}`,
861
+ details: `Expected: ${entry.hash.substring(0, 24)}..., Got: ${actualHash.substring(0, 24)}...`,
862
+ category,
863
+ remediation: this.sourceDir
864
+ ? "Run 'grimoire validate --repair' to restore"
865
+ : 'Re-run installation',
866
+ relativePath,
867
+ };
868
+ this.stats.corruptedFiles++;
869
+ return result;
870
+ }
871
+ } catch (error) {
872
+ // SECURITY [H3]: Hash errors are failures, not skips
873
+ result.issue = {
874
+ type: IssueType.HASH_ERROR,
875
+ severity: Severity.HIGH,
876
+ message: `Hash verification error: ${relativePath}`,
877
+ details: error.message,
878
+ category,
879
+ remediation: 'Check file accessibility and try again',
880
+ relativePath,
881
+ };
882
+ this.stats.corruptedFiles++;
883
+ return result;
884
+ }
885
+ }
886
+
887
+ // File is valid
888
+ this.stats.validFiles++;
889
+ return result;
890
+ }
891
+
892
+ /**
893
+ * Scan for extra files not in manifest
894
+ * SECURITY [H6]: Implements depth and file count limits
895
+ *
896
+ * @returns {Promise<Array>} - List of extra file paths
897
+ */
898
+ async detectExtraFiles() {
899
+ if (!this.options.detectExtras || !this.manifest) {
900
+ return [];
901
+ }
902
+
903
+ // SECURITY: Only use case-insensitive comparison on Windows
904
+ // On case-sensitive filesystems (Linux/macOS), preserve case to detect
905
+ // malicious files that differ only by case (e.g., Malicious.js vs malicious.js)
906
+ const isWindows = process.platform === 'win32';
907
+ const normalizePath = (p) => (isWindows ? p.toLowerCase() : p);
908
+ const manifestPaths = new Set(this.manifest.files.map((f) => normalizePath(f.path)));
909
+ const extraFiles = [];
910
+ let filesScanned = 0;
911
+
912
+ const scanDir = async (dir, basePath, depth = 0) => {
913
+ // SECURITY [H6]: Depth limit
914
+ if (depth > SecurityLimits.MAX_SCAN_DEPTH) {
915
+ this.log(`SECURITY: Max scan depth exceeded at ${dir}`);
916
+ return;
917
+ }
918
+
919
+ // SECURITY [H6]: File count limit
920
+ if (filesScanned >= SecurityLimits.MAX_SCAN_FILES) {
921
+ this.log('SECURITY: Max scan file count exceeded');
922
+ return;
923
+ }
924
+
925
+ if (!fs.existsSync(dir)) return;
926
+
927
+ let entries;
928
+ try {
929
+ entries = fs.readdirSync(dir, { withFileTypes: true });
930
+ } catch (error) {
931
+ this.log(`Cannot read directory: ${dir} - ${error.message}`);
932
+ return;
933
+ }
934
+
935
+ for (const entry of entries) {
936
+ if (filesScanned >= SecurityLimits.MAX_SCAN_FILES) break;
937
+
938
+ const fullPath = path.join(dir, entry.name);
939
+ const relativePath = path.relative(basePath, fullPath).replace(/\\/g, '/');
940
+
941
+ filesScanned++;
942
+
943
+ if (entry.isDirectory()) {
944
+ await scanDir(fullPath, basePath, depth + 1);
945
+ } else if (entry.isFile()) {
946
+ // Skip manifests
947
+ if (
948
+ relativePath === 'install-manifest.yaml' ||
949
+ relativePath === 'install-manifest.yaml.minisig' ||
950
+ relativePath === '.installed-manifest.yaml'
951
+ ) {
952
+ continue;
953
+ }
954
+
955
+ if (!manifestPaths.has(normalizePath(relativePath))) {
956
+ extraFiles.push(relativePath);
957
+ this.stats.extraFiles++;
958
+ }
959
+ }
960
+ // Symlinks and special files are silently ignored in extra detection
961
+ }
962
+ };
963
+
964
+ await scanDir(this.grimoireCoreTarget, this.grimoireCoreTarget);
965
+ return extraFiles;
966
+ }
967
+
968
+ /**
969
+ * Run full validation
970
+ *
971
+ * @returns {Promise<Object>} - Comprehensive validation report
972
+ */
973
+ async validate() {
974
+ const startTime = Date.now();
975
+
976
+ this.log('Starting post-installation validation...');
977
+
978
+ // Reset state
979
+ this.issues = [];
980
+ this.manifestVerified = false;
981
+ this.stats = {
982
+ totalFiles: 0,
983
+ validFiles: 0,
984
+ missingFiles: 0,
985
+ corruptedFiles: 0,
986
+ extraFiles: 0,
987
+ skippedFiles: 0,
988
+ };
989
+
990
+ // Check target directory
991
+ if (!fs.existsSync(this.grimoireCoreTarget)) {
992
+ this.issues.push({
993
+ type: IssueType.MISSING_FILE,
994
+ severity: Severity.CRITICAL,
995
+ message: 'grimoire directory not found',
996
+ details: `Expected at: ${this.grimoireCoreTarget}`,
997
+ remediation: 'Run `npx grimoire install`',
998
+ relativePath: null,
999
+ });
1000
+ return this.generateReport(startTime);
1001
+ }
1002
+
1003
+ // Load and verify manifest
1004
+ const manifest = await this.loadManifest();
1005
+ if (!manifest) {
1006
+ return this.generateReport(startTime);
1007
+ }
1008
+
1009
+ this.stats.totalFiles = manifest.files.length;
1010
+
1011
+ // Validate each file
1012
+ const fileResults = [];
1013
+ for (let i = 0; i < manifest.files.length; i++) {
1014
+ const entry = manifest.files[i];
1015
+ this.options.onProgress(i + 1, manifest.files.length, entry.path);
1016
+
1017
+ const result = await this.validateFile(entry);
1018
+ fileResults.push(result);
1019
+
1020
+ if (result.issue) {
1021
+ this.issues.push(result.issue);
1022
+ }
1023
+ }
1024
+
1025
+ // Detect extra files
1026
+ const extraFiles = await this.detectExtraFiles();
1027
+ for (const extraPath of extraFiles) {
1028
+ this.issues.push({
1029
+ type: IssueType.EXTRA_FILE,
1030
+ severity: Severity.INFO,
1031
+ message: `Extra file: ${extraPath}`,
1032
+ details: 'File not in manifest',
1033
+ category: categorizeFile(extraPath),
1034
+ remediation: 'Review if this file should be kept',
1035
+ relativePath: extraPath,
1036
+ });
1037
+ }
1038
+
1039
+ return this.generateReport(startTime, fileResults);
1040
+ }
1041
+
1042
+ /**
1043
+ * Generate validation report
1044
+ *
1045
+ * @param {number} startTime - Start timestamp
1046
+ * @param {Array} [fileResults] - File validation results
1047
+ * @returns {Object} - Report
1048
+ */
1049
+ generateReport(startTime, _fileResults = []) {
1050
+ const duration = Date.now() - startTime;
1051
+
1052
+ // Group by severity
1053
+ const issuesBySeverity = {
1054
+ [Severity.CRITICAL]: [],
1055
+ [Severity.HIGH]: [],
1056
+ [Severity.MEDIUM]: [],
1057
+ [Severity.LOW]: [],
1058
+ [Severity.INFO]: [],
1059
+ };
1060
+
1061
+ for (const issue of this.issues) {
1062
+ issuesBySeverity[issue.severity].push(issue);
1063
+ }
1064
+
1065
+ // Group missing by category
1066
+ const missingByCategory = {};
1067
+ for (const issue of this.issues.filter((i) => i.type === IssueType.MISSING_FILE)) {
1068
+ const category = issue.category || FileCategory.OTHER;
1069
+ if (!missingByCategory[category]) {
1070
+ missingByCategory[category] = [];
1071
+ }
1072
+ missingByCategory[category].push(issue.relativePath);
1073
+ }
1074
+
1075
+ // Determine status
1076
+ let status = 'success';
1077
+ if (issuesBySeverity[Severity.CRITICAL].length > 0) {
1078
+ status = 'failed';
1079
+ } else if (
1080
+ issuesBySeverity[Severity.HIGH].length > 0 ||
1081
+ issuesBySeverity[Severity.MEDIUM].length > 0
1082
+ ) {
1083
+ status = 'warning';
1084
+ } else if (this.issues.length > 0) {
1085
+ status = 'info';
1086
+ }
1087
+
1088
+ // Integrity score
1089
+ const integrityScore =
1090
+ this.stats.totalFiles > 0
1091
+ ? Math.round((this.stats.validFiles / this.stats.totalFiles) * 100)
1092
+ : 0;
1093
+
1094
+ return {
1095
+ status,
1096
+ integrityScore,
1097
+ manifestVerified: this.manifestVerified,
1098
+ timestamp: new Date().toISOString(),
1099
+ duration: `${duration}ms`,
1100
+ manifest: this.manifest
1101
+ ? {
1102
+ version: this.manifest.version,
1103
+ generatedAt: this.manifest.generated_at,
1104
+ totalFiles: this.manifest.files.length,
1105
+ }
1106
+ : null,
1107
+ stats: { ...this.stats },
1108
+ issues: this.issues,
1109
+ issuesBySeverity,
1110
+ missingByCategory,
1111
+ summary: {
1112
+ total: this.stats.totalFiles,
1113
+ valid: this.stats.validFiles,
1114
+ missing: this.stats.missingFiles,
1115
+ corrupted: this.stats.corruptedFiles,
1116
+ extra: this.stats.extraFiles,
1117
+ skipped: this.stats.skippedFiles,
1118
+ },
1119
+ recommendations: this.generateRecommendations(),
1120
+ };
1121
+ }
1122
+
1123
+ /**
1124
+ * Generate recommendations
1125
+ *
1126
+ * @returns {Array<string>} - Recommendations
1127
+ */
1128
+ generateRecommendations() {
1129
+ const recommendations = [];
1130
+
1131
+ if (!this.manifestVerified && this.options.requireSignature) {
1132
+ recommendations.push(
1133
+ 'CRITICAL: Manifest signature verification failed. Do not trust validation results.',
1134
+ );
1135
+ }
1136
+
1137
+ if (this.stats.missingFiles > 0) {
1138
+ if (this.stats.missingFiles > 50) {
1139
+ recommendations.push('Consider re-running full installation.');
1140
+ } else {
1141
+ recommendations.push(
1142
+ `${this.stats.missingFiles} file(s) missing. Run 'grimoire validate --repair'.`,
1143
+ );
1144
+ }
1145
+ }
1146
+
1147
+ if (this.stats.corruptedFiles > 0) {
1148
+ recommendations.push(
1149
+ `${this.stats.corruptedFiles} file(s) corrupted. Run 'grimoire validate --repair'.`,
1150
+ );
1151
+ }
1152
+
1153
+ if (this.stats.validFiles === this.stats.totalFiles && this.stats.totalFiles > 0) {
1154
+ recommendations.push('Installation verified successfully.');
1155
+ }
1156
+
1157
+ return recommendations;
1158
+ }
1159
+
1160
+ /**
1161
+ * Repair installation by copying missing/corrupted files
1162
+ * SECURITY [C4]: Verifies source file hash before copying
1163
+ *
1164
+ * @param {Object} [options] - Repair options
1165
+ * @param {boolean} [options.dryRun=false] - Only report, don't copy
1166
+ * @param {Function} [options.onProgress] - Progress callback
1167
+ * @returns {Promise<Object>} - Repair result
1168
+ */
1169
+ async repair(options = {}) {
1170
+ const dryRun = options.dryRun === true;
1171
+ const onProgress = options.onProgress || (() => {});
1172
+
1173
+ // SECURITY [C4]: Repair requires hash verification enabled
1174
+ if (!this.options.verifyHashes) {
1175
+ return {
1176
+ success: false,
1177
+ error: 'Repair requires hash verification to be enabled',
1178
+ repaired: [],
1179
+ failed: [],
1180
+ skipped: [],
1181
+ };
1182
+ }
1183
+
1184
+ // SECURITY [C4]: Repair requires verified manifest
1185
+ if (this.options.requireSignature && !this.manifestVerified) {
1186
+ return {
1187
+ success: false,
1188
+ error: 'Repair requires a verified manifest signature',
1189
+ repaired: [],
1190
+ failed: [],
1191
+ skipped: [],
1192
+ };
1193
+ }
1194
+
1195
+ if (!this.sourceDir || !fs.existsSync(this.grimoireCoreSource)) {
1196
+ return {
1197
+ success: false,
1198
+ error: 'Source directory not available',
1199
+ repaired: [],
1200
+ failed: [],
1201
+ skipped: [],
1202
+ };
1203
+ }
1204
+
1205
+ // Run validation first if needed
1206
+ if (this.issues.length === 0 && this.stats.totalFiles === 0) {
1207
+ await this.validate();
1208
+ }
1209
+
1210
+ const repairableIssues = this.issues.filter(
1211
+ (i) =>
1212
+ i.type === IssueType.MISSING_FILE ||
1213
+ i.type === IssueType.CORRUPTED_FILE ||
1214
+ i.type === IssueType.SIZE_MISMATCH,
1215
+ );
1216
+
1217
+ const result = {
1218
+ success: true,
1219
+ dryRun,
1220
+ repaired: [],
1221
+ failed: [],
1222
+ skipped: [],
1223
+ };
1224
+
1225
+ for (let i = 0; i < repairableIssues.length; i++) {
1226
+ const issue = repairableIssues[i];
1227
+ // SECURITY [H4]: Use relativePath from issue, not parsed from message
1228
+ const relativePath = issue.relativePath;
1229
+
1230
+ if (!relativePath) {
1231
+ result.failed.push({ path: 'unknown', reason: 'Missing path in issue' });
1232
+ continue;
1233
+ }
1234
+
1235
+ const sourcePath = path.resolve(this.grimoireCoreSource, relativePath);
1236
+ const targetPath = path.resolve(this.grimoireCoreTarget, relativePath);
1237
+
1238
+ onProgress(i + 1, repairableIssues.length, relativePath);
1239
+
1240
+ // SECURITY: Path containment for source
1241
+ if (!isPathContained(sourcePath, this.grimoireCoreSource)) {
1242
+ result.skipped.push({ path: relativePath, reason: 'Source path traversal blocked' });
1243
+ continue;
1244
+ }
1245
+
1246
+ // SECURITY: Path containment for target
1247
+ if (!isPathContained(targetPath, this.grimoireCoreTarget)) {
1248
+ result.skipped.push({ path: relativePath, reason: 'Target path traversal blocked' });
1249
+ continue;
1250
+ }
1251
+
1252
+ // Check source exists
1253
+ let sourceLstat;
1254
+ try {
1255
+ sourceLstat = fs.lstatSync(sourcePath);
1256
+ } catch (_error) {
1257
+ result.failed.push({ path: relativePath, reason: 'Source file not found' });
1258
+ result.success = false;
1259
+ continue;
1260
+ }
1261
+
1262
+ // SECURITY [C3]: Reject source symlinks
1263
+ if (sourceLstat.isSymbolicLink()) {
1264
+ result.skipped.push({ path: relativePath, reason: 'Source is symlink' });
1265
+ continue;
1266
+ }
1267
+
1268
+ if (!sourceLstat.isFile()) {
1269
+ result.skipped.push({ path: relativePath, reason: 'Source is not a regular file' });
1270
+ continue;
1271
+ }
1272
+
1273
+ // SECURITY [C4]: Verify source file hash matches manifest
1274
+ const manifestEntry = this.manifest.files.find((f) => f.path === relativePath);
1275
+ if (!manifestEntry || !manifestEntry.hash) {
1276
+ result.failed.push({ path: relativePath, reason: 'No hash in manifest for verification' });
1277
+ result.success = false;
1278
+ continue;
1279
+ }
1280
+
1281
+ try {
1282
+ const sourceHash = `sha256:${hashFile(sourcePath)}`;
1283
+ if (!hashesMatch(sourceHash, manifestEntry.hash)) {
1284
+ result.failed.push({
1285
+ path: relativePath,
1286
+ reason: 'Source file hash does not match signed manifest',
1287
+ });
1288
+ result.success = false;
1289
+ continue;
1290
+ }
1291
+ } catch (error) {
1292
+ result.failed.push({ path: relativePath, reason: `Cannot hash source: ${error.message}` });
1293
+ result.success = false;
1294
+ continue;
1295
+ }
1296
+
1297
+ // Dry run - just report
1298
+ if (dryRun) {
1299
+ result.repaired.push({
1300
+ path: relativePath,
1301
+ action: issue.type === IssueType.MISSING_FILE ? 'would_copy' : 'would_replace',
1302
+ });
1303
+ continue;
1304
+ }
1305
+
1306
+ // SECURITY [TOCTOU]: Verify target path has no symlinks in any component
1307
+ // This prevents race condition attacks where a directory is replaced with a symlink
1308
+ // between the containment check and the actual copy operation
1309
+ try {
1310
+ const targetDir = path.dirname(targetPath);
1311
+
1312
+ // Walk each path component from grimoireCoreTarget to targetDir
1313
+ // and verify none are symlinks
1314
+ let currentPath = this.grimoireCoreTarget;
1315
+ const relativeParts = path.relative(this.grimoireCoreTarget, targetDir).split(path.sep);
1316
+
1317
+ for (const part of relativeParts) {
1318
+ if (!part || part === '.') continue;
1319
+ currentPath = path.join(currentPath, part);
1320
+
1321
+ // Check if this path component exists and is a symlink
1322
+ try {
1323
+ const componentStat = fs.lstatSync(currentPath);
1324
+ if (componentStat.isSymbolicLink()) {
1325
+ result.skipped.push({
1326
+ path: relativePath,
1327
+ reason: `Symlink detected in path component: ${path.relative(this.grimoireCoreTarget, currentPath)}`,
1328
+ });
1329
+ continue;
1330
+ }
1331
+ } catch (_statError) {
1332
+ // Path component doesn't exist yet, will be created by ensureDir
1333
+ // This is OK - we'll create it as a real directory
1334
+ break;
1335
+ }
1336
+ }
1337
+
1338
+ // Final realpath verification: ensure resolved target stays within resolved grimoireCoreTarget
1339
+ // This catches any symlinks that might have been missed or created during the check
1340
+ if (fs.existsSync(targetDir)) {
1341
+ const realTargetDir = fs.realpathSync(targetDir);
1342
+ const realgrimoireCoreTarget = fs.realpathSync(this.grimoireCoreTarget);
1343
+
1344
+ if (!isPathContained(realTargetDir, realgrimoireCoreTarget)) {
1345
+ result.skipped.push({
1346
+ path: relativePath,
1347
+ reason: `Realpath escapes target directory: ${realTargetDir} is outside ${realgrimoireCoreTarget}`,
1348
+ });
1349
+ continue;
1350
+ }
1351
+ }
1352
+ } catch (toctouError) {
1353
+ result.skipped.push({
1354
+ path: relativePath,
1355
+ reason: `TOCTOU verification failed: ${toctouError.message}`,
1356
+ });
1357
+ continue;
1358
+ }
1359
+
1360
+ // Perform copy
1361
+ try {
1362
+ await fs.ensureDir(path.dirname(targetPath));
1363
+ await fs.copy(sourcePath, targetPath, { overwrite: true });
1364
+ result.repaired.push({
1365
+ path: relativePath,
1366
+ action: issue.type === IssueType.MISSING_FILE ? 'copied' : 'replaced',
1367
+ });
1368
+ } catch (error) {
1369
+ result.failed.push({ path: relativePath, reason: error.message });
1370
+ result.success = false;
1371
+ }
1372
+ }
1373
+
1374
+ return result;
1375
+ }
1376
+
1377
+ /**
1378
+ * Log if verbose
1379
+ * @param {string} message - Message
1380
+ */
1381
+ log(message) {
1382
+ if (this.options.verbose) {
1383
+ console.log(`[PostInstallValidator] ${message}`);
1384
+ }
1385
+ }
1386
+ }
1387
+
1388
+ /**
1389
+ * Format report for console
1390
+ *
1391
+ * @param {Object} report - Validation report
1392
+ * @param {Object} [options] - Format options
1393
+ * @returns {string} - Formatted report
1394
+ */
1395
+ function formatReport(report, options = {}) {
1396
+ const useColors = options.colors !== false;
1397
+ // Note: detailed option is parsed from CLI but detailed view is handled by caller
1398
+ // eslint-disable-next-line no-unused-vars
1399
+ const detailed = options.detailed === true;
1400
+
1401
+ const c = {
1402
+ reset: useColors ? '\x1b[0m' : '',
1403
+ bold: useColors ? '\x1b[1m' : '',
1404
+ dim: useColors ? '\x1b[2m' : '',
1405
+ red: useColors ? '\x1b[31m' : '',
1406
+ green: useColors ? '\x1b[32m' : '',
1407
+ yellow: useColors ? '\x1b[33m' : '',
1408
+ blue: useColors ? '\x1b[34m' : '',
1409
+ cyan: useColors ? '\x1b[36m' : '',
1410
+ gray: useColors ? '\x1b[90m' : '',
1411
+ };
1412
+
1413
+ const lines = [];
1414
+
1415
+ lines.push('');
1416
+ lines.push(`${c.bold}grimoire Installation Validation Report${c.reset}`);
1417
+ lines.push(`${c.gray}${'─'.repeat(50)}${c.reset}`);
1418
+
1419
+ // Signature status
1420
+ if (report.manifestVerified) {
1421
+ lines.push(`${c.green}✓${c.reset} Manifest signature: ${c.green}VERIFIED${c.reset}`);
1422
+ } else {
1423
+ lines.push(`${c.red}✗${c.reset} Manifest signature: ${c.red}NOT VERIFIED${c.reset}`);
1424
+ }
1425
+
1426
+ // Status
1427
+ const statusIcon =
1428
+ {
1429
+ success: `${c.green}✓${c.reset}`,
1430
+ warning: `${c.yellow}⚠${c.reset}`,
1431
+ failed: `${c.red}✗${c.reset}`,
1432
+ info: `${c.blue}ℹ${c.reset}`,
1433
+ }[report.status] || '?';
1434
+
1435
+ const statusText =
1436
+ {
1437
+ success: `${c.green}PASSED${c.reset}`,
1438
+ warning: `${c.yellow}WARNING${c.reset}`,
1439
+ failed: `${c.red}FAILED${c.reset}`,
1440
+ info: `${c.blue}INFO${c.reset}`,
1441
+ }[report.status] || 'UNKNOWN';
1442
+
1443
+ lines.push(`${statusIcon} Status: ${statusText}`);
1444
+ lines.push(`${c.dim} Integrity Score: ${report.integrityScore}%${c.reset}`);
1445
+
1446
+ lines.push('');
1447
+ lines.push(`${c.bold}Summary${c.reset}`);
1448
+ lines.push(` Total files: ${report.summary.total}`);
1449
+ lines.push(` ${c.green}Valid:${c.reset} ${report.summary.valid}`);
1450
+
1451
+ if (report.summary.missing > 0) {
1452
+ lines.push(` ${c.red}Missing:${c.reset} ${report.summary.missing}`);
1453
+ }
1454
+ if (report.summary.corrupted > 0) {
1455
+ lines.push(` ${c.yellow}Corrupted:${c.reset} ${report.summary.corrupted}`);
1456
+ }
1457
+ if (report.summary.extra > 0) {
1458
+ lines.push(` ${c.cyan}Extra:${c.reset} ${report.summary.extra}`);
1459
+ }
1460
+ if (report.summary.skipped > 0) {
1461
+ lines.push(` ${c.gray}Skipped:${c.reset} ${report.summary.skipped}`);
1462
+ }
1463
+
1464
+ // Critical issues
1465
+ const criticalIssues = report.issuesBySeverity[Severity.CRITICAL] || [];
1466
+ if (criticalIssues.length > 0) {
1467
+ lines.push('');
1468
+ lines.push(`${c.red}${c.bold}Critical Issues${c.reset}`);
1469
+ for (const issue of criticalIssues.slice(0, 5)) {
1470
+ lines.push(` ${c.red}✗${c.reset} ${issue.message}`);
1471
+ if (issue.remediation) {
1472
+ lines.push(` ${c.dim}→ ${issue.remediation}${c.reset}`);
1473
+ }
1474
+ }
1475
+ }
1476
+
1477
+ // Recommendations
1478
+ if (report.recommendations && report.recommendations.length > 0) {
1479
+ lines.push('');
1480
+ lines.push(`${c.bold}Recommendations${c.reset}`);
1481
+ for (const rec of report.recommendations) {
1482
+ lines.push(` ${c.cyan}→${c.reset} ${rec}`);
1483
+ }
1484
+ }
1485
+
1486
+ lines.push('');
1487
+ lines.push(`${c.dim}Completed in ${report.duration}${c.reset}`);
1488
+ lines.push('');
1489
+
1490
+ return lines.join('\n');
1491
+ }
1492
+
1493
+ /**
1494
+ * Quick validation helper
1495
+ *
1496
+ * @param {string} targetDir - Target directory
1497
+ * @param {Object} [options] - Options
1498
+ * @returns {Promise<Object>} - Report
1499
+ */
1500
+ async function quickValidate(targetDir, options = {}) {
1501
+ const validator = new PostInstallValidator(targetDir, options.sourceDir, {
1502
+ verifyHashes: options.verifyHashes !== false,
1503
+ detectExtras: options.detectExtras === true,
1504
+ verbose: options.verbose === true,
1505
+ requireSignature: options.requireSignature !== false,
1506
+ onProgress: options.onProgress,
1507
+ });
1508
+
1509
+ return validator.validate();
1510
+ }
1511
+
1512
+ module.exports = {
1513
+ PostInstallValidator,
1514
+ formatReport,
1515
+ quickValidate,
1516
+ Severity,
1517
+ IssueType,
1518
+ FileCategory,
1519
+ SecurityLimits,
1520
+ isPathContained,
1521
+ validateManifestEntry,
1522
+ };
1523
+
1524
+