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,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File writer for `onto install` — persists the resolved decisions to
|
|
3
|
+
* `config.yml`, `.env`, and `.env.example` atomically.
|
|
4
|
+
*
|
|
5
|
+
* # What this module is
|
|
6
|
+
*
|
|
7
|
+
* A pure function seat (where possible): the rendering helpers
|
|
8
|
+
* (`renderConfigYml`, `renderEnvExample`, `renderEnv`, `parseEnv`) are
|
|
9
|
+
* filesystem-free so they can be unit-tested without tmpdirs. Only
|
|
10
|
+
* `writeInstallFiles` touches disk, and even that delegates content
|
|
11
|
+
* generation to the renderers.
|
|
12
|
+
*
|
|
13
|
+
* # Why atomic writes
|
|
14
|
+
*
|
|
15
|
+
* Both `config.yml` and `.env` are read on every onto invocation — a
|
|
16
|
+
* partial write (e.g. disk full mid-write, process killed) would leave
|
|
17
|
+
* an invalid file that blocks all future commands. Writing to a temp
|
|
18
|
+
* file in the same directory and renaming (POSIX atomic on same
|
|
19
|
+
* filesystem) means a crashed install leaves the prior state intact.
|
|
20
|
+
*
|
|
21
|
+
* # Why merge `.env` instead of overwrite
|
|
22
|
+
*
|
|
23
|
+
* The user may have unrelated keys in `.env` (third-party tool
|
|
24
|
+
* credentials, local overrides). Install touches only the keys it
|
|
25
|
+
* captured this session — the merge step preserves everything else.
|
|
26
|
+
* `.env.example` is overwritten wholesale since it's a template
|
|
27
|
+
* derived purely from the current install decisions.
|
|
28
|
+
*
|
|
29
|
+
* # File modes
|
|
30
|
+
*
|
|
31
|
+
* `.env` is set to 0600 so other users on the machine can't read the
|
|
32
|
+
* secrets file. On Windows, Node's fs module accepts the mode flag but
|
|
33
|
+
* NTFS ACLs don't map cleanly — treat the mode as best-effort and rely
|
|
34
|
+
* on filesystem isolation on that platform.
|
|
35
|
+
*/
|
|
36
|
+
import fs from "node:fs";
|
|
37
|
+
import os from "node:os";
|
|
38
|
+
import path from "node:path";
|
|
39
|
+
import yaml from "yaml";
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Path resolution
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Resolve the four file targets for a given profile scope.
|
|
45
|
+
*
|
|
46
|
+
* Global scope uses `~/.onto/` (no gitignore touched — there's no repo
|
|
47
|
+
* at the user-home layer). Project scope uses `<projectRoot>/.onto/`
|
|
48
|
+
* and also needs the project's root `.gitignore` path so the write
|
|
49
|
+
* step can ensure `.onto/.env` is ignored.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveInstallPaths(scope, projectRoot, homeDir = os.homedir()) {
|
|
52
|
+
if (scope === "global") {
|
|
53
|
+
const ontoDir = path.join(homeDir, ".onto");
|
|
54
|
+
return {
|
|
55
|
+
ontoDir,
|
|
56
|
+
configYmlPath: path.join(ontoDir, "config.yml"),
|
|
57
|
+
envPath: path.join(ontoDir, ".env"),
|
|
58
|
+
envExamplePath: path.join(ontoDir, ".env.example"),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const ontoDir = path.join(projectRoot, ".onto");
|
|
62
|
+
return {
|
|
63
|
+
ontoDir,
|
|
64
|
+
configYmlPath: path.join(ontoDir, "config.yml"),
|
|
65
|
+
envPath: path.join(ontoDir, ".env"),
|
|
66
|
+
envExamplePath: path.join(ontoDir, ".env.example"),
|
|
67
|
+
gitignorePath: path.join(projectRoot, ".gitignore"),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// config.yml rendering
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
/**
|
|
74
|
+
* Produce the YAML text that install writes for the current decisions.
|
|
75
|
+
*
|
|
76
|
+
* Shape rationale:
|
|
77
|
+
*
|
|
78
|
+
* - `output_language` is always set (user-facing render boundary).
|
|
79
|
+
* - `review.subagent.provider` records the review channel choice.
|
|
80
|
+
* For `main-native` this is sufficient — no model_id / effort
|
|
81
|
+
* fields at install time.
|
|
82
|
+
* - `subagent_llm.provider` records the learn/background channel.
|
|
83
|
+
* - `external_http_provider` is ALSO set when learn provider is
|
|
84
|
+
* anthropic/openai/litellm — it's the ladder's user-override seat
|
|
85
|
+
* in `llm-caller.ts`, so explicitly matching the user's choice
|
|
86
|
+
* makes the intent sticky across future env drift.
|
|
87
|
+
* - `external_http_provider` is NOT set for codex learn — codex is
|
|
88
|
+
* not a valid value for that field (see config-chain.ts L37).
|
|
89
|
+
* - Model fields are omitted intentionally. `onto config edit` is
|
|
90
|
+
* the next step for users who want to pin a specific model; the
|
|
91
|
+
* install completion message points there.
|
|
92
|
+
*/
|
|
93
|
+
export function renderConfigYml(decisions) {
|
|
94
|
+
const config = {
|
|
95
|
+
output_language: decisions.outputLanguage,
|
|
96
|
+
review: {
|
|
97
|
+
subagent: { provider: decisions.reviewProvider },
|
|
98
|
+
},
|
|
99
|
+
subagent_llm: {
|
|
100
|
+
provider: decisions.learnProvider,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
if (decisions.learnProvider === "anthropic" ||
|
|
104
|
+
decisions.learnProvider === "openai" ||
|
|
105
|
+
decisions.learnProvider === "litellm") {
|
|
106
|
+
config.external_http_provider = decisions.learnProvider;
|
|
107
|
+
}
|
|
108
|
+
const header = [
|
|
109
|
+
"# Written by `onto install` — edit with `onto config edit` or",
|
|
110
|
+
"# re-run `onto install --reconfigure`. Full key reference:",
|
|
111
|
+
"# .onto/processes/configuration.md",
|
|
112
|
+
"",
|
|
113
|
+
].join("\n");
|
|
114
|
+
return header + yaml.stringify(config);
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// .env / .env.example rendering
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
/**
|
|
120
|
+
* Lightweight `.env` parser. Preserves KEY=VALUE lines, drops comments
|
|
121
|
+
* and blanks. NOT a full shell parser — no variable expansion, no
|
|
122
|
+
* quoting nuance. The write path likewise emits unquoted values.
|
|
123
|
+
*
|
|
124
|
+
* Keys are trimmed; values are taken verbatim after the first `=`
|
|
125
|
+
* (including leading/trailing whitespace, which `.env` consumers
|
|
126
|
+
* typically preserve).
|
|
127
|
+
*/
|
|
128
|
+
export function parseEnv(contents) {
|
|
129
|
+
const out = new Map();
|
|
130
|
+
for (const rawLine of contents.split(/\r?\n/)) {
|
|
131
|
+
const line = rawLine.trim();
|
|
132
|
+
if (!line || line.startsWith("#"))
|
|
133
|
+
continue;
|
|
134
|
+
const eq = line.indexOf("=");
|
|
135
|
+
if (eq === -1)
|
|
136
|
+
continue;
|
|
137
|
+
const key = line.slice(0, eq).trim();
|
|
138
|
+
const value = line.slice(eq + 1);
|
|
139
|
+
if (key)
|
|
140
|
+
out.set(key, value);
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Serialize a KEY=VALUE map deterministically (sorted by key).
|
|
146
|
+
*
|
|
147
|
+
* Deterministic order matters so a reconfigure that doesn't change any
|
|
148
|
+
* key produces an identical file — no spurious diffs, easy to grep.
|
|
149
|
+
*/
|
|
150
|
+
export function renderEnv(kv) {
|
|
151
|
+
const header = "# onto runtime credentials — managed by `onto install`.\n";
|
|
152
|
+
const lines = [header];
|
|
153
|
+
const sorted = [...kv.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
154
|
+
for (const [k, v] of sorted) {
|
|
155
|
+
lines.push(`${k}=${v}`);
|
|
156
|
+
}
|
|
157
|
+
return lines.join("\n") + "\n";
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Build the `.env.example` text for the current install decisions.
|
|
161
|
+
*
|
|
162
|
+
* Only includes sections for providers actually selected — no point
|
|
163
|
+
* in shipping an ANTHROPIC_API_KEY template to a user who picked
|
|
164
|
+
* codex + openai. The LiteLLM section includes the expanded guidance
|
|
165
|
+
* block (local runtime examples) because that field is the one new
|
|
166
|
+
* users most often fumble — "just the port" is a common mistake.
|
|
167
|
+
*/
|
|
168
|
+
export function renderEnvExample(decisions) {
|
|
169
|
+
const needsAnthropic = decisions.reviewProvider === "anthropic" ||
|
|
170
|
+
decisions.learnProvider === "anthropic";
|
|
171
|
+
const needsOpenai = decisions.reviewProvider === "openai" ||
|
|
172
|
+
decisions.learnProvider === "openai";
|
|
173
|
+
const needsLitellm = decisions.reviewProvider === "litellm" ||
|
|
174
|
+
decisions.learnProvider === "litellm";
|
|
175
|
+
const lines = [
|
|
176
|
+
"# ---------------------------------------------------------------------------",
|
|
177
|
+
"# onto runtime credentials",
|
|
178
|
+
"# Copy this file to .env and fill in values as needed.",
|
|
179
|
+
"# Tracked in git; .env is gitignored.",
|
|
180
|
+
"# ---------------------------------------------------------------------------",
|
|
181
|
+
"",
|
|
182
|
+
];
|
|
183
|
+
if (needsAnthropic) {
|
|
184
|
+
lines.push("# Anthropic API (per-token)", "# ANTHROPIC_API_KEY=sk-ant-...", "");
|
|
185
|
+
}
|
|
186
|
+
if (needsOpenai) {
|
|
187
|
+
lines.push("# OpenAI API (per-token)", "# OPENAI_API_KEY=sk-...", "");
|
|
188
|
+
}
|
|
189
|
+
if (needsLitellm) {
|
|
190
|
+
lines.push("# LiteLLM / OpenAI-compatible endpoint base URL", "#", "# Full URL required: scheme + host + port + /v1 path prefix.", "# Accepts any OpenAI-compatible endpoint — local runtime or remote proxy.", "#", "# Local examples:", "# LiteLLM proxy http://localhost:4000/v1", "# Ollama http://localhost:11434/v1", "# LM Studio http://localhost:1234/v1", "# vLLM http://localhost:8000/v1", "# MLX http://localhost:8080/v1", "#", "# Remote example:", "# https://litellm.example.com/v1", "#", "# LITELLM_BASE_URL=http://localhost:4000/v1", "", "# Optional — only when the endpoint enforces authentication.", "# Local endpoints without auth (Ollama 등) leave this blank.", "# LITELLM_API_KEY=sk-proxy-token", "");
|
|
191
|
+
}
|
|
192
|
+
return lines.join("\n");
|
|
193
|
+
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Atomic file write
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
function atomicWrite(target, content, mode) {
|
|
198
|
+
const dir = path.dirname(target);
|
|
199
|
+
const tmp = path.join(dir, `.${path.basename(target)}.tmp-${process.pid}-${Date.now()}`);
|
|
200
|
+
fs.writeFileSync(tmp, content, { encoding: "utf8", mode });
|
|
201
|
+
fs.renameSync(tmp, target);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Write (or dry-run) the three install output files.
|
|
205
|
+
*
|
|
206
|
+
* Order:
|
|
207
|
+
* 1. Ensure `.onto/` dir exists (idempotent).
|
|
208
|
+
* 2. Read existing `.env` to preserve unrelated keys.
|
|
209
|
+
* 3. Merge newly-captured secrets into the key map.
|
|
210
|
+
* 4. Atomic-write config.yml (0644), .env (0600), .env.example (0644).
|
|
211
|
+
*
|
|
212
|
+
* Returns the content strings for display / testing. Callers handle
|
|
213
|
+
* side-effects like the completion summary print — writer stays focused
|
|
214
|
+
* on file state.
|
|
215
|
+
*/
|
|
216
|
+
export function writeInstallFiles(args) {
|
|
217
|
+
const { paths, decisions, secrets, dryRun } = args;
|
|
218
|
+
const configYml = renderConfigYml(decisions);
|
|
219
|
+
const envExample = renderEnvExample(decisions);
|
|
220
|
+
// Merge existing .env (if any) with newly-captured secrets.
|
|
221
|
+
let envMap = new Map();
|
|
222
|
+
if (!dryRun && fs.existsSync(paths.envPath)) {
|
|
223
|
+
envMap = parseEnv(fs.readFileSync(paths.envPath, "utf8"));
|
|
224
|
+
}
|
|
225
|
+
if (secrets.anthropicApiKey) {
|
|
226
|
+
envMap.set("ANTHROPIC_API_KEY", secrets.anthropicApiKey);
|
|
227
|
+
}
|
|
228
|
+
if (secrets.openaiApiKey) {
|
|
229
|
+
envMap.set("OPENAI_API_KEY", secrets.openaiApiKey);
|
|
230
|
+
}
|
|
231
|
+
if (secrets.litellmBaseUrl) {
|
|
232
|
+
envMap.set("LITELLM_BASE_URL", secrets.litellmBaseUrl);
|
|
233
|
+
}
|
|
234
|
+
if (secrets.litellmApiKey) {
|
|
235
|
+
envMap.set("LITELLM_API_KEY", secrets.litellmApiKey);
|
|
236
|
+
}
|
|
237
|
+
const env = renderEnv(envMap);
|
|
238
|
+
if (!dryRun) {
|
|
239
|
+
fs.mkdirSync(paths.ontoDir, { recursive: true });
|
|
240
|
+
atomicWrite(paths.configYmlPath, configYml, 0o644);
|
|
241
|
+
atomicWrite(paths.envPath, env, 0o600);
|
|
242
|
+
atomicWrite(paths.envExamplePath, envExample, 0o644);
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
configYml,
|
|
246
|
+
env,
|
|
247
|
+
envExample,
|
|
248
|
+
writtenTo: {
|
|
249
|
+
configYml: paths.configYmlPath,
|
|
250
|
+
env: paths.envPath,
|
|
251
|
+
envExample: paths.envExamplePath,
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import yaml from "yaml";
|
|
6
|
+
import { parseEnv, renderConfigYml, renderEnv, renderEnvExample, resolveInstallPaths, writeInstallFiles, } from "./writer.js";
|
|
7
|
+
const SAMPLE = {
|
|
8
|
+
profileScope: "project",
|
|
9
|
+
reviewProvider: "anthropic",
|
|
10
|
+
learnProvider: "anthropic",
|
|
11
|
+
outputLanguage: "ko",
|
|
12
|
+
};
|
|
13
|
+
describe("resolveInstallPaths", () => {
|
|
14
|
+
it("global scope points at ~/.onto/ and omits gitignorePath", () => {
|
|
15
|
+
const paths = resolveInstallPaths("global", "/unused", "/home/tester");
|
|
16
|
+
expect(paths.ontoDir).toBe("/home/tester/.onto");
|
|
17
|
+
expect(paths.configYmlPath).toBe("/home/tester/.onto/config.yml");
|
|
18
|
+
expect(paths.envPath).toBe("/home/tester/.onto/.env");
|
|
19
|
+
expect(paths.envExamplePath).toBe("/home/tester/.onto/.env.example");
|
|
20
|
+
expect(paths.gitignorePath).toBeUndefined();
|
|
21
|
+
});
|
|
22
|
+
it("project scope points at <projectRoot>/.onto/ and sets gitignorePath", () => {
|
|
23
|
+
const paths = resolveInstallPaths("project", "/tmp/proj", "/home/tester");
|
|
24
|
+
expect(paths.ontoDir).toBe("/tmp/proj/.onto");
|
|
25
|
+
expect(paths.configYmlPath).toBe("/tmp/proj/.onto/config.yml");
|
|
26
|
+
expect(paths.envPath).toBe("/tmp/proj/.onto/.env");
|
|
27
|
+
expect(paths.envExamplePath).toBe("/tmp/proj/.onto/.env.example");
|
|
28
|
+
expect(paths.gitignorePath).toBe("/tmp/proj/.gitignore");
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe("renderConfigYml", () => {
|
|
32
|
+
it("sets review.subagent.provider and subagent_llm.provider", () => {
|
|
33
|
+
const out = renderConfigYml(SAMPLE);
|
|
34
|
+
const parsed = yaml.parse(stripHeader(out));
|
|
35
|
+
expect(parsed.output_language).toBe("ko");
|
|
36
|
+
expect(parsed.review).toEqual({ subagent: { provider: "anthropic" } });
|
|
37
|
+
expect(parsed.subagent_llm).toEqual({ provider: "anthropic" });
|
|
38
|
+
expect(parsed.external_http_provider).toBe("anthropic");
|
|
39
|
+
});
|
|
40
|
+
it("omits external_http_provider for codex learn (codex not a valid value)", () => {
|
|
41
|
+
const decisions = {
|
|
42
|
+
...SAMPLE,
|
|
43
|
+
reviewProvider: "codex",
|
|
44
|
+
learnProvider: "codex",
|
|
45
|
+
};
|
|
46
|
+
const parsed = yaml.parse(stripHeader(renderConfigYml(decisions)));
|
|
47
|
+
expect(parsed.external_http_provider).toBeUndefined();
|
|
48
|
+
expect(parsed.subagent_llm).toEqual({ provider: "codex" });
|
|
49
|
+
});
|
|
50
|
+
it("records main-native review provider without external fields", () => {
|
|
51
|
+
const decisions = {
|
|
52
|
+
...SAMPLE,
|
|
53
|
+
reviewProvider: "main-native",
|
|
54
|
+
learnProvider: "anthropic",
|
|
55
|
+
};
|
|
56
|
+
const parsed = yaml.parse(stripHeader(renderConfigYml(decisions)));
|
|
57
|
+
expect(parsed.review).toEqual({
|
|
58
|
+
subagent: { provider: "main-native" },
|
|
59
|
+
});
|
|
60
|
+
expect(parsed.external_http_provider).toBe("anthropic");
|
|
61
|
+
});
|
|
62
|
+
it("emits a human-readable header comment at the top", () => {
|
|
63
|
+
const out = renderConfigYml(SAMPLE);
|
|
64
|
+
expect(out.startsWith("# Written by `onto install`")).toBe(true);
|
|
65
|
+
expect(out).toContain("onto config edit");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe("parseEnv / renderEnv", () => {
|
|
69
|
+
it("parses KEY=VALUE lines and skips comments/blank lines", () => {
|
|
70
|
+
const input = [
|
|
71
|
+
"# comment",
|
|
72
|
+
"",
|
|
73
|
+
"FOO=bar",
|
|
74
|
+
" # indented comment",
|
|
75
|
+
"BAZ=quux=extra",
|
|
76
|
+
"malformed-line-no-equals",
|
|
77
|
+
].join("\n");
|
|
78
|
+
const kv = parseEnv(input);
|
|
79
|
+
expect(kv.get("FOO")).toBe("bar");
|
|
80
|
+
expect(kv.get("BAZ")).toBe("quux=extra");
|
|
81
|
+
expect(kv.has("malformed-line-no-equals")).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
it("renderEnv emits keys sorted alphabetically", () => {
|
|
84
|
+
const kv = new Map([
|
|
85
|
+
["ZZZ", "last"],
|
|
86
|
+
["AAA", "first"],
|
|
87
|
+
["MMM", "middle"],
|
|
88
|
+
]);
|
|
89
|
+
const out = renderEnv(kv);
|
|
90
|
+
const keyOrder = out
|
|
91
|
+
.split("\n")
|
|
92
|
+
.filter((line) => !line.startsWith("#") && line.includes("="))
|
|
93
|
+
.map((line) => line.split("=")[0]);
|
|
94
|
+
expect(keyOrder).toEqual(["AAA", "MMM", "ZZZ"]);
|
|
95
|
+
});
|
|
96
|
+
it("roundtrips through parse → render", () => {
|
|
97
|
+
const original = new Map([
|
|
98
|
+
["ANTHROPIC_API_KEY", "sk-ant-xyz"],
|
|
99
|
+
["LITELLM_BASE_URL", "http://localhost:4000/v1"],
|
|
100
|
+
]);
|
|
101
|
+
const rendered = renderEnv(original);
|
|
102
|
+
const reparsed = parseEnv(rendered);
|
|
103
|
+
expect(reparsed).toEqual(original);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe("renderEnvExample", () => {
|
|
107
|
+
it("includes sections only for selected providers", () => {
|
|
108
|
+
const anthOnly = renderEnvExample({
|
|
109
|
+
...SAMPLE,
|
|
110
|
+
reviewProvider: "anthropic",
|
|
111
|
+
learnProvider: "anthropic",
|
|
112
|
+
});
|
|
113
|
+
expect(anthOnly).toContain("ANTHROPIC_API_KEY");
|
|
114
|
+
expect(anthOnly).not.toContain("OPENAI_API_KEY");
|
|
115
|
+
expect(anthOnly).not.toContain("LITELLM_BASE_URL");
|
|
116
|
+
});
|
|
117
|
+
it("includes LiteLLM guidance block with local runtime examples", () => {
|
|
118
|
+
const out = renderEnvExample({
|
|
119
|
+
...SAMPLE,
|
|
120
|
+
reviewProvider: "litellm",
|
|
121
|
+
learnProvider: "litellm",
|
|
122
|
+
});
|
|
123
|
+
expect(out).toContain("LITELLM_BASE_URL");
|
|
124
|
+
expect(out).toContain("Ollama");
|
|
125
|
+
expect(out).toContain("http://localhost:11434/v1");
|
|
126
|
+
expect(out).toContain("# LITELLM_API_KEY=");
|
|
127
|
+
});
|
|
128
|
+
it("merges sections when review and learn providers differ", () => {
|
|
129
|
+
const out = renderEnvExample({
|
|
130
|
+
...SAMPLE,
|
|
131
|
+
reviewProvider: "openai",
|
|
132
|
+
learnProvider: "anthropic",
|
|
133
|
+
});
|
|
134
|
+
expect(out).toContain("OPENAI_API_KEY");
|
|
135
|
+
expect(out).toContain("ANTHROPIC_API_KEY");
|
|
136
|
+
});
|
|
137
|
+
it("produces no provider sections for codex-only setup", () => {
|
|
138
|
+
const out = renderEnvExample({
|
|
139
|
+
...SAMPLE,
|
|
140
|
+
reviewProvider: "codex",
|
|
141
|
+
learnProvider: "codex",
|
|
142
|
+
});
|
|
143
|
+
expect(out).not.toContain("ANTHROPIC_API_KEY");
|
|
144
|
+
expect(out).not.toContain("OPENAI_API_KEY");
|
|
145
|
+
expect(out).not.toContain("LITELLM_BASE_URL");
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
describe("writeInstallFiles", () => {
|
|
149
|
+
let tmpHome;
|
|
150
|
+
beforeEach(() => {
|
|
151
|
+
tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "onto-install-writer-"));
|
|
152
|
+
});
|
|
153
|
+
afterEach(() => {
|
|
154
|
+
fs.rmSync(tmpHome, { recursive: true, force: true });
|
|
155
|
+
});
|
|
156
|
+
it("creates .onto/ and writes all three files with correct modes", () => {
|
|
157
|
+
const paths = resolveInstallPaths("global", "/unused", tmpHome);
|
|
158
|
+
const result = writeInstallFiles({
|
|
159
|
+
paths,
|
|
160
|
+
decisions: SAMPLE,
|
|
161
|
+
secrets: { anthropicApiKey: "sk-ant-test" },
|
|
162
|
+
});
|
|
163
|
+
expect(fs.existsSync(paths.ontoDir)).toBe(true);
|
|
164
|
+
expect(fs.existsSync(paths.configYmlPath)).toBe(true);
|
|
165
|
+
expect(fs.existsSync(paths.envPath)).toBe(true);
|
|
166
|
+
expect(fs.existsSync(paths.envExamplePath)).toBe(true);
|
|
167
|
+
expect(fs.readFileSync(paths.configYmlPath, "utf8")).toBe(result.configYml);
|
|
168
|
+
expect(fs.readFileSync(paths.envPath, "utf8")).toBe(result.env);
|
|
169
|
+
// .env mode should be 0600 on POSIX.
|
|
170
|
+
if (process.platform !== "win32") {
|
|
171
|
+
const mode = fs.statSync(paths.envPath).mode & 0o777;
|
|
172
|
+
expect(mode).toBe(0o600);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
it("preserves unrelated keys during .env merge", () => {
|
|
176
|
+
const paths = resolveInstallPaths("global", "/unused", tmpHome);
|
|
177
|
+
fs.mkdirSync(paths.ontoDir, { recursive: true });
|
|
178
|
+
fs.writeFileSync(paths.envPath, "# user\nCUSTOM_TOOL_KEY=preserve-me\nANTHROPIC_API_KEY=old-value\n");
|
|
179
|
+
writeInstallFiles({
|
|
180
|
+
paths,
|
|
181
|
+
decisions: SAMPLE,
|
|
182
|
+
secrets: { anthropicApiKey: "new-value" },
|
|
183
|
+
});
|
|
184
|
+
const merged = parseEnv(fs.readFileSync(paths.envPath, "utf8"));
|
|
185
|
+
expect(merged.get("CUSTOM_TOOL_KEY")).toBe("preserve-me");
|
|
186
|
+
expect(merged.get("ANTHROPIC_API_KEY")).toBe("new-value");
|
|
187
|
+
});
|
|
188
|
+
it("dry-run returns content without touching the filesystem", () => {
|
|
189
|
+
const paths = resolveInstallPaths("global", "/unused", tmpHome);
|
|
190
|
+
const result = writeInstallFiles({
|
|
191
|
+
paths,
|
|
192
|
+
decisions: SAMPLE,
|
|
193
|
+
secrets: { anthropicApiKey: "sk-ant-test" },
|
|
194
|
+
dryRun: true,
|
|
195
|
+
});
|
|
196
|
+
expect(fs.existsSync(paths.ontoDir)).toBe(false);
|
|
197
|
+
expect(result.configYml).toContain("output_language: ko");
|
|
198
|
+
expect(result.env).toContain("ANTHROPIC_API_KEY=sk-ant-test");
|
|
199
|
+
});
|
|
200
|
+
it("atomic write: no partial temp file left behind on success", () => {
|
|
201
|
+
const paths = resolveInstallPaths("global", "/unused", tmpHome);
|
|
202
|
+
writeInstallFiles({
|
|
203
|
+
paths,
|
|
204
|
+
decisions: SAMPLE,
|
|
205
|
+
secrets: { anthropicApiKey: "sk" },
|
|
206
|
+
});
|
|
207
|
+
const files = fs.readdirSync(paths.ontoDir);
|
|
208
|
+
const tmpFiles = files.filter((f) => f.startsWith(".") && f.includes(".tmp-"));
|
|
209
|
+
expect(tmpFiles).toEqual([]);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
/** Strip the leading comment header block so `yaml.parse` sees clean YAML. */
|
|
213
|
+
function stripHeader(text) {
|
|
214
|
+
return text
|
|
215
|
+
.split("\n")
|
|
216
|
+
.filter((line) => !line.startsWith("#"))
|
|
217
|
+
.join("\n");
|
|
218
|
+
}
|