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
package/LICENSE
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 BMad Code, LLC (BMad Method - original work)
|
|
4
|
-
Copyright (c) 2025 SynkraAI Inc. (AIOS Framework - derivative work)
|
|
5
|
-
|
|
6
|
-
This project was originally derived from the BMad Method
|
|
7
|
-
(https://github.com/bmad-code-org/BMAD-METHOD), created by Brian Madison.
|
|
8
|
-
Synkra AIOS is NOT affiliated with, endorsed by, or sanctioned by the
|
|
9
|
-
BMad Method or BMad Code, LLC.
|
|
10
|
-
|
|
11
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
-
in the Software without restriction, including without limitation the rights
|
|
14
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
-
furnished to do so, subject to the following conditions:
|
|
17
|
-
|
|
18
|
-
The above copyright notice and this permission notice shall be included in all
|
|
19
|
-
copies or substantial portions of the Software.
|
|
20
|
-
|
|
21
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
-
SOFTWARE.
|
|
28
|
-
|
|
29
|
-
TRADEMARK NOTICE:
|
|
30
|
-
BMad, BMad Method, and BMad Core are trademarks of BMad Code, LLC.
|
|
31
|
-
These trademarks are NOT licensed under the MIT License. See the BMad Method
|
|
32
|
-
TRADEMARK.md (https://github.com/bmad-code-org/BMAD-METHOD/blob/main/TRADEMARK.md)
|
|
33
|
-
for detailed guidelines on trademark usage.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 BMad Code, LLC (BMad Method - original work)
|
|
4
|
+
Copyright (c) 2025 SynkraAI Inc. (AIOS Framework - derivative work)
|
|
5
|
+
|
|
6
|
+
This project was originally derived from the BMad Method
|
|
7
|
+
(https://github.com/bmad-code-org/BMAD-METHOD), created by Brian Madison.
|
|
8
|
+
Synkra AIOS is NOT affiliated with, endorsed by, or sanctioned by the
|
|
9
|
+
BMad Method or BMad Code, LLC.
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
TRADEMARK NOTICE:
|
|
30
|
+
BMad, BMad Method, and BMad Core are trademarks of BMad Code, LLC.
|
|
31
|
+
These trademarks are NOT licensed under the MIT License. See the BMad Method
|
|
32
|
+
TRADEMARK.md (https://github.com/bmad-code-org/BMAD-METHOD/blob/main/TRADEMARK.md)
|
|
33
|
+
for detailed guidelines on trademark usage.
|
package/bin/aios-init.js
CHANGED
|
@@ -85,7 +85,7 @@ function resolveAiosCoreModule(modulePath) {
|
|
|
85
85
|
throw new Error(
|
|
86
86
|
`Cannot find AIOS Core module: ${modulePath}\n` +
|
|
87
87
|
`Searched: ${aiosCoreModule}\n` +
|
|
88
|
-
'Please ensure
|
|
88
|
+
'Please ensure aios-core is installed correctly.'
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -766,7 +766,7 @@ See .aios-core/user-guide.md for complete documentation.
|
|
|
766
766
|
// Secondary: context-based framework location - squads/
|
|
767
767
|
path.join(context.frameworkLocation, 'squads'),
|
|
768
768
|
// Tertiary: installed in project's node_modules - squads/
|
|
769
|
-
path.join(context.projectRoot, 'node_modules', '
|
|
769
|
+
path.join(context.projectRoot, 'node_modules', 'aios-core', 'squads'),
|
|
770
770
|
path.join(context.projectRoot, 'node_modules', '@aios', 'fullstack', 'squads'),
|
|
771
771
|
];
|
|
772
772
|
|
package/bin/aios-minimal.js
CHANGED
|
File without changes
|
package/bin/aios.js
CHANGED
|
@@ -206,6 +206,7 @@ function showInfo() {
|
|
|
206
206
|
console.log(` - Tasks: ${countFiles(path.join(componentBase, 'tasks'))}`);
|
|
207
207
|
console.log(` - Templates: ${countFiles(path.join(componentBase, 'templates'))}`);
|
|
208
208
|
console.log(` - Workflows: ${countFiles(path.join(componentBase, 'workflows'))}`);
|
|
209
|
+
|
|
209
210
|
} else {
|
|
210
211
|
console.log('\n⚠️ AIOS Core not found');
|
|
211
212
|
}
|
|
@@ -350,230 +351,23 @@ async function runUpdate() {
|
|
|
350
351
|
}
|
|
351
352
|
}
|
|
352
353
|
|
|
353
|
-
// Helper: Run doctor diagnostics
|
|
354
|
-
async function runDoctor() {
|
|
355
|
-
const
|
|
356
|
-
const shouldFix = doctorArgs.includes('--fix');
|
|
357
|
-
const isDryRun = doctorArgs.includes('--dry-run');
|
|
358
|
-
const showHelp = doctorArgs.includes('--help') || doctorArgs.includes('-h');
|
|
359
|
-
|
|
360
|
-
if (showHelp) {
|
|
361
|
-
console.log(`
|
|
362
|
-
Usage: aios-core doctor [options]
|
|
363
|
-
|
|
364
|
-
Run system diagnostics and optionally fix issues.
|
|
365
|
-
|
|
366
|
-
Options:
|
|
367
|
-
--fix Attempt to automatically fix detected issues
|
|
368
|
-
--dry-run Show what would be fixed without making changes
|
|
369
|
-
-h, --help Show this help message
|
|
370
|
-
|
|
371
|
-
Examples:
|
|
372
|
-
$ npx aios-core doctor # Run diagnostics
|
|
373
|
-
$ npx aios-core doctor --fix # Fix detected issues
|
|
374
|
-
$ npx aios-core doctor --dry-run # Preview fixes
|
|
375
|
-
`);
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
console.log('🏥 AIOS System Diagnostics\n');
|
|
380
|
-
|
|
381
|
-
const issues = [];
|
|
382
|
-
let hasErrors = false;
|
|
383
|
-
|
|
384
|
-
// Helper: Compare semver versions
|
|
385
|
-
const compareVersions = (a, b) => {
|
|
386
|
-
const pa = a.split('.').map((n) => parseInt(n, 10));
|
|
387
|
-
const pb = b.split('.').map((n) => parseInt(n, 10));
|
|
388
|
-
for (let i = 0; i < 3; i++) {
|
|
389
|
-
const na = pa[i] || 0;
|
|
390
|
-
const nb = pb[i] || 0;
|
|
391
|
-
if (na > nb) return 1;
|
|
392
|
-
if (na < nb) return -1;
|
|
393
|
-
}
|
|
394
|
-
return 0;
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
// Check 1: Node.js version
|
|
398
|
-
const nodeVersion = process.version.replace('v', '');
|
|
399
|
-
const requiredNodeVersion = '18.0.0';
|
|
400
|
-
const nodeOk = compareVersions(nodeVersion, requiredNodeVersion) >= 0;
|
|
401
|
-
|
|
402
|
-
if (!nodeOk) {
|
|
403
|
-
issues.push({
|
|
404
|
-
type: 'node_version',
|
|
405
|
-
autoFix: false,
|
|
406
|
-
message: `Node.js version: ${process.version} (requires >=18.0.0)`,
|
|
407
|
-
suggestion: 'nvm install 20 && nvm use 20',
|
|
408
|
-
});
|
|
409
|
-
hasErrors = true;
|
|
410
|
-
}
|
|
411
|
-
console.log(
|
|
412
|
-
`${nodeOk ? '✔' : '✗'} Node.js version: ${process.version} ${nodeOk ? '(meets requirement: >=18.0.0)' : '(requires >=18.0.0)'}`,
|
|
413
|
-
);
|
|
414
|
-
|
|
415
|
-
// Check 2: npm
|
|
416
|
-
try {
|
|
417
|
-
const npmVersion = execSync('npm --version', { encoding: 'utf8' }).trim();
|
|
418
|
-
console.log(`✔ npm version: ${npmVersion}`);
|
|
419
|
-
} catch {
|
|
420
|
-
issues.push({
|
|
421
|
-
type: 'npm',
|
|
422
|
-
autoFix: false,
|
|
423
|
-
message: 'npm not found',
|
|
424
|
-
suggestion: 'Install Node.js from https://nodejs.org (includes npm)',
|
|
425
|
-
});
|
|
426
|
-
console.log('✗ npm not found');
|
|
427
|
-
hasErrors = true;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Check 3: Git
|
|
431
|
-
try {
|
|
432
|
-
const gitVersion = execSync('git --version', { encoding: 'utf8' }).trim();
|
|
433
|
-
console.log(`✔ Git installed: ${gitVersion}`);
|
|
434
|
-
} catch {
|
|
435
|
-
issues.push({
|
|
436
|
-
type: 'git',
|
|
437
|
-
autoFix: false,
|
|
438
|
-
message: 'Git not found (optional but recommended)',
|
|
439
|
-
suggestion: 'Install Git from https://git-scm.com',
|
|
440
|
-
});
|
|
441
|
-
console.log('⚠️ Git not found (optional but recommended)');
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
// Check 4: AIOS installation
|
|
445
|
-
const aiosCoreDir = path.join(__dirname, '..', '.aios-core');
|
|
446
|
-
if (fs.existsSync(aiosCoreDir)) {
|
|
447
|
-
console.log(`✔ Synkra AIOS: v${packageJson.version}`);
|
|
448
|
-
|
|
449
|
-
// Check for corruption using validate (if available)
|
|
450
|
-
try {
|
|
451
|
-
const validatorPath = path.join(__dirname, '..', 'packages', 'installer', 'src', 'installer', 'post-install-validator');
|
|
452
|
-
const { PostInstallValidator } = require(validatorPath);
|
|
453
|
-
const validator = new PostInstallValidator(process.cwd(), path.join(__dirname, '..'));
|
|
454
|
-
const report = await validator.validate();
|
|
455
|
-
|
|
456
|
-
if (report.stats && (report.stats.missingFiles > 0 || report.stats.corruptedFiles > 0)) {
|
|
457
|
-
issues.push({
|
|
458
|
-
type: 'aios_corrupted',
|
|
459
|
-
autoFix: true,
|
|
460
|
-
message: `AIOS Core: ${report.stats.missingFiles} missing, ${report.stats.corruptedFiles} corrupted files`,
|
|
461
|
-
fixAction: async () => {
|
|
462
|
-
console.log(' 🔧 Repairing AIOS installation...');
|
|
463
|
-
await validator.repair();
|
|
464
|
-
console.log(' ✓ Repair complete');
|
|
465
|
-
},
|
|
466
|
-
});
|
|
467
|
-
hasErrors = true;
|
|
468
|
-
console.log(`⚠️ AIOS Core: ${report.stats.missingFiles} missing, ${report.stats.corruptedFiles} corrupted files`);
|
|
469
|
-
}
|
|
470
|
-
} catch {
|
|
471
|
-
// Validation not available, skip corruption check
|
|
472
|
-
}
|
|
473
|
-
} else {
|
|
474
|
-
issues.push({
|
|
475
|
-
type: 'aios_missing',
|
|
476
|
-
autoFix: true,
|
|
477
|
-
message: 'AIOS Core not installed',
|
|
478
|
-
fixAction: async () => {
|
|
479
|
-
console.log(' 🔧 Installing AIOS...');
|
|
480
|
-
try {
|
|
481
|
-
execSync('npx aios-core install --force --quiet', { stdio: 'inherit', timeout: 60000 });
|
|
482
|
-
console.log(' ✓ Installation complete');
|
|
483
|
-
} catch (installError) {
|
|
484
|
-
console.error(` ✗ Installation failed: ${installError.message}`);
|
|
485
|
-
throw installError;
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
});
|
|
489
|
-
hasErrors = true;
|
|
490
|
-
console.log('✗ AIOS Core not installed');
|
|
491
|
-
console.log(' Run: npx aios-core@latest');
|
|
492
|
-
}
|
|
354
|
+
// Helper: Run doctor diagnostics (v2.0 — delegates to modular doctor)
|
|
355
|
+
async function runDoctor(options = {}) {
|
|
356
|
+
const { runDoctorChecks } = require(path.join(__dirname, '..', '.aios-core', 'core', 'doctor'));
|
|
493
357
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const stateEmoji = {
|
|
502
|
-
'Active': '✔',
|
|
503
|
-
'Grace': '⚠️',
|
|
504
|
-
'Expired': '✗',
|
|
505
|
-
'Not Activated': '➖',
|
|
506
|
-
};
|
|
507
|
-
|
|
508
|
-
if (state === 'Active') {
|
|
509
|
-
console.log(`${stateEmoji[state]} AIOS Pro: License active`);
|
|
510
|
-
} else if (state === 'Grace') {
|
|
511
|
-
console.log(`${stateEmoji[state]} AIOS Pro: License in grace period`);
|
|
512
|
-
console.log(' Run: aios pro validate');
|
|
513
|
-
} else if (state === 'Expired') {
|
|
514
|
-
console.log(`${stateEmoji[state]} AIOS Pro: License expired`);
|
|
515
|
-
console.log(' Run: aios pro activate --key <KEY>');
|
|
516
|
-
} else {
|
|
517
|
-
console.log(`${stateEmoji[state]} AIOS Pro: Not activated`);
|
|
518
|
-
console.log(' Run: aios pro activate --key <KEY>');
|
|
519
|
-
}
|
|
520
|
-
} catch {
|
|
521
|
-
console.log('⚠️ AIOS Pro: Unable to check license status');
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Apply fixes if --fix
|
|
526
|
-
if (shouldFix && issues.length > 0) {
|
|
527
|
-
console.log('\n🔧 Attempting fixes...\n');
|
|
358
|
+
const result = await runDoctorChecks({
|
|
359
|
+
fix: options.fix || false,
|
|
360
|
+
json: options.json || false,
|
|
361
|
+
dryRun: options.dryRun || false,
|
|
362
|
+
quiet: options.quiet || false,
|
|
363
|
+
projectRoot: process.cwd(),
|
|
364
|
+
});
|
|
528
365
|
|
|
529
|
-
|
|
530
|
-
let manual = 0;
|
|
366
|
+
console.log(result.formatted);
|
|
531
367
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
console.log(` [DRY RUN] Would fix: ${issue.type}`);
|
|
536
|
-
fixed++;
|
|
537
|
-
} else {
|
|
538
|
-
try {
|
|
539
|
-
await issue.fixAction();
|
|
540
|
-
fixed++;
|
|
541
|
-
} catch (fixError) {
|
|
542
|
-
console.error(` ✗ Failed to fix ${issue.type}: ${fixError.message}`);
|
|
543
|
-
manual++;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
} else {
|
|
547
|
-
manual++;
|
|
548
|
-
console.log(` ⚠️ ${issue.message}`);
|
|
549
|
-
console.log(` 💡 Fix: ${issue.suggestion}`);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
console.log('');
|
|
554
|
-
if (isDryRun) {
|
|
555
|
-
console.log(`✅ Dry run completed - ${fixed} issues would be fixed`);
|
|
556
|
-
if (manual > 0) {
|
|
557
|
-
console.log(`⚠️ ${manual} issues require manual action`);
|
|
558
|
-
}
|
|
559
|
-
} else {
|
|
560
|
-
if (fixed > 0) {
|
|
561
|
-
console.log(`✅ Fixed ${fixed} issue${fixed > 1 ? 's' : ''}`);
|
|
562
|
-
}
|
|
563
|
-
if (manual > 0) {
|
|
564
|
-
console.log(`⚠️ ${manual} issue${manual > 1 ? 's' : ''} require manual action`);
|
|
565
|
-
process.exit(1);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
} else {
|
|
569
|
-
// Summary (no --fix)
|
|
570
|
-
console.log('');
|
|
571
|
-
if (hasErrors) {
|
|
572
|
-
console.log('⚠️ Some issues were detected. Run with --fix to auto-repair.');
|
|
573
|
-
process.exit(1);
|
|
574
|
-
} else {
|
|
575
|
-
console.log('✅ All checks passed! Your installation is healthy.');
|
|
576
|
-
}
|
|
368
|
+
// Exit with code 1 if any FAIL results
|
|
369
|
+
if (result.data && result.data.summary && result.data.summary.fail > 0) {
|
|
370
|
+
process.exit(1);
|
|
577
371
|
}
|
|
578
372
|
}
|
|
579
373
|
|
|
@@ -671,6 +465,7 @@ Run health checks on your AIOS installation.
|
|
|
671
465
|
Options:
|
|
672
466
|
--fix Automatically fix detected issues
|
|
673
467
|
--dry-run Show what --fix would do without making changes
|
|
468
|
+
--json Output results as structured JSON
|
|
674
469
|
--quiet Minimal output (exit code only)
|
|
675
470
|
-h, --help Show this help message
|
|
676
471
|
|
|
@@ -1096,6 +891,7 @@ async function main() {
|
|
|
1096
891
|
}
|
|
1097
892
|
const doctorOptions = {
|
|
1098
893
|
fix: doctorArgs.includes('--fix'),
|
|
894
|
+
json: doctorArgs.includes('--json'),
|
|
1099
895
|
dryRun: doctorArgs.includes('--dry-run'),
|
|
1100
896
|
quiet: doctorArgs.includes('--quiet'),
|
|
1101
897
|
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git fsmonitor detection utility.
|
|
3
|
+
* Shared between bin/aios.js (runDoctor) and tests.
|
|
4
|
+
* Story: NOG-13
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { execSync } = require('child_process');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Compare semver versions: returns 1 if a > b, -1 if a < b, 0 if equal.
|
|
11
|
+
* @param {string} a
|
|
12
|
+
* @param {string} b
|
|
13
|
+
* @returns {number}
|
|
14
|
+
*/
|
|
15
|
+
function compareVersions(a, b) {
|
|
16
|
+
const pa = a.split('.').map((n) => parseInt(n, 10));
|
|
17
|
+
const pb = b.split('.').map((n) => parseInt(n, 10));
|
|
18
|
+
for (let i = 0; i < 3; i++) {
|
|
19
|
+
const na = pa[i] || 0;
|
|
20
|
+
const nb = pb[i] || 0;
|
|
21
|
+
if (na > nb) return 1;
|
|
22
|
+
if (na < nb) return -1;
|
|
23
|
+
}
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Detect git fsmonitor status based on git version string.
|
|
29
|
+
*
|
|
30
|
+
* @param {string|null} gitVersionStr - Output of `git --version` (e.g. "git version 2.43.0.windows.1")
|
|
31
|
+
* @returns {{ status: string, message: string, suggestion?: string }}
|
|
32
|
+
*/
|
|
33
|
+
function detectFsmonitor(gitVersionStr) {
|
|
34
|
+
if (!gitVersionStr) {
|
|
35
|
+
return { status: 'unavailable', message: 'Git not installed' };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const versionMatch = gitVersionStr.match(/(\d+\.\d+\.\d+)/);
|
|
39
|
+
const gitVer = versionMatch ? versionMatch[1] : '0.0.0';
|
|
40
|
+
const gitSupportsFsmonitor = compareVersions(gitVer, '2.37.0') >= 0;
|
|
41
|
+
|
|
42
|
+
let fsmonitorValue = '';
|
|
43
|
+
try {
|
|
44
|
+
fsmonitorValue = execSync('git config core.fsmonitor', { encoding: 'utf8' }).trim();
|
|
45
|
+
} catch {
|
|
46
|
+
// Not set
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const isEnabled = fsmonitorValue === 'true';
|
|
50
|
+
|
|
51
|
+
if (isEnabled) {
|
|
52
|
+
return {
|
|
53
|
+
status: 'enabled',
|
|
54
|
+
message: 'Git fsmonitor: enabled (git status acceleration active)',
|
|
55
|
+
};
|
|
56
|
+
} else if (gitSupportsFsmonitor) {
|
|
57
|
+
return {
|
|
58
|
+
status: 'available',
|
|
59
|
+
message: 'Git fsmonitor: not enabled (opt-in optimization available)',
|
|
60
|
+
suggestion: 'git config core.fsmonitor true',
|
|
61
|
+
};
|
|
62
|
+
} else {
|
|
63
|
+
return {
|
|
64
|
+
status: 'unavailable',
|
|
65
|
+
message: `Git fsmonitor: not available (Git 2.37+ required, found ${gitVer})`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = { detectFsmonitor, compareVersions };
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework Guard — Pre-commit hook that blocks commits to L1/L2 protected paths.
|
|
3
|
+
*
|
|
4
|
+
* Reads ALL configuration from core-config.yaml (single source of truth):
|
|
5
|
+
* - boundary.frameworkProtection: toggle (true/false)
|
|
6
|
+
* - boundary.protected: L1/L2 blocked glob patterns
|
|
7
|
+
* - boundary.exceptions: L3 allowed glob patterns
|
|
8
|
+
*
|
|
9
|
+
* When frameworkProtection is true (default), blocks staged changes to protected paths.
|
|
10
|
+
* When false, acts as a no-op (contributor mode).
|
|
11
|
+
*
|
|
12
|
+
* Story: BM-3 (Epic: Boundary Mapping & Framework-Project Separation)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
// Hardcoded fallbacks — used ONLY if core-config.yaml is missing or malformed.
|
|
22
|
+
// The canonical source is core-config.yaml boundary.protected/exceptions.
|
|
23
|
+
const FALLBACK_PROTECTED = [
|
|
24
|
+
'.aios-core/core/**',
|
|
25
|
+
'.aios-core/development/tasks/**',
|
|
26
|
+
'.aios-core/development/templates/**',
|
|
27
|
+
'.aios-core/development/checklists/**',
|
|
28
|
+
'.aios-core/development/workflows/**',
|
|
29
|
+
'.aios-core/infrastructure/**',
|
|
30
|
+
'.aios-core/constitution.md',
|
|
31
|
+
'bin/aios.js',
|
|
32
|
+
'bin/aios-init.js',
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const FALLBACK_EXCEPTIONS = [
|
|
36
|
+
'.aios-core/data/**',
|
|
37
|
+
'.aios-core/development/agents/*/MEMORY.md',
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Convert a glob pattern to a RegExp.
|
|
42
|
+
* Supports: ** (any depth), * (single segment), literal dots.
|
|
43
|
+
* @param {string} glob
|
|
44
|
+
* @returns {RegExp}
|
|
45
|
+
*/
|
|
46
|
+
function globToRegex(glob) {
|
|
47
|
+
let pattern = glob
|
|
48
|
+
.replace(/\./g, '\\.') // escape dots
|
|
49
|
+
.replace(/\*\*/g, '\u0000') // placeholder for **
|
|
50
|
+
.replace(/\*/g, '[^/]+') // * = single segment
|
|
51
|
+
.replace(/\u0000/g, '.+'); // ** = any depth
|
|
52
|
+
|
|
53
|
+
// If pattern ends with .+ (was **), match prefix
|
|
54
|
+
if (glob.endsWith('**')) {
|
|
55
|
+
return new RegExp('^' + pattern);
|
|
56
|
+
}
|
|
57
|
+
// Exact file match
|
|
58
|
+
return new RegExp('^' + pattern + '$');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Read the raw content of core-config.yaml.
|
|
63
|
+
* @returns {string|null}
|
|
64
|
+
*/
|
|
65
|
+
function readConfigContent() {
|
|
66
|
+
const configPath = path.resolve(__dirname, '../../.aios-core/core-config.yaml');
|
|
67
|
+
if (!fs.existsSync(configPath)) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return fs.readFileSync(configPath, 'utf8');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse a YAML list under a given key using simple line-based parsing.
|
|
75
|
+
* Avoids js-yaml dependency for speed.
|
|
76
|
+
* @param {string} content - YAML file content
|
|
77
|
+
* @param {string} parentKey - Parent key (e.g., 'boundary')
|
|
78
|
+
* @param {string} listKey - List key (e.g., 'protected')
|
|
79
|
+
* @returns {string[]}
|
|
80
|
+
*/
|
|
81
|
+
function parseYamlList(content, parentKey, listKey) {
|
|
82
|
+
const lines = content.split('\n');
|
|
83
|
+
const items = [];
|
|
84
|
+
let inParent = false;
|
|
85
|
+
let inList = false;
|
|
86
|
+
let parentIndent = -1;
|
|
87
|
+
let listIndent = -1;
|
|
88
|
+
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
const trimmed = line.trimStart();
|
|
91
|
+
const indent = line.length - trimmed.length;
|
|
92
|
+
|
|
93
|
+
// Find parent key (e.g., "boundary:")
|
|
94
|
+
if (trimmed === parentKey + ':' || trimmed.startsWith(parentKey + ':')) {
|
|
95
|
+
inParent = true;
|
|
96
|
+
parentIndent = indent;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// If we're past the parent section (back to same or lower indent)
|
|
101
|
+
if (inParent && indent <= parentIndent && trimmed.length > 0 && !trimmed.startsWith('#')) {
|
|
102
|
+
inParent = false;
|
|
103
|
+
inList = false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!inParent) continue;
|
|
107
|
+
|
|
108
|
+
// Find list key within parent (e.g., "protected:")
|
|
109
|
+
if (trimmed === listKey + ':' || trimmed.startsWith(listKey + ':')) {
|
|
110
|
+
inList = true;
|
|
111
|
+
listIndent = indent;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// If we're past the list (back to same or lower indent within parent)
|
|
116
|
+
if (inList && indent <= listIndent && trimmed.length > 0 && !trimmed.startsWith('#') && !trimmed.startsWith('-')) {
|
|
117
|
+
inList = false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Collect list items
|
|
121
|
+
if (inList && trimmed.startsWith('- ')) {
|
|
122
|
+
items.push(trimmed.slice(2).trim());
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return items;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Read boundary config from core-config.yaml.
|
|
131
|
+
* @returns {{ enabled: boolean, protected: string[], exceptions: string[] }}
|
|
132
|
+
*/
|
|
133
|
+
function readBoundaryConfig() {
|
|
134
|
+
const content = readConfigContent();
|
|
135
|
+
if (!content) {
|
|
136
|
+
return { enabled: true, protected: FALLBACK_PROTECTED, exceptions: FALLBACK_EXCEPTIONS };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Read toggle
|
|
140
|
+
const toggleMatch = content.match(/frameworkProtection:\s*(true|false)/);
|
|
141
|
+
const enabled = toggleMatch ? toggleMatch[1] === 'true' : true;
|
|
142
|
+
|
|
143
|
+
// Read lists
|
|
144
|
+
const protectedPaths = parseYamlList(content, 'boundary', 'protected');
|
|
145
|
+
const exceptionPaths = parseYamlList(content, 'boundary', 'exceptions');
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
enabled,
|
|
149
|
+
protected: protectedPaths.length > 0 ? protectedPaths : FALLBACK_PROTECTED,
|
|
150
|
+
exceptions: exceptionPaths.length > 0 ? exceptionPaths : FALLBACK_EXCEPTIONS,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Check if a file path matches any pattern in the list.
|
|
156
|
+
* @param {string} filePath
|
|
157
|
+
* @param {RegExp[]} patterns
|
|
158
|
+
* @returns {boolean}
|
|
159
|
+
*/
|
|
160
|
+
function matchesAny(filePath, patterns) {
|
|
161
|
+
return patterns.some((pattern) => pattern.test(filePath));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get list of staged files from git.
|
|
166
|
+
* @returns {string[]}
|
|
167
|
+
*/
|
|
168
|
+
function getStagedFiles() {
|
|
169
|
+
try {
|
|
170
|
+
const output = execSync('git diff --cached --name-only', { encoding: 'utf8' });
|
|
171
|
+
return output
|
|
172
|
+
.split('\n')
|
|
173
|
+
.map((f) => f.trim())
|
|
174
|
+
.filter(Boolean);
|
|
175
|
+
} catch {
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function main() {
|
|
181
|
+
// Step 1: Read config (single source of truth)
|
|
182
|
+
const config = readBoundaryConfig();
|
|
183
|
+
|
|
184
|
+
if (!config.enabled) {
|
|
185
|
+
process.exit(0);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Step 2: Compile glob patterns to regex
|
|
189
|
+
const blockedPatterns = config.protected.map(globToRegex);
|
|
190
|
+
const allowedPatterns = config.exceptions.map(globToRegex);
|
|
191
|
+
|
|
192
|
+
// Step 3: Get staged files
|
|
193
|
+
const stagedFiles = getStagedFiles();
|
|
194
|
+
if (stagedFiles.length === 0) {
|
|
195
|
+
process.exit(0);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Step 4: Check each staged file
|
|
199
|
+
const blockedFiles = [];
|
|
200
|
+
for (const file of stagedFiles) {
|
|
201
|
+
// Normalize to forward slashes (Windows compat)
|
|
202
|
+
const normalized = file.replace(/\\/g, '/');
|
|
203
|
+
if (matchesAny(normalized, blockedPatterns) && !matchesAny(normalized, allowedPatterns)) {
|
|
204
|
+
blockedFiles.push(normalized);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Step 5: Report
|
|
209
|
+
if (blockedFiles.length > 0) {
|
|
210
|
+
console.error('');
|
|
211
|
+
console.error('Framework Guard: Commit blocked!');
|
|
212
|
+
console.error('');
|
|
213
|
+
console.error('The following framework files are protected (L1/L2):');
|
|
214
|
+
for (const file of blockedFiles) {
|
|
215
|
+
console.error(` - ${file}`);
|
|
216
|
+
}
|
|
217
|
+
console.error('');
|
|
218
|
+
console.error('These files are read-only in project mode (boundary.frameworkProtection: true).');
|
|
219
|
+
console.error('');
|
|
220
|
+
console.error('To bypass (framework contributors only):');
|
|
221
|
+
console.error(' git commit --no-verify');
|
|
222
|
+
console.error('');
|
|
223
|
+
console.error('To disable permanently (contributors):');
|
|
224
|
+
console.error(' Set boundary.frameworkProtection: false in core-config.yaml');
|
|
225
|
+
console.error('');
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
process.exit(0);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Export for testing
|
|
233
|
+
module.exports = { readBoundaryConfig, globToRegex, matchesAny, getStagedFiles, FALLBACK_PROTECTED, FALLBACK_EXCEPTIONS };
|
|
234
|
+
|
|
235
|
+
// Run when executed directly
|
|
236
|
+
if (require.main === module) {
|
|
237
|
+
main();
|
|
238
|
+
}
|