aios-core 4.2.15 → 4.4.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.
- package/.aios-core/cli/commands/validate/index.js +1 -1
- package/.aios-core/core/code-intel/code-intel-client.js +19 -5
- package/.aios-core/core/code-intel/helpers/creation-helper.js +183 -0
- package/.aios-core/core/code-intel/helpers/devops-helper.js +166 -0
- package/.aios-core/core/code-intel/helpers/planning-helper.js +248 -0
- package/.aios-core/core/code-intel/helpers/qa-helper.js +187 -0
- package/.aios-core/core/code-intel/helpers/story-helper.js +146 -0
- package/.aios-core/core/code-intel/hook-runtime.js +186 -0
- package/.aios-core/core/code-intel/index.js +2 -0
- package/.aios-core/core/code-intel/providers/code-graph-provider.js +8 -0
- package/.aios-core/core/code-intel/providers/provider-interface.js +9 -0
- package/.aios-core/core/code-intel/providers/registry-provider.js +515 -0
- package/.aios-core/core/config/schemas/framework-config.schema.json +155 -7
- package/.aios-core/core/config/schemas/project-config.schema.json +329 -15
- package/.aios-core/core/config/template-overrides.js +84 -0
- package/.aios-core/core/docs/troubleshooting-guide.md +1 -1
- package/.aios-core/core/doctor/checks/agent-memory.js +63 -0
- package/.aios-core/core/doctor/checks/claude-md.js +56 -0
- package/.aios-core/core/doctor/checks/code-intel.js +131 -0
- package/.aios-core/core/doctor/checks/commands-count.js +81 -0
- package/.aios-core/core/doctor/checks/core-config.js +53 -0
- package/.aios-core/core/doctor/checks/entity-registry.js +53 -0
- package/.aios-core/core/doctor/checks/git-hooks.js +50 -0
- package/.aios-core/core/doctor/checks/graph-dashboard.js +48 -0
- package/.aios-core/core/doctor/checks/hooks-claude-count.js +118 -0
- package/.aios-core/core/doctor/checks/ide-sync.js +85 -0
- package/.aios-core/core/doctor/checks/index.js +46 -0
- package/.aios-core/core/doctor/checks/node-version.js +33 -0
- package/.aios-core/core/doctor/checks/npm-packages.js +35 -0
- package/.aios-core/core/doctor/checks/rules-files.js +61 -0
- package/.aios-core/core/doctor/checks/settings-json.js +121 -0
- package/.aios-core/core/doctor/checks/skills-count.js +72 -0
- package/.aios-core/core/doctor/fix-handler.js +165 -0
- package/.aios-core/core/doctor/formatters/json.js +14 -0
- package/.aios-core/core/doctor/formatters/text.js +59 -0
- package/.aios-core/core/doctor/index.js +94 -0
- package/.aios-core/core/graph-dashboard/cli.js +361 -0
- package/.aios-core/core/graph-dashboard/data-sources/code-intel-source.js +234 -0
- package/.aios-core/core/graph-dashboard/data-sources/metrics-source.js +95 -0
- package/.aios-core/core/graph-dashboard/data-sources/registry-source.js +106 -0
- package/.aios-core/core/graph-dashboard/formatters/dot-formatter.js +45 -0
- package/.aios-core/core/graph-dashboard/formatters/html-formatter.js +1437 -0
- package/.aios-core/core/graph-dashboard/formatters/json-formatter.js +13 -0
- package/.aios-core/core/graph-dashboard/formatters/mermaid-formatter.js +59 -0
- package/.aios-core/core/graph-dashboard/index.js +21 -0
- package/.aios-core/core/graph-dashboard/renderers/stats-renderer.js +217 -0
- package/.aios-core/core/graph-dashboard/renderers/status-renderer.js +125 -0
- package/.aios-core/core/graph-dashboard/renderers/tree-renderer.js +119 -0
- package/.aios-core/core/health-check/base-check.js +1 -1
- package/.aios-core/core/health-check/check-registry.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/build-config.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/ci-config.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/deployment-readiness.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/docker-config.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/env-file.js +1 -1
- package/.aios-core/core/health-check/checks/deployment/index.js +1 -1
- package/.aios-core/core/health-check/checks/index.js +1 -1
- package/.aios-core/core/health-check/checks/local/disk-space.js +1 -1
- package/.aios-core/core/health-check/checks/local/environment-vars.js +1 -1
- package/.aios-core/core/health-check/checks/local/git-install.js +1 -1
- package/.aios-core/core/health-check/checks/local/ide-detection.js +1 -1
- package/.aios-core/core/health-check/checks/local/index.js +1 -1
- package/.aios-core/core/health-check/checks/local/memory.js +1 -1
- package/.aios-core/core/health-check/checks/local/network.js +1 -1
- package/.aios-core/core/health-check/checks/local/npm-install.js +1 -1
- package/.aios-core/core/health-check/checks/local/shell-environment.js +1 -1
- package/.aios-core/core/health-check/checks/project/agent-config.js +1 -1
- package/.aios-core/core/health-check/checks/project/aios-directory.js +1 -1
- package/.aios-core/core/health-check/checks/project/dependencies.js +1 -1
- package/.aios-core/core/health-check/checks/project/framework-config.js +1 -1
- package/.aios-core/core/health-check/checks/project/index.js +1 -1
- package/.aios-core/core/health-check/checks/project/node-version.js +1 -1
- package/.aios-core/core/health-check/checks/project/package-json.js +1 -1
- package/.aios-core/core/health-check/checks/project/task-definitions.js +1 -1
- package/.aios-core/core/health-check/checks/project/workflow-dependencies.js +1 -1
- package/.aios-core/core/health-check/checks/repository/branch-protection.js +1 -1
- package/.aios-core/core/health-check/checks/repository/commit-history.js +1 -1
- package/.aios-core/core/health-check/checks/repository/conflicts.js +1 -1
- package/.aios-core/core/health-check/checks/repository/git-repo.js +1 -1
- package/.aios-core/core/health-check/checks/repository/git-status.js +1 -1
- package/.aios-core/core/health-check/checks/repository/gitignore.js +1 -1
- package/.aios-core/core/health-check/checks/repository/index.js +1 -1
- package/.aios-core/core/health-check/checks/repository/large-files.js +1 -1
- package/.aios-core/core/health-check/checks/repository/lockfile-integrity.js +1 -1
- package/.aios-core/core/health-check/checks/services/api-endpoints.js +1 -1
- package/.aios-core/core/health-check/checks/services/claude-code.js +1 -1
- package/.aios-core/core/health-check/checks/services/gemini-cli.js +1 -1
- package/.aios-core/core/health-check/checks/services/github-cli.js +1 -1
- package/.aios-core/core/health-check/checks/services/index.js +1 -1
- package/.aios-core/core/health-check/checks/services/mcp-integration.js +1 -1
- package/.aios-core/core/health-check/engine.js +1 -1
- package/.aios-core/core/health-check/healers/backup-manager.js +1 -1
- package/.aios-core/core/health-check/healers/index.js +1 -1
- package/.aios-core/core/health-check/index.js +9 -2
- package/.aios-core/core/health-check/reporters/console.js +1 -1
- package/.aios-core/core/health-check/reporters/index.js +1 -1
- package/.aios-core/core/health-check/reporters/json.js +1 -1
- package/.aios-core/core/health-check/reporters/markdown.js +1 -1
- package/.aios-core/core/ids/layer-classifier.js +65 -0
- package/.aios-core/core/ids/registry-updater.js +49 -0
- package/.aios-core/core/index.esm.js +1 -1
- package/.aios-core/core/index.js +1 -1
- package/.aios-core/core/session/context-detector.js +2 -7
- package/.aios-core/core/synapse/context/context-tracker.js +9 -1
- package/.aios-core/core/synapse/engine.js +33 -13
- package/.aios-core/core/synapse/memory/memory-bridge.js +17 -43
- package/.aios-core/core/synapse/memory/synapse-memory-provider.js +201 -0
- package/.aios-core/core/synapse/runtime/hook-runtime.js +40 -2
- package/.aios-core/core/synapse/session/session-manager.js +3 -2
- package/.aios-core/core/synapse/utils/atomic-write.js +79 -0
- package/.aios-core/core-config.yaml +34 -1
- package/.aios-core/data/aios-kb.md +2 -2
- package/.aios-core/data/capability-detection.js +290 -0
- package/.aios-core/data/entity-registry.yaml +10450 -2129
- package/.aios-core/data/mcp-discipline.js +166 -0
- package/.aios-core/data/mcp-tool-examples.yaml +215 -0
- package/.aios-core/data/tok2-validation.js +168 -0
- package/.aios-core/data/tok3-token-comparison.js +123 -0
- package/.aios-core/data/tool-registry.yaml +648 -0
- package/.aios-core/data/tool-search-validation.js +174 -0
- package/.aios-core/data/workflow-chains.yaml +156 -0
- package/.aios-core/development/agents/aios-master.md +17 -10
- package/.aios-core/development/agents/analyst/MEMORY.md +33 -0
- package/.aios-core/development/agents/analyst.md +17 -10
- package/.aios-core/development/agents/architect/MEMORY.md +39 -0
- package/.aios-core/development/agents/architect.md +17 -10
- package/.aios-core/development/agents/data-engineer/MEMORY.md +32 -0
- package/.aios-core/development/agents/data-engineer.md +17 -10
- package/.aios-core/development/agents/dev/MEMORY.md +46 -0
- package/.aios-core/development/agents/dev.md +18 -11
- package/.aios-core/development/agents/devops/MEMORY.md +39 -0
- package/.aios-core/development/agents/devops.md +44 -10
- package/.aios-core/development/agents/pm/MEMORY.md +38 -0
- package/.aios-core/development/agents/pm.md +17 -10
- package/.aios-core/development/agents/po/MEMORY.md +45 -0
- package/.aios-core/development/agents/po.md +17 -10
- package/.aios-core/development/agents/qa/MEMORY.md +42 -0
- package/.aios-core/development/agents/qa.md +18 -11
- package/.aios-core/development/agents/sm/MEMORY.md +31 -0
- package/.aios-core/development/agents/sm.md +17 -10
- package/.aios-core/development/agents/squad-creator.md +18 -9
- package/.aios-core/development/agents/ux/MEMORY.md +31 -0
- package/.aios-core/development/agents/ux-design-expert.md +16 -9
- package/.aios-core/development/checklists/issue-triage-checklist.md +35 -0
- package/.aios-core/development/checklists/memory-audit-checklist.md +53 -0
- package/.aios-core/development/scripts/issue-triage.js +171 -0
- package/.aios-core/development/scripts/populate-entity-registry.js +412 -19
- package/.aios-core/development/scripts/unified-activation-pipeline.js +31 -10
- package/.aios-core/development/tasks/analyze-project-structure.md +48 -0
- package/.aios-core/development/tasks/apply-qa-fixes.md +7 -0
- package/.aios-core/development/tasks/architect-analyze-impact.md +8 -1
- package/.aios-core/development/tasks/brownfield-create-epic.md +41 -0
- package/.aios-core/development/tasks/brownfield-create-story.md +7 -0
- package/.aios-core/development/tasks/build-autonomous.md +7 -0
- package/.aios-core/development/tasks/create-deep-research-prompt.md +7 -0
- package/.aios-core/development/tasks/create-doc.md +44 -0
- package/.aios-core/development/tasks/create-next-story.md +17 -0
- package/.aios-core/development/tasks/create-suite.md +7 -0
- package/.aios-core/development/tasks/dev-develop-story.md +9 -1
- package/.aios-core/development/tasks/execute-checklist.md +7 -0
- package/.aios-core/development/tasks/github-devops-github-pr-automation.md +56 -0
- package/.aios-core/development/tasks/github-devops-pre-push-quality-gate.md +70 -0
- package/.aios-core/development/tasks/github-issue-triage.md +118 -0
- package/.aios-core/development/tasks/health-check.yaml +206 -171
- package/.aios-core/development/tasks/kb-mode-interaction.md +3 -3
- package/.aios-core/development/tasks/plan-create-context.md +47 -1
- package/.aios-core/development/tasks/plan-create-implementation.md +55 -0
- package/.aios-core/development/tasks/po-close-story.md +7 -0
- package/.aios-core/development/tasks/pr-automation.md +5 -5
- package/.aios-core/development/tasks/qa-create-fix-request.md +7 -0
- package/.aios-core/development/tasks/qa-fix-issues.md +7 -0
- package/.aios-core/development/tasks/qa-gate.md +56 -0
- package/.aios-core/development/tasks/qa-review-story.md +32 -1
- package/.aios-core/development/tasks/release-management.md +7 -0
- package/.aios-core/development/tasks/resolve-github-issue.md +608 -0
- package/.aios-core/development/tasks/review-contributor-pr.md +152 -0
- package/.aios-core/development/tasks/setup-llm-routing.md +1 -1
- package/.aios-core/development/tasks/spec-critique.md +8 -0
- package/.aios-core/development/tasks/spec-gather-requirements.md +7 -0
- package/.aios-core/development/tasks/spec-research-dependencies.md +4 -0
- package/.aios-core/development/tasks/spec-write-spec.md +5 -0
- package/.aios-core/development/tasks/triage-github-issues.md +356 -0
- package/.aios-core/development/tasks/validate-agents.md +4 -0
- package/.aios-core/development/tasks/validate-next-story.md +17 -0
- package/.aios-core/development/templates/agent-handoff-tmpl.yaml +48 -0
- package/.aios-core/development/templates/code-intel-integration-pattern.md +199 -0
- package/.aios-core/development/templates/ptc-entity-validation.md +113 -0
- package/.aios-core/development/templates/ptc-qa-gate.md +100 -0
- package/.aios-core/development/templates/ptc-research-aggregation.md +94 -0
- package/.aios-core/development/templates/service-template/README.md.hbs +158 -158
- package/.aios-core/development/templates/service-template/__tests__/index.test.ts.hbs +237 -237
- package/.aios-core/development/templates/service-template/client.ts.hbs +403 -403
- package/.aios-core/development/templates/service-template/errors.ts.hbs +182 -182
- package/.aios-core/development/templates/service-template/index.ts.hbs +120 -120
- package/.aios-core/development/templates/service-template/package.json.hbs +87 -87
- package/.aios-core/development/templates/service-template/types.ts.hbs +145 -145
- package/.aios-core/development/templates/squad/agent-template.md +11 -0
- package/.aios-core/development/templates/squad/task-template.md +21 -0
- package/.aios-core/development/templates/squad-template/LICENSE +21 -21
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +1 -1
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +1 -1
- package/.aios-core/framework-config.yaml +8 -0
- package/.aios-core/index.esm.js +1 -1
- package/.aios-core/index.js +1 -1
- package/.aios-core/infrastructure/integrations/ai-providers/index.js +1 -1
- package/.aios-core/infrastructure/schemas/task-v3-schema.json +6 -0
- package/.aios-core/infrastructure/scripts/collect-tool-usage.js +311 -0
- package/.aios-core/infrastructure/scripts/generate-optimization-report.js +497 -0
- package/.aios-core/infrastructure/scripts/generate-settings-json.js +300 -0
- package/.aios-core/infrastructure/scripts/git-config-detector.js +65 -9
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +3 -1
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/github-copilot.js +184 -0
- package/.aios-core/infrastructure/scripts/repository-detector.js +3 -3
- package/.aios-core/infrastructure/templates/aios-sync.yaml.template +182 -182
- package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
- package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
- package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
- package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
- package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
- package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
- package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
- package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
- package/.aios-core/install-manifest.yaml +613 -305
- package/.aios-core/lib/build.json +1 -0
- package/.aios-core/local-config.yaml.template +71 -71
- package/.aios-core/monitor/hooks/lib/__init__.py +1 -1
- package/.aios-core/monitor/hooks/lib/enrich.py +58 -58
- package/.aios-core/monitor/hooks/lib/send_event.py +47 -47
- package/.aios-core/monitor/hooks/notification.py +29 -29
- package/.aios-core/monitor/hooks/post_tool_use.py +45 -45
- package/.aios-core/monitor/hooks/pre_compact.py +29 -29
- package/.aios-core/monitor/hooks/pre_tool_use.py +40 -40
- package/.aios-core/monitor/hooks/stop.py +29 -29
- package/.aios-core/monitor/hooks/subagent_stop.py +29 -29
- package/.aios-core/monitor/hooks/user_prompt_submit.py +38 -38
- package/.aios-core/product/templates/adr.hbs +125 -125
- package/.aios-core/product/templates/dbdr.hbs +241 -241
- package/.aios-core/product/templates/epic.hbs +212 -212
- package/.aios-core/product/templates/ide-rules/claude-rules.md +125 -0
- package/.aios-core/product/templates/pmdr.hbs +186 -186
- package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
- package/.aios-core/product/templates/prd.hbs +201 -201
- package/.aios-core/product/templates/story.hbs +263 -263
- package/.aios-core/product/templates/task.hbs +170 -170
- package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
- package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
- package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
- package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
- package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
- package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
- package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
- package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
- package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
- package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
- package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
- package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
- package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
- package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
- package/.aios-core/product/templates/tmpl-view.sql +177 -177
- package/.aios-core/scripts/pm.sh +0 -0
- package/.aios-core/user-guide.md +15 -15
- package/.aios-core/utils/filters/constants.js +10 -0
- package/.aios-core/utils/filters/content-filter.js +223 -0
- package/.aios-core/utils/filters/field-filter.js +126 -0
- package/.aios-core/utils/filters/index.js +180 -0
- package/.aios-core/utils/filters/schema-filter.js +157 -0
- package/.claude/CLAUDE.md +62 -0
- package/.claude/hooks/enforce-architecture-first.py +196 -196
- package/.claude/hooks/enforce-git-push-authority.sh +33 -0
- package/.claude/hooks/mind-clone-governance.py +192 -192
- package/.claude/hooks/read-protection.py +151 -151
- package/.claude/hooks/slug-validation.py +176 -176
- package/.claude/hooks/sql-governance.py +182 -182
- package/.claude/hooks/synapse-engine.cjs +28 -5
- package/.claude/hooks/write-path-validation.py +194 -194
- package/.claude/rules/agent-authority.md +105 -0
- package/.claude/rules/agent-handoff.md +97 -0
- package/.claude/rules/agent-memory-imports.md +15 -0
- package/.claude/rules/coderabbit-integration.md +101 -0
- package/.claude/rules/ids-principles.md +119 -0
- package/.claude/rules/story-lifecycle.md +145 -0
- package/.claude/rules/tool-examples.md +64 -0
- package/.claude/rules/tool-response-filtering.md +57 -0
- package/.claude/rules/workflow-execution.md +150 -0
- package/LICENSE +33 -33
- package/bin/aios-graph.js +9 -0
- package/bin/aios-init.js +2 -2
- package/bin/aios-minimal.js +0 -0
- package/bin/aios.js +17 -221
- package/bin/utils/detect-fsmonitor.js +70 -0
- package/bin/utils/framework-guard.js +238 -0
- package/bin/utils/validate-publish.js +108 -0
- package/package.json +6 -3
- package/packages/aios-install/bin/aios-install.js +0 -0
- package/packages/aios-install/bin/edmcp.js +0 -0
- package/packages/aios-pro-cli/bin/aios-pro.js +2 -0
- package/packages/installer/src/config/templates/core-config-template.js +25 -0
- package/packages/installer/src/installer/brownfield-upgrader.js +68 -5
- package/packages/installer/src/merger/index.js +3 -0
- package/packages/installer/src/merger/strategies/index.js +6 -0
- package/packages/installer/src/merger/strategies/yaml-merger.js +181 -0
- package/packages/installer/src/updater/index.js +4 -4
- package/packages/installer/src/wizard/i18n.js +321 -3
- package/packages/installer/src/wizard/ide-config-generator.js +173 -25
- package/packages/installer/src/wizard/index.js +119 -1
- package/packages/installer/src/wizard/pro-setup.js +137 -121
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +271 -0
- package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +192 -0
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +610 -0
- package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +134 -0
- package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +186 -0
- package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +309 -0
- package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +230 -0
- package/packages/installer/tests/unit/merger/strategies.test.js +2 -2
- package/packages/installer/tests/unit/merger/yaml-merger.test.js +327 -0
- package/scripts/check-markdown-links.py +352 -352
- package/scripts/dashboard-parallel-dev.sh +0 -0
- package/scripts/dashboard-parallel-phase3.sh +0 -0
- package/scripts/dashboard-parallel-phase4.sh +0 -0
- package/scripts/install-monitor-hooks.sh +0 -0
- package/scripts/package-synapse.js +2 -1
- package/pro/README.md +0 -66
- package/pro/license/degradation.js +0 -220
- package/pro/license/errors.js +0 -450
- package/pro/license/feature-gate.js +0 -354
- package/pro/license/index.js +0 -181
- package/pro/license/license-api.js +0 -651
- package/pro/license/license-cache.js +0 -523
- package/pro/license/license-crypto.js +0 -303
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
copySkillFiles,
|
|
9
|
+
copyExtraCommandFiles,
|
|
10
|
+
createClaudeSettingsLocal,
|
|
11
|
+
} = require('../../../../../packages/installer/src/wizard/ide-config-generator');
|
|
12
|
+
|
|
13
|
+
function createTempDir() {
|
|
14
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), 'artifact-copy-'));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function cleanup(dir) {
|
|
18
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe('artifact-copy-pipeline (Story INS-4.3)', () => {
|
|
22
|
+
describe('copySkillFiles', () => {
|
|
23
|
+
test('copies skill directories from source to target via real function', async () => {
|
|
24
|
+
const sourceRoot = createTempDir();
|
|
25
|
+
const targetRoot = createTempDir();
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// Create source skills
|
|
29
|
+
const skillsDir = path.join(sourceRoot, '.claude', 'skills');
|
|
30
|
+
for (const skill of ['skill-a', 'skill-b', 'skill-c']) {
|
|
31
|
+
const dir = path.join(skillsDir, skill);
|
|
32
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
33
|
+
fs.writeFileSync(path.join(dir, 'SKILL.md'), `# ${skill}`, 'utf8');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Call the REAL exported function with _sourceRoot override
|
|
37
|
+
const result = await copySkillFiles(targetRoot, sourceRoot);
|
|
38
|
+
|
|
39
|
+
expect(result.count).toBe(3);
|
|
40
|
+
expect(result.skipped).toBe(false);
|
|
41
|
+
|
|
42
|
+
// Verify files actually copied to target
|
|
43
|
+
const targetSkills = path.join(targetRoot, '.claude', 'skills');
|
|
44
|
+
const copied = fs.readdirSync(targetSkills);
|
|
45
|
+
expect(copied).toContain('skill-a');
|
|
46
|
+
expect(copied).toContain('skill-b');
|
|
47
|
+
expect(copied).toContain('skill-c');
|
|
48
|
+
expect(copied.length).toBe(3);
|
|
49
|
+
|
|
50
|
+
// Verify SKILL.md content preserved
|
|
51
|
+
const skillMd = fs.readFileSync(path.join(targetSkills, 'skill-a', 'SKILL.md'), 'utf8');
|
|
52
|
+
expect(skillMd).toBe('# skill-a');
|
|
53
|
+
} finally {
|
|
54
|
+
cleanup(sourceRoot);
|
|
55
|
+
cleanup(targetRoot);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('returns skipped when source does not exist', async () => {
|
|
60
|
+
const targetRoot = createTempDir();
|
|
61
|
+
const fakeSourceRoot = path.join(os.tmpdir(), 'nonexistent-source-' + Date.now());
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
// Call the REAL function with a non-existent source
|
|
65
|
+
const result = await copySkillFiles(targetRoot, fakeSourceRoot);
|
|
66
|
+
|
|
67
|
+
expect(result.skipped).toBe(true);
|
|
68
|
+
expect(result.count).toBe(0);
|
|
69
|
+
} finally {
|
|
70
|
+
cleanup(targetRoot);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('copy is idempotent — re-copy overwrites without corruption', async () => {
|
|
75
|
+
const sourceRoot = createTempDir();
|
|
76
|
+
const targetRoot = createTempDir();
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const skillsDir = path.join(sourceRoot, '.claude', 'skills', 'test-skill');
|
|
80
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
81
|
+
fs.writeFileSync(path.join(skillsDir, 'SKILL.md'), '# v1', 'utf8');
|
|
82
|
+
|
|
83
|
+
// First copy
|
|
84
|
+
await copySkillFiles(targetRoot, sourceRoot);
|
|
85
|
+
|
|
86
|
+
// Update source to v2
|
|
87
|
+
fs.writeFileSync(path.join(skillsDir, 'SKILL.md'), '# v2', 'utf8');
|
|
88
|
+
|
|
89
|
+
// Second copy (idempotent overwrite)
|
|
90
|
+
const result = await copySkillFiles(targetRoot, sourceRoot);
|
|
91
|
+
|
|
92
|
+
expect(result.count).toBe(1);
|
|
93
|
+
const content = fs.readFileSync(
|
|
94
|
+
path.join(targetRoot, '.claude', 'skills', 'test-skill', 'SKILL.md'),
|
|
95
|
+
'utf8'
|
|
96
|
+
);
|
|
97
|
+
expect(content).toBe('# v2');
|
|
98
|
+
} finally {
|
|
99
|
+
cleanup(sourceRoot);
|
|
100
|
+
cleanup(targetRoot);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('copyExtraCommandFiles', () => {
|
|
106
|
+
test('copies .md files recursively excluding AIOS/agents/ via real function', async () => {
|
|
107
|
+
const sourceRoot = createTempDir();
|
|
108
|
+
const targetRoot = createTempDir();
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
const cmdDir = path.join(sourceRoot, '.claude', 'commands');
|
|
112
|
+
|
|
113
|
+
// Create greet.md (root level)
|
|
114
|
+
fs.mkdirSync(cmdDir, { recursive: true });
|
|
115
|
+
fs.writeFileSync(path.join(cmdDir, 'greet.md'), '# Greet', 'utf8');
|
|
116
|
+
|
|
117
|
+
// Create synapse/manager.md
|
|
118
|
+
const synapseDir = path.join(cmdDir, 'synapse');
|
|
119
|
+
fs.mkdirSync(synapseDir, { recursive: true });
|
|
120
|
+
fs.writeFileSync(path.join(synapseDir, 'manager.md'), '# Manager', 'utf8');
|
|
121
|
+
|
|
122
|
+
// Create synapse/tasks/add-rule.md
|
|
123
|
+
const tasksDir = path.join(synapseDir, 'tasks');
|
|
124
|
+
fs.mkdirSync(tasksDir, { recursive: true });
|
|
125
|
+
fs.writeFileSync(path.join(tasksDir, 'add-rule.md'), '# Add Rule', 'utf8');
|
|
126
|
+
|
|
127
|
+
// Create AIOS/agents/dev.md (should be EXCLUDED)
|
|
128
|
+
const agentsDir = path.join(cmdDir, 'AIOS', 'agents');
|
|
129
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
130
|
+
fs.writeFileSync(path.join(agentsDir, 'dev.md'), '# Dev Agent', 'utf8');
|
|
131
|
+
|
|
132
|
+
// Create AIOS/stories/story.md (should be EXCLUDED — project-specific)
|
|
133
|
+
const storiesDir = path.join(cmdDir, 'AIOS', 'stories');
|
|
134
|
+
fs.mkdirSync(storiesDir, { recursive: true });
|
|
135
|
+
fs.writeFileSync(path.join(storiesDir, 'story.md'), '# Story', 'utf8');
|
|
136
|
+
|
|
137
|
+
// Create squad directory (should be EXCLUDED — private)
|
|
138
|
+
const squadDir = path.join(cmdDir, 'cohort-squad');
|
|
139
|
+
fs.mkdirSync(squadDir, { recursive: true });
|
|
140
|
+
fs.writeFileSync(path.join(squadDir, 'manager.md'), '# Squad', 'utf8');
|
|
141
|
+
|
|
142
|
+
// Call the REAL exported function with _sourceRoot override
|
|
143
|
+
const result = await copyExtraCommandFiles(targetRoot, sourceRoot);
|
|
144
|
+
|
|
145
|
+
expect(result.count).toBe(3); // greet.md, manager.md, add-rule.md
|
|
146
|
+
expect(result.skipped).toBe(false);
|
|
147
|
+
|
|
148
|
+
// Verify distributable entries copied
|
|
149
|
+
const targetCmd = path.join(targetRoot, '.claude', 'commands');
|
|
150
|
+
expect(fs.existsSync(path.join(targetCmd, 'greet.md'))).toBe(true);
|
|
151
|
+
expect(fs.existsSync(path.join(targetCmd, 'synapse', 'manager.md'))).toBe(true);
|
|
152
|
+
expect(fs.existsSync(path.join(targetCmd, 'synapse', 'tasks', 'add-rule.md'))).toBe(true);
|
|
153
|
+
|
|
154
|
+
// Verify AIOS/agents/ was excluded (handled by copyAgentFiles)
|
|
155
|
+
expect(fs.existsSync(path.join(targetCmd, 'AIOS', 'agents', 'dev.md'))).toBe(false);
|
|
156
|
+
|
|
157
|
+
// Verify AIOS/stories/ was excluded (project-specific)
|
|
158
|
+
expect(fs.existsSync(path.join(targetCmd, 'AIOS', 'stories', 'story.md'))).toBe(false);
|
|
159
|
+
|
|
160
|
+
// Verify squad directories not copied (private)
|
|
161
|
+
expect(fs.existsSync(path.join(targetCmd, 'cohort-squad'))).toBe(false);
|
|
162
|
+
} finally {
|
|
163
|
+
cleanup(sourceRoot);
|
|
164
|
+
cleanup(targetRoot);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('createClaudeSettingsLocal — hooks registration', () => {
|
|
170
|
+
test('registers ALL .cjs hooks in settings.local.json', async () => {
|
|
171
|
+
const tmpDir = createTempDir();
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
// Create hooks directory with 2 .cjs files
|
|
175
|
+
const hooksDir = path.join(tmpDir, '.claude', 'hooks');
|
|
176
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
177
|
+
fs.writeFileSync(path.join(hooksDir, 'synapse-engine.cjs'), '// hook 1', 'utf8');
|
|
178
|
+
fs.writeFileSync(path.join(hooksDir, 'precompact-session-digest.cjs'), '// hook 2', 'utf8');
|
|
179
|
+
fs.writeFileSync(path.join(hooksDir, 'README.md'), '# Hooks', 'utf8');
|
|
180
|
+
|
|
181
|
+
const result = await createClaudeSettingsLocal(tmpDir);
|
|
182
|
+
|
|
183
|
+
expect(result).not.toBeNull();
|
|
184
|
+
|
|
185
|
+
const settingsContent = fs.readFileSync(path.join(tmpDir, '.claude', 'settings.local.json'), 'utf8');
|
|
186
|
+
const settings = JSON.parse(settingsContent);
|
|
187
|
+
|
|
188
|
+
// Should have hooks.UserPromptSubmit with 2 entries
|
|
189
|
+
expect(settings.hooks).toBeDefined();
|
|
190
|
+
expect(settings.hooks.UserPromptSubmit).toBeDefined();
|
|
191
|
+
expect(settings.hooks.UserPromptSubmit.length).toBe(2);
|
|
192
|
+
|
|
193
|
+
// Both hooks registered
|
|
194
|
+
const commands = settings.hooks.UserPromptSubmit.flatMap(entry =>
|
|
195
|
+
entry.hooks.map(h => h.command)
|
|
196
|
+
);
|
|
197
|
+
expect(commands.some(c => c.includes('synapse-engine'))).toBe(true);
|
|
198
|
+
expect(commands.some(c => c.includes('precompact-session-digest'))).toBe(true);
|
|
199
|
+
} finally {
|
|
200
|
+
cleanup(tmpDir);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('returns null when no hooks directory exists', async () => {
|
|
205
|
+
const tmpDir = createTempDir();
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
fs.mkdirSync(path.join(tmpDir, '.claude'), { recursive: true });
|
|
209
|
+
const result = await createClaudeSettingsLocal(tmpDir);
|
|
210
|
+
expect(result).toBeNull();
|
|
211
|
+
} finally {
|
|
212
|
+
cleanup(tmpDir);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test('does not duplicate hooks on re-run (idempotent)', async () => {
|
|
217
|
+
const tmpDir = createTempDir();
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
const hooksDir = path.join(tmpDir, '.claude', 'hooks');
|
|
221
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
222
|
+
fs.writeFileSync(path.join(hooksDir, 'synapse-engine.cjs'), '// hook', 'utf8');
|
|
223
|
+
|
|
224
|
+
// Run twice
|
|
225
|
+
await createClaudeSettingsLocal(tmpDir);
|
|
226
|
+
await createClaudeSettingsLocal(tmpDir);
|
|
227
|
+
|
|
228
|
+
const settingsContent = fs.readFileSync(path.join(tmpDir, '.claude', 'settings.local.json'), 'utf8');
|
|
229
|
+
const settings = JSON.parse(settingsContent);
|
|
230
|
+
|
|
231
|
+
// Should still have only 1 entry
|
|
232
|
+
expect(settings.hooks.UserPromptSubmit.length).toBe(1);
|
|
233
|
+
} finally {
|
|
234
|
+
cleanup(tmpDir);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test('preserves existing settings when merging hooks', async () => {
|
|
239
|
+
const tmpDir = createTempDir();
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const hooksDir = path.join(tmpDir, '.claude', 'hooks');
|
|
243
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
244
|
+
fs.writeFileSync(path.join(hooksDir, 'synapse-engine.cjs'), '// hook', 'utf8');
|
|
245
|
+
|
|
246
|
+
// Create existing settings
|
|
247
|
+
const settingsPath = path.join(tmpDir, '.claude', 'settings.local.json');
|
|
248
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ customKey: 'preserved' }, null, 2), 'utf8');
|
|
249
|
+
|
|
250
|
+
await createClaudeSettingsLocal(tmpDir);
|
|
251
|
+
|
|
252
|
+
const settingsContent = fs.readFileSync(settingsPath, 'utf8');
|
|
253
|
+
const settings = JSON.parse(settingsContent);
|
|
254
|
+
|
|
255
|
+
expect(settings.customKey).toBe('preserved');
|
|
256
|
+
expect(settings.hooks.UserPromptSubmit.length).toBe(1);
|
|
257
|
+
} finally {
|
|
258
|
+
cleanup(tmpDir);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
describe('generator failure graceful degradation', () => {
|
|
264
|
+
test('generate-settings-json throws on missing config — install should catch', () => {
|
|
265
|
+
const { generate } = require('../../../../../.aios-core/infrastructure/scripts/generate-settings-json');
|
|
266
|
+
|
|
267
|
+
// Calling generate on a non-existent path should throw
|
|
268
|
+
expect(() => generate('/nonexistent/path')).toThrow();
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
});
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { MarkdownMerger } = require('../../../src/merger/strategies/markdown-merger.js');
|
|
6
|
+
const {
|
|
7
|
+
parseMarkdownSections,
|
|
8
|
+
hasAiosMarkers,
|
|
9
|
+
} = require('../../../src/merger/parsers/markdown-section-parser.js');
|
|
10
|
+
|
|
11
|
+
const TEMPLATE_PATH = path.join(
|
|
12
|
+
__dirname, '..', '..', '..', '..', '..', '.aios-core',
|
|
13
|
+
'product', 'templates', 'ide-rules', 'claude-rules.md'
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
describe('CLAUDE.md Template v5 (Story INS-4.4)', () => {
|
|
17
|
+
let templateContent;
|
|
18
|
+
|
|
19
|
+
beforeAll(() => {
|
|
20
|
+
templateContent = fs.readFileSync(TEMPLATE_PATH, 'utf8');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('template has 4 new sections with AIOS-MANAGED markers', () => {
|
|
24
|
+
test('template file exists and has AIOS markers', () => {
|
|
25
|
+
expect(templateContent).toBeTruthy();
|
|
26
|
+
expect(hasAiosMarkers(templateContent)).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('contains framework-boundary section', () => {
|
|
30
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: framework-boundary -->');
|
|
31
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-END: framework-boundary -->');
|
|
32
|
+
expect(templateContent).toContain('## Framework vs Project Boundary');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('contains rules-system section', () => {
|
|
36
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: rules-system -->');
|
|
37
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-END: rules-system -->');
|
|
38
|
+
expect(templateContent).toContain('## Rules System');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('contains code-intelligence section', () => {
|
|
42
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: code-intelligence -->');
|
|
43
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-END: code-intelligence -->');
|
|
44
|
+
expect(templateContent).toContain('## Code Intelligence');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('contains graph-dashboard section', () => {
|
|
48
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: graph-dashboard -->');
|
|
49
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-END: graph-dashboard -->');
|
|
50
|
+
expect(templateContent).toContain('## Graph Dashboard');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('template has exactly 11 AIOS-MANAGED sections total', () => {
|
|
54
|
+
const startMatches = templateContent.match(/<!-- AIOS-MANAGED-START:/g);
|
|
55
|
+
const endMatches = templateContent.match(/<!-- AIOS-MANAGED-END:/g);
|
|
56
|
+
expect(startMatches.length).toBe(11);
|
|
57
|
+
expect(endMatches.length).toBe(11);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('section content quality', () => {
|
|
62
|
+
test('framework-boundary has L1-L4 table', () => {
|
|
63
|
+
expect(templateContent).toContain('**L1** Framework Core');
|
|
64
|
+
expect(templateContent).toContain('**L2** Framework Templates');
|
|
65
|
+
expect(templateContent).toContain('**L3** Project Config');
|
|
66
|
+
expect(templateContent).toContain('**L4** Project Runtime');
|
|
67
|
+
expect(templateContent).toContain('frameworkProtection');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('rules-system lists all 8 rule files', () => {
|
|
71
|
+
const ruleFiles = [
|
|
72
|
+
'agent-authority.md',
|
|
73
|
+
'agent-handoff.md',
|
|
74
|
+
'agent-memory-imports.md',
|
|
75
|
+
'coderabbit-integration.md',
|
|
76
|
+
'ids-principles.md',
|
|
77
|
+
'mcp-usage.md',
|
|
78
|
+
'story-lifecycle.md',
|
|
79
|
+
'workflow-execution.md',
|
|
80
|
+
];
|
|
81
|
+
for (const file of ruleFiles) {
|
|
82
|
+
expect(templateContent).toContain(file);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('code-intelligence has provider status table', () => {
|
|
87
|
+
expect(templateContent).toContain('**Configured**');
|
|
88
|
+
expect(templateContent).toContain('**Fallback**');
|
|
89
|
+
expect(templateContent).toContain('**Disabled**');
|
|
90
|
+
expect(templateContent).toContain('isCodeIntelAvailable()');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('graph-dashboard has CLI commands', () => {
|
|
94
|
+
expect(templateContent).toContain('aios graph --deps');
|
|
95
|
+
expect(templateContent).toContain('--format=json');
|
|
96
|
+
expect(templateContent).toContain('--format=html');
|
|
97
|
+
expect(templateContent).toContain('--watch');
|
|
98
|
+
expect(templateContent).toContain('aios graph --stats');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('existing sections preserved', () => {
|
|
103
|
+
test('original 5 AIOS-MANAGED sections still present', () => {
|
|
104
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: core-framework -->');
|
|
105
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: agent-system -->');
|
|
106
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: framework-structure -->');
|
|
107
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: aios-patterns -->');
|
|
108
|
+
expect(templateContent).toContain('<!-- AIOS-MANAGED-START: common-commands -->');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('non-managed sections still present', () => {
|
|
112
|
+
expect(templateContent).toContain('## Development Methodology');
|
|
113
|
+
expect(templateContent).toContain('## Workflow Execution');
|
|
114
|
+
expect(templateContent).toContain('## Best Practices');
|
|
115
|
+
expect(templateContent).toContain('## Debugging');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('upgrade: new sections added to existing CLAUDE.md', () => {
|
|
120
|
+
let merger;
|
|
121
|
+
|
|
122
|
+
beforeEach(() => {
|
|
123
|
+
merger = new MarkdownMerger();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('upgrade adds 4 new sections to CLAUDE.md without them', async () => {
|
|
127
|
+
const existingClaudeMd = `# Synkra AIOS
|
|
128
|
+
|
|
129
|
+
<!-- AIOS-MANAGED-START: core-framework -->
|
|
130
|
+
## Core Framework Understanding
|
|
131
|
+
Old core content
|
|
132
|
+
<!-- AIOS-MANAGED-END: core-framework -->
|
|
133
|
+
|
|
134
|
+
## My Custom Section
|
|
135
|
+
User content that must be preserved`;
|
|
136
|
+
|
|
137
|
+
const result = await merger.merge(existingClaudeMd, templateContent);
|
|
138
|
+
|
|
139
|
+
// New sections added
|
|
140
|
+
expect(result.content).toContain('## Framework vs Project Boundary');
|
|
141
|
+
expect(result.content).toContain('## Rules System');
|
|
142
|
+
expect(result.content).toContain('## Code Intelligence');
|
|
143
|
+
expect(result.content).toContain('## Graph Dashboard');
|
|
144
|
+
|
|
145
|
+
// User content preserved
|
|
146
|
+
expect(result.content).toContain('## My Custom Section');
|
|
147
|
+
expect(result.content).toContain('User content that must be preserved');
|
|
148
|
+
|
|
149
|
+
// Stats reflect additions
|
|
150
|
+
expect(result.stats.added).toBeGreaterThanOrEqual(4);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('upgrade preserves custom PROJECT-CUSTOMIZED content', async () => {
|
|
154
|
+
const existingClaudeMd = `# My Project Rules
|
|
155
|
+
|
|
156
|
+
<!-- AIOS-MANAGED-START: core-framework -->
|
|
157
|
+
## Core Framework Understanding
|
|
158
|
+
Core content
|
|
159
|
+
<!-- AIOS-MANAGED-END: core-framework -->
|
|
160
|
+
|
|
161
|
+
## Padroes de Codigo
|
|
162
|
+
My custom coding standards here
|
|
163
|
+
|
|
164
|
+
## Testes & Quality Gates
|
|
165
|
+
My custom testing rules`;
|
|
166
|
+
|
|
167
|
+
const result = await merger.merge(existingClaudeMd, templateContent);
|
|
168
|
+
|
|
169
|
+
// Custom sections preserved
|
|
170
|
+
expect(result.content).toContain('## Padroes de Codigo');
|
|
171
|
+
expect(result.content).toContain('My custom coding standards here');
|
|
172
|
+
expect(result.content).toContain('## Testes & Quality Gates');
|
|
173
|
+
expect(result.content).toContain('My custom testing rules');
|
|
174
|
+
|
|
175
|
+
// Managed sections updated
|
|
176
|
+
expect(result.content).toContain('<!-- AIOS-MANAGED-START: framework-boundary -->');
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('section order in template', () => {
|
|
181
|
+
test('4 new sections come after framework-structure and before workflow-execution', () => {
|
|
182
|
+
const frameworkStructureEnd = templateContent.indexOf('<!-- AIOS-MANAGED-END: framework-structure -->');
|
|
183
|
+
const frameworkBoundaryStart = templateContent.indexOf('<!-- AIOS-MANAGED-START: framework-boundary -->');
|
|
184
|
+
const graphDashboardEnd = templateContent.indexOf('<!-- AIOS-MANAGED-END: graph-dashboard -->');
|
|
185
|
+
const workflowExecution = templateContent.indexOf('## Workflow Execution');
|
|
186
|
+
|
|
187
|
+
expect(frameworkStructureEnd).toBeLessThan(frameworkBoundaryStart);
|
|
188
|
+
expect(frameworkBoundaryStart).toBeLessThan(graphDashboardEnd);
|
|
189
|
+
expect(graphDashboardEnd).toBeLessThan(workflowExecution);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|