onto-mcp 0.3.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/.onto/authority/core-lens-registry.yaml +134 -0
- package/.onto/authority/core-lexicon.yaml +1562 -0
- package/.onto/authority/diagnostic-codes.yaml +94 -0
- package/.onto/domains/accounting/competency_qs.md +384 -0
- package/.onto/domains/accounting/concepts.md +186 -0
- package/.onto/domains/accounting/conciseness_rules.md +160 -0
- package/.onto/domains/accounting/dependency_rules.md +239 -0
- package/.onto/domains/accounting/domain_scope.md +213 -0
- package/.onto/domains/accounting/extension_cases.md +416 -0
- package/.onto/domains/accounting/logic_rules.md +226 -0
- package/.onto/domains/accounting/structure_spec.md +298 -0
- package/.onto/domains/accounting-kr/competency_qs.md +562 -0
- package/.onto/domains/accounting-kr/concepts.md +187 -0
- package/.onto/domains/accounting-kr/conciseness_rules.md +125 -0
- package/.onto/domains/accounting-kr/dependency_rules.md +93 -0
- package/.onto/domains/accounting-kr/domain_scope.md +140 -0
- package/.onto/domains/accounting-kr/extension_cases.md +343 -0
- package/.onto/domains/accounting-kr/logic_rules.md +160 -0
- package/.onto/domains/accounting-kr/structure_spec.md +85 -0
- package/.onto/domains/business/competency_qs.md +263 -0
- package/.onto/domains/business/concepts.md +200 -0
- package/.onto/domains/business/conciseness_rules.md +135 -0
- package/.onto/domains/business/dependency_rules.md +113 -0
- package/.onto/domains/business/domain_scope.md +240 -0
- package/.onto/domains/business/extension_cases.md +249 -0
- package/.onto/domains/business/logic_rules.md +134 -0
- package/.onto/domains/business/structure_spec.md +114 -0
- package/.onto/domains/finance/competency_qs.md +362 -0
- package/.onto/domains/finance/concepts.md +194 -0
- package/.onto/domains/finance/conciseness_rules.md +155 -0
- package/.onto/domains/finance/dependency_rules.md +171 -0
- package/.onto/domains/finance/domain_scope.md +215 -0
- package/.onto/domains/finance/extension_cases.md +350 -0
- package/.onto/domains/finance/logic_rules.md +191 -0
- package/.onto/domains/finance/structure_spec.md +182 -0
- package/.onto/domains/llm-native-development/competency_qs.md +430 -0
- package/.onto/domains/llm-native-development/concepts.md +242 -0
- package/.onto/domains/llm-native-development/conciseness_rules.md +163 -0
- package/.onto/domains/llm-native-development/dependency_rules.md +216 -0
- package/.onto/domains/llm-native-development/domain_scope.md +197 -0
- package/.onto/domains/llm-native-development/extension_cases.md +474 -0
- package/.onto/domains/llm-native-development/logic_rules.md +123 -0
- package/.onto/domains/llm-native-development/prompt_interface.md +49 -0
- package/.onto/domains/llm-native-development/structure_spec.md +245 -0
- package/.onto/domains/market-intelligence/competency_qs.md +274 -0
- package/.onto/domains/market-intelligence/concepts.md +233 -0
- package/.onto/domains/market-intelligence/conciseness_rules.md +165 -0
- package/.onto/domains/market-intelligence/dependency_rules.md +197 -0
- package/.onto/domains/market-intelligence/domain_scope.md +231 -0
- package/.onto/domains/market-intelligence/extension_cases.md +425 -0
- package/.onto/domains/market-intelligence/logic_rules.md +247 -0
- package/.onto/domains/market-intelligence/structure_spec.md +209 -0
- package/.onto/domains/ontology/competency_qs.md +394 -0
- package/.onto/domains/ontology/concepts.md +172 -0
- package/.onto/domains/ontology/conciseness_rules.md +134 -0
- package/.onto/domains/ontology/dependency_rules.md +125 -0
- package/.onto/domains/ontology/domain_scope.md +114 -0
- package/.onto/domains/ontology/extension_cases.md +501 -0
- package/.onto/domains/ontology/logic_rules.md +114 -0
- package/.onto/domains/ontology/problem_framing_profile.md +67 -0
- package/.onto/domains/ontology/structure_spec.md +115 -0
- package/.onto/domains/palantir-foundry/RESEARCH_NOTES.md +911 -0
- package/.onto/domains/palantir-foundry/competency_qs.md +191 -0
- package/.onto/domains/palantir-foundry/competitive_comparison.md +329 -0
- package/.onto/domains/palantir-foundry/concepts.md +197 -0
- package/.onto/domains/palantir-foundry/conciseness_rules.md +245 -0
- package/.onto/domains/palantir-foundry/dependency_rules.md +135 -0
- package/.onto/domains/palantir-foundry/domain_scope.md +395 -0
- package/.onto/domains/palantir-foundry/extension_cases.md +210 -0
- package/.onto/domains/palantir-foundry/logic_rules.md +172 -0
- package/.onto/domains/palantir-foundry/structure_spec.md +291 -0
- package/.onto/domains/software-engineering/competency_qs.md +538 -0
- package/.onto/domains/software-engineering/concepts.md +238 -0
- package/.onto/domains/software-engineering/conciseness_rules.md +167 -0
- package/.onto/domains/software-engineering/dependency_rules.md +216 -0
- package/.onto/domains/software-engineering/domain_scope.md +183 -0
- package/.onto/domains/software-engineering/extension_cases.md +551 -0
- package/.onto/domains/software-engineering/logic_rules.md +240 -0
- package/.onto/domains/software-engineering/problem_framing_profile.md +68 -0
- package/.onto/domains/software-engineering/structure_spec.md +185 -0
- package/.onto/domains/ui-design/competency_qs.md +567 -0
- package/.onto/domains/ui-design/concepts.md +194 -0
- package/.onto/domains/ui-design/conciseness_rules.md +190 -0
- package/.onto/domains/ui-design/dependency_rules.md +323 -0
- package/.onto/domains/ui-design/domain_scope.md +340 -0
- package/.onto/domains/ui-design/extension_cases.md +563 -0
- package/.onto/domains/ui-design/logic_rules.md +349 -0
- package/.onto/domains/ui-design/structure_spec.md +252 -0
- package/.onto/domains/visual-design/competency_qs.md +472 -0
- package/.onto/domains/visual-design/concepts.md +147 -0
- package/.onto/domains/visual-design/conciseness_rules.md +186 -0
- package/.onto/domains/visual-design/dependency_rules.md +282 -0
- package/.onto/domains/visual-design/domain_scope.md +290 -0
- package/.onto/domains/visual-design/extension_cases.md +480 -0
- package/.onto/domains/visual-design/logic_rules.md +232 -0
- package/.onto/domains/visual-design/structure_spec.md +213 -0
- package/.onto/principles/llm-native-development-guideline.md +401 -0
- package/.onto/principles/llm-runtime-interface-principles.md +665 -0
- package/.onto/principles/non-specialist-communication-guideline.md +74 -0
- package/.onto/principles/ontology-as-code-guideline.md +243 -0
- package/.onto/principles/ontology-as-code-naming-charter.md +130 -0
- package/.onto/principles/product-locality-principle.md +129 -0
- package/.onto/principles/productization-charter.md +569 -0
- package/.onto/processes/evolve/material-kind-adapter-contract.md +113 -0
- package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +366 -0
- package/.onto/processes/reconstruct/source-profile-contract.md +107 -0
- package/.onto/processes/reconstruct/source-profiles/code.md +72 -0
- package/.onto/processes/reconstruct/source-profiles/database.md +74 -0
- package/.onto/processes/reconstruct/source-profiles/document.md +71 -0
- package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +79 -0
- package/.onto/processes/review/binding-contract.md +270 -0
- package/.onto/processes/review/execution-preparation-artifacts.md +281 -0
- package/.onto/processes/review/interpretation-contract.md +245 -0
- package/.onto/processes/review/issue-stance-deliberation-contract.md +761 -0
- package/.onto/processes/review/lens-prompt-contract.md +402 -0
- package/.onto/processes/review/lens-registry.md +127 -0
- package/.onto/processes/review/pre-dispatch-contracts.md +428 -0
- package/.onto/processes/review/productized-live-path.md +398 -0
- package/.onto/processes/review/prompt-execution-runner-contract.md +187 -0
- package/.onto/processes/review/record-contract.md +427 -0
- package/.onto/processes/review/record-field-mapping.md +337 -0
- package/.onto/processes/review/review-context-manifest-contract.md +356 -0
- package/.onto/processes/review/review-execution-ux-contract.md +809 -0
- package/.onto/processes/review/review-target-profile-contract.md +259 -0
- package/.onto/processes/review/shared-phenomenon-contract.md +129 -0
- package/.onto/processes/review/synthesize-prompt-contract.md +343 -0
- package/.onto/processes/shared/target-material-kind-contract.md +198 -0
- package/.onto/roles/axiology.md +81 -0
- package/.onto/roles/conciseness.md +36 -0
- package/.onto/roles/coverage.md +34 -0
- package/.onto/roles/dependency.md +37 -0
- package/.onto/roles/evolution.md +35 -0
- package/.onto/roles/logic.md +104 -0
- package/.onto/roles/pragmatics.md +32 -0
- package/.onto/roles/semantics.md +36 -0
- package/.onto/roles/structure.md +33 -0
- package/.onto/roles/synthesize.md +92 -0
- package/AGENTS.md +240 -0
- package/CLAUDE.md +39 -0
- package/README.md +287 -0
- package/bin/onto +92 -0
- package/dist/cli.js +101 -0
- package/dist/core-api/reconstruct-api.js +222 -0
- package/dist/core-api/review-api.js +1271 -0
- package/dist/core-runtime/cli/assemble-review-record.js +431 -0
- package/dist/core-runtime/cli/bootstrap-review-binding.js +186 -0
- package/dist/core-runtime/cli/codex-nested-dispatch.js +226 -0
- package/dist/core-runtime/cli/codex-nested-dispatch.test.js +390 -0
- package/dist/core-runtime/cli/codex-nested-teamlead-executor.js +464 -0
- package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +335 -0
- package/dist/core-runtime/cli/codex-review-unit-executor.js +228 -0
- package/dist/core-runtime/cli/complete-review-session.js +64 -0
- package/dist/core-runtime/cli/complexity-assessment.js +153 -0
- package/dist/core-runtime/cli/coordinator-helpers.js +583 -0
- package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +167 -0
- package/dist/core-runtime/cli/coordinator-state-machine.js +794 -0
- package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +615 -0
- package/dist/core-runtime/cli/e2e-start-review-session.test.js +312 -0
- package/dist/core-runtime/cli/health.js +44 -0
- package/dist/core-runtime/cli/inline-http-review-unit-executor.js +656 -0
- package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +567 -0
- package/dist/core-runtime/cli/materialize-review-execution-preparation.js +104 -0
- package/dist/core-runtime/cli/materialize-review-prompt-packets.js +952 -0
- package/dist/core-runtime/cli/migrate-session-roots.js +118 -0
- package/dist/core-runtime/cli/mock-review-unit-executor.js +285 -0
- package/dist/core-runtime/cli/onto-tools.js +369 -0
- package/dist/core-runtime/cli/prepare-review-session.js +272 -0
- package/dist/core-runtime/cli/render-review-final-output.js +350 -0
- package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +106 -0
- package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +268 -0
- package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +136 -0
- package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +201 -0
- package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +192 -0
- package/dist/core-runtime/cli/review-invoke.js +2030 -0
- package/dist/core-runtime/cli/run-review-prompt-execution.js +2152 -0
- package/dist/core-runtime/cli/session-root-guard.js +168 -0
- package/dist/core-runtime/cli/spawn-watcher.js +173 -0
- package/dist/core-runtime/cli/spawn-watcher.test.js +457 -0
- package/dist/core-runtime/cli/start-review-session.js +68 -0
- package/dist/core-runtime/cli/strip-wrapping-code-fence.js +56 -0
- package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +79 -0
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +412 -0
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +351 -0
- package/dist/core-runtime/cli/topology-executor-mapping.js +139 -0
- package/dist/core-runtime/cli/topology-executor-mapping.test.js +173 -0
- package/dist/core-runtime/cli/write-review-interpretation.js +81 -0
- package/dist/core-runtime/config/onto-config-cli.js +278 -0
- package/dist/core-runtime/config/onto-config-key-path.js +288 -0
- package/dist/core-runtime/config/onto-config-key-path.test.js +195 -0
- package/dist/core-runtime/config/onto-config-preview.js +108 -0
- package/dist/core-runtime/config/onto-config-preview.test.js +132 -0
- package/dist/core-runtime/discovery/config-chain.js +118 -0
- package/dist/core-runtime/discovery/config-chain.test.js +103 -0
- package/dist/core-runtime/discovery/config-profile.js +199 -0
- package/dist/core-runtime/discovery/config-profile.test.js +233 -0
- package/dist/core-runtime/discovery/host-detection.js +33 -0
- package/dist/core-runtime/discovery/host-detection.test.js +186 -0
- package/dist/core-runtime/discovery/installation-paths.js +21 -0
- package/dist/core-runtime/discovery/installation-paths.test.js +65 -0
- package/dist/core-runtime/discovery/lens-registry.js +60 -0
- package/dist/core-runtime/discovery/lens-registry.test.js +81 -0
- package/dist/core-runtime/discovery/onto-home.js +71 -0
- package/dist/core-runtime/discovery/path-normalization.js +28 -0
- package/dist/core-runtime/discovery/path-normalization.test.js +22 -0
- package/dist/core-runtime/discovery/plugin-path.js +72 -0
- package/dist/core-runtime/discovery/plugin-path.test.js +95 -0
- package/dist/core-runtime/discovery/project-root.js +47 -0
- package/dist/core-runtime/discovery/settings-chain.js +353 -0
- package/dist/core-runtime/discovery/walk-up.js +17 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +344 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +915 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +564 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +708 -0
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +165 -0
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +227 -0
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +59 -0
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +205 -0
- package/dist/core-runtime/evolve/adapters/methodology/adapter.js +16 -0
- package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +9 -0
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +298 -0
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +70 -0
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +46 -0
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +73 -0
- package/dist/core-runtime/evolve/adapters/registry.js +47 -0
- package/dist/core-runtime/evolve/adapters/registry.test.js +67 -0
- package/dist/core-runtime/evolve/cli.js +256 -0
- package/dist/core-runtime/evolve/commands/align.js +194 -0
- package/dist/core-runtime/evolve/commands/align.test.js +82 -0
- package/dist/core-runtime/evolve/commands/apply.js +161 -0
- package/dist/core-runtime/evolve/commands/apply.test.js +138 -0
- package/dist/core-runtime/evolve/commands/close.js +39 -0
- package/dist/core-runtime/evolve/commands/close.test.js +99 -0
- package/dist/core-runtime/evolve/commands/defer.js +40 -0
- package/dist/core-runtime/evolve/commands/defer.test.js +134 -0
- package/dist/core-runtime/evolve/commands/draft.js +323 -0
- package/dist/core-runtime/evolve/commands/draft.test.js +178 -0
- package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +208 -0
- package/dist/core-runtime/evolve/commands/error-messages.js +125 -0
- package/dist/core-runtime/evolve/commands/error-messages.test.js +167 -0
- package/dist/core-runtime/evolve/commands/propose-align.js +222 -0
- package/dist/core-runtime/evolve/commands/propose-align.test.js +136 -0
- package/dist/core-runtime/evolve/commands/reconstruct.js +330 -0
- package/dist/core-runtime/evolve/commands/reconstruct.test.js +278 -0
- package/dist/core-runtime/evolve/commands/shared.js +22 -0
- package/dist/core-runtime/evolve/commands/stale-check.js +103 -0
- package/dist/core-runtime/evolve/commands/stale-check.test.js +84 -0
- package/dist/core-runtime/evolve/commands/start.js +887 -0
- package/dist/core-runtime/evolve/commands/start.test.js +396 -0
- package/dist/core-runtime/evolve/config/project-config.js +99 -0
- package/dist/core-runtime/evolve/config/project-config.test.js +170 -0
- package/dist/core-runtime/evolve/renderers/align-packet.js +280 -0
- package/dist/core-runtime/evolve/renderers/align-packet.test.js +332 -0
- package/dist/core-runtime/evolve/renderers/draft-packet.js +303 -0
- package/dist/core-runtime/evolve/renderers/draft-packet.test.js +377 -0
- package/dist/core-runtime/evolve/renderers/format.js +5 -0
- package/dist/core-runtime/evolve/renderers/scope-md.js +237 -0
- package/dist/core-runtime/evolve/renderers/scope-md.test.js +306 -0
- package/dist/core-runtime/govern/cli.js +369 -0
- package/dist/core-runtime/govern/cli.test.js +314 -0
- package/dist/core-runtime/govern/drift-engine.js +103 -0
- package/dist/core-runtime/govern/drift-engine.test.js +319 -0
- package/dist/core-runtime/govern/promote-principle.js +206 -0
- package/dist/core-runtime/govern/promote-principle.test.js +368 -0
- package/dist/core-runtime/govern/queue.js +81 -0
- package/dist/core-runtime/govern/types.js +16 -0
- package/dist/core-runtime/install/cli.js +530 -0
- package/dist/core-runtime/install/detect.js +128 -0
- package/dist/core-runtime/install/detect.test.js +155 -0
- package/dist/core-runtime/install/gitignore-update.js +74 -0
- package/dist/core-runtime/install/gitignore-update.test.js +64 -0
- package/dist/core-runtime/install/install-integration.test.js +373 -0
- package/dist/core-runtime/install/prompts.js +389 -0
- package/dist/core-runtime/install/prompts.test.js +293 -0
- package/dist/core-runtime/install/types.js +26 -0
- package/dist/core-runtime/install/validation.js +295 -0
- package/dist/core-runtime/install/validation.test.js +313 -0
- package/dist/core-runtime/install/writer.js +254 -0
- package/dist/core-runtime/install/writer.test.js +218 -0
- package/dist/core-runtime/learning/extractor.js +461 -0
- package/dist/core-runtime/learning/feedback.js +179 -0
- package/dist/core-runtime/learning/health-report.js +165 -0
- package/dist/core-runtime/learning/health-report.test.js +169 -0
- package/dist/core-runtime/learning/loader.js +388 -0
- package/dist/core-runtime/learning/loader.test.js +102 -0
- package/dist/core-runtime/learning/promote/apply-state.js +240 -0
- package/dist/core-runtime/learning/promote/audit-obligation.js +195 -0
- package/dist/core-runtime/learning/promote/collector.js +432 -0
- package/dist/core-runtime/learning/promote/degraded-state.js +125 -0
- package/dist/core-runtime/learning/promote/domain-doc-proposer.js +166 -0
- package/dist/core-runtime/learning/promote/e2e-promote.test.js +6385 -0
- package/dist/core-runtime/learning/promote/health-snapshot.js +150 -0
- package/dist/core-runtime/learning/promote/insight-reclassifier.js +544 -0
- package/dist/core-runtime/learning/promote/judgment-auditor.js +517 -0
- package/dist/core-runtime/learning/promote/panel-reviewer.js +1158 -0
- package/dist/core-runtime/learning/promote/promote-executor.js +1675 -0
- package/dist/core-runtime/learning/promote/promoter.js +307 -0
- package/dist/core-runtime/learning/promote/retirement.js +122 -0
- package/dist/core-runtime/learning/promote/types.js +23 -0
- package/dist/core-runtime/learning/prompt-sections.js +51 -0
- package/dist/core-runtime/learning/shared/artifact-registry-init.js +45 -0
- package/dist/core-runtime/learning/shared/artifact-registry.js +254 -0
- package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +73 -0
- package/dist/core-runtime/learning/shared/audit-state.js +99 -0
- package/dist/core-runtime/learning/shared/duplicate-check.js +28 -0
- package/dist/core-runtime/learning/shared/llm-caller.js +831 -0
- package/dist/core-runtime/learning/shared/llm-caller.test.js +601 -0
- package/dist/core-runtime/learning/shared/llm-tool-loop.js +393 -0
- package/dist/core-runtime/learning/shared/mode.js +25 -0
- package/dist/core-runtime/learning/shared/paths.js +84 -0
- package/dist/core-runtime/learning/shared/paths.test.js +79 -0
- package/dist/core-runtime/learning/shared/patterns.js +37 -0
- package/dist/core-runtime/learning/shared/recoverability.js +355 -0
- package/dist/core-runtime/learning/shared/recovery-context.js +374 -0
- package/dist/core-runtime/learning/shared/scope.js +1 -0
- package/dist/core-runtime/learning/shared/semantic-classifier.js +94 -0
- package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +42 -0
- package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +37 -0
- package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +39 -0
- package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +41 -0
- package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +38 -0
- package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +43 -0
- package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +113 -0
- package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +36 -0
- package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +48 -0
- package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +43 -0
- package/dist/core-runtime/learning/shared/specs/spec-helpers.js +64 -0
- package/dist/core-runtime/learning/usage-tracker.js +190 -0
- package/dist/core-runtime/learning/usage-tracker.test.js +176 -0
- package/dist/core-runtime/llm/llm-caller.js +649 -0
- package/dist/core-runtime/llm/llm-tool-loop.js +401 -0
- package/dist/core-runtime/llm/model-switcher.js +62 -0
- package/dist/core-runtime/logger.js +22 -0
- package/dist/core-runtime/onboard/detect-review-axes.js +122 -0
- package/dist/core-runtime/onboard/detect-review-axes.test.js +127 -0
- package/dist/core-runtime/onboard/write-review-block.js +188 -0
- package/dist/core-runtime/onboard/write-review-block.test.js +240 -0
- package/dist/core-runtime/readers/brownfield-builder.js +150 -0
- package/dist/core-runtime/readers/brownfield-builder.test.js +136 -0
- package/dist/core-runtime/readers/code-chunk-collector.js +53 -0
- package/dist/core-runtime/readers/code-chunk-collector.test.js +136 -0
- package/dist/core-runtime/readers/file-utils.js +240 -0
- package/dist/core-runtime/readers/file-utils.test.js +146 -0
- package/dist/core-runtime/readers/lexicon-citation-check.js +93 -0
- package/dist/core-runtime/readers/lexicon-citation-check.test.js +77 -0
- package/dist/core-runtime/readers/mcp-figma.js +30 -0
- package/dist/core-runtime/readers/mcp-figma.test.js +82 -0
- package/dist/core-runtime/readers/mcp-generic.js +31 -0
- package/dist/core-runtime/readers/mcp-generic.test.js +76 -0
- package/dist/core-runtime/readers/ontology-index.js +148 -0
- package/dist/core-runtime/readers/ontology-index.test.js +245 -0
- package/dist/core-runtime/readers/ontology-query.js +168 -0
- package/dist/core-runtime/readers/ontology-query.test.js +311 -0
- package/dist/core-runtime/readers/ontology-resolve.js +48 -0
- package/dist/core-runtime/readers/ontology-resolve.test.js +48 -0
- package/dist/core-runtime/readers/patterns/index.js +7 -0
- package/dist/core-runtime/readers/review-log.js +213 -0
- package/dist/core-runtime/readers/review-log.test.js +313 -0
- package/dist/core-runtime/readers/scan-local.js +102 -0
- package/dist/core-runtime/readers/scan-local.test.js +102 -0
- package/dist/core-runtime/readers/scan-tarball.js +121 -0
- package/dist/core-runtime/readers/scan-tarball.test.js +283 -0
- package/dist/core-runtime/readers/scan-vault.js +34 -0
- package/dist/core-runtime/readers/scan-vault.test.js +81 -0
- package/dist/core-runtime/readers/types.js +42 -0
- package/dist/core-runtime/readers/types.test.js +94 -0
- package/dist/core-runtime/readers/viewpoint-collectors.js +229 -0
- package/dist/core-runtime/reconstruct/artifact-types.js +1 -0
- package/dist/core-runtime/reconstruct/directive-validation.js +123 -0
- package/dist/core-runtime/reconstruct/materialize-preparation.js +251 -0
- package/dist/core-runtime/reconstruct/record.js +198 -0
- package/dist/core-runtime/reconstruct/run.js +578 -0
- package/dist/core-runtime/reconstruct/seed-candidate-validation.js +356 -0
- package/dist/core-runtime/reconstruct/source-observations.js +62 -0
- package/dist/core-runtime/reconstruct/source-profiles.js +73 -0
- package/dist/core-runtime/release-channel/release-channel.js +90 -0
- package/dist/core-runtime/review/artifact-types.js +13 -0
- package/dist/core-runtime/review/citation-audit.js +204 -0
- package/dist/core-runtime/review/citation-audit.test.js +165 -0
- package/dist/core-runtime/review/controlled-lens-deliberation.js +125 -0
- package/dist/core-runtime/review/execution-plan-resolver.js +247 -0
- package/dist/core-runtime/review/execution-plan-resolver.test.js +243 -0
- package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +246 -0
- package/dist/core-runtime/review/execution-topology-resolver.js +401 -0
- package/dist/core-runtime/review/execution-topology-resolver.test.js +315 -0
- package/dist/core-runtime/review/failure-records.js +57 -0
- package/dist/core-runtime/review/inline-context-embedder.js +141 -0
- package/dist/core-runtime/review/inline-context-embedder.test.js +154 -0
- package/dist/core-runtime/review/issue-artifact-runtime.js +859 -0
- package/dist/core-runtime/review/legacy-mode-policy.js +88 -0
- package/dist/core-runtime/review/lens-completion-policy.js +17 -0
- package/dist/core-runtime/review/materializers-effort-persist.test.js +79 -0
- package/dist/core-runtime/review/materializers.js +963 -0
- package/dist/core-runtime/review/ontology-path-classifier.js +179 -0
- package/dist/core-runtime/review/ontology-path-classifier.test.js +216 -0
- package/dist/core-runtime/review/packet-boundary-policy.js +215 -0
- package/dist/core-runtime/review/packet-boundary-policy.test.js +107 -0
- package/dist/core-runtime/review/participating-lens-paths.js +61 -0
- package/dist/core-runtime/review/participating-lens-paths.test.js +73 -0
- package/dist/core-runtime/review/review-artifact-utils.js +287 -0
- package/dist/core-runtime/review/review-config-legacy-translate.js +244 -0
- package/dist/core-runtime/review/review-config-legacy-translate.test.js +161 -0
- package/dist/core-runtime/review/review-config-validator.js +289 -0
- package/dist/core-runtime/review/review-config-validator.test.js +236 -0
- package/dist/core-runtime/review/review-execution-profile.js +193 -0
- package/dist/core-runtime/review/review-execution-route.js +52 -0
- package/dist/core-runtime/review/review-progress-contract.js +123 -0
- package/dist/core-runtime/review/review-record-validation.js +251 -0
- package/dist/core-runtime/review/review-result-classification.js +379 -0
- package/dist/core-runtime/review/review-state-machine.js +39 -0
- package/dist/core-runtime/review/route-visibility.js +125 -0
- package/dist/core-runtime/review/shape-pipeline-audit.test.js +311 -0
- package/dist/core-runtime/review/shape-to-topology-id.js +117 -0
- package/dist/core-runtime/review/shape-to-topology-id.test.js +132 -0
- package/dist/core-runtime/review/topology-shape-derivation.js +155 -0
- package/dist/core-runtime/review/topology-shape-derivation.test.js +195 -0
- package/dist/core-runtime/scope-runtime/constants.js +12 -0
- package/dist/core-runtime/scope-runtime/constraint-pool.js +166 -0
- package/dist/core-runtime/scope-runtime/constraint-pool.test.js +674 -0
- package/dist/core-runtime/scope-runtime/domain-validation-log.js +135 -0
- package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +156 -0
- package/dist/core-runtime/scope-runtime/eval-persistence.js +65 -0
- package/dist/core-runtime/scope-runtime/eval-persistence.test.js +84 -0
- package/dist/core-runtime/scope-runtime/event-pipeline.js +64 -0
- package/dist/core-runtime/scope-runtime/event-pipeline.test.js +450 -0
- package/dist/core-runtime/scope-runtime/event-store.js +39 -0
- package/dist/core-runtime/scope-runtime/event-store.test.js +95 -0
- package/dist/core-runtime/scope-runtime/gate-guard.js +348 -0
- package/dist/core-runtime/scope-runtime/gate-guard.test.js +1047 -0
- package/dist/core-runtime/scope-runtime/hash.js +4 -0
- package/dist/core-runtime/scope-runtime/hash.test.js +33 -0
- package/dist/core-runtime/scope-runtime/id.js +4 -0
- package/dist/core-runtime/scope-runtime/id.test.js +17 -0
- package/dist/core-runtime/scope-runtime/reducer.js +297 -0
- package/dist/core-runtime/scope-runtime/reducer.test.js +759 -0
- package/dist/core-runtime/scope-runtime/scope-manager.js +161 -0
- package/dist/core-runtime/scope-runtime/state-machine.js +309 -0
- package/dist/core-runtime/scope-runtime/state-machine.test.js +704 -0
- package/dist/core-runtime/scope-runtime/types.js +116 -0
- package/dist/core-runtime/scope-runtime/types.test.js +69 -0
- package/dist/core-runtime/target-material-kind.js +256 -0
- package/dist/core-runtime/translate/render-for-user.js +169 -0
- package/dist/core-runtime/translate/render-for-user.test.js +122 -0
- package/dist/mcp/server.js +1011 -0
- package/dist/mcp/tool-schemas.js +93 -0
- package/dist/providers/capability-contract.js +1 -0
- package/package.json +68 -0
- package/settings.example.json +33 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { detectReviewAxes } from "./detect-review-axes.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// detectReviewAxes — Review UX Redesign P4 (2026-04-21)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
//
|
|
7
|
+
// These tests exercise the projection of env signals into the onboard
|
|
8
|
+
// axis vocabulary. The underlying detection helpers (from discovery/) are
|
|
9
|
+
// covered by their own suite; here we only verify:
|
|
10
|
+
//
|
|
11
|
+
// (1) Host priority ordering — Claude Code > Codex CLI > plain.
|
|
12
|
+
// (2) agent_teams_available reads CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS.
|
|
13
|
+
// (3) litellm_endpoint returns the URL string (not just a boolean).
|
|
14
|
+
// (4) codex_available is sourced from the shared discovery helper.
|
|
15
|
+
//
|
|
16
|
+
// The codex binary / auth.json probe is filesystem-backed, so we mock
|
|
17
|
+
// `detectCodexBinaryAvailable` from the discovery module to keep the tests
|
|
18
|
+
// hermetic.
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
vi.mock("../discovery/host-detection.js", async (importOriginal) => {
|
|
21
|
+
const actual = (await importOriginal());
|
|
22
|
+
return {
|
|
23
|
+
...actual,
|
|
24
|
+
// Override only the filesystem-dependent probe. The env-signal helpers
|
|
25
|
+
// remain real so we can control behaviour via process.env.
|
|
26
|
+
detectCodexBinaryAvailable: vi.fn(() => false),
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
const savedEnv = {};
|
|
30
|
+
const VOLATILE_ENV_KEYS = [
|
|
31
|
+
"CLAUDECODE",
|
|
32
|
+
"CLAUDE_PROJECT_DIR",
|
|
33
|
+
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS",
|
|
34
|
+
"CODEX_THREAD_ID",
|
|
35
|
+
"CODEX_CI",
|
|
36
|
+
"LITELLM_BASE_URL",
|
|
37
|
+
];
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
for (const key of VOLATILE_ENV_KEYS) {
|
|
40
|
+
savedEnv[key] = process.env[key];
|
|
41
|
+
delete process.env[key];
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
afterEach(() => {
|
|
45
|
+
for (const key of VOLATILE_ENV_KEYS) {
|
|
46
|
+
const original = savedEnv[key];
|
|
47
|
+
if (original === undefined) {
|
|
48
|
+
delete process.env[key];
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
process.env[key] = original;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
vi.resetAllMocks();
|
|
55
|
+
});
|
|
56
|
+
describe("detectReviewAxes — host category", () => {
|
|
57
|
+
it("returns plain-terminal when no host signal is present", () => {
|
|
58
|
+
const result = detectReviewAxes();
|
|
59
|
+
expect(result.detected.host).toBe("plain-terminal");
|
|
60
|
+
});
|
|
61
|
+
it("returns claude-code when CLAUDECODE=1", () => {
|
|
62
|
+
process.env.CLAUDECODE = "1";
|
|
63
|
+
expect(detectReviewAxes().detected.host).toBe("claude-code");
|
|
64
|
+
});
|
|
65
|
+
it("returns claude-code when CLAUDE_PROJECT_DIR is set", () => {
|
|
66
|
+
process.env.CLAUDE_PROJECT_DIR = "/tmp/proj";
|
|
67
|
+
expect(detectReviewAxes().detected.host).toBe("claude-code");
|
|
68
|
+
});
|
|
69
|
+
it("returns codex-cli when CODEX_THREAD_ID is set", () => {
|
|
70
|
+
process.env.CODEX_THREAD_ID = "thr-123";
|
|
71
|
+
expect(detectReviewAxes().detected.host).toBe("codex-cli");
|
|
72
|
+
});
|
|
73
|
+
it("prefers claude-code over codex-cli when both signals are present", () => {
|
|
74
|
+
// An inner Codex exec inside a Claude Code session — onboard context
|
|
75
|
+
// is Claude Code; codex availability is surfaced separately.
|
|
76
|
+
process.env.CLAUDECODE = "1";
|
|
77
|
+
process.env.CODEX_THREAD_ID = "thr-123";
|
|
78
|
+
expect(detectReviewAxes().detected.host).toBe("claude-code");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("detectReviewAxes — agent_teams_available (strict =1)", () => {
|
|
82
|
+
// The resolver uses `env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1"`.
|
|
83
|
+
// Onboard MUST use the same check so the two layers never disagree on
|
|
84
|
+
// whether teams are available — otherwise onboard writes a config the
|
|
85
|
+
// runtime silently rejects (P3 would degrade it, violating the UX
|
|
86
|
+
// promise that "what onboard accepts is what runs").
|
|
87
|
+
it("is false when env var is absent", () => {
|
|
88
|
+
expect(detectReviewAxes().detected.agent_teams_available).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
it('is true only when CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1"', () => {
|
|
91
|
+
process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1";
|
|
92
|
+
expect(detectReviewAxes().detected.agent_teams_available).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
it('is false for truthy-looking strings that are not "1"', () => {
|
|
95
|
+
// These would pass a naive Boolean() check but must NOT activate teams.
|
|
96
|
+
// The resolver rejects them; onboard must match.
|
|
97
|
+
for (const value of ["true", "yes", "on", "enabled", "TRUE", "2"]) {
|
|
98
|
+
process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = value;
|
|
99
|
+
expect(detectReviewAxes().detected.agent_teams_available).toBe(false);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
it('is false for falsy-looking strings ("0", "false", empty)', () => {
|
|
103
|
+
for (const value of ["0", "false", ""]) {
|
|
104
|
+
process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = value;
|
|
105
|
+
expect(detectReviewAxes().detected.agent_teams_available).toBe(false);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe("detectReviewAxes — litellm_endpoint", () => {
|
|
110
|
+
it("is null when LITELLM_BASE_URL is unset", () => {
|
|
111
|
+
expect(detectReviewAxes().detected.litellm_endpoint).toBeNull();
|
|
112
|
+
});
|
|
113
|
+
it("returns the URL string when LITELLM_BASE_URL is set", () => {
|
|
114
|
+
process.env.LITELLM_BASE_URL = "http://localhost:4000";
|
|
115
|
+
expect(detectReviewAxes().detected.litellm_endpoint).toBe("http://localhost:4000");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe("detectReviewAxes — codex_available", () => {
|
|
119
|
+
it("surfaces the discovery helper verdict (mocked false by default)", async () => {
|
|
120
|
+
const mod = await import("../discovery/host-detection.js");
|
|
121
|
+
const spy = vi.mocked(mod.detectCodexBinaryAvailable);
|
|
122
|
+
spy.mockReturnValue(false);
|
|
123
|
+
expect(detectReviewAxes().detected.codex_available).toBe(false);
|
|
124
|
+
spy.mockReturnValue(true);
|
|
125
|
+
expect(detectReviewAxes().detected.codex_available).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review UX Redesign P4 — write/update the `review:` block in `.onto/config.yml`.
|
|
3
|
+
*
|
|
4
|
+
* # What this module is
|
|
5
|
+
*
|
|
6
|
+
* A small helper that takes a validated `OntoReviewConfig` plus a path to
|
|
7
|
+
* an `.onto/config.yml` file and either (a) adds a `review:` block to the
|
|
8
|
+
* file or (b) replaces an existing one.
|
|
9
|
+
*
|
|
10
|
+
* # Why it exists
|
|
11
|
+
*
|
|
12
|
+
* Onboard stage 7 (design doc §5.2) writes the user's chosen review axes
|
|
13
|
+
* into `.onto/config.yml`. Without a dedicated seat this would require the
|
|
14
|
+
* prose to embed YAML serialization instructions, which is error-prone — a
|
|
15
|
+
* stray indent produces a silently invalid config. Centralizing the write
|
|
16
|
+
* path means the onboard prose can describe the intent ("record the user's
|
|
17
|
+
* answers in the review block") and delegate formatting to this helper.
|
|
18
|
+
*
|
|
19
|
+
* We use `yaml`'s `parseDocument` / `Document` API (not `parse` +
|
|
20
|
+
* `stringify`) because the document round-trip preserves comments and
|
|
21
|
+
* formatting where the existing file has them. That matters for configs
|
|
22
|
+
* authored by humans — they often annotate fields with rationale.
|
|
23
|
+
*
|
|
24
|
+
* # How it relates
|
|
25
|
+
*
|
|
26
|
+
* - Consumes: `OntoReviewConfig` type from `discovery/config-chain.ts`.
|
|
27
|
+
* - Validates with: `validateReviewConfig` from
|
|
28
|
+
* `review/review-config-validator.ts` — we re-validate to catch caller
|
|
29
|
+
* errors early (the onboard prose is a weak integrator).
|
|
30
|
+
* - Exposed via: `npm run onboard:write-review-block -- <path> <json>`.
|
|
31
|
+
*
|
|
32
|
+
* # Guarantees
|
|
33
|
+
*
|
|
34
|
+
* 1. Existing top-level fields are preserved in order.
|
|
35
|
+
* 2. Comments attached to preserved fields survive the round-trip.
|
|
36
|
+
* 3. If the file does not exist, it is created with a minimal document
|
|
37
|
+
* containing only the `review:` block.
|
|
38
|
+
* 4. If the input is not a valid `OntoReviewConfig`, the function returns a
|
|
39
|
+
* result object with `ok: false` and no write is performed.
|
|
40
|
+
*/
|
|
41
|
+
import fs from "node:fs";
|
|
42
|
+
import path from "node:path";
|
|
43
|
+
import { Document, parseDocument } from "yaml";
|
|
44
|
+
import { validateReviewConfig, } from "../review/review-config-validator.js";
|
|
45
|
+
/**
|
|
46
|
+
* Write (or update) the `review:` block in the given config file.
|
|
47
|
+
*
|
|
48
|
+
* The function re-validates `review` with `validateReviewConfig` before
|
|
49
|
+
* touching the file — if validation fails, nothing is written and the
|
|
50
|
+
* caller receives the structured error list.
|
|
51
|
+
*/
|
|
52
|
+
export function writeReviewBlock(configPath, review) {
|
|
53
|
+
// Re-validate. The type system alone cannot catch callers who constructed
|
|
54
|
+
// the object manually from JSON input (the most common P4 path — the
|
|
55
|
+
// onboard prose builds the object from interactive answers).
|
|
56
|
+
const validation = validateReviewConfig(review);
|
|
57
|
+
if (!validation.ok) {
|
|
58
|
+
return { ok: false, errors: validation.errors };
|
|
59
|
+
}
|
|
60
|
+
const absolute = path.resolve(configPath);
|
|
61
|
+
const exists = fs.existsSync(absolute);
|
|
62
|
+
// Load the existing document (or a fresh empty one). `parseDocument`
|
|
63
|
+
// returns a `Document` node the YAML library can mutate and re-serialize
|
|
64
|
+
// while preserving source formatting where practical.
|
|
65
|
+
let doc;
|
|
66
|
+
if (exists) {
|
|
67
|
+
const raw = fs.readFileSync(absolute, "utf8");
|
|
68
|
+
doc = parseDocument(raw, { keepSourceTokens: false });
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Ensure the parent directory exists — `.onto/` may not be present on
|
|
72
|
+
// a brand-new project until onboard creates it.
|
|
73
|
+
fs.mkdirSync(path.dirname(absolute), { recursive: true });
|
|
74
|
+
doc = new Document({});
|
|
75
|
+
}
|
|
76
|
+
// Detect the prior state of the document so we can report it back to the
|
|
77
|
+
// onboard prose (for the user-facing summary).
|
|
78
|
+
const replacedExistingBlock = exists && doc.has("review");
|
|
79
|
+
// The yaml library accepts a plain object for `set` — it converts that
|
|
80
|
+
// into the internal Node graph. We filter out undefined leaves so the
|
|
81
|
+
// output does not carry `key: null` artifacts for absent axes.
|
|
82
|
+
const serializable = pruneUndefined(review);
|
|
83
|
+
doc.set("review", serializable);
|
|
84
|
+
const serialized = doc.toString();
|
|
85
|
+
fs.writeFileSync(absolute, serialized, "utf8");
|
|
86
|
+
return {
|
|
87
|
+
ok: true,
|
|
88
|
+
path: absolute,
|
|
89
|
+
created: !exists,
|
|
90
|
+
replacedExistingBlock,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
// Internal helpers
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
/**
|
|
97
|
+
* Strip `undefined` leaves from a nested object. The `yaml` library would
|
|
98
|
+
* otherwise serialize them as `null`, which is semantically different from
|
|
99
|
+
* "absent" in the review block (an absent key = use review defaults).
|
|
100
|
+
*/
|
|
101
|
+
function pruneUndefined(input) {
|
|
102
|
+
if (input === null || input === undefined)
|
|
103
|
+
return input;
|
|
104
|
+
if (Array.isArray(input)) {
|
|
105
|
+
return input.map((v) => pruneUndefined(v));
|
|
106
|
+
}
|
|
107
|
+
if (typeof input !== "object")
|
|
108
|
+
return input;
|
|
109
|
+
const out = {};
|
|
110
|
+
for (const [key, value] of Object.entries(input)) {
|
|
111
|
+
if (value === undefined)
|
|
112
|
+
continue;
|
|
113
|
+
out[key] = pruneUndefined(value);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// CLI entry — `npm run onboard:write-review-block -- <path> <json>`
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
function printHelp() {
|
|
121
|
+
const lines = [
|
|
122
|
+
"onboard:write-review-block",
|
|
123
|
+
"",
|
|
124
|
+
"Write or update the `review:` block in a .onto/config.yml file.",
|
|
125
|
+
"",
|
|
126
|
+
"Usage:",
|
|
127
|
+
" npm run onboard:write-review-block -- <config-path> <review-json>",
|
|
128
|
+
" npm run onboard:write-review-block -- --help",
|
|
129
|
+
"",
|
|
130
|
+
"Arguments:",
|
|
131
|
+
" <config-path> Path to .onto/config.yml (created if missing).",
|
|
132
|
+
" <review-json> JSON string representing an OntoReviewConfig.",
|
|
133
|
+
"",
|
|
134
|
+
"Example:",
|
|
135
|
+
" npm run onboard:write-review-block -- .onto/config.yml \\",
|
|
136
|
+
" '{\"teamlead\":{\"model\":\"main\"},\"subagent\":{\"provider\":\"main-native\"}}'",
|
|
137
|
+
"",
|
|
138
|
+
"Output: single-line JSON describing the write result on stdout.",
|
|
139
|
+
"Exit code 0 on success, 1 on validation/IO failure.",
|
|
140
|
+
];
|
|
141
|
+
console.log(lines.join("\n"));
|
|
142
|
+
}
|
|
143
|
+
function isMainModule() {
|
|
144
|
+
const entry = process.argv[1];
|
|
145
|
+
if (typeof entry !== "string" || entry.length === 0)
|
|
146
|
+
return false;
|
|
147
|
+
try {
|
|
148
|
+
const entryUrl = new URL(`file://${entry}`).href;
|
|
149
|
+
return import.meta.url === entryUrl;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function runCli(argv) {
|
|
156
|
+
if (argv.length === 0 || argv.includes("--help") || argv.includes("-h")) {
|
|
157
|
+
printHelp();
|
|
158
|
+
return argv.length === 0 ? 1 : 0;
|
|
159
|
+
}
|
|
160
|
+
const unsupportedFlags = argv.filter((a) => a.startsWith("--"));
|
|
161
|
+
if (unsupportedFlags.length > 0) {
|
|
162
|
+
console.error(`error: unsupported option(s): ${unsupportedFlags.join(", ")}`);
|
|
163
|
+
return 1;
|
|
164
|
+
}
|
|
165
|
+
const positional = argv.filter((a) => !a.startsWith("--"));
|
|
166
|
+
if (positional.length < 2) {
|
|
167
|
+
console.error("error: two positional arguments required: <config-path> <review-json>. " +
|
|
168
|
+
"Run with --help for usage.");
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
const [configPath, reviewJson] = positional;
|
|
172
|
+
let parsed;
|
|
173
|
+
try {
|
|
174
|
+
parsed = JSON.parse(reviewJson);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
178
|
+
console.error(`error: <review-json> is not valid JSON: ${message}`);
|
|
179
|
+
return 1;
|
|
180
|
+
}
|
|
181
|
+
const result = writeReviewBlock(configPath, parsed);
|
|
182
|
+
console.log(JSON.stringify(result));
|
|
183
|
+
return result.ok ? 0 : 1;
|
|
184
|
+
}
|
|
185
|
+
if (isMainModule()) {
|
|
186
|
+
const exitCode = runCli(process.argv.slice(2));
|
|
187
|
+
process.exit(exitCode);
|
|
188
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { writeReviewBlock } from "./write-review-block.js";
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// writeReviewBlock — Review UX Redesign P4 (2026-04-21)
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
//
|
|
10
|
+
// These tests cover the four behaviours the onboard prose flow depends on:
|
|
11
|
+
//
|
|
12
|
+
// (1) Fresh-file creation — onboard on a brand-new project must create
|
|
13
|
+
// the file + parent directory + write the review block.
|
|
14
|
+
// (2) Round-trip preservation — existing top-level fields (e.g.
|
|
15
|
+
// output_language, domains) and their comments must survive the
|
|
16
|
+
// write.
|
|
17
|
+
// (3) Replace semantics — a pre-existing `review:` block is REPLACED,
|
|
18
|
+
// not merged. The caller's config object is the authoritative shape.
|
|
19
|
+
// (4) Legacy stripping — when stripLegacyPriority=true, the
|
|
20
|
+
// execution_topology_priority field is removed and reported.
|
|
21
|
+
//
|
|
22
|
+
// Validation failure paths (foreign provider without model_id, etc.) are
|
|
23
|
+
// covered indirectly via validateReviewConfig's own tests — here we spot-
|
|
24
|
+
// check that invalid input blocks the write entirely.
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
let tmpDir;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "onto-onboard-p4-"));
|
|
29
|
+
});
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
32
|
+
});
|
|
33
|
+
function makeConfigPath(name = "config.yml") {
|
|
34
|
+
return path.join(tmpDir, ".onto", name);
|
|
35
|
+
}
|
|
36
|
+
function read(p) {
|
|
37
|
+
return fs.readFileSync(p, "utf8");
|
|
38
|
+
}
|
|
39
|
+
describe("writeReviewBlock — fresh file", () => {
|
|
40
|
+
it("creates the parent directory + file when neither exists", () => {
|
|
41
|
+
const configPath = makeConfigPath();
|
|
42
|
+
const review = {
|
|
43
|
+
teamlead: { model: "main" },
|
|
44
|
+
subagent: { provider: "main-native" },
|
|
45
|
+
};
|
|
46
|
+
const result = writeReviewBlock(configPath, review);
|
|
47
|
+
expect(result.ok).toBe(true);
|
|
48
|
+
if (!result.ok)
|
|
49
|
+
return;
|
|
50
|
+
expect(result.created).toBe(true);
|
|
51
|
+
expect(result.replacedExistingBlock).toBe(false);
|
|
52
|
+
expect(result.strippedLegacyPriority).toBe(false);
|
|
53
|
+
const written = read(configPath);
|
|
54
|
+
expect(written).toContain("review:");
|
|
55
|
+
expect(written).toContain("teamlead:");
|
|
56
|
+
expect(written).toContain("model: main");
|
|
57
|
+
expect(written).toContain("provider: main-native");
|
|
58
|
+
});
|
|
59
|
+
it("serializes foreign-provider subagent with model_id + effort", () => {
|
|
60
|
+
const configPath = makeConfigPath();
|
|
61
|
+
const review = {
|
|
62
|
+
teamlead: { model: "main" },
|
|
63
|
+
subagent: { provider: "codex", model_id: "gpt-5.4", effort: "high" },
|
|
64
|
+
max_concurrent_lenses: 6,
|
|
65
|
+
lens_deliberation: "synthesizer-only",
|
|
66
|
+
};
|
|
67
|
+
const result = writeReviewBlock(configPath, review);
|
|
68
|
+
expect(result.ok).toBe(true);
|
|
69
|
+
const written = read(configPath);
|
|
70
|
+
expect(written).toContain("provider: codex");
|
|
71
|
+
expect(written).toContain("model_id: gpt-5.4");
|
|
72
|
+
expect(written).toContain("effort: high");
|
|
73
|
+
expect(written).toContain("max_concurrent_lenses: 6");
|
|
74
|
+
expect(written).toContain("lens_deliberation: synthesizer-only");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe("writeReviewBlock — existing file", () => {
|
|
78
|
+
it("preserves top-level fields + trailing content when adding review", () => {
|
|
79
|
+
const configPath = makeConfigPath();
|
|
80
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
81
|
+
const original = [
|
|
82
|
+
"# Project config — hand-written",
|
|
83
|
+
"output_language: en",
|
|
84
|
+
"",
|
|
85
|
+
"domains:",
|
|
86
|
+
" - software-engineering",
|
|
87
|
+
" - ontology",
|
|
88
|
+
"",
|
|
89
|
+
].join("\n");
|
|
90
|
+
fs.writeFileSync(configPath, original, "utf8");
|
|
91
|
+
const review = {
|
|
92
|
+
teamlead: { model: "main" },
|
|
93
|
+
subagent: { provider: "main-native" },
|
|
94
|
+
};
|
|
95
|
+
const result = writeReviewBlock(configPath, review);
|
|
96
|
+
expect(result.ok).toBe(true);
|
|
97
|
+
if (!result.ok)
|
|
98
|
+
return;
|
|
99
|
+
expect(result.created).toBe(false);
|
|
100
|
+
expect(result.replacedExistingBlock).toBe(false);
|
|
101
|
+
const written = read(configPath);
|
|
102
|
+
expect(written).toContain("output_language: en");
|
|
103
|
+
expect(written).toContain("software-engineering");
|
|
104
|
+
expect(written).toContain("ontology");
|
|
105
|
+
expect(written).toContain("review:");
|
|
106
|
+
expect(written).toContain("provider: main-native");
|
|
107
|
+
});
|
|
108
|
+
it("replaces (not merges) a pre-existing review block", () => {
|
|
109
|
+
const configPath = makeConfigPath();
|
|
110
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
111
|
+
const original = [
|
|
112
|
+
"output_language: en",
|
|
113
|
+
"review:",
|
|
114
|
+
" teamlead:",
|
|
115
|
+
" model: main",
|
|
116
|
+
" subagent:",
|
|
117
|
+
" provider: codex",
|
|
118
|
+
" model_id: gpt-5.4",
|
|
119
|
+
" effort: high",
|
|
120
|
+
" max_concurrent_lenses: 6",
|
|
121
|
+
"",
|
|
122
|
+
].join("\n");
|
|
123
|
+
fs.writeFileSync(configPath, original, "utf8");
|
|
124
|
+
// New config chooses main-native — previous codex fields must not leak.
|
|
125
|
+
const review = {
|
|
126
|
+
teamlead: { model: "main" },
|
|
127
|
+
subagent: { provider: "main-native" },
|
|
128
|
+
};
|
|
129
|
+
const result = writeReviewBlock(configPath, review);
|
|
130
|
+
expect(result.ok).toBe(true);
|
|
131
|
+
if (!result.ok)
|
|
132
|
+
return;
|
|
133
|
+
expect(result.replacedExistingBlock).toBe(true);
|
|
134
|
+
const written = read(configPath);
|
|
135
|
+
expect(written).toContain("provider: main-native");
|
|
136
|
+
expect(written).not.toContain("gpt-5.4");
|
|
137
|
+
expect(written).not.toContain("effort: high");
|
|
138
|
+
expect(written).not.toMatch(/max_concurrent_lenses:\s*6/);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("writeReviewBlock — legacy stripping", () => {
|
|
142
|
+
it("strips execution_topology_priority when stripLegacyPriority=true", () => {
|
|
143
|
+
const configPath = makeConfigPath();
|
|
144
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
145
|
+
const original = [
|
|
146
|
+
"output_language: en",
|
|
147
|
+
"execution_topology_priority:",
|
|
148
|
+
" - cc-teams-codex-subprocess",
|
|
149
|
+
" - cc-main-agent-subagent",
|
|
150
|
+
"",
|
|
151
|
+
].join("\n");
|
|
152
|
+
fs.writeFileSync(configPath, original, "utf8");
|
|
153
|
+
const review = {
|
|
154
|
+
teamlead: { model: "main" },
|
|
155
|
+
subagent: { provider: "codex", model_id: "gpt-5.4", effort: "high" },
|
|
156
|
+
};
|
|
157
|
+
const result = writeReviewBlock(configPath, review, {
|
|
158
|
+
stripLegacyPriority: true,
|
|
159
|
+
});
|
|
160
|
+
expect(result.ok).toBe(true);
|
|
161
|
+
if (!result.ok)
|
|
162
|
+
return;
|
|
163
|
+
expect(result.strippedLegacyPriority).toBe(true);
|
|
164
|
+
const written = read(configPath);
|
|
165
|
+
expect(written).not.toContain("execution_topology_priority");
|
|
166
|
+
expect(written).not.toContain("cc-teams-codex-subprocess");
|
|
167
|
+
expect(written).toContain("review:");
|
|
168
|
+
expect(written).toContain("provider: codex");
|
|
169
|
+
});
|
|
170
|
+
it("leaves legacy field alone when stripLegacyPriority is false/absent", () => {
|
|
171
|
+
const configPath = makeConfigPath();
|
|
172
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
173
|
+
const original = [
|
|
174
|
+
"output_language: en",
|
|
175
|
+
"execution_topology_priority:",
|
|
176
|
+
" - cc-main-agent-subagent",
|
|
177
|
+
"",
|
|
178
|
+
].join("\n");
|
|
179
|
+
fs.writeFileSync(configPath, original, "utf8");
|
|
180
|
+
const review = {
|
|
181
|
+
teamlead: { model: "main" },
|
|
182
|
+
subagent: { provider: "main-native" },
|
|
183
|
+
};
|
|
184
|
+
const result = writeReviewBlock(configPath, review);
|
|
185
|
+
expect(result.ok).toBe(true);
|
|
186
|
+
if (!result.ok)
|
|
187
|
+
return;
|
|
188
|
+
expect(result.strippedLegacyPriority).toBe(false);
|
|
189
|
+
const written = read(configPath);
|
|
190
|
+
expect(written).toContain("execution_topology_priority");
|
|
191
|
+
expect(written).toContain("cc-main-agent-subagent");
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe("writeReviewBlock — validation failure", () => {
|
|
195
|
+
it("returns errors without writing when config is invalid", () => {
|
|
196
|
+
const configPath = makeConfigPath();
|
|
197
|
+
// provider=codex is a foreign provider, so model_id is required.
|
|
198
|
+
// The validator catches this; writeReviewBlock must propagate.
|
|
199
|
+
const invalid = {
|
|
200
|
+
subagent: { provider: "codex" },
|
|
201
|
+
};
|
|
202
|
+
const result = writeReviewBlock(configPath, invalid);
|
|
203
|
+
expect(result.ok).toBe(false);
|
|
204
|
+
if (result.ok)
|
|
205
|
+
return;
|
|
206
|
+
expect(result.errors.length).toBeGreaterThan(0);
|
|
207
|
+
expect(result.errors.some((e) => e.path.includes("subagent"))).toBe(true);
|
|
208
|
+
expect(fs.existsSync(configPath)).toBe(false);
|
|
209
|
+
});
|
|
210
|
+
it("rejects mismatched deliberation + teamlead combination", () => {
|
|
211
|
+
const configPath = makeConfigPath();
|
|
212
|
+
const invalid = {
|
|
213
|
+
teamlead: {
|
|
214
|
+
model: { provider: "codex", model_id: "gpt-5.4" },
|
|
215
|
+
},
|
|
216
|
+
lens_deliberation: "sendmessage-a2a",
|
|
217
|
+
};
|
|
218
|
+
const result = writeReviewBlock(configPath, invalid);
|
|
219
|
+
expect(result.ok).toBe(false);
|
|
220
|
+
if (result.ok)
|
|
221
|
+
return;
|
|
222
|
+
expect(result.errors.some((e) => e.path === "review.lens_deliberation")).toBe(true);
|
|
223
|
+
expect(fs.existsSync(configPath)).toBe(false);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe("writeReviewBlock — pruneUndefined behaviour", () => {
|
|
227
|
+
it("does not emit null keys for undefined axes", () => {
|
|
228
|
+
const configPath = makeConfigPath();
|
|
229
|
+
const review = {
|
|
230
|
+
teamlead: { model: "main" },
|
|
231
|
+
// subagent, max_concurrent_lenses, lens_deliberation intentionally absent
|
|
232
|
+
};
|
|
233
|
+
const result = writeReviewBlock(configPath, review);
|
|
234
|
+
expect(result.ok).toBe(true);
|
|
235
|
+
const written = read(configPath);
|
|
236
|
+
expect(written).not.toContain("subagent: null");
|
|
237
|
+
expect(written).not.toContain("max_concurrent_lenses: null");
|
|
238
|
+
expect(written).not.toContain("lens_deliberation: null");
|
|
239
|
+
});
|
|
240
|
+
});
|