@harness-mix/cli 0.1.3
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/CHANGELOG.md +19 -0
- package/LICENSE +202 -0
- package/NOTICE +14 -0
- package/README.md +262 -0
- package/Start-Codex.cmd +5 -0
- package/config/codex-desktop-compatibility.json +29 -0
- package/docs/chatgpt-web-sidebar.md +27 -0
- package/docs/cross-platform.md +73 -0
- package/docs/harness-management.md +44 -0
- package/docs/images/codex-desktop-home.png +0 -0
- package/docs/images/codex-desktop-session.png +0 -0
- package/docs/kiro-cursor-integration.md +3 -0
- package/docs/multi-agent-collaboration.md +89 -0
- package/docs/native-acp.md +122 -0
- package/docs/native-codex.md +95 -0
- package/docs/superpowers/specs/2026-09-13-native-hardening-design.md +326 -0
- package/licenses/codex-host-MIT.txt +21 -0
- package/output/native-build/desktop-controller.mjs +1466 -0
- package/output/native-build/harness-mix-appx.exe +0 -0
- package/output/native-build/harness-mix-secret.exe +0 -0
- package/output/native-build/harness-mix-shim.exe +0 -0
- package/output/native-build/renderer-extension.js +29380 -0
- package/package.json +168 -0
- package/scripts/acp-capabilities-probe.cjs +100 -0
- package/scripts/adapters-test.cjs +17 -0
- package/scripts/antigravity-adapter-test.cjs +529 -0
- package/scripts/architecture-test.cjs +62 -0
- package/scripts/build-native.cjs +56 -0
- package/scripts/catalog-test.cjs +25 -0
- package/scripts/cdp-eval.cjs +40 -0
- package/scripts/cdp-watch.cjs +36 -0
- package/scripts/check.cjs +23 -0
- package/scripts/codebuddy-migration-test.cjs +47 -0
- package/scripts/codex-adapter-test.cjs +83 -0
- package/scripts/collaboration-recovery-test.cjs +111 -0
- package/scripts/collaboration-test.cjs +108 -0
- package/scripts/collaboration-ui-smoke.cjs +57 -0
- package/scripts/concurrency-layers-test.cjs +181 -0
- package/scripts/contracts-test.cjs +105 -0
- package/scripts/core-concurrency-test.cjs +103 -0
- package/scripts/core-replay-test.cjs +179 -0
- package/scripts/core-runtime-test.cjs +104 -0
- package/scripts/core-services-test.cjs +50 -0
- package/scripts/determinism-test.cjs +36 -0
- package/scripts/diagnostics.cjs +63 -0
- package/scripts/docs-command-test.cjs +49 -0
- package/scripts/dsh-adapter-test.cjs +90 -0
- package/scripts/dsh-collaboration-acp-test.cjs +19 -0
- package/scripts/dsh-native.cjs +9 -0
- package/scripts/dsh-native.cmd +2 -0
- package/scripts/e2e-codex.cjs +82 -0
- package/scripts/e2e-collaboration.cjs +60 -0
- package/scripts/e2e-core-files.cjs +58 -0
- package/scripts/e2e-core-fork.cjs +49 -0
- package/scripts/e2e-core-resume.cjs +49 -0
- package/scripts/e2e-delegate.cjs +38 -0
- package/scripts/e2e-dsh.cjs +23 -0
- package/scripts/e2e-native-acp.cjs +42 -0
- package/scripts/e2e-native-commands.cjs +54 -0
- package/scripts/e2e-native-host.cjs +144 -0
- package/scripts/e2e-openclaw-image.cjs +59 -0
- package/scripts/e2e-openclaw.cjs +21 -0
- package/scripts/e2e-pi.cjs +23 -0
- package/scripts/e2e-shadow.cjs +52 -0
- package/scripts/fixture-capture.cjs +103 -0
- package/scripts/harness-health-check.cjs +72 -0
- package/scripts/kiro-cursor-adapters-test.cjs +82 -0
- package/scripts/launch-codex.cjs +5 -0
- package/scripts/native-acp-depth-test.cjs +189 -0
- package/scripts/native-compatibility-test.cjs +42 -0
- package/scripts/native-config-test.cjs +25 -0
- package/scripts/native-file-change-test.cjs +94 -0
- package/scripts/native-host.cjs +8 -0
- package/scripts/native-images-test.cjs +56 -0
- package/scripts/native-job-object-test.cjs +83 -0
- package/scripts/native-protocol-test.cjs +258 -0
- package/scripts/native-rollback-test.cjs +46 -0
- package/scripts/native-secret-test.cjs +57 -0
- package/scripts/native-shim-test.cjs +41 -0
- package/scripts/native-sidebar-test.cjs +88 -0
- package/scripts/native-ui-smoke.cjs +94 -0
- package/scripts/native-update-apply-test.cjs +215 -0
- package/scripts/native-updater-test.cjs +109 -0
- package/scripts/native-vendor-adapters-test.cjs +88 -0
- package/scripts/openclaw-acp-probe.cjs +39 -0
- package/scripts/openclaw-adapter-test.cjs +180 -0
- package/scripts/openclaw-models-probe.cjs +13 -0
- package/scripts/platform-test.cjs +62 -0
- package/scripts/projector-test.cjs +144 -0
- package/scripts/sequence-test.cjs +57 -0
- package/scripts/shadow-test.cjs +154 -0
- package/scripts/support/legacy-projection.cjs +95 -0
- package/scripts/support/legacy-transcript.cjs +48 -0
- package/scripts/support/parity-observer.cjs +27 -0
- package/scripts/support/shadow-comparator.cjs +62 -0
- package/scripts/support/shadow.cjs +114 -0
- package/scripts/switch-harness-test.cjs +145 -0
- package/scripts/thread-title-test.cjs +98 -0
- package/scripts/tool-concurrency-regression-test.cjs +119 -0
- package/scripts/transcript-test.cjs +24 -0
- package/scripts/turn-manager-test.cjs +91 -0
- package/scripts/workspace-test.cjs +86 -0
- package/src/assets/brand-harness-mix.png +0 -0
- package/src/assets/icons/antigravity-color.svg +1 -0
- package/src/assets/icons/claude-color.svg +1 -0
- package/src/assets/icons/codebuddy-color.svg +1 -0
- package/src/assets/icons/codex-color.svg +1 -0
- package/src/assets/icons/codex-harness.svg +1 -0
- package/src/assets/icons/cursor-cli-color.svg +1 -0
- package/src/assets/icons/cursor.svg +1 -0
- package/src/assets/icons/deepseek-color.svg +1 -0
- package/src/assets/icons/grok-color.svg +1 -0
- package/src/assets/icons/hermes-color.svg +1 -0
- package/src/assets/icons/kiro-cli-color.svg +11 -0
- package/src/assets/icons/model-astra.svg +1 -0
- package/src/assets/icons/model-claude.svg +1 -0
- package/src/assets/icons/model-deepseek.svg +1 -0
- package/src/assets/icons/model-gemini.svg +1 -0
- package/src/assets/icons/model-grok.svg +1 -0
- package/src/assets/icons/model-hunyuan.svg +1 -0
- package/src/assets/icons/model-kimi.svg +1 -0
- package/src/assets/icons/model-minimax.svg +1 -0
- package/src/assets/icons/model-openai.svg +1 -0
- package/src/assets/icons/model-qwen-color.svg +1 -0
- package/src/assets/icons/model-xiaomimimo.svg +1 -0
- package/src/assets/icons/model-zai.svg +1 -0
- package/src/assets/icons/omp-color.svg +1 -0
- package/src/assets/icons/openclaw-color.svg +1 -0
- package/src/assets/icons/opencode-color.svg +1 -0
- package/src/assets/icons/pi.svg +1 -0
- package/src/assets/icons/pinumber1_80899.svg +48 -0
- package/src/assets/icons/qoder-color.svg +1 -0
- package/src/assets/icons/trae-color.svg +1 -0
- package/src/assets/icons/workbuddy-color.svg +1 -0
- package/src/assets/icons/zcode-color.svg +1 -0
- package/src/main/adapters/acp-interactions.js +132 -0
- package/src/main/adapters/acp.js +191 -0
- package/src/main/adapters/antigravity.js +1368 -0
- package/src/main/adapters/claude.js +520 -0
- package/src/main/adapters/codebuddy-history.js +90 -0
- package/src/main/adapters/codebuddy.js +2 -0
- package/src/main/adapters/codex-app-server.js +119 -0
- package/src/main/adapters/codex.js +559 -0
- package/src/main/adapters/cursor.js +2 -0
- package/src/main/adapters/dsh-web-host.js +202 -0
- package/src/main/adapters/dsh.js +446 -0
- package/src/main/adapters/grok.js +277 -0
- package/src/main/adapters/hermes.js +24 -0
- package/src/main/adapters/index.js +32 -0
- package/src/main/adapters/kiro-history.js +43 -0
- package/src/main/adapters/kiro.js +2 -0
- package/src/main/adapters/native-acp-command.js +47 -0
- package/src/main/adapters/native-acp.js +435 -0
- package/src/main/adapters/omp.js +12 -0
- package/src/main/adapters/openclaw-gateway.js +211 -0
- package/src/main/adapters/openclaw.js +337 -0
- package/src/main/adapters/opencode-server.js +73 -0
- package/src/main/adapters/opencode.js +178 -0
- package/src/main/adapters/pi-family.js +342 -0
- package/src/main/adapters/pi-usage.js +24 -0
- package/src/main/adapters/pi.js +10 -0
- package/src/main/adapters/qoder.js +7 -0
- package/src/main/adapters/trae.js +7 -0
- package/src/main/adapters/workbuddy.js +2 -0
- package/src/main/adapters/zcode.js +7 -0
- package/src/main/harness-adapter/contract-test.js +53 -0
- package/src/main/harness-adapter/contract.js +34 -0
- package/src/main/harness-adapter/event-normalizer.js +252 -0
- package/src/main/harness-adapter/fixture-recorder.js +56 -0
- package/src/main/harness-adapter/index.js +6 -0
- package/src/main/harness-adapter/manifest.js +44 -0
- package/src/main/host/collaboration-mcp.cjs +35 -0
- package/src/main/host/collaboration-pi.mjs +17 -0
- package/src/main/host/collaboration-tools.js +16 -0
- package/src/main/host/collaboration-worktree.js +151 -0
- package/src/main/host/collaboration.js +264 -0
- package/src/main/host/core-session.js +81 -0
- package/src/main/host/handoff.js +46 -0
- package/src/main/host/history-import.js +55 -0
- package/src/main/host/jsonl.js +116 -0
- package/src/main/host/native-history.js +79 -0
- package/src/main/host/runtime.js +1050 -0
- package/src/main/host/session-history.js +63 -0
- package/src/main/host/store.js +75 -0
- package/src/main/native/compatibility.js +56 -0
- package/src/main/native/config.js +55 -0
- package/src/main/native/host.js +153 -0
- package/src/main/native/icons.js +105 -0
- package/src/main/native/input.js +43 -0
- package/src/main/native/launcher.js +188 -0
- package/src/main/native/platform.js +64 -0
- package/src/main/native/process-utils.js +57 -0
- package/src/main/native/protocol.js +836 -0
- package/src/main/native/redact.js +35 -0
- package/src/main/native/rs/Cargo.lock +15 -0
- package/src/main/native/rs/Cargo.toml +9 -0
- package/src/main/native/rs/crates/appx/Cargo.toml +13 -0
- package/src/main/native/rs/crates/appx/src/main.rs +309 -0
- package/src/main/native/rs/crates/secret/Cargo.toml +10 -0
- package/src/main/native/rs/crates/secret/src/main.rs +262 -0
- package/src/main/native/rs/crates/shim/Cargo.toml +10 -0
- package/src/main/native/rs/crates/shim/src/job.rs +83 -0
- package/src/main/native/rs/crates/shim/src/main.rs +257 -0
- package/src/main/native/secure-store.js +59 -0
- package/src/main/native/thread-list.js +38 -0
- package/src/main/native/update-state.js +110 -0
- package/src/main/native/updater.js +394 -0
- package/src/main/native/usage.js +105 -0
- package/src/main/protocol-core/capability-manager.js +16 -0
- package/src/main/protocol-core/event-router.js +32 -0
- package/src/main/protocol-core/file-change-projector.js +45 -0
- package/src/main/protocol-core/index.js +8 -0
- package/src/main/protocol-core/interaction-router.js +30 -0
- package/src/main/protocol-core/projector.js +238 -0
- package/src/main/protocol-core/protocol-core.js +132 -0
- package/src/main/protocol-core/sequence-validator.js +44 -0
- package/src/main/protocol-core/thread-manager.js +50 -0
- package/src/main/protocol-core/turn-manager.js +63 -0
- package/src/main/shared-contracts/capability.js +35 -0
- package/src/main/shared-contracts/event.js +55 -0
- package/src/main/shared-contracts/ids.js +12 -0
- package/src/main/shared-contracts/index.js +11 -0
- package/src/main/shared-contracts/interaction.js +37 -0
- package/src/main/shared-contracts/item.js +51 -0
- package/src/main/shared-contracts/native-ref.js +24 -0
- package/src/main/shared-contracts/thread.js +36 -0
- package/src/main/shared-contracts/turn.js +54 -0
- package/src/main/workspace/core-review.js +53 -0
- package/src/main/workspace/diff.js +27 -0
- package/src/main/workspace/file-changes.js +21 -0
- package/src/main/workspace/files.js +76 -0
- package/src/main/workspace/review-controller.js +102 -0
- package/src/main/workspace/review.js +88 -0
- package/src/native-ui/LICENSE +21 -0
- package/src/native-ui/README.md +16 -0
- package/src/native-ui/desktop-control/dist/cdp-client.d.ts +53 -0
- package/src/native-ui/desktop-control/dist/cdp-client.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/cdp-client.js +258 -0
- package/src/native-ui/desktop-control/dist/cdp-client.js.map +1 -0
- package/src/native-ui/desktop-control/dist/contract-audit.d.ts +73 -0
- package/src/native-ui/desktop-control/dist/contract-audit.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/contract-audit.js +152 -0
- package/src/native-ui/desktop-control/dist/contract-audit.js.map +1 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.d.ts +10 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.js +77 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.js.map +1 -0
- package/src/native-ui/desktop-control/dist/index.d.ts +21 -0
- package/src/native-ui/desktop-control/dist/index.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/index.js +14 -0
- package/src/native-ui/desktop-control/dist/index.js.map +1 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.d.ts +24 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.js +284 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.js.map +1 -0
- package/src/native-ui/desktop-control/dist/production-controller.d.ts +32 -0
- package/src/native-ui/desktop-control/dist/production-controller.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/production-controller.js +294 -0
- package/src/native-ui/desktop-control/dist/production-controller.js.map +1 -0
- package/src/native-ui/desktop-control/dist/release-main.d.ts +2 -0
- package/src/native-ui/desktop-control/dist/release-main.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/release-main.js +17 -0
- package/src/native-ui/desktop-control/dist/release-main.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.d.ts +49 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js +214 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.d.ts +79 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.js +366 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.d.ts +24 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.js +110 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.d.ts +20 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.js +173 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.d.ts +38 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js +637 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js.map +1 -0
- package/src/native-ui/desktop-control/dist/tsconfig.tsbuildinfo +1 -0
- package/src/native-ui/desktop-control/package.json +22 -0
- package/src/native-ui/desktop-control/scripts/build-release.mjs +94 -0
- package/src/native-ui/desktop-control/src/cdp-client.ts +347 -0
- package/src/native-ui/desktop-control/src/contract-audit.ts +291 -0
- package/src/native-ui/desktop-control/src/controller-attachment-server.ts +93 -0
- package/src/native-ui/desktop-control/src/index.ts +91 -0
- package/src/native-ui/desktop-control/src/main-process-title-policy.ts +372 -0
- package/src/native-ui/desktop-control/src/production-controller.ts +347 -0
- package/src/native-ui/desktop-control/src/release-main.ts +18 -0
- package/src/native-ui/desktop-control/src/renderer-cdp-control-session.ts +358 -0
- package/src/native-ui/desktop-control/src/renderer-control-session.ts +595 -0
- package/src/native-ui/desktop-control/src/renderer-dom.ts +144 -0
- package/src/native-ui/desktop-control/src/renderer-draft-prewarm-policy.ts +217 -0
- package/src/native-ui/desktop-control/src/renderer-draft-prewarm-runtime.ts +749 -0
- package/src/native-ui/desktop-control/test/cdp-client.test.ts +157 -0
- package/src/native-ui/desktop-control/test/contract-audit.test.ts +56 -0
- package/src/native-ui/desktop-control/test/controller-attachment-server.test.ts +98 -0
- package/src/native-ui/desktop-control/test/index.test.ts +11 -0
- package/src/native-ui/desktop-control/test/main-process-title-policy.test.ts +168 -0
- package/src/native-ui/desktop-control/test/production-controller.test.ts +392 -0
- package/src/native-ui/desktop-control/test/renderer-cdp-control-session.test.ts +205 -0
- package/src/native-ui/desktop-control/test/renderer-control-session.test.ts +451 -0
- package/src/native-ui/desktop-control/test/renderer-dom.test.ts +62 -0
- package/src/native-ui/desktop-control/test/renderer-draft-prewarm-policy.test.ts +1029 -0
- package/src/native-ui/desktop-control/tsconfig.json +12 -0
- package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts +39 -0
- package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts +85 -0
- package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/audit-entry.d.ts +2 -0
- package/src/native-ui/renderer-extension/dist/types/audit-entry.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/codex-locale-adapter.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/codex-locale-adapter.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/collaboration-icon.d.ts +2 -0
- package/src/native-ui/renderer-extension/dist/types/collaboration-icon.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts +37 -0
- package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-icons.d.ts +3 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-icons.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-settings.d.ts +3 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-settings.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/index.d.ts +51 -0
- package/src/native-ui/renderer-extension/dist/types/index.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/install-renderer-binding.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/install-renderer-binding.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/probe-entry.d.ts +2 -0
- package/src/native-ui/renderer-extension/dist/types/probe-entry.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts +62 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts +70 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts +34 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts +19 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts +40 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts +82 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts +21 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-external-steering.d.ts +7 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-external-steering.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts +34 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts +15 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts +25 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +102 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker-positioning.d.ts +22 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker-positioning.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts +54 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts +18 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts +42 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts +12 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts +18 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts +45 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts +3 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts +72 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts +24 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts +18 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts +27 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts +44 -0
- package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/core.d.ts +38 -0
- package/src/native-ui/renderer-extension/dist/types/settings/core.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts +21 -0
- package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts +6 -0
- package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts +247 -0
- package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/release-notes.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/settings/release-notes.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts +12 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts +8 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts +24 -0
- package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts +45 -0
- package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/update-request.d.ts +6 -0
- package/src/native-ui/renderer-extension/dist/types/settings/update-request.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -0
- package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts +143 -0
- package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/package.json +22 -0
- package/src/native-ui/renderer-extension/src/agent-group-preference.ts +174 -0
- package/src/native-ui/renderer-extension/src/agent-selection-state.ts +627 -0
- package/src/native-ui/renderer-extension/src/assets/README.md +13 -0
- package/src/native-ui/renderer-extension/src/assets/antigravity-agent.svg +1 -0
- package/src/native-ui/renderer-extension/src/assets/codex-agent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/grok-agent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/kiro-agent.svg +11 -0
- package/src/native-ui/renderer-extension/src/assets/omp-agent.svg +14 -0
- package/src/native-ui/renderer-extension/src/assets/opencode-agent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets.d.ts +26 -0
- package/src/native-ui/renderer-extension/src/audit-entry.ts +5 -0
- package/src/native-ui/renderer-extension/src/codex-locale-adapter.ts +321 -0
- package/src/native-ui/renderer-extension/src/collaboration-icon.ts +13 -0
- package/src/native-ui/renderer-extension/src/contract-audit.ts +102 -0
- package/src/native-ui/renderer-extension/src/harness-mix-icons.ts +31 -0
- package/src/native-ui/renderer-extension/src/harness-mix-settings.ts +88 -0
- package/src/native-ui/renderer-extension/src/index.ts +275 -0
- package/src/native-ui/renderer-extension/src/install-renderer-binding.ts +30 -0
- package/src/native-ui/renderer-extension/src/probe-entry.ts +4 -0
- package/src/native-ui/renderer-extension/src/production-entry.ts +23 -0
- package/src/native-ui/renderer-extension/src/renderer-agent-icon.ts +146 -0
- package/src/native-ui/renderer-extension/src/renderer-agent-picker.ts +814 -0
- package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +3002 -0
- package/src/native-ui/renderer-extension/src/renderer-codex-account-options.ts +281 -0
- package/src/native-ui/renderer-extension/src/renderer-codex-account-state.ts +53 -0
- package/src/native-ui/renderer-extension/src/renderer-collab-cards.ts +198 -0
- package/src/native-ui/renderer-extension/src/renderer-composer-dom.ts +782 -0
- package/src/native-ui/renderer-extension/src/renderer-credits-control.ts +520 -0
- package/src/native-ui/renderer-extension/src/renderer-external-steering.ts +339 -0
- package/src/native-ui/renderer-extension/src/renderer-fork-control.ts +273 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-command-claim.ts +64 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-command-control.ts +417 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-localization.ts +144 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-mentions.ts +306 -0
- package/src/native-ui/renderer-extension/src/renderer-model-client.ts +572 -0
- package/src/native-ui/renderer-extension/src/renderer-model-picker-positioning.ts +65 -0
- package/src/native-ui/renderer-extension/src/renderer-model-picker.ts +640 -0
- package/src/native-ui/renderer-extension/src/renderer-new-thread-preference.ts +177 -0
- package/src/native-ui/renderer-extension/src/renderer-permission-mode-picker.ts +413 -0
- package/src/native-ui/renderer-extension/src/renderer-permission-mode-preference.ts +49 -0
- package/src/native-ui/renderer-extension/src/renderer-request-sender.ts +43 -0
- package/src/native-ui/renderer-extension/src/renderer-session-import-client.ts +68 -0
- package/src/native-ui/renderer-extension/src/renderer-settings-lifecycle.ts +239 -0
- package/src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts +457 -0
- package/src/native-ui/renderer-extension/src/renderer-transcript-dom.ts +47 -0
- package/src/native-ui/renderer-extension/src/renderer-trigger-chip-style.ts +52 -0
- package/src/native-ui/renderer-extension/src/renderer-usage-control.ts +633 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-list.ts +236 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-page.ts +585 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-usage.ts +221 -0
- package/src/native-ui/renderer-extension/src/settings/accounts.css +683 -0
- package/src/native-ui/renderer-extension/src/settings/connections-page.ts +1394 -0
- package/src/native-ui/renderer-extension/src/settings/core.ts +158 -0
- package/src/native-ui/renderer-extension/src/settings/harness-accounts.ts +195 -0
- package/src/native-ui/renderer-extension/src/settings/icons.ts +141 -0
- package/src/native-ui/renderer-extension/src/settings/localization.ts +800 -0
- package/src/native-ui/renderer-extension/src/settings/pages.ts +632 -0
- package/src/native-ui/renderer-extension/src/settings/release-notes.ts +222 -0
- package/src/native-ui/renderer-extension/src/settings/session-import-list-controls.ts +128 -0
- package/src/native-ui/renderer-extension/src/settings/session-import-page.ts +461 -0
- package/src/native-ui/renderer-extension/src/settings/shell.css +2238 -0
- package/src/native-ui/renderer-extension/src/settings/shell.ts +329 -0
- package/src/native-ui/renderer-extension/src/settings/trigger.ts +323 -0
- package/src/native-ui/renderer-extension/src/settings/update-request.ts +49 -0
- package/src/native-ui/renderer-extension/src/versioned-renderer-adapter.ts +1289 -0
- package/src/native-ui/renderer-extension/test/agent-selection-state.test.ts +611 -0
- package/src/native-ui/renderer-extension/test/codebuddy-migration.test.ts +22 -0
- package/src/native-ui/renderer-extension/test/codex-locale-adapter.test.ts +152 -0
- package/src/native-ui/renderer-extension/test/contract-audit.test.ts +71 -0
- package/src/native-ui/renderer-extension/test/harness-mix-icons.test.ts +58 -0
- package/src/native-ui/renderer-extension/test/index.test.ts +9 -0
- package/src/native-ui/renderer-extension/test/renderer-agent-icon.test.ts +98 -0
- package/src/native-ui/renderer-extension/test/renderer-agent-picker.test.ts +226 -0
- package/src/native-ui/renderer-extension/test/renderer-binding-probe-host-catalog.test.ts +728 -0
- package/src/native-ui/renderer-extension/test/renderer-binding-probe.test.ts +1290 -0
- package/src/native-ui/renderer-extension/test/renderer-codex-account-state.test.ts +65 -0
- package/src/native-ui/renderer-extension/test/renderer-collab-cards.test.ts +45 -0
- package/src/native-ui/renderer-extension/test/renderer-composer-permissions.test.ts +75 -0
- package/src/native-ui/renderer-extension/test/renderer-credits-control.test.ts +70 -0
- package/src/native-ui/renderer-extension/test/renderer-external-steering-rpc.test.ts +184 -0
- package/src/native-ui/renderer-extension/test/renderer-external-steering.test.ts +279 -0
- package/src/native-ui/renderer-extension/test/renderer-fork-control.test.ts +363 -0
- package/src/native-ui/renderer-extension/test/renderer-harness-command-claim.test.ts +167 -0
- package/src/native-ui/renderer-extension/test/renderer-harness-command-control.test.ts +54 -0
- package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +709 -0
- package/src/native-ui/renderer-extension/test/renderer-model-picker.test.ts +302 -0
- package/src/native-ui/renderer-extension/test/renderer-native-thread-ownership.test.ts +84 -0
- package/src/native-ui/renderer-extension/test/renderer-new-thread-preference.test.ts +81 -0
- package/src/native-ui/renderer-extension/test/renderer-permission-mode-picker.test.ts +269 -0
- package/src/native-ui/renderer-extension/test/renderer-permission-mode-preference.test.ts +48 -0
- package/src/native-ui/renderer-extension/test/renderer-settings-lifecycle.test.ts +156 -0
- package/src/native-ui/renderer-extension/test/renderer-sidebar-agent-icons.test.ts +575 -0
- package/src/native-ui/renderer-extension/test/renderer-unsupported-methods.test.ts +167 -0
- package/src/native-ui/renderer-extension/test/renderer-usage-control.test.ts +96 -0
- package/src/native-ui/renderer-extension/test/settings/accounts-usage.test.ts +208 -0
- package/src/native-ui/renderer-extension/test/settings/core.test.ts +145 -0
- package/src/native-ui/renderer-extension/test/settings/harness-settings.test.ts +92 -0
- package/src/native-ui/renderer-extension/test/settings/localization.test.ts +80 -0
- package/src/native-ui/renderer-extension/test/settings/pages.test.ts +2000 -0
- package/src/native-ui/renderer-extension/test/settings/release-notes.test.ts +163 -0
- package/src/native-ui/renderer-extension/test/settings/shell.test.ts +74 -0
- package/src/native-ui/renderer-extension/test/settings/trigger.test.ts +270 -0
- package/src/native-ui/renderer-extension/test/settings/update-request.test.ts +48 -0
- package/src/native-ui/renderer-extension/test/versioned-renderer-adapter.test.ts +695 -0
- package/src/native-ui/renderer-extension/tsconfig.json +15 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.d.ts +246 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.js +99 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.d.ts +37 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.js +36 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/errors.d.ts +17 -0
- package/src/native-ui/shared-contracts/dist/errors.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/errors.js +14 -0
- package/src/native-ui/shared-contracts/dist/errors.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.d.ts +11 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.js +14 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.d.ts +78 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.js +27 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.d.ts +46 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.js +61 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-models.d.ts +300 -0
- package/src/native-ui/shared-contracts/dist/harness-models.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-models.js +318 -0
- package/src/native-ui/shared-contracts/dist/harness-models.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.d.ts +30 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.js +57 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.d.ts +56 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.js +75 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-route.d.ts +16 -0
- package/src/native-ui/shared-contracts/dist/harness-route.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-route.js +42 -0
- package/src/native-ui/shared-contracts/dist/harness-route.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts +54 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.js +72 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/ids.d.ts +12 -0
- package/src/native-ui/shared-contracts/dist/ids.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/ids.js +10 -0
- package/src/native-ui/shared-contracts/dist/ids.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/index.d.ts +47 -0
- package/src/native-ui/shared-contracts/dist/index.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/index.js +29 -0
- package/src/native-ui/shared-contracts/dist/index.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.d.ts +84 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.js +65 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-value.d.ts +13 -0
- package/src/native-ui/shared-contracts/dist/json-value.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-value.js +60 -0
- package/src/native-ui/shared-contracts/dist/json-value.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/native-refs.d.ts +43 -0
- package/src/native-ui/shared-contracts/dist/native-refs.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/native-refs.js +35 -0
- package/src/native-ui/shared-contracts/dist/native-refs.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.d.ts +7 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.js +7 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.d.ts +22 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.js +30 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts +16 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.js +19 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.d.ts +106 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.js +103 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/tsconfig.tsbuildinfo +1 -0
- package/src/native-ui/shared-contracts/dist/updates.d.ts +128 -0
- package/src/native-ui/shared-contracts/dist/updates.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/updates.js +58 -0
- package/src/native-ui/shared-contracts/dist/updates.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/version.d.ts +2 -0
- package/src/native-ui/shared-contracts/dist/version.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/version.js +2 -0
- package/src/native-ui/shared-contracts/dist/version.js.map +1 -0
- package/src/native-ui/shared-contracts/package.json +25 -0
- package/src/native-ui/shared-contracts/src/codex-accounts.ts +140 -0
- package/src/native-ui/shared-contracts/src/deepseek-modern-sessions.ts +67 -0
- package/src/native-ui/shared-contracts/src/errors.ts +25 -0
- package/src/native-ui/shared-contracts/src/external-thread-fork.ts +20 -0
- package/src/native-ui/shared-contracts/src/harness-accounts.ts +32 -0
- package/src/native-ui/shared-contracts/src/harness-commands.ts +81 -0
- package/src/native-ui/shared-contracts/src/harness-models.ts +406 -0
- package/src/native-ui/shared-contracts/src/harness-permission-modes.ts +73 -0
- package/src/native-ui/shared-contracts/src/harness-plugins.ts +96 -0
- package/src/native-ui/shared-contracts/src/harness-route.ts +47 -0
- package/src/native-ui/shared-contracts/src/harness-session-import.ts +90 -0
- package/src/native-ui/shared-contracts/src/ids.ts +20 -0
- package/src/native-ui/shared-contracts/src/index.ts +320 -0
- package/src/native-ui/shared-contracts/src/json-rpc.ts +80 -0
- package/src/native-ui/shared-contracts/src/json-value.ts +78 -0
- package/src/native-ui/shared-contracts/src/native-refs.ts +58 -0
- package/src/native-ui/shared-contracts/src/reasoning-transcript.ts +6 -0
- package/src/native-ui/shared-contracts/src/thread-delegate.ts +40 -0
- package/src/native-ui/shared-contracts/src/thread-harness-switch.ts +25 -0
- package/src/native-ui/shared-contracts/src/thread-usage.ts +126 -0
- package/src/native-ui/shared-contracts/src/updates.ts +78 -0
- package/src/native-ui/shared-contracts/src/version.ts +1 -0
- package/src/native-ui/shared-contracts/test/browser-bundle.test.ts +36 -0
- package/src/native-ui/shared-contracts/test/deepseek-modern-sessions.test.ts +120 -0
- package/src/native-ui/shared-contracts/test/errors.test.ts +72 -0
- package/src/native-ui/shared-contracts/test/harness-commands.test.ts +64 -0
- package/src/native-ui/shared-contracts/test/harness-models.test.ts +390 -0
- package/src/native-ui/shared-contracts/test/harness-permission-modes.test.ts +134 -0
- package/src/native-ui/shared-contracts/test/harness-plugins.test.ts +113 -0
- package/src/native-ui/shared-contracts/test/harness-session-import.test.ts +117 -0
- package/src/native-ui/shared-contracts/test/ids.test.ts +69 -0
- package/src/native-ui/shared-contracts/test/index.test.ts +80 -0
- package/src/native-ui/shared-contracts/test/json-rpc.test.ts +177 -0
- package/src/native-ui/shared-contracts/test/json-value.test.ts +62 -0
- package/src/native-ui/shared-contracts/test/native-refs.test.ts +95 -0
- package/src/native-ui/shared-contracts/test/thread-usage.test.ts +115 -0
- package/src/native-ui/shared-contracts/test/updates.test.ts +120 -0
- package/src/native-ui/shared-contracts/tsconfig.json +10 -0
- package/src/tsconfig.base.json +19 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const { ParityObserver } = require('./support/parity-observer.cjs');
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const os = require('node:os');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
const { HostRuntime } = require('../src/main/host/runtime');
|
|
7
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
8
|
+
async function until(fn) {
|
|
9
|
+
for (let i = 0; i < 200; i++) { if (fn()) return; await sleep(10); }
|
|
10
|
+
throw new Error('timed out');
|
|
11
|
+
}
|
|
12
|
+
(async () => {
|
|
13
|
+
const directory = await fs.mkdtemp(path.join(os.tmpdir(), 'hm-core-runtime-'));
|
|
14
|
+
const root = path.join(directory, 'workspace'); await fs.mkdir(root);
|
|
15
|
+
const rt = new HostRuntime({ observer: new ParityObserver(), dataDirectory: directory });
|
|
16
|
+
await rt.store.load();
|
|
17
|
+
let emit, sent = 0, mode = 'hold', rejectResponse = false;
|
|
18
|
+
const adapter = {
|
|
19
|
+
manifest: { id: 'test-harness', name: 'Test', capabilities: {} },
|
|
20
|
+
async open(input) { emit = input.emit; return {}; },
|
|
21
|
+
async send() {
|
|
22
|
+
sent++;
|
|
23
|
+
const turn = rt.execution.lastTurn(thread.id);
|
|
24
|
+
assert.equal(turn.status, 'running', 'Core Turn exists before native send');
|
|
25
|
+
if (mode === 'failure') throw new Error('native failure');
|
|
26
|
+
},
|
|
27
|
+
async cancel() { emit({ kind: 'completed', finalAnswer: true }); emit({ kind: 'text-delta', text: 'LATE' }); },
|
|
28
|
+
async respond() { if (rejectResponse) throw new Error('response failed'); },
|
|
29
|
+
async close() {},
|
|
30
|
+
};
|
|
31
|
+
rt.adapters.set(adapter.manifest.id, adapter); rt.status[adapter.manifest.id] = { available: true };
|
|
32
|
+
const thread = await rt.createThread({ harnessId: adapter.manifest.id, cwd: root });
|
|
33
|
+
try {
|
|
34
|
+
await rt.send(thread.id, 'hello');
|
|
35
|
+
const first = thread.messages.at(-1).coreTurnId;
|
|
36
|
+
const notices = []; const unsubscribe = rt.subscribe(event => notices.push(event));
|
|
37
|
+
emit({ kind: 'status', text: 'native progress' });
|
|
38
|
+
assert.ok(notices.some(event => event.type === 'toast' && event.threadId === thread.id));
|
|
39
|
+
unsubscribe();
|
|
40
|
+
emit({ kind: 'approval', requestId: 'a', method: 'confirm', title: 'Allow?' });
|
|
41
|
+
emit({ kind: 'approval', requestId: 'q', method: 'input', title: 'Name?' });
|
|
42
|
+
assert.equal(rt.execution.lastTurn(thread.id).status, 'waiting_interaction');
|
|
43
|
+
rejectResponse = true;
|
|
44
|
+
await assert.rejects(rt.respondApproval(thread.id, 'a', {}), /response failed/);
|
|
45
|
+
assert.equal(rt.execution.lastTurn(thread.id).status, 'waiting_interaction');
|
|
46
|
+
rejectResponse = false;
|
|
47
|
+
await rt.respondApproval(thread.id, 'a', { confirmed: true });
|
|
48
|
+
assert.equal(rt.execution.lastTurn(thread.id).status, 'waiting_interaction');
|
|
49
|
+
await rt.respondApproval(thread.id, 'q', { value: 'test' });
|
|
50
|
+
assert.equal(rt.execution.lastTurn(thread.id).status, 'running');
|
|
51
|
+
emit({ kind: 'thinking-delta', text: 'think' });
|
|
52
|
+
emit({ kind: 'text-delta', text: 'answer' });
|
|
53
|
+
emit({ kind: 'usage', usage: { inputTokens: 10 } });
|
|
54
|
+
await fs.writeFile(path.join(root, 'change.txt'), 'Core review content');
|
|
55
|
+
emit({ kind: 'completed', finalAnswer: true });
|
|
56
|
+
await until(() => (thread.status === 'ready' && !thread.reviewPending));
|
|
57
|
+
assert.equal(thread.messages.at(-1).coreTurn.status, 'completed');
|
|
58
|
+
const completedMessage = thread.messages.at(-1);
|
|
59
|
+
const review = await rt.readReview(thread, completedMessage);
|
|
60
|
+
assert.equal(review.files[0].type, 'file_change');
|
|
61
|
+
assert.equal(review.files[0].source, 'snapshot');
|
|
62
|
+
assert.equal((await rt.readReview(thread, completedMessage, 'change.txt')).rows[0].kind, 'add');
|
|
63
|
+
await rt.undoFile(thread.id, completedMessage.id, 'change.txt');
|
|
64
|
+
assert.equal(completedMessage.coreReview.files[0].undone, true);
|
|
65
|
+
await assert.rejects(fs.access(path.join(root, 'change.txt')));
|
|
66
|
+
assert.ok(thread.messages.at(-1).coreItems.some(i => i.phase === 'final' && i.content === 'answer'));
|
|
67
|
+
assert.deepEqual(rt.shadowReport().mismatches, []);
|
|
68
|
+
await rt.send(thread.id, 'cancel');
|
|
69
|
+
assert.notEqual(thread.messages.at(-1).coreTurnId, first);
|
|
70
|
+
await rt.cancel(thread.id);
|
|
71
|
+
await until(() => (thread.status === 'ready' && !thread.reviewPending));
|
|
72
|
+
assert.equal(thread.messages.at(-1).coreTurn.status, 'cancelled');
|
|
73
|
+
assert.equal(thread.messages.at(-1).text, '');
|
|
74
|
+
mode = 'failure';
|
|
75
|
+
await rt.send(thread.id, 'fail');
|
|
76
|
+
await until(() => thread.status === 'error' && !thread.reviewPending);
|
|
77
|
+
assert.equal(thread.messages.at(-1).coreTurn.status, 'error');
|
|
78
|
+
mode = 'hold';
|
|
79
|
+
let release;
|
|
80
|
+
const begin = rt.reviews.begin.bind(rt.reviews);
|
|
81
|
+
rt.reviews.begin = () => new Promise(resolve => { release = resolve; });
|
|
82
|
+
const before = sent;
|
|
83
|
+
const pending = rt.send(thread.id, 'cancel during preparation');
|
|
84
|
+
await until(() => release);
|
|
85
|
+
await rt.cancel(thread.id);
|
|
86
|
+
release(undefined); await pending;
|
|
87
|
+
await until(() => (thread.status === 'ready' && !thread.reviewPending));
|
|
88
|
+
assert.equal(sent, before);
|
|
89
|
+
assert.equal(thread.messages.at(-1).coreTurn.status, 'cancelled');
|
|
90
|
+
rt.reviews.begin = begin;
|
|
91
|
+
assert.deepEqual(rt.shadowReport().errors, []);
|
|
92
|
+
await rt.close();
|
|
93
|
+
const saved = await rt.store.load();
|
|
94
|
+
assert.equal(saved[0].messages.find(m => m.coreTurnId === first).coreTurn.status, 'completed');
|
|
95
|
+
const restored = new HostRuntime({ dataDirectory: directory });
|
|
96
|
+
restored.threads = await restored.store.load();
|
|
97
|
+
for (const record of restored.threads) restored.execution.threadCreated(record);
|
|
98
|
+
assert.equal(restored.core.getTurn(first).status, 'completed');
|
|
99
|
+
assert.ok(restored.core.getItemsForTurn(first).some(i => i.type === 'file_change' && i.undone));
|
|
100
|
+
assert.equal(restored.shadowReport().enabled, false);
|
|
101
|
+
await restored.close();
|
|
102
|
+
console.log('core-runtime: independent turns, waiting/responses, failure, cancel races, persistence passed');
|
|
103
|
+
} finally { await rt.close(); }
|
|
104
|
+
})().catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const assert = require('node:assert/strict');
|
|
2
|
+
const { ProtocolCore } = require('../src/main/protocol-core');
|
|
3
|
+
const { ShadowMirror } = require('./support/shadow.cjs');
|
|
4
|
+
const { CapabilityManager } = require('../src/main/protocol-core/capability-manager');
|
|
5
|
+
const { normalizeCapabilities } = require('../src/main/harness-adapter/manifest');
|
|
6
|
+
|
|
7
|
+
(async () => {
|
|
8
|
+
const core = new ProtocolCore();
|
|
9
|
+
const shadow = new ShadowMirror({ core });
|
|
10
|
+
const thread = { id: 't', cwd: '/test', messages: [{ role: 'assistant', at: 1 }] };
|
|
11
|
+
shadow.threadCreated(thread); shadow.turnStarted(thread, 'test');
|
|
12
|
+
const turn = shadow.lastTurn('t');
|
|
13
|
+
const emit = e => shadow.applyLegacyEvent(thread, e);
|
|
14
|
+
emit({ kind: 'approval', requestId: 'q', method: 'input', title: 'Question' });
|
|
15
|
+
assert.equal(core.interactions.pending('t').length, 1);
|
|
16
|
+
let release, calls = 0;
|
|
17
|
+
const response = core.interactions.respond('t', 'q', {}, async () => { calls++; await new Promise(resolve => { release = resolve; }); });
|
|
18
|
+
await assert.rejects(core.interactions.respond('t', 'q', {}, () => {}), /正在提交/);
|
|
19
|
+
await assert.rejects(core.interactions.respond('other', 'q', {}, () => {}), /过期/);
|
|
20
|
+
release(); await response;
|
|
21
|
+
assert.equal(calls, 1); assert.equal(turn.status, 'running');
|
|
22
|
+
assert.equal(core.interactions.pending('t').length, 0);
|
|
23
|
+
const files = (source, changes, replace = false) => core.dispatch({ threadId: 't', turnId: turn.id,
|
|
24
|
+
type: 'files.updated', payload: { source, changes, replace } });
|
|
25
|
+
files('snapshot', [{ path: 'a', before: 'x', after: 'y', complete: true }]);
|
|
26
|
+
files('native', [{ path: 'a', patch: 'incomplete', complete: false }]);
|
|
27
|
+
assert.equal(core.getItemsForTurn(turn.id).find(i => i.type === 'file_change').source, 'snapshot');
|
|
28
|
+
files('native', [{ path: 'a', before: 'x', after: 'y', complete: true }]);
|
|
29
|
+
files('snapshot', [{ path: 'a', after: 'other' }]);
|
|
30
|
+
const changes = core.getItemsForTurn(turn.id).filter(i => i.type === 'file_change');
|
|
31
|
+
assert.equal(changes.length, 1); assert.equal(changes[0].source, 'native');
|
|
32
|
+
files('git', [{ path: 'b', after: 'z' }]);
|
|
33
|
+
files('git', [], true);
|
|
34
|
+
assert.equal(core.getItemsForTurn(turn.id).filter(i => i.type === 'file_change').length, 1);
|
|
35
|
+
emit({ kind: 'plan', entries: [{ content: 'Inspect', status: 'in_progress' }] });
|
|
36
|
+
emit({ kind: 'plan', entries: [{ content: 'Inspect', status: 'completed' }] });
|
|
37
|
+
assert.equal(core.getItemsForTurn(turn.id).filter(i => i.type === 'plan').length, 1);
|
|
38
|
+
assert.equal(core.getItemsForTurn(turn.id).find(i => i.type === 'plan').entries[0].status, 'completed');
|
|
39
|
+
core.dispatch({ threadId: 't', turnId: turn.id, type: 'turn.completed' });
|
|
40
|
+
files('snapshot', [{ path: 'c', after: 'settled review' }]);
|
|
41
|
+
assert.ok(core.getItemsForTurn(turn.id).some(i => i.path === 'c'));
|
|
42
|
+
const caps = new CapabilityManager();
|
|
43
|
+
caps.register('new-harness', normalizeCapabilities({ fork: true, questions: true, plan: true }));
|
|
44
|
+
caps.require('new-harness', 'session', 'fork');
|
|
45
|
+
assert.throws(() => caps.require('new-harness', 'model', 'selection'));
|
|
46
|
+
const copy = caps.get('new-harness'); copy.session.fork = false;
|
|
47
|
+
assert.equal(caps.get('new-harness').session.fork, true);
|
|
48
|
+
assert.deepEqual(shadow.report().errors, []);
|
|
49
|
+
console.log('core-services: interaction race/ownership, capability negotiation, native precedence, file replacement and plan passed');
|
|
50
|
+
})().catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const assert = require('node:assert/strict');
|
|
2
|
+
const { ProtocolCore } = require('../src/main/protocol-core');
|
|
3
|
+
|
|
4
|
+
// A captured CoreEvent stream must replay without pre-created objects or a clock.
|
|
5
|
+
const events = [
|
|
6
|
+
{ type: 'thread.created', payload: { workspaceId: '/fixture' } },
|
|
7
|
+
{ type: 'turn.started', turnId: 'native-turn' },
|
|
8
|
+
{ type: 'item.started', turnId: 'native-turn', itemId: 'answer', payload: { type: 'agent_message' } },
|
|
9
|
+
{ type: 'item.delta', turnId: 'native-turn', itemId: 'answer', payload: { text: 'hello' } },
|
|
10
|
+
{ type: 'usage.updated', turnId: 'native-turn', payload: { inputTokens: 12 } },
|
|
11
|
+
{ type: 'usage.updated', turnId: 'native-turn', payload: { outputTokens: 3 } },
|
|
12
|
+
{ type: 'turn.waiting', turnId: 'native-turn' },
|
|
13
|
+
{ type: 'turn.completed', turnId: 'native-turn' },
|
|
14
|
+
].map((e, index) => ({ ...e, threadId: 'thread', eventId: `e${index}`, timestamp: 1000 + index, sequence: index + 1 }));
|
|
15
|
+
function replay(clock) {
|
|
16
|
+
const original = Date.now;
|
|
17
|
+
Date.now = () => clock;
|
|
18
|
+
try {
|
|
19
|
+
const core = new ProtocolCore();
|
|
20
|
+
for (const event of events) core.dispatch(structuredClone(event));
|
|
21
|
+
return structuredClone(core.snapshot());
|
|
22
|
+
} finally { Date.now = original; }
|
|
23
|
+
}
|
|
24
|
+
const first = replay(9000);
|
|
25
|
+
assert.deepEqual(first, replay(999999));
|
|
26
|
+
assert.equal(first.turns[0].id, 'native-turn');
|
|
27
|
+
assert.equal(first.turns[0].startedAt, 1001);
|
|
28
|
+
assert.equal(first.turns[0].completedAt, 1007);
|
|
29
|
+
assert.equal(first.items[0].content, 'hello');
|
|
30
|
+
assert.deepEqual(first.turns[0].itemIds, ['answer', 'usage_native-turn']);
|
|
31
|
+
const core = new ProtocolCore();
|
|
32
|
+
for (const event of events) core.dispatch(structuredClone(event));
|
|
33
|
+
const settled = structuredClone(core.snapshot());
|
|
34
|
+
core.dispatch({ threadId: 'thread', turnId: 'native-turn', itemId: 'answer', type: 'item.updated', payload: { content: 'late rewrite' } });
|
|
35
|
+
assert.deepEqual(core.snapshot().items, settled.items, 'terminal items cannot be rewritten');
|
|
36
|
+
console.log('determinism: exact snapshots and native turn identity passed');
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Bundles versions, update/runtime state and redacted log tails into
|
|
3
|
+
// output/diagnostics-<timestamp>.zip for bug reports. Read-only: touches
|
|
4
|
+
// nothing in the desktop, host or install.
|
|
5
|
+
const fs = require('node:fs');
|
|
6
|
+
const os = require('node:os');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
const { execFileSync } = require('node:child_process');
|
|
9
|
+
const { nativeEnvironment } = require('../src/main/native/config');
|
|
10
|
+
const { redactText } = require('../src/main/native/redact');
|
|
11
|
+
|
|
12
|
+
const root = path.resolve(__dirname, '..');
|
|
13
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
14
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
15
|
+
const stage = fs.mkdtempSync(path.join(os.tmpdir(), 'hm-diagnostics-'));
|
|
16
|
+
const out = path.join(root, 'output');
|
|
17
|
+
fs.mkdirSync(out, { recursive: true });
|
|
18
|
+
|
|
19
|
+
const run = (command, args) => {
|
|
20
|
+
try { return execFileSync(command, args, { encoding: 'utf8', windowsHide: true, timeout: 30000 }).trim(); }
|
|
21
|
+
catch (error) { return `unavailable: ${error.message}`; }
|
|
22
|
+
};
|
|
23
|
+
const tail = (file, lines = 200) => {
|
|
24
|
+
try {
|
|
25
|
+
const rows = fs.readFileSync(file, 'utf8').split('\n');
|
|
26
|
+
return rows.slice(-lines).map(redactText).join('\n');
|
|
27
|
+
} catch { return '(missing)'; }
|
|
28
|
+
};
|
|
29
|
+
const write = (name, content) => fs.writeFileSync(path.join(stage, name), String(content));
|
|
30
|
+
|
|
31
|
+
const env = nativeEnvironment();
|
|
32
|
+
const data = env.CODEXHOST_DATA_DIR;
|
|
33
|
+
write('versions.json', JSON.stringify({
|
|
34
|
+
'harness-mix': pkg.version,
|
|
35
|
+
node: process.version,
|
|
36
|
+
npm: run(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['--version']),
|
|
37
|
+
cargo: run('cargo', ['--version']),
|
|
38
|
+
platform: process.platform,
|
|
39
|
+
os: os.release(),
|
|
40
|
+
check: run(process.execPath, [path.join(root, 'scripts', 'launch-codex.cjs'), '--check']),
|
|
41
|
+
}, null, 2));
|
|
42
|
+
write('update-state.json', tail(path.join(data, 'update-state.json'), 400));
|
|
43
|
+
write('instance.json', tail(path.join(data, 'runtime', 'instance.json'), 400));
|
|
44
|
+
write('host-traffic.tail.jsonl', tail(path.join(data, 'host-traffic.jsonl')));
|
|
45
|
+
write('shim-invocations.tail.log', tail(path.join(root, 'output', 'native-build', 'shim-invocations.log')));
|
|
46
|
+
const crashDir = path.join(data, 'runtime');
|
|
47
|
+
if (fs.existsSync(crashDir)) {
|
|
48
|
+
for (const name of fs.readdirSync(crashDir).filter(entry => entry.startsWith('crash-')).slice(-3)) {
|
|
49
|
+
write(name, tail(path.join(crashDir, name), 400));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const zip = path.join(out, `diagnostics-${stamp}.${process.platform === 'win32' ? 'zip' : 'tar.gz'}`);
|
|
54
|
+
// bsdtar treats "E:\..." as a remote host:path spec, so pack via PowerShell.
|
|
55
|
+
if (process.platform === 'win32') {
|
|
56
|
+
const script = `Compress-Archive -Path '${path.join(stage, '*').replace(/'/g, "''")}' -DestinationPath '${zip.replace(/'/g, "''")}' -Force`;
|
|
57
|
+
run('pwsh.exe', ['-NoLogo', '-NoProfile', '-Command', script]);
|
|
58
|
+
} else {
|
|
59
|
+
run('tar', ['-czf', zip, '-C', stage, '.']);
|
|
60
|
+
}
|
|
61
|
+
if (!fs.existsSync(zip)) throw new Error('诊断打包失败:需要 PowerShell 7 (Windows) 或 tar (macOS/Linux)');
|
|
62
|
+
try { fs.rmSync(stage, { recursive: true, force: true }); } catch { /* leave for inspection */ }
|
|
63
|
+
console.log(`[Harness Mix] 诊断包已生成:${zip}`);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
|
|
4
|
+
const root = path.resolve(__dirname, '..');
|
|
5
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
6
|
+
const scripts = new Set(Object.keys(packageJson.scripts || {}));
|
|
7
|
+
const shellFence = /^(powershell|pwsh|bash|sh|shell|cmd|console)?$/i;
|
|
8
|
+
|
|
9
|
+
function markdownFiles(directory) {
|
|
10
|
+
if (!fs.existsSync(directory)) return [];
|
|
11
|
+
return fs.readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
12
|
+
const target = path.join(directory, entry.name);
|
|
13
|
+
if (entry.isDirectory()) return markdownFiles(target);
|
|
14
|
+
return entry.isFile() && entry.name.endsWith('.md') ? [target] : [];
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const files = [path.join(root, 'README.md'), ...markdownFiles(path.join(root, 'docs'))];
|
|
19
|
+
const missing = [];
|
|
20
|
+
let checked = 0;
|
|
21
|
+
|
|
22
|
+
for (const file of files) {
|
|
23
|
+
const lines = fs.readFileSync(file, 'utf8').split(/\r?\n/);
|
|
24
|
+
let inShellFence = false;
|
|
25
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
26
|
+
const line = lines[index];
|
|
27
|
+
const fence = line.match(/^\s*```([^`]*)\s*$/);
|
|
28
|
+
if (fence) {
|
|
29
|
+
if (inShellFence) inShellFence = false;
|
|
30
|
+
else inShellFence = shellFence.test(fence[1].trim());
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!inShellFence || /^\s*#/.test(line)) continue;
|
|
34
|
+
for (const match of line.matchAll(/\bnpm(?:\.cmd)?\s+run\s+([A-Za-z0-9:_-]+)/g)) {
|
|
35
|
+
checked += 1;
|
|
36
|
+
if (!scripts.has(match[1])) {
|
|
37
|
+
missing.push(`${path.relative(root, file)}:${index + 1} npm run ${match[1]}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (missing.length) {
|
|
44
|
+
console.error('Documented npm scripts missing from package.json:');
|
|
45
|
+
for (const item of missing) console.error(`- ${item}`);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
} else {
|
|
48
|
+
console.log(`docs-command: ${checked} runnable npm commands verified across ${files.length} files`);
|
|
49
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const assert = require('node:assert/strict');
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { projectWireEvent, flattenCatalog } = require('../src/main/adapters/dsh');
|
|
5
|
+
|
|
6
|
+
// DSH Web Remote 投影单元测试:session/follow 帧 + $events waterfall + 模型目录。
|
|
7
|
+
// 帧形状以 fixtures/dsh/*.jsonl(真实捕获)为准。
|
|
8
|
+
|
|
9
|
+
function fixture(name) {
|
|
10
|
+
return fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'dsh', name), 'utf8')
|
|
11
|
+
.split('\n').filter(Boolean).map(JSON.parse);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 1. 真实 fixture:tool-call 全链路投影
|
|
15
|
+
const toolEvents = fixture('tool-call.jsonl').flatMap((frame) => projectWireEvent(frame).filter(Boolean));
|
|
16
|
+
assert.ok(toolEvents.some((e) => e.kind === 'tool' && e.state === 'running'), 'tool/call → running');
|
|
17
|
+
assert.ok(toolEvents.some((e) => e.kind === 'tool' && e.state === 'done' && /harness-mix-fixture/.test(e.output ?? '')), 'tool/result → done + 输出');
|
|
18
|
+
assert.ok(toolEvents.some((e) => e.kind === 'completed' && e.finalAnswer === true), 'turn/end → completed');
|
|
19
|
+
assert.ok(toolEvents.some((e) => e.kind === 'usage'), 'usage 事件');
|
|
20
|
+
|
|
21
|
+
// 2. text-delta 流式增量(真实 fixture 的 chunk 序列)
|
|
22
|
+
const deltas = fixture('simple-message.jsonl').flatMap((frame) => projectWireEvent(frame)).filter((e) => e.kind === 'text-delta');
|
|
23
|
+
assert.ok(deltas.length >= 1 && deltas.map((d) => d.text).join('').includes('收到'), 'assistant/chunk text-delta 流式投影');
|
|
24
|
+
|
|
25
|
+
// 3. assistant/message 只记检查点不重复投影文本(chunk 已覆盖)
|
|
26
|
+
const messageFrames = fixture('simple-message.jsonl').filter((f) => f.event?.type === 'assistant/message');
|
|
27
|
+
const session = { nativeSessionId: 'session-x', state: {} };
|
|
28
|
+
const fromMessage = messageFrames.flatMap((f) => projectWireEvent(f, session));
|
|
29
|
+
assert.ok(!fromMessage.some((e) => e.kind === 'text-delta'), 'assistant/message 不产生重复文本');
|
|
30
|
+
assert.equal(session.state.checkpointSeq, messageFrames.at(-1).event.seq, '检查点 seq 记录');
|
|
31
|
+
const fallbackSession = { nativeSessionId: 'session-fallback', state: { turn: { answer: '' } } };
|
|
32
|
+
const fallback = messageFrames.flatMap((f) => projectWireEvent(f, fallbackSession));
|
|
33
|
+
assert.equal(fallback.filter(e => e.kind === 'text-delta').map(e => e.text).join(''), '收到', '缺失 chunk 时从 committed assistant/message 补齐文本');
|
|
34
|
+
const end = fixture('simple-message.jsonl').filter((f) => f.event?.type === 'turn/end').flatMap((f) => projectWireEvent(f, session));
|
|
35
|
+
assert.equal(end.find((e) => e.kind === 'completed').nativeRef.checkpointId, String(session.state.checkpointSeq), 'completed 携带 fork 边界');
|
|
36
|
+
|
|
37
|
+
// 4. request/context 更新上下文窗口与模型
|
|
38
|
+
const ctx = projectWireEvent({ type: 'event', event: { type: 'request/context', seq: 9, time: 0, data: { provider: 'deepseek-official', model: 'deepseek-v4-flash', contextWindow: 1000000 } } }, session);
|
|
39
|
+
assert.equal(session.state.contextWindow, 1000000);
|
|
40
|
+
assert.ok(ctx.some((e) => e.kind === 'session' && e.model?.id === 'deepseek-v4-flash'), 'request/context → 模型更新');
|
|
41
|
+
|
|
42
|
+
// 5. usage chunk → contextPercent 计算
|
|
43
|
+
const withUsage = projectWireEvent({ type: 'event', event: { type: 'assistant/chunk', seq: 10, time: 0, data: { turn: 1, step: 1, chunk: { type: 'usage', usage: { inputTokens: 50000, outputTokens: 100, totalTokens: 50100, cacheReadTokens: 0, reasoningTokens: 0 } } } } }, session);
|
|
44
|
+
const usage = withUsage.find((e) => e.kind === 'usage').usage;
|
|
45
|
+
assert.equal(usage.tokens, 50000);
|
|
46
|
+
assert.equal(usage.contextWindow, 1000000);
|
|
47
|
+
assert.ok(Math.abs(usage.contextPercent - 5) < 0.01, 'contextPercent 由原生窗口计算');
|
|
48
|
+
|
|
49
|
+
// 6. 审批 waterfall → approval 卡片;应答 → allowed-once / rejected / cancelled
|
|
50
|
+
(async () => {
|
|
51
|
+
const { manifest, create } = require('../src/main/adapters/dsh');
|
|
52
|
+
assert.equal(manifest.capabilities.approvals, true);
|
|
53
|
+
assert.equal(manifest.capabilities.fork, true);
|
|
54
|
+
assert.equal(manifest.capabilities.questions, true);
|
|
55
|
+
const adapter = create();
|
|
56
|
+
const answered = [];
|
|
57
|
+
const fakeSession = {
|
|
58
|
+
nativeSessionId: 'session-1',
|
|
59
|
+
pendingApprovals: new Map(),
|
|
60
|
+
host: { answerWaterfall: async (eventId, outcome) => answered.push({ eventId, outcome }) },
|
|
61
|
+
};
|
|
62
|
+
fakeSession.pendingApprovals.set('dsh-evt-1', { eventId: 'evt-1', isQuestion: false });
|
|
63
|
+
await adapter.respond(fakeSession, 'dsh-evt-1', { optionId: 'allowed-once' });
|
|
64
|
+
assert.deepEqual(answered.at(-1), { eventId: 'evt-1', outcome: { kind: 'result', value: 'allowed-once' } }, '允许 → allowed-once');
|
|
65
|
+
fakeSession.pendingApprovals.set('dsh-evt-2', { eventId: 'evt-2', isQuestion: false });
|
|
66
|
+
await adapter.respond(fakeSession, 'dsh-evt-2', { cancelled: true });
|
|
67
|
+
assert.deepEqual(answered.at(-1), { eventId: 'evt-2', outcome: { kind: 'result', value: 'cancelled' } }, '取消 → cancelled');
|
|
68
|
+
|
|
69
|
+
// 7. 提问 waterfall(无选项 → 自由文本 custom;有选项 → selected)
|
|
70
|
+
fakeSession.pendingApprovals.set('dsh-evt-3', { eventId: 'evt-3', isQuestion: true, question: { id: 'q1' } });
|
|
71
|
+
await adapter.respond(fakeSession, 'dsh-evt-3', { value: '自由回答' });
|
|
72
|
+
assert.deepEqual(answered.at(-1).outcome.value, { answers: [{ id: 'q1', selected: [], custom: '自由回答' }] }, '自由文本提问 → custom');
|
|
73
|
+
fakeSession.pendingApprovals.set('dsh-evt-4', { eventId: 'evt-4', isQuestion: true, question: { id: 'q2', options: [{ label: '红色' }] } });
|
|
74
|
+
await adapter.respond(fakeSession, 'dsh-evt-4', { optionId: '红色' });
|
|
75
|
+
assert.deepEqual(answered.at(-1).outcome.value, { answers: [{ id: 'q2', selected: ['红色'] }] }, '选项提问 → selected');
|
|
76
|
+
|
|
77
|
+
// 8. 模型目录展平(provider 分组 + reasoning efforts)
|
|
78
|
+
const models = flattenCatalog({
|
|
79
|
+
default: { provider: 'p1', model: 'm1' },
|
|
80
|
+
groups: [{ id: 'p1', name: 'P1', models: [
|
|
81
|
+
{ id: 'm1', name: 'M1', reasoning: { efforts: [{ id: 'low' }, { id: 'high' }], defaultEffort: 'low' } },
|
|
82
|
+
{ id: 'm2', name: 'M2' },
|
|
83
|
+
] }],
|
|
84
|
+
});
|
|
85
|
+
assert.equal(models.length, 2);
|
|
86
|
+
assert.deepEqual(models[0], { id: 'm1', name: 'M1', provider: 'p1', description: undefined, efforts: [{ id: 'low', label: 'low', hint: undefined }, { id: 'high', label: 'high', hint: undefined }], defaultEffort: 'low' });
|
|
87
|
+
assert.equal(models[1].efforts, undefined);
|
|
88
|
+
|
|
89
|
+
console.log('dsh-adapter: Web Remote 工具/diff 边界/用量/审批/提问/目录投影 passed');
|
|
90
|
+
})().catch((error) => { console.error(error); process.exitCode = 1; });
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const assert = require('node:assert/strict');
|
|
2
|
+
const fs = require('node:fs/promises');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { HostRuntime } = require('../src/main/host/runtime');
|
|
5
|
+
|
|
6
|
+
(async () => {
|
|
7
|
+
const directory = await fs.mkdtemp(path.resolve('output/dsh-collaboration-acp-'));
|
|
8
|
+
const rt = new HostRuntime({ dataDirectory: path.join(directory, 'data') });
|
|
9
|
+
try {
|
|
10
|
+
await rt.initialize();
|
|
11
|
+
const thread = await rt.createThread({ harnessId: 'dsh', cwd: directory, title: 'DSH ACP lead probe' });
|
|
12
|
+
const session = rt.sessions.get(thread.id);
|
|
13
|
+
assert.equal(session.dshAcpLead, true);
|
|
14
|
+
assert.equal(session.collaborationEnabled, true);
|
|
15
|
+
assert.ok(session.mcpServers.some(server => server.name === 'harness-mix'));
|
|
16
|
+
assert.ok(session.nativeSessionId);
|
|
17
|
+
console.log('DSH lead: official ACP session accepted the session-scoped Harness Mix MCP server PASS');
|
|
18
|
+
} finally { await rt.close(); }
|
|
19
|
+
})().catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const { spawn } = require('node:child_process');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const root = process.env.HARNESS_MIX_DSH_ROOT;
|
|
4
|
+
const entry = root ? ['--import', 'tsx/esm', path.join(root, 'apps/cli/src/bin.ts')] : [require.resolve('@deepseek-ai/dsh/lib/bin.js')];
|
|
5
|
+
const child = spawn(process.execPath, [...entry, ...process.argv.slice(2)], {
|
|
6
|
+
cwd: root || process.cwd(), env: process.env, stdio: 'inherit', windowsHide: true,
|
|
7
|
+
});
|
|
8
|
+
child.on('error', error => { console.error(error.message); process.exitCode = 1; });
|
|
9
|
+
child.on('exit', code => { process.exitCode = code ?? 1; });
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const assert = require('node:assert/strict');
|
|
2
|
+
const fs = require('node:fs/promises');
|
|
3
|
+
const os = require('node:os');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { HostRuntime } = require('../src/main/host/runtime');
|
|
6
|
+
const { CodexAppServer } = require('../src/main/adapters/codex-app-server');
|
|
7
|
+
|
|
8
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
9
|
+
|
|
10
|
+
async function settle(thread) {
|
|
11
|
+
for (let i = 0; i < 900 && (thread.status === 'working' || thread.reviewPending); i++) await sleep(200);
|
|
12
|
+
assert.equal(thread.status, 'ready', thread.error);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
(async () => {
|
|
16
|
+
const dataDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'hm-codex-e2e-data-'));
|
|
17
|
+
const cwd = await fs.mkdtemp(path.join(os.tmpdir(), 'hm-codex-e2e-work-'));
|
|
18
|
+
const nativeIds = new Set();
|
|
19
|
+
let runtime;
|
|
20
|
+
try {
|
|
21
|
+
runtime = new HostRuntime({ dataDirectory });
|
|
22
|
+
await runtime.initialize();
|
|
23
|
+
const source = await runtime.createThread({
|
|
24
|
+
harnessId: 'codex', cwd, title: 'Codex native E2E',
|
|
25
|
+
options: { permissionMode: ':danger-full-access' },
|
|
26
|
+
});
|
|
27
|
+
assert.notEqual(source.status, 'error', source.error);
|
|
28
|
+
nativeIds.add(source.nativeSessionId);
|
|
29
|
+
const catalog = await runtime.describe('codex');
|
|
30
|
+
assert.ok(catalog.models.length > 0 && catalog.thinkingLevels.length > 0);
|
|
31
|
+
const selectedModel = catalog.models.find(model => model.isDefault) ?? catalog.models[0];
|
|
32
|
+
await runtime.setModel(source.id, selectedModel);
|
|
33
|
+
await runtime.setThinking(source.id, selectedModel.defaultEffort ?? selectedModel.efforts[0].id);
|
|
34
|
+
|
|
35
|
+
await runtime.send(source.id, 'Remember CODEX-FORK-4172. Reply exactly READY-4172. Do not use tools.');
|
|
36
|
+
await settle(source);
|
|
37
|
+
const boundary = source.messages.at(-1);
|
|
38
|
+
assert.match(boundary.text, /READY-4172/);
|
|
39
|
+
assert.ok(boundary.coreTurn.nativeTurnRef.turnId, 'native Codex turn id captured');
|
|
40
|
+
|
|
41
|
+
await runtime.send(source.id, 'Remember LATER-9386 too. Reply exactly LATER-OK. Do not use tools.');
|
|
42
|
+
await settle(source);
|
|
43
|
+
const fork = await runtime.forkThread(source.id, boundary.id);
|
|
44
|
+
nativeIds.add(fork.nativeSessionId);
|
|
45
|
+
assert.notEqual(fork.nativeSessionId, source.nativeSessionId);
|
|
46
|
+
assert.equal(fork.messages.length, 2, 'fork UI history ends at selected reply');
|
|
47
|
+
|
|
48
|
+
const forkNativeId = fork.nativeSessionId;
|
|
49
|
+
await runtime.close();
|
|
50
|
+
runtime = new HostRuntime({ dataDirectory });
|
|
51
|
+
await runtime.initialize();
|
|
52
|
+
const resumed = runtime.threads.find(thread => thread.nativeSessionId === forkNativeId);
|
|
53
|
+
assert.ok(resumed?.restore, 'persisted Codex task is lazily resumable');
|
|
54
|
+
await runtime.send(resumed.id, 'What CODEX-FORK token did I ask you to remember? Reply only the token.');
|
|
55
|
+
await settle(resumed);
|
|
56
|
+
assert.match(resumed.messages.at(-1).text, /CODEX-FORK-4172/);
|
|
57
|
+
assert.doesNotMatch(resumed.messages.at(-1).text, /LATER-9386/);
|
|
58
|
+
const usage = await runtime.refreshUsage(resumed.id);
|
|
59
|
+
assert.ok(usage.tokens > 0 && usage.contextWindow > 0 && usage.contextPercent > 0);
|
|
60
|
+
await runtime.executeCommand(resumed.id, 'compact');
|
|
61
|
+
await settle(resumed);
|
|
62
|
+
assert.match(resumed.messages.at(-1).text, /Codex 压缩/);
|
|
63
|
+
|
|
64
|
+
await fs.mkdir('output/verification', { recursive: true });
|
|
65
|
+
await fs.writeFile('output/verification/codex-native.json', JSON.stringify({
|
|
66
|
+
at: new Date().toISOString(), sourceId: source.nativeSessionId, forkId: forkNativeId,
|
|
67
|
+
boundaryTurnId: boundary.coreTurn.nativeTurnRef.turnId,
|
|
68
|
+
streamingReply: boundary.text, resumedReply: resumed.messages.at(-1).text,
|
|
69
|
+
laterTurnsExcluded: true, nativeCompact: true, models: catalog.models.length, usage,
|
|
70
|
+
}, null, 2));
|
|
71
|
+
console.log('codex: native app-server streaming, usage, reply fork and cold resume passed');
|
|
72
|
+
} finally {
|
|
73
|
+
if (nativeIds.size) {
|
|
74
|
+
const host = await CodexAppServer.acquire().catch(() => null);
|
|
75
|
+
if (host) {
|
|
76
|
+
for (const threadId of nativeIds) await host.request('thread/delete', { threadId }).catch(() => {});
|
|
77
|
+
host.release();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
await runtime?.close().catch(() => {});
|
|
81
|
+
}
|
|
82
|
+
})().catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Real model-driven collaboration. Arguments: --lead=pi --worker=pi
|
|
2
|
+
const fs = require('node:fs/promises');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const assert = require('node:assert/strict');
|
|
5
|
+
const { HostRuntime } = require('../src/main/host/runtime');
|
|
6
|
+
const { git } = require('../src/main/host/collaboration-worktree');
|
|
7
|
+
const recorder = require('../src/main/harness-adapter/fixture-recorder');
|
|
8
|
+
const arg = (name, fallback) => process.argv.find(a => a.startsWith(`--${name}=`))?.slice(name.length + 3) || fallback;
|
|
9
|
+
async function main() {
|
|
10
|
+
await fs.mkdir('output', { recursive: true });
|
|
11
|
+
const root = await fs.mkdtemp(path.resolve('output/collaboration-live-'));
|
|
12
|
+
const rt = new HostRuntime({ dataDirectory: path.join(root, 'data') });
|
|
13
|
+
const project = path.join(root, 'project'); await fs.mkdir(project);
|
|
14
|
+
await git(project, ['init']); await fs.writeFile(path.join(project, 'README.md'), 'Isolated collaboration verification.\n');
|
|
15
|
+
await git(project, ['add', '.']); await git(project, ['-c', 'user.name=Test', '-c', 'user.email=test@example.invalid', 'commit', '-m', 'fixture']);
|
|
16
|
+
const from = arg('lead', 'pi'), worker = arg('worker', 'pi');
|
|
17
|
+
const cycle = process.argv.includes('--cycle');
|
|
18
|
+
rt.subscribe(e => { if (e.type === 'toast') console.log(e.level, String(e.text).slice(0, 220)); });
|
|
19
|
+
try {
|
|
20
|
+
await rt.initialize();
|
|
21
|
+
const lead = await rt.createThread({ harnessId: from, cwd: project, title: 'Native collaboration verification' });
|
|
22
|
+
if (process.argv.includes('--record')) recorder.startRecording(from, 'collaboration-lead', path.join(root, 'recording'));
|
|
23
|
+
const prompt = cycle
|
|
24
|
+
? `这是一个协作流程验收夹具,所有文件只在当前测试目录内。你是协调者,禁止自己编写或修复文件。先用 update_agent_plan 建立计划。用 delegate_to_agent 委派 @${worker} 创建 answer.cjs,内容为 module.exports = 41;(这是故意准备的错误样本,供下一步审查)。等待完成后,另委派 @pi 作为独立只读审查者:读取 answer.cjs,检查导出值是否严格等于 42,不符合时回复 REVIEW_FAIL 和原因。两位协作者均使用默认共享工作目录,不要指定 isolation。收齐审查后通过 message_agent 把问题交回原开发者,要求修为 42。等待修复完成,再通过 message_agent 让原审查者重新读取并执行检查,正确时回复 REVIEW_PASS。必须复用原来的两个子会话。全部完成后更新计划,汇总结果,最终包含 COLLAB_CYCLE_VERIFIED。`
|
|
25
|
+
: `使用 Harness Mix 的 delegate_to_agent,显式指定 isolation=worktree,委派两个独立任务给 @${worker}。任务一只回复 COLLAB_ALPHA,任务二只回复 COLLAB_BETA。不要执行 shell 或编辑文件。请使用 get_delegation_status 等待两个结果,然后你自己最终回复两条结果和 COLLAB_VERIFIED。`;
|
|
26
|
+
let done = false, failure;
|
|
27
|
+
void rt.send(lead.id, prompt).then(() => { done = true; }, error => { done = true; failure = error; });
|
|
28
|
+
const until = Date.now() + (cycle ? 480000 : 180000);
|
|
29
|
+
while ((!done || rt.execution.isRunning(lead.id) || lead.reviewPending) && Date.now() < until) {
|
|
30
|
+
const approval = rt.threads.flatMap(t => t.pendingApprovals ?? [])[0];
|
|
31
|
+
if (approval) throw new Error(`Native approval required: ${approval.title ?? approval.requestId}. Verification does not auto-approve.`);
|
|
32
|
+
await new Promise(r => setTimeout(r, 200));
|
|
33
|
+
}
|
|
34
|
+
if (failure) throw failure;
|
|
35
|
+
if (rt.execution.isRunning(lead.id)) throw new Error(cycle ? 'Live review cycle did not finish within eight minutes' : 'Live model did not finish within three minutes');
|
|
36
|
+
const jobs = [...rt.collaboration.jobs.values()].filter(j => j.owner === lead.id);
|
|
37
|
+
const final = rt.core.getItemsForTurn(rt.execution.lastTurn(lead.id).id).filter(i => i.type === 'agent_message').map(i => i.content).join('\n');
|
|
38
|
+
console.log(JSON.stringify({ lead: from, worker, jobs: jobs.map(j => rt.collaboration.view(j)), final }, null, 2));
|
|
39
|
+
assert.equal(jobs.length, 2);
|
|
40
|
+
assert.ok(jobs.every(j => j.status === 'completed'));
|
|
41
|
+
if (cycle) {
|
|
42
|
+
assert.ok(jobs.every(j => j.workspace.mode === 'shared' && j.workspace.cwd === project));
|
|
43
|
+
assert.equal(require(path.join(project, 'answer.cjs')), 42);
|
|
44
|
+
assert.match(final, /COLLAB_CYCLE_VERIFIED/);
|
|
45
|
+
const children = jobs.map(j => rt.threads.find(t => t.id === j.childId));
|
|
46
|
+
assert.ok(children.every(t => t.messages.filter(m => m.role === 'user').length >= 2), 'Both native sessions were followed up');
|
|
47
|
+
const transcript = children.flatMap(t => t.messages.filter(m => m.role === 'assistant').map(m => m.text || '')).join('\n');
|
|
48
|
+
assert.match(transcript, /REVIEW_FAIL/); assert.match(transcript, /REVIEW_PASS/);
|
|
49
|
+
const items = rt.core.getItemsForTurn(rt.execution.lastTurn(lead.id).id);
|
|
50
|
+
assert.ok(items.some(i => i.type === 'plan' && i.entries.every(e => e.status === 'completed')));
|
|
51
|
+
assert.ok(items.filter(i => i.collaboration).length >= 4);
|
|
52
|
+
} else {
|
|
53
|
+
assert.ok(jobs.every(j => j.workspace.mode === 'worktree' && j.workspace.cwd !== project));
|
|
54
|
+
assert.notEqual(jobs[0].workspace.cwd, jobs[1].workspace.cwd);
|
|
55
|
+
assert.match(final, /COLLAB_ALPHA/); assert.match(final, /COLLAB_BETA/); assert.match(final, /COLLAB_VERIFIED/);
|
|
56
|
+
}
|
|
57
|
+
console.log('PASS: native lead called tools, spawned two native workers, collected results and synthesized its final answer');
|
|
58
|
+
} finally { recorder.stopRecording(); await rt.close(); }
|
|
59
|
+
}
|
|
60
|
+
main().catch(error => { console.error(error); process.exitCode = 1; });
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const assert = require('node:assert/strict');
|
|
2
|
+
const fs = require('node:fs/promises');
|
|
3
|
+
const os = require('node:os');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { HostRuntime } = require('../src/main/host/runtime');
|
|
6
|
+
const { ParityObserver } = require('./support/parity-observer.cjs');
|
|
7
|
+
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
8
|
+
|
|
9
|
+
(async () => {
|
|
10
|
+
for (const harnessId of process.argv[2] ? [process.argv[2]] : ['codex', 'pi', 'claude', 'dsh']) {
|
|
11
|
+
const data = await fs.mkdtemp(path.join(os.tmpdir(), `hm-core-files-${harnessId}-`));
|
|
12
|
+
const root = path.join(data, 'workspace'); await fs.mkdir(root);
|
|
13
|
+
const rt = new HostRuntime({ observer: new ParityObserver(), dataDirectory: data });
|
|
14
|
+
try {
|
|
15
|
+
await rt.initialize();
|
|
16
|
+
const thread = await rt.createThread({ harnessId, cwd: root, options: { permissionMode: harnessId === 'codex' ? ':danger-full-access' : 'acceptEdits' } });
|
|
17
|
+
assert.notEqual(thread.status, 'error', thread.error);
|
|
18
|
+
let ended = false, sendError;
|
|
19
|
+
const sending = rt.send(thread.id, 'Only in this temporary working directory: use your native file editing tool to create acceptance.txt containing exactly HARNESS-CORE-OK. Do not access other folders. Then reply done.')
|
|
20
|
+
.catch(error => { sendError = error; }).finally(() => { ended = true; });
|
|
21
|
+
for (let i = 0; i < 600; i++) {
|
|
22
|
+
for (const item of [...thread.interactions ?? []]) {
|
|
23
|
+
const allow = item.options?.find(option => option.kind === 'allow_once');
|
|
24
|
+
if (!allow) throw new Error('No one-time native file-edit approval option');
|
|
25
|
+
await rt.respondApproval(thread.id, item.requestId, { optionId: allow.id });
|
|
26
|
+
}
|
|
27
|
+
if (ended && !rt.execution.isRunning(thread.id) && !thread.reviewPending) break;
|
|
28
|
+
await sleep(250);
|
|
29
|
+
}
|
|
30
|
+
assert.equal(ended, true, 'native send timed out'); await sending;
|
|
31
|
+
if (sendError) throw sendError;
|
|
32
|
+
assert.equal(thread.status, 'ready', thread.error);
|
|
33
|
+
assert.equal(await fs.readFile(path.join(root, 'acceptance.txt'), 'utf8').then(text => text.trim()), 'HARNESS-CORE-OK');
|
|
34
|
+
const message = thread.messages.at(-1);
|
|
35
|
+
const review = await rt.readReview(thread, message);
|
|
36
|
+
const file = review.files.find(item => item.path === 'acceptance.txt');
|
|
37
|
+
assert.ok(file); assert.equal(file.type, 'file_change');
|
|
38
|
+
assert.ok(file.after.includes('HARNESS-CORE-OK'));
|
|
39
|
+
assert.ok(message.coreItems.some(item => item.type === 'tool_call'));
|
|
40
|
+
assert.ok((await rt.readReview(thread, message, file.path)).rows.some(row => row.kind === 'add'));
|
|
41
|
+
const report = rt.shadowReport();
|
|
42
|
+
assert.ok(report.comparisons > 0); assert.deepEqual(report.errors, []); assert.deepEqual(report.mismatches, []);
|
|
43
|
+
await rt.undoFile(thread.id, message.id, file.path);
|
|
44
|
+
await assert.rejects(fs.access(path.join(root, file.path)));
|
|
45
|
+
assert.ok(message.coreReview.files.find(item => item.path === file.path).undone);
|
|
46
|
+
await fs.mkdir('output/verification', { recursive: true });
|
|
47
|
+
await fs.writeFile(`output/verification/core-files-${harnessId}.json`, JSON.stringify({ harnessId, at: new Date().toISOString(), source: file.source, nativeRef: file.nativeRef, fileVerified: true, undoVerified: true, report }, null, 2));
|
|
48
|
+
console.log(`${harnessId}: real file edit -> ${file.source} FileChange -> diff -> undo; zero parity mismatch PASSED`);
|
|
49
|
+
} finally {
|
|
50
|
+
if (harnessId === 'codex') {
|
|
51
|
+
for (const session of rt.sessions.values()) {
|
|
52
|
+
await session.host?.request('thread/delete', { threadId: session.nativeSessionId }).catch(() => {});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
await rt.close();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
})().catch(error => { console.error(error); process.exitCode = 1; });
|