sneakoscope 6.0.3 → 6.1.2
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/README.md +29 -12
- package/config/codex-releases/{rust-v0.142.0.json → rust-v0.144.1.json} +6 -6
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +18 -14
- package/dist/bin/sks-dispatch.js +2 -4
- package/dist/cli/args.js +2 -0
- package/dist/cli/command-manifest-lite.js +2 -3
- package/dist/cli/command-registry.js +3 -4
- package/dist/cli/help-fast.js +1 -1
- package/dist/cli/install-helpers.js +348 -763
- package/dist/cli/install-tool-helpers.js +287 -0
- package/dist/cli/router.js +91 -6
- package/dist/commands/codex-lb.js +188 -53
- package/dist/commands/codex.js +44 -5
- package/dist/commands/doctor.js +302 -46
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/versioning.js +7 -0
- package/dist/commands/zellij-monitor-pane.js +2 -0
- package/dist/commands/zellij-viewport-pane.js +3 -1
- package/dist/commands/zellij.js +1 -1
- package/dist/config/skills-manifest.json +59 -59
- package/dist/core/agent-bridge/agent-manifest.js +48 -0
- package/dist/core/agents/agent-central-ledger.js +9 -0
- package/dist/core/agents/agent-cleanup-executor.js +334 -41
- package/dist/core/agents/agent-cleanup.js +20 -1
- package/dist/core/agents/agent-command-surface.js +3 -1
- package/dist/core/agents/agent-effort-policy.js +30 -38
- package/dist/core/agents/agent-janitor.js +9 -10
- package/dist/core/agents/agent-namespace-safety.js +56 -0
- package/dist/core/agents/agent-orchestrator.js +25 -3
- package/dist/core/agents/agent-output-validator.js +1 -1
- package/dist/core/agents/agent-plan.js +100 -21
- package/dist/core/agents/agent-role-config.js +43 -49
- package/dist/core/agents/agent-runner-codex-exec.js +18 -3
- package/dist/core/agents/agent-runner-process.js +1 -0
- package/dist/core/agents/agent-schema.js +3 -2
- package/dist/core/agents/fast-mode-policy.js +3 -5
- package/dist/core/agents/native-cli-session-swarm.js +1 -1
- package/dist/core/agents/native-worker-backend-router.js +2 -1
- package/dist/core/agents/work-partition/repo-inventory.js +68 -7
- package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
- package/dist/core/code-structure.js +5 -4
- package/dist/core/codex/agent-config-file-repair.js +94 -193
- package/dist/core/codex/codex-cli-update.js +723 -0
- package/dist/core/codex/codex-config-guard.js +38 -11
- package/dist/core/codex/codex-project-config-policy.js +3 -6
- package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
- package/dist/core/codex-adapter.js +35 -22
- package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
- package/dist/core/codex-app/codex-app-launcher.js +48 -17
- package/dist/core/codex-app/codex-app-restart.js +23 -2
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
- package/dist/core/codex-app/sks-menubar.js +136 -5
- package/dist/core/codex-app.js +35 -14
- package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
- package/dist/core/codex-compat/codex-release-manifest.js +6 -6
- package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +29 -12
- package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
- package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
- package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
- package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
- package/dist/core/codex-control/codex-0139-web-search-probe.js +28 -14
- package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
- package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
- package/dist/core/codex-control/codex-lb-launch-recovery.js +278 -0
- package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
- package/dist/core/codex-control/codex-reliability-shield.js +93 -30
- package/dist/core/codex-control/codex-sdk-adapter.js +96 -13
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
- package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
- package/dist/core/codex-control/codex-task-runner.js +62 -9
- package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
- package/dist/core/codex-exec-output-schema.js +35 -6
- package/dist/core/codex-lb/codex-lb-env.js +30 -1
- package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +31 -38
- package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
- package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
- package/dist/core/codex-native/core-skill-manifest.js +8 -4
- package/dist/core/codex-native/native-capability-postcheck.js +16 -8
- package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
- package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
- package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +305 -0
- package/dist/core/commands/agent-bridge-command.js +23 -2
- package/dist/core/commands/agent-command.js +38 -5
- package/dist/core/commands/basic-cli.js +77 -30
- package/dist/core/commands/command-utils.js +1 -1
- package/dist/core/commands/gc-command.js +27 -4
- package/dist/core/commands/image-ux-review-command.js +55 -24
- package/dist/core/commands/mad-sks-command.js +182 -137
- package/dist/core/commands/naruto-command.js +643 -1153
- package/dist/core/commands/pipeline-command.js +1 -0
- package/dist/core/commands/research-command.js +293 -231
- package/dist/core/commands/run-command.js +100 -23
- package/dist/core/commands/team-command.js +2 -3
- package/dist/core/commands/team-legacy-observe-command.js +94 -359
- package/dist/core/commands/wiki-command.js +179 -83
- package/dist/core/computer-use-live-evidence.js +166 -3
- package/dist/core/computer-use-status.js +5 -2
- package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
- package/dist/core/daemon/sksd-hook-daemon.js +171 -28
- package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
- package/dist/core/db-safety.js +2 -2
- package/dist/core/decision-lattice.js +6 -6
- package/dist/core/dfix/verification-selector.js +6 -4
- package/dist/core/doctor/browser-use-repair.js +54 -13
- package/dist/core/doctor/codex-0139-doctor.js +3 -2
- package/dist/core/doctor/codex-startup-config-repair.js +8 -3
- package/dist/core/doctor/computer-use-repair.js +28 -39
- package/dist/core/doctor/doctor-codex-startup-repair.js +24 -149
- package/dist/core/doctor/doctor-context7-repair.js +1 -1
- package/dist/core/doctor/doctor-dirty-planner.js +1 -1
- package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
- package/dist/core/doctor/imagegen-repair.js +47 -12
- package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
- package/dist/core/feature-fixture-executor.js +71 -7
- package/dist/core/feature-fixture-runner.js +53 -12
- package/dist/core/feature-fixtures.js +47 -14
- package/dist/core/feature-registry.js +53 -58
- package/dist/core/fsx.js +54 -6
- package/dist/core/harness-conflicts.js +19 -10
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
- package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
- package/dist/core/hooks-runtime/hook-io.js +14 -4
- package/dist/core/hooks-runtime/light-turn.js +70 -0
- package/dist/core/hooks-runtime/payload-signals.js +270 -0
- package/dist/core/hooks-runtime/team-digest.js +0 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
- package/dist/core/hooks-runtime.js +418 -250
- package/dist/core/image/image-artifact-path-contract.js +8 -6
- package/dist/core/image/image-artifact-registry.js +5 -1
- package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
- package/dist/core/imagegen/imagegen-capability.js +10 -13
- package/dist/core/imagegen/require-imagegen.js +37 -11
- package/dist/core/init/skills.js +16 -30
- package/dist/core/init.js +144 -36
- package/dist/core/managed-assets/managed-assets-manifest.js +417 -14
- package/dist/core/mission.js +24 -1
- package/dist/core/naruto/naruto-work-graph.js +70 -4
- package/dist/core/ops/reporting.js +3 -0
- package/dist/core/pipeline-internals/runtime-core.js +578 -180
- package/dist/core/pipeline-internals/runtime-gates.js +191 -49
- package/dist/core/ppt/style-tokens.js +1 -1
- package/dist/core/ppt-review/index.js +1 -1
- package/dist/core/ppt-review/slide-exporter.js +23 -17
- package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
- package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
- package/dist/core/preflight/parallel-preflight-engine.js +50 -1
- package/dist/core/product-design-plugin.js +2 -2
- package/dist/core/proof/route-finalizer.js +1 -1
- package/dist/core/proof/route-proof-gate.js +7 -2
- package/dist/core/proof-field.js +3 -3
- package/dist/core/provider/model-router.js +38 -32
- package/dist/core/recallpulse/policy.js +12 -28
- package/dist/core/recallpulse.js +11 -6
- package/dist/core/release/gate-manifest.js +18 -12
- package/dist/core/release/gate-pack-manifest.js +1 -1
- package/dist/core/release/npm-pack-proof.js +247 -0
- package/dist/core/release/package-dist-snapshot.js +151 -0
- package/dist/core/release/package-size-budget.js +5 -0
- package/dist/core/release/release-authorization-snapshot.js +115 -0
- package/dist/core/release/release-gate-affected-selector.js +15 -3
- package/dist/core/release/release-gate-cache-v2.js +30 -0
- package/dist/core/release/release-gate-contract.js +161 -0
- package/dist/core/release/release-gate-dag.js +44 -3
- package/dist/core/release/release-gate-hermetic-env.js +28 -17
- package/dist/core/release/release-real-contract.js +496 -0
- package/dist/core/release-parallel-full-coverage.js +31 -143
- package/dist/core/research/claim-evidence-matrix.js +41 -6
- package/dist/core/research/experiment-plan.js +14 -10
- package/dist/core/research/falsification.js +9 -2
- package/dist/core/research/implementation-blueprint-densifier.js +82 -60
- package/dist/core/research/implementation-blueprint.js +32 -26
- package/dist/core/research/mock-result.js +122 -11
- package/dist/core/research/replication-pack.js +15 -8
- package/dist/core/research/research-adversarial-review.js +1068 -0
- package/dist/core/research/research-claim-builder.js +69 -17
- package/dist/core/research/research-claim-synthesizer.js +343 -0
- package/dist/core/research/research-cycle-runner.js +53 -3
- package/dist/core/research/research-falsification-runner.js +176 -0
- package/dist/core/research/research-final-reviewer.js +44 -125
- package/dist/core/research/research-realistic-report.js +14 -6
- package/dist/core/research/research-review-artifact-digest.js +66 -0
- package/dist/core/research/research-source-evidence.js +144 -0
- package/dist/core/research/research-source-layer-catalog.js +68 -0
- package/dist/core/research/research-source-ledger-merge.js +250 -12
- package/dist/core/research/research-source-shards.js +26 -70
- package/dist/core/research/research-stage-runner.js +237 -247
- package/dist/core/research/research-super-search.js +184 -0
- package/dist/core/research/research-synthesis-prompt.js +20 -1
- package/dist/core/research/research-synthesis-writer.js +86 -5
- package/dist/core/research/research-work-graph.js +25 -18
- package/dist/core/research/source-quality-report.js +21 -0
- package/dist/core/research.js +429 -280
- package/dist/core/retention/retention-budget.js +25 -6
- package/dist/core/retention.js +980 -101
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/dollar-manifest-lite.js +11 -11
- package/dist/core/routes/evidence.js +4 -4
- package/dist/core/routes/ppt-policy.js +1 -1
- package/dist/core/routes.js +92 -64
- package/dist/core/runtime/task-profile.js +66 -0
- package/dist/core/runtime/verification-budget.js +12 -0
- package/dist/core/secret-redaction.js +4 -0
- package/dist/core/security/high-risk-contracts.js +6 -6
- package/dist/core/stop-gate/stop-gate-check.js +49 -12
- package/dist/core/subagents/agent-catalog.js +215 -0
- package/dist/core/subagents/model-policy.js +118 -0
- package/dist/core/subagents/naruto-help-contract.js +40 -0
- package/dist/core/subagents/official-subagent-config.js +488 -0
- package/dist/core/subagents/official-subagent-preparation.js +251 -0
- package/dist/core/subagents/official-subagent-prompt.js +137 -0
- package/dist/core/subagents/official-subagent-runner.js +129 -0
- package/dist/core/subagents/subagent-evidence.js +663 -0
- package/dist/core/subagents/terminology.js +16 -0
- package/dist/core/subagents/thread-budget.js +21 -0
- package/dist/core/subagents/triwiki-attention.js +65 -0
- package/dist/core/super-search/runtime-helpers.js +173 -19
- package/dist/core/super-search/runtime.js +140 -15
- package/dist/core/super-search/source-records.js +49 -8
- package/dist/core/team-review-policy.js +15 -0
- package/dist/core/triwiki/code-pack.js +8 -2
- package/dist/core/triwiki/triwiki-cache-key.js +108 -29
- package/dist/core/triwiki/triwiki-module-card.js +1 -1
- package/dist/core/triwiki-attention.js +13 -6
- package/dist/core/triwiki-provenance.js +274 -0
- package/dist/core/triwiki-runtime.js +21 -7
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +187 -61
- package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
- package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
- package/dist/core/update-check.js +23 -15
- package/dist/core/version-manager.js +51 -1
- package/dist/core/version.js +1 -1
- package/dist/core/wiki-coordinate.js +128 -12
- package/dist/core/work-order-ledger.js +208 -10
- package/dist/core/zellij/zellij-command.js +12 -1
- package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
- package/dist/core/zellij/zellij-fake-adapter.js +3 -1
- package/dist/core/zellij/zellij-launcher.js +51 -21
- package/dist/core/zellij/zellij-layout-builder.js +14 -5
- package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
- package/dist/core/zellij/zellij-pane-proof.js +32 -6
- package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
- package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
- package/dist/core/zellij/zellij-ui-mode.js +1 -1
- package/dist/core/zellij/zellij-viewport-binder.js +3 -0
- package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
- package/dist/scripts/agent-fast-mode-default-check.js +48 -29
- package/dist/scripts/agent-role-config-repair-check.js +34 -15
- package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
- package/dist/scripts/all-feature-deep-completion-check.js +14 -4
- package/dist/scripts/architecture-guard-check.js +8 -1
- package/dist/scripts/build-dist.js +17 -5
- package/dist/scripts/canonical-test-runner.js +188 -0
- package/dist/scripts/check-command-module-budget.js +38 -16
- package/dist/scripts/check-legacy-free.js +1 -1
- package/dist/scripts/check-route-modularity.js +0 -1
- package/dist/scripts/check-ts-contracts.js +1 -1
- package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
- package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
- package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
- package/dist/scripts/codex-0144-capability-check.js +21 -0
- package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
- package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
- package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
- package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
- package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
- package/dist/scripts/codex-app-provider-model-ui-check.js +53 -19
- package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
- package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
- package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
- package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
- package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
- package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
- package/dist/scripts/codex-model-metadata-check.js +1 -1
- package/dist/scripts/codex-native-agent-role-content-check.js +15 -7
- package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
- package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
- package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
- package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
- package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
- package/dist/scripts/db-route-materialization-check.js +33 -0
- package/dist/scripts/dfix-fixture-check.js +1 -1
- package/dist/scripts/docs-truthfulness-check.js +4 -2
- package/dist/scripts/doctor-codex-startup-repair-check.js +47 -25
- package/dist/scripts/doctor-context7-repair-check.js +2 -1
- package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
- package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +9 -3
- package/dist/scripts/doctor-startup-config-repair-check.js +13 -3
- package/dist/scripts/install-update-preserves-config-check.js +7 -2
- package/dist/scripts/legacy-gate-inventory-check.js +7 -5
- package/dist/scripts/legacy-strong-inventory-check.js +7 -5
- package/dist/scripts/legacy-upgrade-matrix-check.js +4 -4
- package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +173 -13
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +165 -6
- package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
- package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
- package/dist/scripts/naruto-codex-e2e-check.js +14 -7
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
- package/dist/scripts/npm-publish-performance-check.js +20 -12
- package/dist/scripts/official-subagent-workflow-check.js +145 -0
- package/dist/scripts/package-published-contract-check.js +6 -20
- package/dist/scripts/packlist-performance-check.js +17 -3
- package/dist/scripts/parallel-verification-engine-check.js +2 -2
- package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
- package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
- package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
- package/dist/scripts/product-design-plugin-routing-check.js +1 -1
- package/dist/scripts/release-affected-selector-check.js +74 -1
- package/dist/scripts/release-check-stamp.js +324 -239
- package/dist/scripts/release-dag-full-coverage-check.js +7 -15
- package/dist/scripts/release-dynamic-presets-check.js +10 -1
- package/dist/scripts/release-gate-dag-runner-check.js +3 -3
- package/dist/scripts/release-gate-dag-runner.js +35 -11
- package/dist/scripts/release-gate-existence-audit.js +1 -2
- package/dist/scripts/release-gate-script-parity-check.js +1 -1
- package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
- package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
- package/dist/scripts/release-real-check.js +390 -157
- package/dist/scripts/release-registry-check.js +61 -16
- package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
- package/dist/scripts/research-blueprint-densifier-check.js +2 -2
- package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
- package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
- package/dist/scripts/search-visibility-gate-lib.js +1 -1
- package/dist/scripts/seo-geo-route-identity-check.js +30 -4
- package/dist/scripts/sizecheck.js +4 -4
- package/dist/scripts/sks-1-11-gate-lib.js +53 -6
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
- package/dist/scripts/sks-menubar-install-check.js +8 -0
- package/dist/scripts/sks-uninstall-regression-check.js +1 -1
- package/dist/scripts/sksd-daemon-check.js +16 -6
- package/dist/scripts/trust-fixture-check.js +32 -10
- package/dist/scripts/write-build-manifest.js +2 -1
- package/dist/scripts/wrongness-fixture-check.js +1 -1
- package/dist/scripts/zellij-layout-valid-check.js +36 -11
- package/dist/scripts/zellij-pane-proof-check.js +33 -2
- package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
- package/dist/scripts/zellij-real-session-launch-check.js +76 -5
- package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
- package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1486 -0
- package/package.json +32 -19
- package/release-gates.v2.json +4060 -0
- package/runtime-required-scripts.json +9 -0
- package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
- package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
- package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
- package/dist/commands/db.js +0 -6
- package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
- package/dist/core/commands/db-command.js +0 -146
- package/dist/core/research/prompt.js +0 -15
- package/dist/scripts/agent-native-release-gate.js +0 -274
- package/dist/scripts/codex-0142-capability-check.js +0 -21
- package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
- package/dist/scripts/command-performance-scorecard-check.js +0 -204
- package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
- package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
- package/dist/scripts/gate-timing-check.js +0 -16
- package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
- package/dist/scripts/performance-baseline-check.js +0 -12
- package/dist/scripts/performance-improvement-report-check.js +0 -58
- package/dist/scripts/release-parallel-check.js +0 -389
- package/dist/scripts/release-runner-efficiency-check.js +0 -15
- package/dist/scripts/retention-long-run-smoke-check.js +0 -299
- package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
|
@@ -3,6 +3,7 @@ import fsp from 'node:fs/promises';
|
|
|
3
3
|
import { ensureDir, exists, packageRoot, readJson, runProcess, which } from './fsx.js';
|
|
4
4
|
import { codexVersionPolicy, compareSemverLike, parseCodexVersionText } from './codex-compat/codex-version-policy.js';
|
|
5
5
|
import { validateJsonSchemaRecursive } from './json-schema-validator.js';
|
|
6
|
+
import { inspectCodexLbCliLaunchRecovery } from './codex-control/codex-lb-launch-recovery.js';
|
|
6
7
|
export async function detectCodexExecOutputSchemaSyntax(opts = {}) {
|
|
7
8
|
const codexBin = opts.codexBin || await which('codex').catch(() => null);
|
|
8
9
|
if (!codexBin) {
|
|
@@ -167,6 +168,33 @@ export async function buildCodexExecResumeOutputSchemaArgs(input) {
|
|
|
167
168
|
return args;
|
|
168
169
|
}
|
|
169
170
|
export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
171
|
+
const root = opts.cwd || packageRoot();
|
|
172
|
+
const env = opts.env || process.env;
|
|
173
|
+
const toolOutputRecovery = await inspectCodexLbCliLaunchRecovery({
|
|
174
|
+
root,
|
|
175
|
+
env,
|
|
176
|
+
cliArgs: input.extraArgs || [],
|
|
177
|
+
...(opts.recoveryFetch ? { fetchImpl: opts.recoveryFetch } : {}),
|
|
178
|
+
...(opts.recoveryTimeoutMs === undefined ? {} : { timeoutMs: opts.recoveryTimeoutMs })
|
|
179
|
+
});
|
|
180
|
+
if (!toolOutputRecovery.ok) {
|
|
181
|
+
return {
|
|
182
|
+
schema: 'sks.codex-exec-output-schema-run.v1',
|
|
183
|
+
ok: false,
|
|
184
|
+
status: 'blocked',
|
|
185
|
+
args: [],
|
|
186
|
+
codex_bin: opts.codexBin || null,
|
|
187
|
+
output_file: null,
|
|
188
|
+
parsed_json: null,
|
|
189
|
+
blocker: structuredOutputBlocker('codex_lb_tool_output_recovery_blocked', toolOutputRecovery.blockers.join(', ')),
|
|
190
|
+
validation: { ok: false, issues: ['codex_lb_tool_output_recovery_blocked'] },
|
|
191
|
+
stdout_tail: '',
|
|
192
|
+
stderr_tail: '',
|
|
193
|
+
timed_out: false,
|
|
194
|
+
exit_code: null,
|
|
195
|
+
codex_lb_tool_output_recovery: toolOutputRecovery
|
|
196
|
+
};
|
|
197
|
+
}
|
|
170
198
|
const availability = await detectCodexExecResumeOutputSchema({ codexBin: opts.codexBin || undefined });
|
|
171
199
|
if (!availability.codex_bin || availability.status !== 'available' || !availability.output_schema_supported) {
|
|
172
200
|
const status = availability.status === 'available' ? 'degraded_supported' : availability.status;
|
|
@@ -183,7 +211,8 @@ export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
|
183
211
|
stdout_tail: '',
|
|
184
212
|
stderr_tail: '',
|
|
185
213
|
timed_out: false,
|
|
186
|
-
exit_code: null
|
|
214
|
+
exit_code: null,
|
|
215
|
+
codex_lb_tool_output_recovery: toolOutputRecovery
|
|
187
216
|
};
|
|
188
217
|
}
|
|
189
218
|
const outputFile = input.outputFile
|
|
@@ -192,13 +221,12 @@ export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
|
192
221
|
await ensureDir(path.dirname(outputFile));
|
|
193
222
|
const args = await buildCodexExecResumeOutputSchemaArgs({ ...input, outputFile });
|
|
194
223
|
const runOpts = {
|
|
195
|
-
cwd:
|
|
224
|
+
cwd: root,
|
|
196
225
|
timeoutMs: opts.timeoutMs || 120_000,
|
|
197
226
|
maxOutputBytes: opts.maxOutputBytes || 256 * 1024
|
|
198
227
|
};
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const result = await runProcess(availability.codex_bin, args, runOpts);
|
|
228
|
+
runOpts.env = env;
|
|
229
|
+
const result = await (opts.runProcessImpl || runProcess)(availability.codex_bin, args, runOpts);
|
|
202
230
|
const outputText = await readOutputText(outputFile, result.stdout);
|
|
203
231
|
const parsed = parseStructuredCodexOutput(outputText);
|
|
204
232
|
const schema = await readJson(path.resolve(input.outputSchemaPath), null);
|
|
@@ -221,7 +249,8 @@ export async function runCodexExecResumeWithOutputSchema(input, opts = {}) {
|
|
|
221
249
|
stdout_tail: redactCodexOutput(result.stdout).slice(-12_000),
|
|
222
250
|
stderr_tail: redactCodexOutput(result.stderr).slice(-12_000),
|
|
223
251
|
timed_out: result.timedOut,
|
|
224
|
-
exit_code: result.code
|
|
252
|
+
exit_code: result.code,
|
|
253
|
+
codex_lb_tool_output_recovery: toolOutputRecovery
|
|
225
254
|
};
|
|
226
255
|
}
|
|
227
256
|
export function parseStructuredCodexOutput(text) {
|
|
@@ -42,6 +42,18 @@ export async function readCodexLbModelCatalog(opts = {}) {
|
|
|
42
42
|
blockers: loaded.missing.length ? loaded.missing.map((item) => `codex_lb_missing:${item}`) : ['codex_lb_not_configured']
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
const transportBlocker = codexLbBaseUrlSecurityBlocker(loaded.base_url);
|
|
46
|
+
if (transportBlocker) {
|
|
47
|
+
return {
|
|
48
|
+
schema: 'sks.codex-lb-model-catalog.v1',
|
|
49
|
+
ok: false,
|
|
50
|
+
status: 'blocked',
|
|
51
|
+
models: [],
|
|
52
|
+
model_efforts: {},
|
|
53
|
+
http_status: null,
|
|
54
|
+
blockers: [transportBlocker]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
45
57
|
const fetchImpl = opts.fetchImpl || fetch;
|
|
46
58
|
try {
|
|
47
59
|
const response = await fetchImpl(`${loaded.base_url}/models`, {
|
|
@@ -116,6 +128,23 @@ export function normalizeCodexLbBaseUrl(input = '') {
|
|
|
116
128
|
host = host.replace(/\/+$/, '');
|
|
117
129
|
return /\/backend-api\/codex$/i.test(host) ? host : `${host}/backend-api/codex`;
|
|
118
130
|
}
|
|
131
|
+
export function codexLbBaseUrlSecurityBlocker(input) {
|
|
132
|
+
try {
|
|
133
|
+
const url = new URL(String(input || ''));
|
|
134
|
+
if (url.username || url.password)
|
|
135
|
+
return 'codex_lb_base_url_userinfo_forbidden';
|
|
136
|
+
if (url.protocol === 'https:')
|
|
137
|
+
return null;
|
|
138
|
+
const host = url.hostname.toLowerCase();
|
|
139
|
+
const loopback = host === 'localhost' || host === '::1' || host === '[::1]' || /^127(?:\.\d{1,3}){3}$/.test(host);
|
|
140
|
+
if (url.protocol === 'http:' && loopback)
|
|
141
|
+
return null;
|
|
142
|
+
return 'codex_lb_insecure_base_url';
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return 'codex_lb_invalid_base_url';
|
|
146
|
+
}
|
|
147
|
+
}
|
|
119
148
|
export async function loadCodexLbEnv(opts = {}) {
|
|
120
149
|
const home = opts.home || process.env.HOME || os.homedir();
|
|
121
150
|
const envPaths = [
|
|
@@ -125,7 +154,7 @@ export async function loadCodexLbEnv(opts = {}) {
|
|
|
125
154
|
const sourcePriority = ['process.env', 'keychain', 'env-file', 'legacy-env-file'];
|
|
126
155
|
if (opts.allowProjectSecrets)
|
|
127
156
|
sourcePriority.push('project-local');
|
|
128
|
-
const processEnv = pickEnv(process.env);
|
|
157
|
+
const processEnv = pickEnv(opts.processEnv || process.env);
|
|
129
158
|
const envFile = await readEnvFile(envPaths[0]);
|
|
130
159
|
const legacyEnv = await readEnvFile(envPaths[1]);
|
|
131
160
|
const keychain = await readMacKeychain(opts);
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ensureDir, exists, nowIso, sha256, writeTextAtomic } from '../fsx.js';
|
|
4
|
+
import { codexLbBaseUrlSecurityBlocker, normalizeCodexLbBaseUrl } from './codex-lb-env.js';
|
|
5
|
+
export const CODEX_LB_TOOL_CATALOG_FILENAME = 'sks-codex-lb-tool-catalog.json';
|
|
6
|
+
export const CODEX_LB_TOOL_CATALOG_SCHEMA = 'sks.codex-lb-tool-catalog.v1';
|
|
7
|
+
export const CODEX_LB_TOOL_CATALOG_METADATA_SCHEMA = 'sks.codex-lb-tool-catalog-metadata.v1';
|
|
8
|
+
export const CODEX_LB_TOOL_CATALOG_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
|
|
9
|
+
export const CODEX_LB_TOOL_CATALOG_MAX_MODELS = 128;
|
|
10
|
+
const CODEX_LB_TOOL_CATALOG_MAX_METADATA_BYTES = 16 * 1024;
|
|
11
|
+
const DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
12
|
+
const GPT56_MODEL_RE = /^gpt-5\.6-(?:sol|terra|luna)$/;
|
|
13
|
+
const ensureInflight = new Map();
|
|
14
|
+
const REQUIRED_CODEX_0144_MODEL_FIELDS = {
|
|
15
|
+
slug: ['string'],
|
|
16
|
+
display_name: ['string'],
|
|
17
|
+
supported_reasoning_levels: ['array'],
|
|
18
|
+
shell_type: ['string'],
|
|
19
|
+
visibility: ['string'],
|
|
20
|
+
supported_in_api: ['boolean'],
|
|
21
|
+
priority: ['number'],
|
|
22
|
+
base_instructions: ['string'],
|
|
23
|
+
supports_reasoning_summaries: ['boolean'],
|
|
24
|
+
support_verbosity: ['boolean'],
|
|
25
|
+
truncation_policy: ['object'],
|
|
26
|
+
supports_parallel_tool_calls: ['boolean'],
|
|
27
|
+
experimental_supported_tools: ['array']
|
|
28
|
+
};
|
|
29
|
+
// Exact union observed in Codex CLI 0.144.1's native cache and codex-lb catalog.
|
|
30
|
+
// Unknown response fields are deliberately not persisted into a Codex-owned file.
|
|
31
|
+
const CODEX_0144_MODEL_FIELD_TYPES = {
|
|
32
|
+
...REQUIRED_CODEX_0144_MODEL_FIELDS,
|
|
33
|
+
description: ['string'],
|
|
34
|
+
default_reasoning_level: ['string'],
|
|
35
|
+
additional_speed_tiers: ['array'],
|
|
36
|
+
service_tiers: ['array'],
|
|
37
|
+
availability_nux: ['object', 'null'],
|
|
38
|
+
upgrade: ['object', 'null'],
|
|
39
|
+
model_messages: ['object'],
|
|
40
|
+
include_skills_usage_instructions: ['boolean'],
|
|
41
|
+
default_reasoning_summary: ['string'],
|
|
42
|
+
default_verbosity: ['string'],
|
|
43
|
+
apply_patch_tool_type: ['string'],
|
|
44
|
+
web_search_tool_type: ['string'],
|
|
45
|
+
supports_image_detail_original: ['boolean'],
|
|
46
|
+
context_window: ['number'],
|
|
47
|
+
max_context_window: ['number'],
|
|
48
|
+
comp_hash: ['string'],
|
|
49
|
+
effective_context_window_percent: ['number'],
|
|
50
|
+
input_modalities: ['array'],
|
|
51
|
+
supports_search_tool: ['boolean'],
|
|
52
|
+
use_responses_lite: ['boolean'],
|
|
53
|
+
tool_mode: ['string', 'null'],
|
|
54
|
+
multi_agent_version: ['string', 'null'],
|
|
55
|
+
minimal_client_version: ['string'],
|
|
56
|
+
available_in_plans: ['array'],
|
|
57
|
+
prefer_websockets: ['boolean'],
|
|
58
|
+
auto_review_model_override: ['string', 'null'],
|
|
59
|
+
auto_compact_token_limit: ['number', 'null'],
|
|
60
|
+
reasoning_summary_format: ['string'],
|
|
61
|
+
default_service_tier: ['string', 'null']
|
|
62
|
+
};
|
|
63
|
+
export function isCodexLbGpt56Model(model) {
|
|
64
|
+
return GPT56_MODEL_RE.test(String(model || '').trim());
|
|
65
|
+
}
|
|
66
|
+
export function codexLbToolCatalogPath(codexHome) {
|
|
67
|
+
return path.join(path.resolve(codexHome), CODEX_LB_TOOL_CATALOG_FILENAME);
|
|
68
|
+
}
|
|
69
|
+
export function codexLbToolCatalogMetadataPath(catalogPath) {
|
|
70
|
+
return `${path.resolve(catalogPath)}.meta.json`;
|
|
71
|
+
}
|
|
72
|
+
export function normalizeCodexLbToolCatalog(payload, opts = {}) {
|
|
73
|
+
const rows = Array.isArray(payload?.models)
|
|
74
|
+
? payload.models
|
|
75
|
+
: Array.isArray(payload?.data)
|
|
76
|
+
? payload.data
|
|
77
|
+
: [];
|
|
78
|
+
const maxModels = boundedPositiveInt(opts.maxModels, CODEX_LB_TOOL_CATALOG_MAX_MODELS);
|
|
79
|
+
const limitedRows = rows.slice(0, maxModels);
|
|
80
|
+
const patchedModels = [];
|
|
81
|
+
const gpt56Models = [];
|
|
82
|
+
const validationIssues = [];
|
|
83
|
+
const models = limitedRows.map((row, index) => {
|
|
84
|
+
if (!isPlainObject(row)) {
|
|
85
|
+
validationIssues.push(`codex_lb_model_catalog_row_invalid:${index}:object`);
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
const model = String(row.slug || row.id || row.model || row.name || '').trim();
|
|
89
|
+
if (isCodexLbGpt56Model(model))
|
|
90
|
+
gpt56Models.push(model);
|
|
91
|
+
const sanitized = sanitizeCodex0144Model(row);
|
|
92
|
+
validationIssues.push(...validateCodex0144Model(sanitized, index));
|
|
93
|
+
if (!isCodexLbGpt56Model(model))
|
|
94
|
+
return sanitized;
|
|
95
|
+
if (row.use_responses_lite !== false)
|
|
96
|
+
patchedModels.push(model);
|
|
97
|
+
// Codex 0.144.1 omits the request's `tools` field for Responses Lite.
|
|
98
|
+
// Preserve the provider's tool_mode contract, but force full Responses.
|
|
99
|
+
return { ...sanitized, use_responses_lite: false };
|
|
100
|
+
});
|
|
101
|
+
const compatibleRows = models.filter((row) => isCodexLbGpt56Model(row.slug));
|
|
102
|
+
const compatible = gpt56Models.length > 0
|
|
103
|
+
&& compatibleRows.length === gpt56Models.length
|
|
104
|
+
&& compatibleRows.every((row) => row.use_responses_lite === false);
|
|
105
|
+
const blockers = uniqueBounded([
|
|
106
|
+
...(rows.length ? [] : ['codex_lb_model_catalog_empty']),
|
|
107
|
+
...(rows.length > maxModels ? [`codex_lb_model_catalog_model_limit_exceeded:${rows.length}:${maxModels}`] : []),
|
|
108
|
+
...validationIssues,
|
|
109
|
+
...(gpt56Models.length ? [] : ['codex_lb_gpt56_models_missing']),
|
|
110
|
+
...(compatible ? [] : ['codex_lb_gpt56_tools_transport_incompatible'])
|
|
111
|
+
]);
|
|
112
|
+
return {
|
|
113
|
+
schema: CODEX_LB_TOOL_CATALOG_SCHEMA,
|
|
114
|
+
ok: blockers.length === 0,
|
|
115
|
+
catalog: { models },
|
|
116
|
+
model_count: models.length,
|
|
117
|
+
gpt56_models: [...new Set(gpt56Models)].sort(),
|
|
118
|
+
patched_models: [...new Set(patchedModels)].sort(),
|
|
119
|
+
tools_transport: compatible ? 'full_responses' : 'unverified',
|
|
120
|
+
blockers
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export async function inspectCodexLbToolCatalog(file, opts = {}) {
|
|
124
|
+
const maxBytes = boundedPositiveInt(opts.maxBytes, CODEX_LB_TOOL_CATALOG_MAX_RESPONSE_BYTES);
|
|
125
|
+
const fileSafety = await inspectSecureRegularFile(file, maxBytes, 'codex_lb_tool_catalog');
|
|
126
|
+
if (!fileSafety.ok)
|
|
127
|
+
return incompatibleInspection(file, fileSafety, fileSafety.blockers);
|
|
128
|
+
let text = '';
|
|
129
|
+
let payload = null;
|
|
130
|
+
try {
|
|
131
|
+
text = await fs.readFile(file, 'utf8');
|
|
132
|
+
payload = JSON.parse(text);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return incompatibleInspection(file, fileSafety, ['codex_lb_tool_catalog_json_invalid']);
|
|
136
|
+
}
|
|
137
|
+
const normalized = normalizeCodexLbToolCatalog(payload, opts.maxModels === undefined ? {} : { maxModels: opts.maxModels });
|
|
138
|
+
const { catalog: _catalog, ...status } = normalized;
|
|
139
|
+
const metadataPath = codexLbToolCatalogMetadataPath(file);
|
|
140
|
+
const identityBlockers = [];
|
|
141
|
+
let identityVerified = false;
|
|
142
|
+
let cacheOrigin = null;
|
|
143
|
+
if (opts.expectedIdentity) {
|
|
144
|
+
const metadataSafety = await inspectSecureRegularFile(metadataPath, CODEX_LB_TOOL_CATALOG_MAX_METADATA_BYTES, 'codex_lb_tool_catalog_metadata');
|
|
145
|
+
if (!metadataSafety.ok) {
|
|
146
|
+
identityBlockers.push(...metadataSafety.blockers);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
try {
|
|
150
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf8'));
|
|
151
|
+
cacheOrigin = typeof metadata?.identity?.origin === 'string' ? metadata.identity.origin : null;
|
|
152
|
+
if (metadata?.schema !== CODEX_LB_TOOL_CATALOG_METADATA_SCHEMA)
|
|
153
|
+
identityBlockers.push('codex_lb_tool_catalog_metadata_schema_invalid');
|
|
154
|
+
if (metadata?.catalog_sha256 !== sha256(text))
|
|
155
|
+
identityBlockers.push('codex_lb_tool_catalog_metadata_hash_mismatch');
|
|
156
|
+
if (!sameCatalogIdentity(metadata?.identity, opts.expectedIdentity))
|
|
157
|
+
identityBlockers.push('codex_lb_tool_catalog_identity_mismatch');
|
|
158
|
+
identityVerified = identityBlockers.length === 0;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
identityBlockers.push('codex_lb_tool_catalog_metadata_json_invalid');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const blockers = uniqueBounded([...normalized.blockers, ...identityBlockers]);
|
|
166
|
+
return {
|
|
167
|
+
...status,
|
|
168
|
+
ok: blockers.length === 0,
|
|
169
|
+
path: file,
|
|
170
|
+
exists: true,
|
|
171
|
+
updated_at_ms: fileSafety.updated_at_ms,
|
|
172
|
+
size_bytes: fileSafety.size_bytes,
|
|
173
|
+
mode: fileSafety.mode,
|
|
174
|
+
owner_uid: fileSafety.owner_uid,
|
|
175
|
+
metadata_path: metadataPath,
|
|
176
|
+
identity_verified: opts.expectedIdentity ? identityVerified : null,
|
|
177
|
+
cache_origin: cacheOrigin,
|
|
178
|
+
blockers
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
export async function ensureCodexLbToolCatalog(input) {
|
|
182
|
+
const outputPath = path.resolve(input.outputPath || codexLbToolCatalogPath(input.codexHome));
|
|
183
|
+
const baseUrl = normalizeCodexLbBaseUrl(input.baseUrl);
|
|
184
|
+
const apiKey = String(input.apiKey || '').trim();
|
|
185
|
+
const transportBlocker = catalogTransportBlocker(baseUrl);
|
|
186
|
+
if (transportBlocker || !apiKey) {
|
|
187
|
+
return blockedResult(outputPath, [transportBlocker || 'codex_lb_api_key_missing']);
|
|
188
|
+
}
|
|
189
|
+
const identity = catalogIdentity(baseUrl, apiKey);
|
|
190
|
+
const inflightKey = [
|
|
191
|
+
outputPath,
|
|
192
|
+
identity.base_url_sha256,
|
|
193
|
+
identity.api_key_sha256,
|
|
194
|
+
input.force === true ? 'force' : 'normal',
|
|
195
|
+
boundedPositiveInt(input.maxResponseBytes, CODEX_LB_TOOL_CATALOG_MAX_RESPONSE_BYTES),
|
|
196
|
+
boundedPositiveInt(input.maxModels, CODEX_LB_TOOL_CATALOG_MAX_MODELS)
|
|
197
|
+
].join(':');
|
|
198
|
+
const existing = ensureInflight.get(inflightKey);
|
|
199
|
+
if (existing)
|
|
200
|
+
return existing;
|
|
201
|
+
const promise = ensureValidatedCodexLbToolCatalog(input, outputPath, baseUrl, apiKey, identity)
|
|
202
|
+
.finally(() => ensureInflight.delete(inflightKey));
|
|
203
|
+
ensureInflight.set(inflightKey, promise);
|
|
204
|
+
return promise;
|
|
205
|
+
}
|
|
206
|
+
async function ensureValidatedCodexLbToolCatalog(input, outputPath, baseUrl, apiKey, identity) {
|
|
207
|
+
const now = input.now ? input.now() : Date.now();
|
|
208
|
+
const maxAgeMs = Math.max(0, Number(input.maxAgeMs ?? DEFAULT_MAX_AGE_MS));
|
|
209
|
+
const inspectOpts = {
|
|
210
|
+
expectedIdentity: identity,
|
|
211
|
+
...(input.maxResponseBytes === undefined ? {} : { maxBytes: input.maxResponseBytes }),
|
|
212
|
+
...(input.maxModels === undefined ? {} : { maxModels: input.maxModels })
|
|
213
|
+
};
|
|
214
|
+
const cached = await inspectCodexLbToolCatalog(outputPath, inspectOpts);
|
|
215
|
+
if (!input.force && cached.ok && cacheIsFresh(cached.updated_at_ms, now, maxAgeMs)) {
|
|
216
|
+
return { ...cached, generated_at: nowIso(), status: 'cached_compatible', fetched: false, required: true };
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const response = await (input.fetchImpl || fetch)(`${baseUrl}/models`, {
|
|
220
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
221
|
+
signal: AbortSignal.timeout(Math.max(250, Number(input.timeoutMs || 5000)))
|
|
222
|
+
});
|
|
223
|
+
if (!response.ok)
|
|
224
|
+
throw new CatalogFetchError(`codex_lb_models_http_${response.status}`);
|
|
225
|
+
const payload = await readJsonResponseBounded(response, boundedPositiveInt(input.maxResponseBytes, CODEX_LB_TOOL_CATALOG_MAX_RESPONSE_BYTES));
|
|
226
|
+
const normalized = normalizeCodexLbToolCatalog(payload, input.maxModels === undefined ? {} : { maxModels: input.maxModels });
|
|
227
|
+
if (!normalized.ok) {
|
|
228
|
+
const fallback = await inspectCodexLbToolCatalog(outputPath, inspectOpts);
|
|
229
|
+
if (fallback.ok) {
|
|
230
|
+
return { ...fallback, generated_at: nowIso(), status: 'cached_compatible_after_refresh_rejected', fetched: true, required: true, refresh_blockers: normalized.blockers };
|
|
231
|
+
}
|
|
232
|
+
const { catalog: _catalog, ...status } = normalized;
|
|
233
|
+
return { ...status, generated_at: nowIso(), status: 'blocked', path: outputPath, exists: await exists(outputPath), fetched: true, required: true };
|
|
234
|
+
}
|
|
235
|
+
await writeSecureCatalog(outputPath, normalized.catalog, identity);
|
|
236
|
+
const verified = await inspectCodexLbToolCatalog(outputPath, inspectOpts);
|
|
237
|
+
return {
|
|
238
|
+
...verified,
|
|
239
|
+
generated_at: nowIso(),
|
|
240
|
+
status: verified.ok ? 'repaired' : 'write_verification_failed',
|
|
241
|
+
fetched: true,
|
|
242
|
+
required: true,
|
|
243
|
+
patched_models: normalized.patched_models,
|
|
244
|
+
blockers: verified.ok ? [] : verified.blockers
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
const fallback = await inspectCodexLbToolCatalog(outputPath, inspectOpts);
|
|
249
|
+
if (fallback.ok) {
|
|
250
|
+
return {
|
|
251
|
+
...fallback,
|
|
252
|
+
generated_at: nowIso(),
|
|
253
|
+
status: 'cached_compatible_after_refresh_failed',
|
|
254
|
+
fetched: false,
|
|
255
|
+
required: true,
|
|
256
|
+
refresh_error: safeError(error, [apiKey])
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
const code = error instanceof CatalogFetchError ? error.code : 'codex_lb_tool_catalog_fetch_failed';
|
|
260
|
+
return {
|
|
261
|
+
...blockedResult(outputPath, uniqueBounded(['codex_lb_tool_catalog_fetch_failed', code])),
|
|
262
|
+
status: 'fetch_failed',
|
|
263
|
+
fetched: false,
|
|
264
|
+
error: safeError(error, [apiKey])
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async function readJsonResponseBounded(response, maxBytes) {
|
|
269
|
+
const advertised = Number(response.headers.get('content-length'));
|
|
270
|
+
if (Number.isFinite(advertised) && advertised > maxBytes)
|
|
271
|
+
throw new CatalogFetchError('codex_lb_tool_catalog_response_too_large');
|
|
272
|
+
if (!response.body) {
|
|
273
|
+
const text = await response.text();
|
|
274
|
+
if (Buffer.byteLength(text, 'utf8') > maxBytes)
|
|
275
|
+
throw new CatalogFetchError('codex_lb_tool_catalog_response_too_large');
|
|
276
|
+
return parseCatalogJson(text);
|
|
277
|
+
}
|
|
278
|
+
const reader = response.body.getReader();
|
|
279
|
+
const chunks = [];
|
|
280
|
+
let total = 0;
|
|
281
|
+
try {
|
|
282
|
+
while (true) {
|
|
283
|
+
const { done, value } = await reader.read();
|
|
284
|
+
if (done)
|
|
285
|
+
break;
|
|
286
|
+
if (!value)
|
|
287
|
+
continue;
|
|
288
|
+
total += value.byteLength;
|
|
289
|
+
if (total > maxBytes) {
|
|
290
|
+
await reader.cancel().catch(() => undefined);
|
|
291
|
+
throw new CatalogFetchError('codex_lb_tool_catalog_response_too_large');
|
|
292
|
+
}
|
|
293
|
+
chunks.push(value);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
reader.releaseLock();
|
|
298
|
+
}
|
|
299
|
+
const bytes = Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total);
|
|
300
|
+
return parseCatalogJson(bytes.toString('utf8'));
|
|
301
|
+
}
|
|
302
|
+
function parseCatalogJson(text) {
|
|
303
|
+
try {
|
|
304
|
+
return JSON.parse(text);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
throw new CatalogFetchError('codex_lb_tool_catalog_response_json_invalid');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async function writeSecureCatalog(file, catalog, identity) {
|
|
311
|
+
const text = `${JSON.stringify(catalog, null, 2)}\n`;
|
|
312
|
+
const metadataPath = codexLbToolCatalogMetadataPath(file);
|
|
313
|
+
const metadata = {
|
|
314
|
+
schema: CODEX_LB_TOOL_CATALOG_METADATA_SCHEMA,
|
|
315
|
+
generated_at: nowIso(),
|
|
316
|
+
catalog_schema: CODEX_LB_TOOL_CATALOG_SCHEMA,
|
|
317
|
+
catalog_sha256: sha256(text),
|
|
318
|
+
identity,
|
|
319
|
+
model_count: Array.isArray(catalog?.models) ? catalog.models.length : 0
|
|
320
|
+
};
|
|
321
|
+
await ensureDir(path.dirname(file));
|
|
322
|
+
await writeTextAtomic(file, text, { mode: 0o600 });
|
|
323
|
+
const catalogSafety = await inspectSecureRegularFile(file, CODEX_LB_TOOL_CATALOG_MAX_RESPONSE_BYTES, 'codex_lb_tool_catalog');
|
|
324
|
+
if (!catalogSafety.ok)
|
|
325
|
+
throw new CatalogFetchError(catalogSafety.blockers[0] || 'codex_lb_tool_catalog_file_insecure');
|
|
326
|
+
await writeTextAtomic(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`, { mode: 0o600 });
|
|
327
|
+
const metadataSafety = await inspectSecureRegularFile(metadataPath, CODEX_LB_TOOL_CATALOG_MAX_METADATA_BYTES, 'codex_lb_tool_catalog_metadata');
|
|
328
|
+
if (!metadataSafety.ok)
|
|
329
|
+
throw new CatalogFetchError(metadataSafety.blockers[0] || 'codex_lb_tool_catalog_metadata_file_insecure');
|
|
330
|
+
}
|
|
331
|
+
async function inspectSecureRegularFile(file, maxBytes, prefix) {
|
|
332
|
+
const stat = await fs.lstat(file).catch(() => null);
|
|
333
|
+
if (!stat)
|
|
334
|
+
return { ok: false, exists: false, updated_at_ms: null, size_bytes: 0, mode: null, owner_uid: null, blockers: [`${prefix}_missing`] };
|
|
335
|
+
const blockers = [];
|
|
336
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
337
|
+
blockers.push(`${prefix}_not_regular_file`);
|
|
338
|
+
if (stat.size > maxBytes)
|
|
339
|
+
blockers.push(`${prefix}_too_large:${stat.size}:${maxBytes}`);
|
|
340
|
+
const ownerUid = Number.isFinite(Number(stat.uid)) ? Number(stat.uid) : null;
|
|
341
|
+
const expectedUid = typeof process.getuid === 'function' ? process.getuid() : null;
|
|
342
|
+
if (expectedUid !== null && ownerUid !== expectedUid)
|
|
343
|
+
blockers.push(`${prefix}_owner_mismatch`);
|
|
344
|
+
const mode = stat.mode & 0o777;
|
|
345
|
+
if (process.platform !== 'win32' && mode !== 0o600)
|
|
346
|
+
blockers.push(`${prefix}_mode_insecure:${mode.toString(8)}`);
|
|
347
|
+
return { ok: blockers.length === 0, exists: true, updated_at_ms: stat.mtimeMs, size_bytes: stat.size, mode: mode.toString(8).padStart(3, '0'), owner_uid: ownerUid, blockers };
|
|
348
|
+
}
|
|
349
|
+
function sanitizeCodex0144Model(row) {
|
|
350
|
+
return Object.fromEntries(Object.keys(CODEX_0144_MODEL_FIELD_TYPES)
|
|
351
|
+
.filter((field) => Object.prototype.hasOwnProperty.call(row, field))
|
|
352
|
+
.map((field) => [field, row[field]]));
|
|
353
|
+
}
|
|
354
|
+
function validateCodex0144Model(row, index) {
|
|
355
|
+
const issues = [];
|
|
356
|
+
for (const [field, allowedTypes] of Object.entries(REQUIRED_CODEX_0144_MODEL_FIELDS)) {
|
|
357
|
+
if (!Object.prototype.hasOwnProperty.call(row, field)) {
|
|
358
|
+
issues.push(`codex_lb_model_catalog_required_field_missing:${index}:${field}`);
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (!allowedTypes.includes(valueType(row[field])))
|
|
362
|
+
issues.push(`codex_lb_model_catalog_field_type_invalid:${index}:${field}`);
|
|
363
|
+
}
|
|
364
|
+
for (const [field, value] of Object.entries(row)) {
|
|
365
|
+
if (!(CODEX_0144_MODEL_FIELD_TYPES[field] || []).includes(valueType(value)))
|
|
366
|
+
issues.push(`codex_lb_model_catalog_field_type_invalid:${index}:${field}`);
|
|
367
|
+
}
|
|
368
|
+
if (typeof row.slug === 'string' && !row.slug.trim())
|
|
369
|
+
issues.push(`codex_lb_model_catalog_field_empty:${index}:slug`);
|
|
370
|
+
if (typeof row.display_name === 'string' && !row.display_name.trim())
|
|
371
|
+
issues.push(`codex_lb_model_catalog_field_empty:${index}:display_name`);
|
|
372
|
+
if (Array.isArray(row.supported_reasoning_levels) && row.supported_reasoning_levels.some((entry) => !isPlainObject(entry) || typeof entry.effort !== 'string' || !entry.effort.trim())) {
|
|
373
|
+
issues.push(`codex_lb_model_catalog_reasoning_level_invalid:${index}`);
|
|
374
|
+
}
|
|
375
|
+
return issues;
|
|
376
|
+
}
|
|
377
|
+
function catalogTransportBlocker(baseUrl) {
|
|
378
|
+
const blocker = codexLbBaseUrlSecurityBlocker(baseUrl);
|
|
379
|
+
if (blocker)
|
|
380
|
+
return blocker;
|
|
381
|
+
try {
|
|
382
|
+
const url = new URL(baseUrl);
|
|
383
|
+
if (url.search || url.hash)
|
|
384
|
+
return 'codex_lb_base_url_query_or_fragment_forbidden';
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
return 'codex_lb_invalid_base_url';
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function catalogIdentity(baseUrl, apiKey) {
|
|
392
|
+
return {
|
|
393
|
+
origin: new URL(baseUrl).origin,
|
|
394
|
+
base_url_sha256: sha256(baseUrl),
|
|
395
|
+
api_key_sha256: sha256(apiKey),
|
|
396
|
+
contract: 'codex-cli-0.144.1-model-catalog'
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function sameCatalogIdentity(actual, expected) {
|
|
400
|
+
return actual?.origin === expected.origin
|
|
401
|
+
&& actual?.base_url_sha256 === expected.base_url_sha256
|
|
402
|
+
&& actual?.api_key_sha256 === expected.api_key_sha256
|
|
403
|
+
&& actual?.contract === expected.contract;
|
|
404
|
+
}
|
|
405
|
+
function blockedResult(outputPath, blockers) {
|
|
406
|
+
return {
|
|
407
|
+
schema: CODEX_LB_TOOL_CATALOG_SCHEMA,
|
|
408
|
+
generated_at: nowIso(),
|
|
409
|
+
ok: false,
|
|
410
|
+
status: 'blocked',
|
|
411
|
+
path: outputPath,
|
|
412
|
+
exists: false,
|
|
413
|
+
fetched: false,
|
|
414
|
+
required: true,
|
|
415
|
+
model_count: 0,
|
|
416
|
+
gpt56_models: [],
|
|
417
|
+
patched_models: [],
|
|
418
|
+
tools_transport: 'unverified',
|
|
419
|
+
blockers: uniqueBounded(blockers)
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function incompatibleInspection(file, safety, blockers) {
|
|
423
|
+
return {
|
|
424
|
+
schema: CODEX_LB_TOOL_CATALOG_SCHEMA,
|
|
425
|
+
ok: false,
|
|
426
|
+
path: file,
|
|
427
|
+
exists: safety.exists === true,
|
|
428
|
+
updated_at_ms: safety.updated_at_ms || null,
|
|
429
|
+
size_bytes: safety.size_bytes || 0,
|
|
430
|
+
mode: safety.mode || null,
|
|
431
|
+
owner_uid: safety.owner_uid ?? null,
|
|
432
|
+
metadata_path: codexLbToolCatalogMetadataPath(file),
|
|
433
|
+
identity_verified: false,
|
|
434
|
+
cache_origin: null,
|
|
435
|
+
model_count: 0,
|
|
436
|
+
gpt56_models: [],
|
|
437
|
+
patched_models: [],
|
|
438
|
+
tools_transport: 'unverified',
|
|
439
|
+
blockers: uniqueBounded(blockers)
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function cacheIsFresh(updatedAtMs, now, maxAgeMs) {
|
|
443
|
+
const updated = Number(updatedAtMs);
|
|
444
|
+
const age = now - updated;
|
|
445
|
+
return Number.isFinite(updated) && Number.isFinite(age) && age >= 0 && age <= maxAgeMs;
|
|
446
|
+
}
|
|
447
|
+
function boundedPositiveInt(value, fallback) {
|
|
448
|
+
const parsed = Number(value);
|
|
449
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.max(1, Math.floor(parsed)) : fallback;
|
|
450
|
+
}
|
|
451
|
+
function valueType(value) {
|
|
452
|
+
if (value === null)
|
|
453
|
+
return 'null';
|
|
454
|
+
if (Array.isArray(value))
|
|
455
|
+
return 'array';
|
|
456
|
+
return typeof value === 'object' ? 'object' : typeof value;
|
|
457
|
+
}
|
|
458
|
+
function isPlainObject(value) {
|
|
459
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
460
|
+
}
|
|
461
|
+
function uniqueBounded(values) {
|
|
462
|
+
return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))].slice(0, 64);
|
|
463
|
+
}
|
|
464
|
+
function safeError(error, secrets = []) {
|
|
465
|
+
let text = String(error instanceof Error ? error.message : error || 'unknown');
|
|
466
|
+
for (const secret of secrets.filter((value) => value.length >= 4))
|
|
467
|
+
text = text.split(secret).join('<redacted>');
|
|
468
|
+
return text.replace(/(?:sk|key|token|secret)[-_a-z0-9]*/gi, '<redacted>').slice(0, 300);
|
|
469
|
+
}
|
|
470
|
+
class CatalogFetchError extends Error {
|
|
471
|
+
code;
|
|
472
|
+
constructor(code) {
|
|
473
|
+
super(code);
|
|
474
|
+
this.code = code;
|
|
475
|
+
this.name = 'CatalogFetchError';
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
//# sourceMappingURL=codex-lb-tool-catalog.js.map
|