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,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for `onto install` — the interactive + non-interactive
|
|
3
|
+
* first-run setup command.
|
|
4
|
+
*
|
|
5
|
+
* Design reference: spec v3 laid out in the install command design
|
|
6
|
+
* discussion (2026-04-21 session). Key decisions codified here:
|
|
7
|
+
*
|
|
8
|
+
* 1. Two provider channels: review (for 9-lens execution) and learn
|
|
9
|
+
* (for background tasks — learn/govern/promote). They may share
|
|
10
|
+
* a provider or be configured separately.
|
|
11
|
+
*
|
|
12
|
+
* 2. `main-native` is a valid ReviewProvider but NOT a valid
|
|
13
|
+
* LearnProvider. The background ladder in llm-caller.ts does not
|
|
14
|
+
* support host main-model delegation (fail-fast on missing
|
|
15
|
+
* credentials). The type-level exclusion prevents accidentally
|
|
16
|
+
* writing a learn config that would always fail at runtime.
|
|
17
|
+
*
|
|
18
|
+
* 3. API keys are never captured into typed decision shape — they
|
|
19
|
+
* flow via environment (env var or `.env` file) only. This keeps
|
|
20
|
+
* secrets out of logs, serialized state, and command history.
|
|
21
|
+
*
|
|
22
|
+
* 4. Profile scope is atomic (per config-profile.ts adoption rule) —
|
|
23
|
+
* either global owns the full profile set or project does. The
|
|
24
|
+
* scope choice is what determines where every file writes.
|
|
25
|
+
*/
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live provider validation for `onto install`.
|
|
3
|
+
*
|
|
4
|
+
* Given a freshly resolved `{ decisions, secrets, detection }`, this
|
|
5
|
+
* module sends a minimal reachability probe to each non-main-native
|
|
6
|
+
* provider the user selected. A failed probe produces a clear
|
|
7
|
+
* `ValidationCheck` result that the orchestrator surfaces alongside
|
|
8
|
+
* instructions (re-run with `--skip-validation` or fix the credential).
|
|
9
|
+
*
|
|
10
|
+
* # What "ping" means per provider
|
|
11
|
+
*
|
|
12
|
+
* - anthropic GET https://api.anthropic.com/v1/models with the
|
|
13
|
+
* key — models list is free and confirms the key.
|
|
14
|
+
* - openai GET https://api.openai.com/v1/models with the key
|
|
15
|
+
* — same rationale, zero token cost.
|
|
16
|
+
* - litellm GET {base_url}/models (OpenAI-compatible). The
|
|
17
|
+
* `/models` suffix is the OpenAI-compat standard;
|
|
18
|
+
* LiteLLM proxy and every listed local runtime
|
|
19
|
+
* (Ollama, LM Studio, vLLM, MLX) respond to it.
|
|
20
|
+
* - codex Local check only — binary present + auth.json
|
|
21
|
+
* present. No network call; the codex CLI handles
|
|
22
|
+
* its own OAuth dance.
|
|
23
|
+
* - main-native Skipped — there's nothing to probe; the runtime
|
|
24
|
+
* is the host session itself.
|
|
25
|
+
*
|
|
26
|
+
* # Why fetch directly instead of SDK
|
|
27
|
+
*
|
|
28
|
+
* The `@anthropic-ai/sdk` and `openai` SDKs carry non-trivial startup
|
|
29
|
+
* cost and change their response shapes between majors. A raw HTTP
|
|
30
|
+
* GET is dependency-free, gives a crisp HTTP status code (401 vs 200
|
|
31
|
+
* vs 5xx), and doesn't couple install's validation surface to SDK
|
|
32
|
+
* version drift. LiteLLM is already OpenAI-compatible HTTP, so the
|
|
33
|
+
* same pattern works there.
|
|
34
|
+
*
|
|
35
|
+
* # Testability
|
|
36
|
+
*
|
|
37
|
+
* All network and filesystem access flows through a `PingDependencies`
|
|
38
|
+
* struct. Tests inject a stub `fetch` that returns the desired
|
|
39
|
+
* `Response` shape, and stub codex-presence booleans directly.
|
|
40
|
+
*/
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Shape guard
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
/**
|
|
45
|
+
* Runtime sanity check on the `InstallDecisions` shape.
|
|
46
|
+
*
|
|
47
|
+
* TypeScript already enforces most of this at compile time. The one
|
|
48
|
+
* thing that still benefits from a runtime check is the
|
|
49
|
+
* learn-provider exclusion (it's excluded at the type level via the
|
|
50
|
+
* `LearnProvider` union but a consumer could still construct
|
|
51
|
+
* decisions outside the normal flow).
|
|
52
|
+
*/
|
|
53
|
+
export function checkDecisionShape(decisions) {
|
|
54
|
+
const checks = [];
|
|
55
|
+
if (decisions.learnProvider === "main-native") {
|
|
56
|
+
checks.push({
|
|
57
|
+
name: "decisions",
|
|
58
|
+
passed: false,
|
|
59
|
+
message: "learn provider는 main-native를 지원하지 않습니다. " +
|
|
60
|
+
"background ladder(llm-caller.ts)에서 main-native는 ladder의 일부가 아닙니다.",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return checks;
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Fetch helpers
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
async function fetchWithTimeout(fetchFn, url, init, timeoutMs) {
|
|
69
|
+
const controller = new AbortController();
|
|
70
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
71
|
+
try {
|
|
72
|
+
return await fetchFn(url, { ...init, signal: controller.signal });
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function resolveFetch(deps) {
|
|
79
|
+
return deps.fetch ?? globalThis.fetch;
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Per-provider pings
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
export async function pingAnthropic(apiKey, deps = {}) {
|
|
85
|
+
const fetchFn = resolveFetch(deps);
|
|
86
|
+
const timeoutMs = deps.timeoutMs ?? 5000;
|
|
87
|
+
try {
|
|
88
|
+
const res = await fetchWithTimeout(fetchFn, "https://api.anthropic.com/v1/models", {
|
|
89
|
+
method: "GET",
|
|
90
|
+
headers: {
|
|
91
|
+
"x-api-key": apiKey,
|
|
92
|
+
"anthropic-version": "2023-06-01",
|
|
93
|
+
},
|
|
94
|
+
}, timeoutMs);
|
|
95
|
+
if (res.status >= 200 && res.status < 300) {
|
|
96
|
+
return { name: "anthropic", passed: true };
|
|
97
|
+
}
|
|
98
|
+
if (res.status === 401 || res.status === 403) {
|
|
99
|
+
return {
|
|
100
|
+
name: "anthropic",
|
|
101
|
+
passed: false,
|
|
102
|
+
message: "인증 실패 (API key 거부). 키 값을 확인하세요.",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
name: "anthropic",
|
|
107
|
+
passed: false,
|
|
108
|
+
message: `api.anthropic.com 응답 HTTP ${res.status}`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
return {
|
|
113
|
+
name: "anthropic",
|
|
114
|
+
passed: false,
|
|
115
|
+
message: `네트워크 오류: ${err instanceof Error ? err.message : String(err)}`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export async function pingOpenai(apiKey, deps = {}) {
|
|
120
|
+
const fetchFn = resolveFetch(deps);
|
|
121
|
+
const timeoutMs = deps.timeoutMs ?? 5000;
|
|
122
|
+
try {
|
|
123
|
+
const res = await fetchWithTimeout(fetchFn, "https://api.openai.com/v1/models", {
|
|
124
|
+
method: "GET",
|
|
125
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
126
|
+
}, timeoutMs);
|
|
127
|
+
if (res.status >= 200 && res.status < 300) {
|
|
128
|
+
return { name: "openai", passed: true };
|
|
129
|
+
}
|
|
130
|
+
if (res.status === 401 || res.status === 403) {
|
|
131
|
+
return {
|
|
132
|
+
name: "openai",
|
|
133
|
+
passed: false,
|
|
134
|
+
message: "인증 실패 (API key 거부). 키 값을 확인하세요.",
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
name: "openai",
|
|
139
|
+
passed: false,
|
|
140
|
+
message: `api.openai.com 응답 HTTP ${res.status}`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
return {
|
|
145
|
+
name: "openai",
|
|
146
|
+
passed: false,
|
|
147
|
+
message: `네트워크 오류: ${err instanceof Error ? err.message : String(err)}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export async function pingLitellm(baseUrl, apiKey, deps = {}) {
|
|
152
|
+
const fetchFn = resolveFetch(deps);
|
|
153
|
+
const timeoutMs = deps.timeoutMs ?? 5000;
|
|
154
|
+
const url = baseUrl.replace(/\/+$/, "") + "/models";
|
|
155
|
+
try {
|
|
156
|
+
const headers = {};
|
|
157
|
+
if (apiKey)
|
|
158
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
159
|
+
const res = await fetchWithTimeout(fetchFn, url, { method: "GET", headers }, timeoutMs);
|
|
160
|
+
if (res.status >= 200 && res.status < 300) {
|
|
161
|
+
return { name: "litellm", passed: true };
|
|
162
|
+
}
|
|
163
|
+
if (res.status === 401 || res.status === 403) {
|
|
164
|
+
return {
|
|
165
|
+
name: "litellm",
|
|
166
|
+
passed: false,
|
|
167
|
+
message: "인증 실패. 엔드포인트가 key를 요구합니다 — LITELLM_API_KEY를 설정하세요.",
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
name: "litellm",
|
|
172
|
+
passed: false,
|
|
173
|
+
message: `${url} 응답 HTTP ${res.status}`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
return {
|
|
178
|
+
name: "litellm",
|
|
179
|
+
passed: false,
|
|
180
|
+
message: `연결 실패 (${url}): ${err instanceof Error ? err.message : String(err)}`,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export function verifyCodex(detection, deps = {}) {
|
|
185
|
+
const binaryPresent = deps.codexBinaryPresent
|
|
186
|
+
? deps.codexBinaryPresent()
|
|
187
|
+
: detection.hasCodexBinary;
|
|
188
|
+
const authPresent = deps.codexAuthPresent
|
|
189
|
+
? deps.codexAuthPresent()
|
|
190
|
+
: detection.hasCodexAuth;
|
|
191
|
+
if (!binaryPresent) {
|
|
192
|
+
return {
|
|
193
|
+
name: "codex",
|
|
194
|
+
passed: false,
|
|
195
|
+
message: "codex binary가 PATH에 없습니다.",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (!authPresent) {
|
|
199
|
+
return {
|
|
200
|
+
name: "codex",
|
|
201
|
+
passed: false,
|
|
202
|
+
message: "~/.codex/auth.json 없음. `codex login` 실행 필요.",
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return { name: "codex", passed: true };
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Validate the full install outcome.
|
|
209
|
+
*
|
|
210
|
+
* Dedupes the review + learn providers (when same, only pings once),
|
|
211
|
+
* reads credentials from `secrets` with `process.env` as the fallback
|
|
212
|
+
* (so a user who set ANTHROPIC_API_KEY in the shell gets validated
|
|
213
|
+
* without install having to re-capture the key).
|
|
214
|
+
*
|
|
215
|
+
* Never throws — all errors surface as failed `ValidationCheck`
|
|
216
|
+
* entries so the orchestrator can render a complete summary.
|
|
217
|
+
*/
|
|
218
|
+
export async function validateInstall(args) {
|
|
219
|
+
const { decisions, secrets, detection, deps = {} } = args;
|
|
220
|
+
const checks = [];
|
|
221
|
+
checks.push(...checkDecisionShape(decisions));
|
|
222
|
+
const providers = new Set();
|
|
223
|
+
providers.add(decisions.reviewProvider);
|
|
224
|
+
providers.add(decisions.learnProvider);
|
|
225
|
+
for (const provider of providers) {
|
|
226
|
+
switch (provider) {
|
|
227
|
+
case "main-native":
|
|
228
|
+
// Nothing to probe — host session is the runtime.
|
|
229
|
+
break;
|
|
230
|
+
case "anthropic": {
|
|
231
|
+
const apiKey = secrets.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
232
|
+
if (!apiKey) {
|
|
233
|
+
checks.push({
|
|
234
|
+
name: "anthropic",
|
|
235
|
+
passed: false,
|
|
236
|
+
message: "ANTHROPIC_API_KEY를 찾을 수 없습니다.",
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
checks.push(await pingAnthropic(apiKey, deps));
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
case "openai": {
|
|
245
|
+
const apiKey = secrets.openaiApiKey ?? process.env.OPENAI_API_KEY;
|
|
246
|
+
if (!apiKey) {
|
|
247
|
+
checks.push({
|
|
248
|
+
name: "openai",
|
|
249
|
+
passed: false,
|
|
250
|
+
message: "OPENAI_API_KEY를 찾을 수 없습니다.",
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
checks.push(await pingOpenai(apiKey, deps));
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
case "litellm": {
|
|
259
|
+
const baseUrl = secrets.litellmBaseUrl ?? process.env.LITELLM_BASE_URL;
|
|
260
|
+
const apiKey = secrets.litellmApiKey ?? process.env.LITELLM_API_KEY;
|
|
261
|
+
if (!baseUrl) {
|
|
262
|
+
checks.push({
|
|
263
|
+
name: "litellm",
|
|
264
|
+
passed: false,
|
|
265
|
+
message: "LITELLM_BASE_URL을 찾을 수 없습니다.",
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
checks.push(await pingLitellm(baseUrl, apiKey, deps));
|
|
270
|
+
}
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case "codex":
|
|
274
|
+
checks.push(verifyCodex(detection, deps));
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
ok: checks.every((c) => c.passed),
|
|
280
|
+
checks,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Pretty-print a validation result as text. One line per check,
|
|
285
|
+
* `✓` / `✗` prefix, and indented error message on the same line.
|
|
286
|
+
*/
|
|
287
|
+
export function formatValidationResult(result) {
|
|
288
|
+
const lines = [];
|
|
289
|
+
for (const check of result.checks) {
|
|
290
|
+
const mark = check.passed ? "✓" : "✗";
|
|
291
|
+
const suffix = check.message ? ` — ${check.message}` : "";
|
|
292
|
+
lines.push(` ${mark} ${check.name}${suffix}`);
|
|
293
|
+
}
|
|
294
|
+
return lines.join("\n");
|
|
295
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { formatValidationResult, pingAnthropic, pingLitellm, pingOpenai, validateInstall, verifyCodex, } from "./validation.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Helpers
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
const BLANK_DETECTION = {
|
|
7
|
+
existingGlobalConfig: false,
|
|
8
|
+
existingProjectConfig: false,
|
|
9
|
+
hasAnthropicKey: false,
|
|
10
|
+
hasOpenAiKey: false,
|
|
11
|
+
hasLitellmBaseUrl: false,
|
|
12
|
+
hasCodexBinary: false,
|
|
13
|
+
hasCodexAuth: false,
|
|
14
|
+
hostIsClaudeCode: false,
|
|
15
|
+
};
|
|
16
|
+
/** Build a stub fetch that returns a fixed Response for every call. */
|
|
17
|
+
function stubFetchReturning(status, body = {}) {
|
|
18
|
+
return (async () => new Response(JSON.stringify(body), {
|
|
19
|
+
status,
|
|
20
|
+
headers: { "content-type": "application/json" },
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
/** Build a stub fetch that throws — network error scenario. */
|
|
24
|
+
function stubFetchThrowing(message) {
|
|
25
|
+
return (async () => {
|
|
26
|
+
throw new Error(message);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Capture the URL + headers of the first request. */
|
|
30
|
+
function spyFetch() {
|
|
31
|
+
const calls = [];
|
|
32
|
+
const fetchFn = async (url, init) => {
|
|
33
|
+
const headers = {};
|
|
34
|
+
const raw = init?.headers;
|
|
35
|
+
if (raw && !Array.isArray(raw) && !(raw instanceof Headers)) {
|
|
36
|
+
Object.assign(headers, raw);
|
|
37
|
+
}
|
|
38
|
+
calls.push({ url: String(url), headers });
|
|
39
|
+
return new Response("{}", { status: 200 });
|
|
40
|
+
};
|
|
41
|
+
return { fetch: fetchFn, calls };
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// pingAnthropic
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
describe("pingAnthropic", () => {
|
|
47
|
+
it("returns passed=true on 200", async () => {
|
|
48
|
+
const check = await pingAnthropic("sk-ant-test", {
|
|
49
|
+
fetch: stubFetchReturning(200),
|
|
50
|
+
});
|
|
51
|
+
expect(check).toEqual({ name: "anthropic", passed: true });
|
|
52
|
+
});
|
|
53
|
+
it("reports auth failure on 401", async () => {
|
|
54
|
+
const check = await pingAnthropic("sk-ant-bad", {
|
|
55
|
+
fetch: stubFetchReturning(401),
|
|
56
|
+
});
|
|
57
|
+
expect(check.passed).toBe(false);
|
|
58
|
+
expect(check.message).toContain("인증 실패");
|
|
59
|
+
});
|
|
60
|
+
it("reports generic HTTP failure on 5xx", async () => {
|
|
61
|
+
const check = await pingAnthropic("sk-ant-test", {
|
|
62
|
+
fetch: stubFetchReturning(500),
|
|
63
|
+
});
|
|
64
|
+
expect(check.passed).toBe(false);
|
|
65
|
+
expect(check.message).toContain("500");
|
|
66
|
+
});
|
|
67
|
+
it("reports network error on fetch throw", async () => {
|
|
68
|
+
const check = await pingAnthropic("sk-ant-test", {
|
|
69
|
+
fetch: stubFetchThrowing("ECONNREFUSED"),
|
|
70
|
+
});
|
|
71
|
+
expect(check.passed).toBe(false);
|
|
72
|
+
expect(check.message).toContain("네트워크");
|
|
73
|
+
expect(check.message).toContain("ECONNREFUSED");
|
|
74
|
+
});
|
|
75
|
+
it("sends x-api-key header and anthropic-version", async () => {
|
|
76
|
+
const spy = spyFetch();
|
|
77
|
+
await pingAnthropic("sk-ant-xyz", { fetch: spy.fetch });
|
|
78
|
+
expect(spy.calls[0]?.url).toBe("https://api.anthropic.com/v1/models");
|
|
79
|
+
expect(spy.calls[0]?.headers["x-api-key"]).toBe("sk-ant-xyz");
|
|
80
|
+
expect(spy.calls[0]?.headers["anthropic-version"]).toBeTruthy();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// pingOpenai
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
describe("pingOpenai", () => {
|
|
87
|
+
it("returns passed=true on 200", async () => {
|
|
88
|
+
const check = await pingOpenai("sk-test", {
|
|
89
|
+
fetch: stubFetchReturning(200),
|
|
90
|
+
});
|
|
91
|
+
expect(check.passed).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
it("sends Authorization: Bearer header", async () => {
|
|
94
|
+
const spy = spyFetch();
|
|
95
|
+
await pingOpenai("sk-test", { fetch: spy.fetch });
|
|
96
|
+
expect(spy.calls[0]?.url).toBe("https://api.openai.com/v1/models");
|
|
97
|
+
expect(spy.calls[0]?.headers.Authorization).toBe("Bearer sk-test");
|
|
98
|
+
});
|
|
99
|
+
it("reports 401 as auth failure", async () => {
|
|
100
|
+
const check = await pingOpenai("bad", {
|
|
101
|
+
fetch: stubFetchReturning(401),
|
|
102
|
+
});
|
|
103
|
+
expect(check.passed).toBe(false);
|
|
104
|
+
expect(check.message).toContain("인증 실패");
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// pingLitellm
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
describe("pingLitellm", () => {
|
|
111
|
+
it("appends /models to the base URL", async () => {
|
|
112
|
+
const spy = spyFetch();
|
|
113
|
+
await pingLitellm("http://localhost:4000/v1", undefined, {
|
|
114
|
+
fetch: spy.fetch,
|
|
115
|
+
});
|
|
116
|
+
expect(spy.calls[0]?.url).toBe("http://localhost:4000/v1/models");
|
|
117
|
+
});
|
|
118
|
+
it("strips trailing slashes before appending /models", async () => {
|
|
119
|
+
const spy = spyFetch();
|
|
120
|
+
await pingLitellm("http://localhost:4000/v1/", undefined, {
|
|
121
|
+
fetch: spy.fetch,
|
|
122
|
+
});
|
|
123
|
+
expect(spy.calls[0]?.url).toBe("http://localhost:4000/v1/models");
|
|
124
|
+
});
|
|
125
|
+
it("omits Authorization when no apiKey given", async () => {
|
|
126
|
+
const spy = spyFetch();
|
|
127
|
+
await pingLitellm("http://localhost:11434/v1", undefined, {
|
|
128
|
+
fetch: spy.fetch,
|
|
129
|
+
});
|
|
130
|
+
expect(spy.calls[0]?.headers.Authorization).toBeUndefined();
|
|
131
|
+
});
|
|
132
|
+
it("sends Bearer token when apiKey provided", async () => {
|
|
133
|
+
const spy = spyFetch();
|
|
134
|
+
await pingLitellm("https://litellm.example.com/v1", "sk-proxy", {
|
|
135
|
+
fetch: spy.fetch,
|
|
136
|
+
});
|
|
137
|
+
expect(spy.calls[0]?.headers.Authorization).toBe("Bearer sk-proxy");
|
|
138
|
+
});
|
|
139
|
+
it("reports 401 with guidance to set LITELLM_API_KEY", async () => {
|
|
140
|
+
const check = await pingLitellm("http://localhost:4000/v1", undefined, {
|
|
141
|
+
fetch: stubFetchReturning(401),
|
|
142
|
+
});
|
|
143
|
+
expect(check.passed).toBe(false);
|
|
144
|
+
expect(check.message).toContain("LITELLM_API_KEY");
|
|
145
|
+
});
|
|
146
|
+
it("reports network failure on ECONNREFUSED", async () => {
|
|
147
|
+
const check = await pingLitellm("http://localhost:4000/v1", undefined, {
|
|
148
|
+
fetch: stubFetchThrowing("fetch failed"),
|
|
149
|
+
});
|
|
150
|
+
expect(check.passed).toBe(false);
|
|
151
|
+
expect(check.message).toContain("연결 실패");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// verifyCodex (filesystem-level, no network)
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
describe("verifyCodex", () => {
|
|
158
|
+
it("passes when both binary and auth present in detection", () => {
|
|
159
|
+
const check = verifyCodex({
|
|
160
|
+
...BLANK_DETECTION,
|
|
161
|
+
hasCodexBinary: true,
|
|
162
|
+
hasCodexAuth: true,
|
|
163
|
+
});
|
|
164
|
+
expect(check).toEqual({ name: "codex", passed: true });
|
|
165
|
+
});
|
|
166
|
+
it("fails with binary missing message", () => {
|
|
167
|
+
const check = verifyCodex(BLANK_DETECTION);
|
|
168
|
+
expect(check.passed).toBe(false);
|
|
169
|
+
expect(check.message).toContain("binary");
|
|
170
|
+
});
|
|
171
|
+
it("fails with auth missing message when binary present", () => {
|
|
172
|
+
const check = verifyCodex({ ...BLANK_DETECTION, hasCodexBinary: true });
|
|
173
|
+
expect(check.passed).toBe(false);
|
|
174
|
+
expect(check.message).toContain("codex login");
|
|
175
|
+
});
|
|
176
|
+
it("dependency overrides win over detection values", () => {
|
|
177
|
+
const check = verifyCodex(BLANK_DETECTION, {
|
|
178
|
+
codexBinaryPresent: () => true,
|
|
179
|
+
codexAuthPresent: () => true,
|
|
180
|
+
});
|
|
181
|
+
expect(check.passed).toBe(true);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
// validateInstall orchestrator
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
const ANTHROPIC_DECISIONS = {
|
|
188
|
+
profileScope: "project",
|
|
189
|
+
reviewProvider: "anthropic",
|
|
190
|
+
learnProvider: "anthropic",
|
|
191
|
+
outputLanguage: "ko",
|
|
192
|
+
};
|
|
193
|
+
describe("validateInstall", () => {
|
|
194
|
+
it("skips network probe for main-native review + anthropic learn", async () => {
|
|
195
|
+
const spy = spyFetch();
|
|
196
|
+
const result = await validateInstall({
|
|
197
|
+
decisions: {
|
|
198
|
+
...ANTHROPIC_DECISIONS,
|
|
199
|
+
reviewProvider: "main-native",
|
|
200
|
+
},
|
|
201
|
+
secrets: { anthropicApiKey: "sk-ant-test" },
|
|
202
|
+
detection: BLANK_DETECTION,
|
|
203
|
+
deps: { fetch: spy.fetch },
|
|
204
|
+
});
|
|
205
|
+
// Only anthropic is probed — main-native contributes no network call.
|
|
206
|
+
expect(spy.calls.length).toBe(1);
|
|
207
|
+
expect(spy.calls[0]?.url).toContain("api.anthropic.com");
|
|
208
|
+
expect(result.ok).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
it("dedupes when review and learn providers match", async () => {
|
|
211
|
+
const spy = spyFetch();
|
|
212
|
+
await validateInstall({
|
|
213
|
+
decisions: ANTHROPIC_DECISIONS,
|
|
214
|
+
secrets: { anthropicApiKey: "sk-ant-test" },
|
|
215
|
+
detection: BLANK_DETECTION,
|
|
216
|
+
deps: { fetch: spy.fetch },
|
|
217
|
+
});
|
|
218
|
+
expect(spy.calls.length).toBe(1);
|
|
219
|
+
});
|
|
220
|
+
it("probes both providers when they differ", async () => {
|
|
221
|
+
const spy = spyFetch();
|
|
222
|
+
await validateInstall({
|
|
223
|
+
decisions: {
|
|
224
|
+
...ANTHROPIC_DECISIONS,
|
|
225
|
+
reviewProvider: "anthropic",
|
|
226
|
+
learnProvider: "openai",
|
|
227
|
+
},
|
|
228
|
+
secrets: { anthropicApiKey: "sk-ant", openaiApiKey: "sk-oai" },
|
|
229
|
+
detection: BLANK_DETECTION,
|
|
230
|
+
deps: { fetch: spy.fetch },
|
|
231
|
+
});
|
|
232
|
+
const urls = spy.calls.map((c) => c.url);
|
|
233
|
+
expect(urls.some((u) => u.includes("api.anthropic.com"))).toBe(true);
|
|
234
|
+
expect(urls.some((u) => u.includes("api.openai.com"))).toBe(true);
|
|
235
|
+
});
|
|
236
|
+
it("fails when credential is missing entirely", async () => {
|
|
237
|
+
const result = await validateInstall({
|
|
238
|
+
decisions: ANTHROPIC_DECISIONS,
|
|
239
|
+
secrets: {},
|
|
240
|
+
detection: BLANK_DETECTION,
|
|
241
|
+
deps: { fetch: stubFetchReturning(200) },
|
|
242
|
+
});
|
|
243
|
+
expect(result.ok).toBe(false);
|
|
244
|
+
expect(result.checks.some((c) => c.message?.includes("ANTHROPIC_API_KEY"))).toBe(true);
|
|
245
|
+
});
|
|
246
|
+
it("falls back to process.env when secrets are empty", async () => {
|
|
247
|
+
const prev = process.env.ANTHROPIC_API_KEY;
|
|
248
|
+
process.env.ANTHROPIC_API_KEY = "from-env";
|
|
249
|
+
try {
|
|
250
|
+
const spy = spyFetch();
|
|
251
|
+
const result = await validateInstall({
|
|
252
|
+
decisions: ANTHROPIC_DECISIONS,
|
|
253
|
+
secrets: {},
|
|
254
|
+
detection: BLANK_DETECTION,
|
|
255
|
+
deps: { fetch: spy.fetch },
|
|
256
|
+
});
|
|
257
|
+
expect(result.ok).toBe(true);
|
|
258
|
+
expect(spy.calls[0]?.headers["x-api-key"]).toBe("from-env");
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
if (prev === undefined)
|
|
262
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
263
|
+
else
|
|
264
|
+
process.env.ANTHROPIC_API_KEY = prev;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
it("surfaces codex check in mixed-provider setup", async () => {
|
|
268
|
+
const result = await validateInstall({
|
|
269
|
+
decisions: {
|
|
270
|
+
...ANTHROPIC_DECISIONS,
|
|
271
|
+
reviewProvider: "codex",
|
|
272
|
+
learnProvider: "anthropic",
|
|
273
|
+
},
|
|
274
|
+
secrets: { anthropicApiKey: "sk-ant" },
|
|
275
|
+
detection: BLANK_DETECTION,
|
|
276
|
+
deps: { fetch: stubFetchReturning(200) },
|
|
277
|
+
});
|
|
278
|
+
expect(result.checks.some((c) => c.name === "codex")).toBe(true);
|
|
279
|
+
expect(result.ok).toBe(false); // codex check fails on blank detection
|
|
280
|
+
});
|
|
281
|
+
it("catches learn-provider=main-native shape violation", async () => {
|
|
282
|
+
const result = await validateInstall({
|
|
283
|
+
decisions: {
|
|
284
|
+
...ANTHROPIC_DECISIONS,
|
|
285
|
+
reviewProvider: "main-native",
|
|
286
|
+
// @ts-expect-error — intentional runtime-only invalid shape
|
|
287
|
+
learnProvider: "main-native",
|
|
288
|
+
},
|
|
289
|
+
secrets: {},
|
|
290
|
+
detection: BLANK_DETECTION,
|
|
291
|
+
deps: { fetch: stubFetchReturning(200) },
|
|
292
|
+
});
|
|
293
|
+
expect(result.ok).toBe(false);
|
|
294
|
+
expect(result.checks.some((c) => c.message?.includes("main-native"))).toBe(true);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
// formatValidationResult
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
describe("formatValidationResult", () => {
|
|
301
|
+
it("marks passed checks with ✓ and failed with ✗", () => {
|
|
302
|
+
const text = formatValidationResult({
|
|
303
|
+
ok: false,
|
|
304
|
+
checks: [
|
|
305
|
+
{ name: "anthropic", passed: true },
|
|
306
|
+
{ name: "openai", passed: false, message: "oops" },
|
|
307
|
+
],
|
|
308
|
+
});
|
|
309
|
+
expect(text).toContain("✓ anthropic");
|
|
310
|
+
expect(text).toContain("✗ openai");
|
|
311
|
+
expect(text).toContain("oops");
|
|
312
|
+
});
|
|
313
|
+
});
|