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,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Publish Safety Gate — Submodule + File Count Validation
|
|
6
|
+
* Story INS-4.10
|
|
7
|
+
*
|
|
8
|
+
* Prevents publishing incomplete packages by validating:
|
|
9
|
+
* 1. pro/ submodule is populated (not empty or uninitialized)
|
|
10
|
+
* 2. Critical file pro/license/license-api.js exists
|
|
11
|
+
* 3. Package file count meets minimum threshold (>= 50)
|
|
12
|
+
*
|
|
13
|
+
* Exit codes: 0 = PASS, 1 = FAIL
|
|
14
|
+
* Usage: node bin/utils/validate-publish.js
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const { execSync } = require('child_process');
|
|
20
|
+
|
|
21
|
+
const PROJECT_ROOT = path.join(__dirname, '..', '..');
|
|
22
|
+
const PRO_DIR = path.join(PROJECT_ROOT, 'pro');
|
|
23
|
+
const CRITICAL_FILE = path.join(PRO_DIR, 'license', 'license-api.js');
|
|
24
|
+
const MIN_FILE_COUNT = 50;
|
|
25
|
+
|
|
26
|
+
// CI environments may not have access to the private pro submodule
|
|
27
|
+
const IS_CI = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
|
|
28
|
+
|
|
29
|
+
let passed = true;
|
|
30
|
+
let fileCount = 0;
|
|
31
|
+
|
|
32
|
+
// Check 1: pro/ submodule populated
|
|
33
|
+
console.log('--- Publish Safety Gate (INS-4.10) ---\n');
|
|
34
|
+
|
|
35
|
+
if (!fs.existsSync(PRO_DIR)) {
|
|
36
|
+
if (IS_CI) {
|
|
37
|
+
console.log('SKIP: pro/ directory not available (CI — private submodule requires separate access token)');
|
|
38
|
+
} else {
|
|
39
|
+
console.error('FAIL: pro/ directory does not exist.');
|
|
40
|
+
console.error(' Fix: git submodule update --init pro');
|
|
41
|
+
passed = false;
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
const entries = fs.readdirSync(PRO_DIR).filter(e => e !== '.git');
|
|
45
|
+
if (entries.length === 0) {
|
|
46
|
+
if (IS_CI) {
|
|
47
|
+
console.log('SKIP: pro/ submodule empty (CI — private submodule requires separate access token)');
|
|
48
|
+
} else {
|
|
49
|
+
console.error('FAIL: pro/ submodule not initialized (directory is empty).');
|
|
50
|
+
console.error(' Fix: git submodule update --init pro');
|
|
51
|
+
passed = false;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
console.log(`PASS: pro/ submodule populated (${entries.length} entries)`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Check 2: Critical file exists
|
|
59
|
+
if (!fs.existsSync(CRITICAL_FILE)) {
|
|
60
|
+
if (IS_CI) {
|
|
61
|
+
console.log('SKIP: pro/license/license-api.js not available (CI — private submodule)');
|
|
62
|
+
} else {
|
|
63
|
+
console.error('FAIL: pro/license/license-api.js not found.');
|
|
64
|
+
console.error(' This is a critical file required for Pro license validation.');
|
|
65
|
+
console.error(' Fix: git submodule update --init --recursive pro');
|
|
66
|
+
passed = false;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
console.log('PASS: pro/license/license-api.js exists');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check 3: File count threshold via npm pack --dry-run
|
|
73
|
+
try {
|
|
74
|
+
const packOutput = execSync('npm pack --dry-run 2>&1', {
|
|
75
|
+
encoding: 'utf8',
|
|
76
|
+
cwd: PROJECT_ROOT,
|
|
77
|
+
timeout: 30000,
|
|
78
|
+
});
|
|
79
|
+
// npm pack --dry-run outputs lines starting with "npm notice" for each file
|
|
80
|
+
const fileLines = packOutput.split('\n').filter(line =>
|
|
81
|
+
line.includes('npm notice') && !line.includes('Tarball') && !line.includes('name:') &&
|
|
82
|
+
!line.includes('version:') && !line.includes('filename:') && !line.includes('package size:') &&
|
|
83
|
+
!line.includes('unpacked size:') && !line.includes('shasum:') && !line.includes('integrity:') &&
|
|
84
|
+
!line.includes('total files:')
|
|
85
|
+
);
|
|
86
|
+
fileCount = fileLines.length;
|
|
87
|
+
|
|
88
|
+
if (fileCount < MIN_FILE_COUNT) {
|
|
89
|
+
console.error(`FAIL: Package has only ${fileCount} files, expected >= ${MIN_FILE_COUNT}.`);
|
|
90
|
+
console.error(' Check that all directories in "files" array are populated.');
|
|
91
|
+
passed = false;
|
|
92
|
+
} else {
|
|
93
|
+
console.log(`PASS: Package contains ${fileCount} files (minimum: ${MIN_FILE_COUNT})`);
|
|
94
|
+
}
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error(`FAIL: npm pack --dry-run failed: ${err.message}`);
|
|
97
|
+
passed = false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Summary
|
|
101
|
+
console.log('');
|
|
102
|
+
if (passed) {
|
|
103
|
+
console.log(`PUBLISH SAFETY GATE: PASS (${fileCount} files in package)`);
|
|
104
|
+
process.exit(0);
|
|
105
|
+
} else {
|
|
106
|
+
console.error('PUBLISH SAFETY GATE: FAIL — publish blocked. Fix issues above before retrying.');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aios-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"aios": "bin/aios.js",
|
|
7
7
|
"aios-core": "bin/aios.js",
|
|
8
|
-
"aios-minimal": "bin/aios-minimal.js"
|
|
8
|
+
"aios-minimal": "bin/aios-minimal.js",
|
|
9
|
+
"aios-graph": "bin/aios-graph.js"
|
|
9
10
|
},
|
|
10
11
|
"preferGlobal": false,
|
|
11
12
|
"workspaces": [
|
|
@@ -61,7 +62,8 @@
|
|
|
61
62
|
"validate:semantic-lint": "node scripts/semantic-lint.js",
|
|
62
63
|
"manifest:ensure": "node scripts/ensure-manifest.js",
|
|
63
64
|
"sync:ide:cursor": "node .aios-core/infrastructure/scripts/ide-sync/index.js sync --ide cursor",
|
|
64
|
-
"
|
|
65
|
+
"validate:publish": "node bin/utils/validate-publish.js",
|
|
66
|
+
"prepublishOnly": "node bin/utils/validate-publish.js && npm run generate:manifest && npm run validate:manifest",
|
|
65
67
|
"prepare": "husky"
|
|
66
68
|
},
|
|
67
69
|
"dependencies": {
|
|
@@ -70,6 +72,7 @@
|
|
|
70
72
|
"ajv": "^8.17.1",
|
|
71
73
|
"ajv-formats": "^3.0.1",
|
|
72
74
|
"ansi-to-html": "^0.7.2",
|
|
75
|
+
"asciichart": "^1.5.25",
|
|
73
76
|
"chalk": "^4.1.2",
|
|
74
77
|
"chokidar": "^3.5.3",
|
|
75
78
|
"cli-progress": "^3.12.0",
|
|
File without changes
|
|
File without changes
|
|
@@ -142,6 +142,7 @@ Commands:
|
|
|
142
142
|
features List available pro features
|
|
143
143
|
validate Force online license revalidation
|
|
144
144
|
recover Recover lost license key via email
|
|
145
|
+
reset-password Reset your password (alias for recover)
|
|
145
146
|
help Show this help message
|
|
146
147
|
|
|
147
148
|
Examples:
|
|
@@ -205,6 +206,7 @@ switch (command) {
|
|
|
205
206
|
}
|
|
206
207
|
|
|
207
208
|
case 'recover':
|
|
209
|
+
case 'reset-password':
|
|
208
210
|
recoverLicense().catch((err) => {
|
|
209
211
|
console.error(`\n Recovery failed: ${err.message}\n`);
|
|
210
212
|
process.exit(1);
|
|
@@ -170,6 +170,31 @@ function generateCoreConfig(options = {}) {
|
|
|
170
170
|
maxRecentCommits: 2,
|
|
171
171
|
},
|
|
172
172
|
|
|
173
|
+
// Boundary Protection (Epic BM — Boundary Mapping)
|
|
174
|
+
// frameworkProtection: true enforces deny rules in settings.json for L1-L4 layers
|
|
175
|
+
boundary: {
|
|
176
|
+
frameworkProtection: true,
|
|
177
|
+
// L1/L2 paths — blocked from editing in project mode
|
|
178
|
+
protected: [
|
|
179
|
+
'.aios-core/core/**',
|
|
180
|
+
'.aios-core/development/tasks/**',
|
|
181
|
+
'.aios-core/development/templates/**',
|
|
182
|
+
'.aios-core/development/checklists/**',
|
|
183
|
+
'.aios-core/development/workflows/**',
|
|
184
|
+
'.aios-core/infrastructure/**',
|
|
185
|
+
'.aios-core/constitution.md',
|
|
186
|
+
'bin/aios.js',
|
|
187
|
+
'bin/aios-init.js',
|
|
188
|
+
],
|
|
189
|
+
// L3 paths — mutable exceptions (allowed even within .aios-core/)
|
|
190
|
+
exceptions: [
|
|
191
|
+
'.aios-core/data/**',
|
|
192
|
+
'.aios-core/development/agents/*/MEMORY.md',
|
|
193
|
+
'.aios-core/core/config/schemas/**',
|
|
194
|
+
'.aios-core/core/config/template-overrides.js',
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
|
|
173
198
|
// Agent Identity Configuration
|
|
174
199
|
agentIdentity: {
|
|
175
200
|
greeting: {
|
|
@@ -11,6 +11,7 @@ const path = require('path');
|
|
|
11
11
|
const yaml = require('js-yaml');
|
|
12
12
|
const semver = require('semver');
|
|
13
13
|
const { hashFile, hashesMatch } = require('./file-hasher');
|
|
14
|
+
const { YamlMerger } = require('../merger/strategies/yaml-merger.js');
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Upgrade report structure
|
|
@@ -257,12 +258,74 @@ async function applyUpgrade(report, sourceDir, targetDir, options = {}) {
|
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
260
|
|
|
260
|
-
//
|
|
261
|
+
// Handle user-modified files: skip most, but smart-merge core-config.yaml
|
|
261
262
|
for (const file of report.userModifiedFiles) {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
if (file.path.endsWith('core-config.yaml')) {
|
|
264
|
+
// Story INS-4.7: Smart merge for core-config.yaml instead of skipping
|
|
265
|
+
let backupPath;
|
|
266
|
+
try {
|
|
267
|
+
const sourcePath = path.join(sourceDir, file.path);
|
|
268
|
+
const targetPath = path.join(aiosCoreDir, file.path);
|
|
269
|
+
|
|
270
|
+
if (!dryRun && fs.existsSync(sourcePath) && fs.existsSync(targetPath)) {
|
|
271
|
+
const sourceContent = fs.readFileSync(sourcePath, 'utf8');
|
|
272
|
+
const targetContent = fs.readFileSync(targetPath, 'utf8');
|
|
273
|
+
|
|
274
|
+
// Backup before merge
|
|
275
|
+
backupPath = `${targetPath}.backup-${Date.now()}`;
|
|
276
|
+
fs.copyFileSync(targetPath, backupPath);
|
|
277
|
+
|
|
278
|
+
const merger = new YamlMerger();
|
|
279
|
+
const mergeResult = await merger.merge(sourceContent, targetContent);
|
|
280
|
+
|
|
281
|
+
// Write merged content
|
|
282
|
+
fs.writeFileSync(targetPath, mergeResult.content, 'utf8');
|
|
283
|
+
|
|
284
|
+
// Log conflict warnings
|
|
285
|
+
const conflicts = mergeResult.changes.filter(c => c.type === 'conflict');
|
|
286
|
+
if (conflicts.length > 0) {
|
|
287
|
+
result.mergeWarnings = result.mergeWarnings || [];
|
|
288
|
+
for (const conflict of conflicts) {
|
|
289
|
+
result.mergeWarnings.push(
|
|
290
|
+
`core-config.yaml: ${conflict.identifier} — ${conflict.reason}`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
result.filesInstalled.push({
|
|
296
|
+
path: file.path,
|
|
297
|
+
action: 'merged',
|
|
298
|
+
stats: mergeResult.stats,
|
|
299
|
+
backupPath,
|
|
300
|
+
});
|
|
301
|
+
} else if (dryRun) {
|
|
302
|
+
result.filesInstalled.push({ path: file.path, action: 'merge (dry-run)' });
|
|
303
|
+
} else {
|
|
304
|
+
result.filesSkipped.push({
|
|
305
|
+
path: file.path,
|
|
306
|
+
reason: 'User modified - source or target missing for merge',
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
} catch (mergeError) {
|
|
310
|
+
// Merge failed — restore backup if exists, skip file
|
|
311
|
+
if (backupPath && fs.existsSync(backupPath)) {
|
|
312
|
+
try {
|
|
313
|
+
const targetPath = path.join(aiosCoreDir, file.path);
|
|
314
|
+
fs.copyFileSync(backupPath, targetPath);
|
|
315
|
+
} catch { /* restore failed — backup file still available */ }
|
|
316
|
+
}
|
|
317
|
+
console.warn(`⚠️ core-config.yaml merge failed: ${mergeError.message}`);
|
|
318
|
+
result.filesSkipped.push({
|
|
319
|
+
path: file.path,
|
|
320
|
+
reason: `Merge failed: ${mergeError.message} — user config preserved`,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
result.filesSkipped.push({
|
|
325
|
+
path: file.path,
|
|
326
|
+
reason: 'User modified - preserving local changes',
|
|
327
|
+
});
|
|
328
|
+
}
|
|
266
329
|
}
|
|
267
330
|
|
|
268
331
|
// Note: We don't delete files that were removed from source
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Supported file types:
|
|
9
9
|
* - .env files: Key-based merge (adds new variables, preserves existing)
|
|
10
10
|
* - .md files: Section-based merge using AIOS-MANAGED markers
|
|
11
|
+
* - .yaml/.yml files: Deep merge with target-wins (Phase 1 — Story INS-4.7)
|
|
11
12
|
*
|
|
12
13
|
* @module merger
|
|
13
14
|
* @example
|
|
@@ -32,6 +33,7 @@ const {
|
|
|
32
33
|
ReplaceMerger,
|
|
33
34
|
EnvMerger,
|
|
34
35
|
MarkdownMerger,
|
|
36
|
+
YamlMerger,
|
|
35
37
|
} = require('./strategies/index.js');
|
|
36
38
|
|
|
37
39
|
// Re-export types and utilities
|
|
@@ -62,6 +64,7 @@ module.exports = {
|
|
|
62
64
|
ReplaceMerger,
|
|
63
65
|
EnvMerger,
|
|
64
66
|
MarkdownMerger,
|
|
67
|
+
YamlMerger,
|
|
65
68
|
|
|
66
69
|
// Parsers
|
|
67
70
|
parseEnvFile,
|
|
@@ -7,6 +7,7 @@ const path = require('path');
|
|
|
7
7
|
const { ReplaceMerger } = require('./replace-merger.js');
|
|
8
8
|
const { EnvMerger } = require('./env-merger.js');
|
|
9
9
|
const { MarkdownMerger } = require('./markdown-merger.js');
|
|
10
|
+
const { YamlMerger } = require('./yaml-merger.js');
|
|
10
11
|
|
|
11
12
|
// Strategy registry - maps file extensions to merger classes
|
|
12
13
|
const strategies = new Map();
|
|
@@ -23,6 +24,10 @@ fileNameStrategies.set('.env.example', EnvMerger);
|
|
|
23
24
|
// Markdown files
|
|
24
25
|
strategies.set('.md', MarkdownMerger);
|
|
25
26
|
|
|
27
|
+
// YAML files (Story INS-4.7)
|
|
28
|
+
strategies.set('.yaml', YamlMerger);
|
|
29
|
+
strategies.set('.yml', YamlMerger);
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* Register a merge strategy for a file extension
|
|
28
33
|
* @param {string} extension - File extension (e.g., '.md', '.env')
|
|
@@ -102,4 +107,5 @@ module.exports = {
|
|
|
102
107
|
ReplaceMerger,
|
|
103
108
|
EnvMerger,
|
|
104
109
|
MarkdownMerger,
|
|
110
|
+
YamlMerger,
|
|
105
111
|
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Merge strategy for YAML config files (Phase 1)
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 rules (target/user always wins):
|
|
5
|
+
* - New keys in source (not in target) → added to target
|
|
6
|
+
* - Keys in both with same value → preserved
|
|
7
|
+
* - Keys in both with different values → target wins (conflict logged)
|
|
8
|
+
* - Keys in target but not source → kept (deprecated warning)
|
|
9
|
+
*
|
|
10
|
+
* @module merger/strategies/yaml-merger
|
|
11
|
+
* @story INS-4.7
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const yaml = require('js-yaml');
|
|
17
|
+
const { BaseMerger } = require('./base-merger.js');
|
|
18
|
+
const { createMergeResult, createEmptyStats } = require('../types.js');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Merge strategy for YAML configuration files.
|
|
22
|
+
* Implements Phase 1: add new keys + preserve user values + warn conflicts.
|
|
23
|
+
* @extends BaseMerger
|
|
24
|
+
*/
|
|
25
|
+
class YamlMerger extends BaseMerger {
|
|
26
|
+
name = 'yaml';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Can merge if both contents are valid YAML
|
|
30
|
+
* @param {string} existingContent - Existing YAML content
|
|
31
|
+
* @param {string} newContent - New YAML content
|
|
32
|
+
* @returns {boolean} True if both are parseable YAML
|
|
33
|
+
*/
|
|
34
|
+
canMerge(existingContent, newContent) {
|
|
35
|
+
try {
|
|
36
|
+
yaml.load(existingContent);
|
|
37
|
+
yaml.load(newContent);
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Merge source (framework) YAML with target (user) YAML.
|
|
46
|
+
* Target/user values always win on conflict (Phase 1).
|
|
47
|
+
*
|
|
48
|
+
* @param {string} sourceContent - Framework YAML content
|
|
49
|
+
* @param {string} targetContent - User YAML content
|
|
50
|
+
* @param {import('../types.js').MergeOptions} [options] - Merge options
|
|
51
|
+
* @returns {Promise<import('../types.js').MergeResult>} Merge result
|
|
52
|
+
*/
|
|
53
|
+
async merge(sourceContent, targetContent, _options = {}) {
|
|
54
|
+
const source = yaml.load(sourceContent) || {};
|
|
55
|
+
const target = yaml.load(targetContent) || {};
|
|
56
|
+
const stats = createEmptyStats();
|
|
57
|
+
const changes = [];
|
|
58
|
+
|
|
59
|
+
const merged = this._deepMergeTargetWins(source, target, '', stats, changes);
|
|
60
|
+
|
|
61
|
+
// Detect deprecated keys (in target but not in source) at top level
|
|
62
|
+
this._detectDeprecated(source, target, '', stats, changes);
|
|
63
|
+
|
|
64
|
+
const content = yaml.dump(merged, {
|
|
65
|
+
indent: 2,
|
|
66
|
+
lineWidth: 120,
|
|
67
|
+
noRefs: true,
|
|
68
|
+
sortKeys: false,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return createMergeResult(content, stats, changes);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Deep merge where target (user) values always win.
|
|
76
|
+
* New keys from source are added; existing keys preserved.
|
|
77
|
+
*
|
|
78
|
+
* @param {Object} source - Framework config
|
|
79
|
+
* @param {Object} target - User config
|
|
80
|
+
* @param {string} prefix - Key path prefix for change tracking
|
|
81
|
+
* @param {import('../types.js').MergeStats} stats - Stats accumulator
|
|
82
|
+
* @param {import('../types.js').MergeChange[]} changes - Changes accumulator
|
|
83
|
+
* @returns {Object} Merged object
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
_deepMergeTargetWins(source, target, prefix, stats, changes) {
|
|
87
|
+
const result = { ...target };
|
|
88
|
+
|
|
89
|
+
for (const key of Object.keys(source)) {
|
|
90
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
91
|
+
|
|
92
|
+
if (!(key in target)) {
|
|
93
|
+
// New key from source — add it
|
|
94
|
+
result[key] = source[key];
|
|
95
|
+
stats.added++;
|
|
96
|
+
changes.push({
|
|
97
|
+
type: 'added',
|
|
98
|
+
identifier: fullKey,
|
|
99
|
+
reason: 'New key from framework',
|
|
100
|
+
});
|
|
101
|
+
} else if (
|
|
102
|
+
this._isPlainObject(source[key]) &&
|
|
103
|
+
this._isPlainObject(target[key])
|
|
104
|
+
) {
|
|
105
|
+
// Both are objects — recurse
|
|
106
|
+
result[key] = this._deepMergeTargetWins(
|
|
107
|
+
source[key], target[key], fullKey, stats, changes,
|
|
108
|
+
);
|
|
109
|
+
} else if (JSON.stringify(target[key]) !== JSON.stringify(source[key])) {
|
|
110
|
+
// Conflict: different values — target (user) wins
|
|
111
|
+
stats.conflicts++;
|
|
112
|
+
changes.push({
|
|
113
|
+
type: 'conflict',
|
|
114
|
+
identifier: fullKey,
|
|
115
|
+
reason: 'Keeping user value',
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
// Same value — preserved
|
|
119
|
+
stats.preserved++;
|
|
120
|
+
changes.push({
|
|
121
|
+
type: 'preserved',
|
|
122
|
+
identifier: fullKey,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Detect deprecated keys (in target but not in source) recursively.
|
|
132
|
+
*
|
|
133
|
+
* @param {Object} source - Framework config
|
|
134
|
+
* @param {Object} target - User config
|
|
135
|
+
* @param {string} prefix - Key path prefix
|
|
136
|
+
* @param {import('../types.js').MergeStats} stats - Stats accumulator
|
|
137
|
+
* @param {import('../types.js').MergeChange[]} changes - Changes accumulator
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
_detectDeprecated(source, target, prefix, stats, changes) {
|
|
141
|
+
for (const key of Object.keys(target)) {
|
|
142
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
143
|
+
|
|
144
|
+
if (!(key in source)) {
|
|
145
|
+
stats.conflicts++;
|
|
146
|
+
changes.push({
|
|
147
|
+
type: 'conflict',
|
|
148
|
+
identifier: fullKey,
|
|
149
|
+
reason: 'Deprecated key — may be removed in future version',
|
|
150
|
+
});
|
|
151
|
+
} else if (
|
|
152
|
+
this._isPlainObject(source[key]) &&
|
|
153
|
+
this._isPlainObject(target[key])
|
|
154
|
+
) {
|
|
155
|
+
this._detectDeprecated(source[key], target[key], fullKey, stats, changes);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Check if value is a plain object (not array, null, etc.)
|
|
162
|
+
* @param {*} value - Value to check
|
|
163
|
+
* @returns {boolean}
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
_isPlainObject(value) {
|
|
167
|
+
if (value === null || typeof value !== 'object') return false;
|
|
168
|
+
if (Array.isArray(value)) return false;
|
|
169
|
+
const proto = Object.getPrototypeOf(value);
|
|
170
|
+
return proto === Object.prototype || proto === null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @returns {string} Description of this strategy
|
|
175
|
+
*/
|
|
176
|
+
getDescription() {
|
|
177
|
+
return 'Merges YAML config files by adding new keys while preserving user values (Phase 1)';
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = { YamlMerger };
|
|
@@ -118,7 +118,7 @@ class AIOSUpdater {
|
|
|
118
118
|
if (!isOnline) {
|
|
119
119
|
result.error = 'You appear to be offline. Please check your internet connection.';
|
|
120
120
|
} else {
|
|
121
|
-
result.error = 'Package
|
|
121
|
+
result.error = 'Package aios-core not found on npm registry. This may be a local development installation.';
|
|
122
122
|
}
|
|
123
123
|
return result;
|
|
124
124
|
}
|
|
@@ -165,7 +165,7 @@ class AIOSUpdater {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
// Fallback to package.json
|
|
168
|
-
const packageJsonPath = path.join(this.projectRoot, 'node_modules', '
|
|
168
|
+
const packageJsonPath = path.join(this.projectRoot, 'node_modules', 'aios-core', 'package.json');
|
|
169
169
|
if (fs.existsSync(packageJsonPath)) {
|
|
170
170
|
try {
|
|
171
171
|
const pkg = await fs.readJson(packageJsonPath);
|
|
@@ -199,7 +199,7 @@ class AIOSUpdater {
|
|
|
199
199
|
async getLatestVersion() {
|
|
200
200
|
return new Promise((resolve) => {
|
|
201
201
|
const request = https.get(
|
|
202
|
-
'https://registry.npmjs.org
|
|
202
|
+
'https://registry.npmjs.org/aios-core/latest',
|
|
203
203
|
{ timeout: this.options.timeout },
|
|
204
204
|
(res) => {
|
|
205
205
|
let data = '';
|
|
@@ -587,7 +587,7 @@ class AIOSUpdater {
|
|
|
587
587
|
|
|
588
588
|
try {
|
|
589
589
|
// Use npm to update the package
|
|
590
|
-
const cmd = `npm install
|
|
590
|
+
const cmd = `npm install aios-core@${targetVersion} --save-exact`;
|
|
591
591
|
this.log(`Running: ${cmd}`);
|
|
592
592
|
|
|
593
593
|
execSync(cmd, {
|