@harness-mix/cli 0.1.11 → 0.1.12
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 +16 -0
- package/NOTICE +16 -2
- package/README.md +265 -3
- package/docs/cross-platform.md +3 -3
- package/docs/multi-agent-collaboration.md +37 -23
- package/docs/native-acp.md +2 -2
- package/docs/native-codex.md +5 -5
- package/docs/{superpowers/specs → specs}/2026-09-13-native-hardening-design.md +2 -2
- package/docs/storage-verification-design.md +5 -5
- package/licenses/lobe-icons-MIT.txt +21 -0
- package/output/native-build/desktop-controller.mjs +24 -24
- 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 +1325 -658
- package/package.json +2 -2
- package/scripts/adapters-test.cjs +9 -1
- package/scripts/antigravity-adapter-test.cjs +381 -284
- package/scripts/build-native.cjs +64 -46
- package/scripts/codex-accounts-test.cjs +1 -1
- package/scripts/codex-accounts-ui-smoke.cjs +1 -1
- package/scripts/collaboration-recovery-test.cjs +11 -2
- package/scripts/collaboration-test.cjs +114 -27
- package/scripts/collaboration-ui-smoke.cjs +45 -8
- package/scripts/concurrency-layers-test.cjs +5 -0
- package/scripts/diagnostics.cjs +1 -1
- package/scripts/e2e-native-host.cjs +13 -13
- package/scripts/error-kind-test.cjs +3 -3
- package/scripts/integrations-test.cjs +2 -2
- package/scripts/integrations-ui-smoke.cjs +6 -6
- package/scripts/native-config-test.cjs +6 -6
- package/scripts/native-job-object-test.cjs +1 -1
- package/scripts/native-protocol-test.cjs +44 -38
- package/scripts/native-rollback-test.cjs +1 -1
- package/scripts/native-secret-test.cjs +1 -1
- package/scripts/native-shim-test.cjs +1 -1
- package/scripts/native-sidebar-test.cjs +4 -4
- package/scripts/native-ui-smoke.cjs +12 -12
- package/scripts/pets-test.cjs +223 -3
- package/scripts/platform-test.cjs +6 -6
- package/scripts/publish-native-package.cjs +1 -1
- package/scripts/test-live-mentions.cjs +2 -2
- package/scripts/workspace-test.cjs +4 -2
- package/src/assets/icons/PROVENANCE.md +92 -0
- package/src/main/adapters/antigravity.js +1415 -1368
- package/src/main/adapters/claude.js +1 -1
- package/src/main/adapters/codex-app-server.js +1 -1
- package/src/main/adapters/dsh.js +1 -1
- package/src/main/adapters/index.js +1 -1
- package/src/main/adapters/pi-usage.js +2 -2
- package/src/main/harness-adapter/error-kind.js +1 -1
- package/src/main/harness-adapter/manifest.js +7 -1
- package/src/main/host/collaboration-tools.js +8 -1
- package/src/main/host/collaboration-worktree.js +27 -1
- package/src/main/host/collaboration.js +348 -15
- package/src/main/host/runtime.js +23 -15
- package/src/main/native/codex-accounts.js +1 -1
- package/src/main/native/config.js +9 -9
- package/src/main/native/host.js +1 -1
- package/src/main/native/launcher.js +10 -8
- package/src/main/native/pets.js +188 -49
- package/src/main/native/platform.js +19 -9
- package/src/main/native/protocol.js +83 -80
- package/src/main/native/rs/crates/appx/Cargo.toml +1 -1
- package/src/main/native/rs/crates/secret/Cargo.toml +1 -1
- package/src/main/native/rs/crates/secret/src/main.rs +3 -3
- package/src/main/native/rs/crates/shim/Cargo.toml +1 -1
- package/src/main/native/rs/crates/shim/src/main.rs +2 -2
- package/src/main/native/thread-list.js +1 -1
- package/src/main/shared-contracts/capability.js +3 -1
- package/src/main/workspace/core-review.js +4 -3
- package/src/native-ui/README.md +2 -2
- package/src/native-ui/desktop-control/dist/contract-audit.js +4 -4
- package/src/native-ui/desktop-control/dist/index.d.ts +1 -1
- package/src/native-ui/desktop-control/dist/index.js +2 -2
- package/src/native-ui/desktop-control/dist/index.js.map +1 -1
- package/src/native-ui/desktop-control/dist/main-process-title-policy.js +5 -5
- package/src/native-ui/desktop-control/dist/main-process-title-policy.js.map +1 -1
- package/src/native-ui/desktop-control/dist/production-controller.js +3 -3
- package/src/native-ui/desktop-control/dist/production-controller.js.map +1 -1
- package/src/native-ui/desktop-control/dist/release-main.js +1 -1
- package/src/native-ui/desktop-control/dist/release-main.js.map +1 -1
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js +1 -1
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js.map +1 -1
- package/src/native-ui/desktop-control/dist/renderer-control-session.js +3 -3
- package/src/native-ui/desktop-control/dist/renderer-control-session.js.map +1 -1
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js +25 -25
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js.map +1 -1
- package/src/native-ui/desktop-control/dist/tsconfig.tsbuildinfo +1 -1
- package/src/native-ui/desktop-control/package.json +2 -2
- package/src/native-ui/desktop-control/scripts/build-release.mjs +2 -2
- package/src/native-ui/desktop-control/src/contract-audit.ts +4 -4
- package/src/native-ui/desktop-control/src/index.ts +2 -2
- package/src/native-ui/desktop-control/src/main-process-title-policy.ts +5 -5
- package/src/native-ui/desktop-control/src/production-controller.ts +3 -3
- package/src/native-ui/desktop-control/src/release-main.ts +1 -1
- package/src/native-ui/desktop-control/src/renderer-cdp-control-session.ts +1 -1
- package/src/native-ui/desktop-control/src/renderer-control-session.ts +3 -3
- package/src/native-ui/desktop-control/src/renderer-draft-prewarm-runtime.ts +25 -25
- package/src/native-ui/desktop-control/test/index.test.ts +1 -1
- package/src/native-ui/desktop-control/test/production-controller.test.ts +1 -1
- package/src/native-ui/desktop-control/test/renderer-cdp-control-session.test.ts +1 -1
- package/src/native-ui/desktop-control/test/renderer-draft-prewarm-policy.test.ts +43 -43
- package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/index.d.ts +3 -1
- package/src/native-ui/renderer-extension/dist/types/index.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts +2 -2
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts +3 -3
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-collab-cards.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-handoff.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-handoff.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +36 -31
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts +2 -2
- package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts +2 -2
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts +18 -2
- package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts +2 -2
- package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-team-cards.d.ts +58 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-team-cards.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts +3 -3
- package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +4 -4
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/pet-market.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts +2 -2
- package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts +1 -1
- package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -1
- package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts +18 -18
- package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts.map +1 -1
- package/src/native-ui/renderer-extension/package.json +2 -2
- package/src/native-ui/renderer-extension/src/agent-group-preference.ts +1 -1
- package/src/native-ui/renderer-extension/src/agent-selection-state.ts +31 -16
- package/src/native-ui/renderer-extension/src/audit-entry.ts +1 -1
- package/src/native-ui/renderer-extension/src/contract-audit.ts +4 -4
- package/src/native-ui/renderer-extension/src/index.ts +4 -2
- package/src/native-ui/renderer-extension/src/install-renderer-binding.ts +2 -2
- package/src/native-ui/renderer-extension/src/production-entry.ts +3 -3
- package/src/native-ui/renderer-extension/src/renderer-agent-picker.ts +7 -7
- package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +112 -89
- package/src/native-ui/renderer-extension/src/renderer-codex-account-options.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-codex-account-state.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-collab-cards.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-composer-dom.ts +12 -12
- package/src/native-ui/renderer-extension/src/renderer-credits-control.ts +7 -7
- package/src/native-ui/renderer-extension/src/renderer-external-steering.ts +3 -3
- package/src/native-ui/renderer-extension/src/renderer-fork-control.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-harness-command-claim.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-harness-command-control.ts +3 -3
- package/src/native-ui/renderer-extension/src/renderer-harness-handoff.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-harness-localization.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-harness-mentions.ts +4 -0
- package/src/native-ui/renderer-extension/src/renderer-integrations-client.ts +5 -5
- package/src/native-ui/renderer-extension/src/renderer-model-client.ts +63 -42
- package/src/native-ui/renderer-extension/src/renderer-model-picker.ts +16 -16
- package/src/native-ui/renderer-extension/src/renderer-new-thread-preference.ts +2 -2
- package/src/native-ui/renderer-extension/src/renderer-permission-mode-picker.ts +3 -3
- package/src/native-ui/renderer-extension/src/renderer-permission-mode-preference.ts +2 -2
- package/src/native-ui/renderer-extension/src/renderer-request-sender.ts +46 -3
- package/src/native-ui/renderer-extension/src/renderer-session-import-client.ts +4 -4
- package/src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts +24 -20
- package/src/native-ui/renderer-extension/src/renderer-team-cards.ts +312 -0
- package/src/native-ui/renderer-extension/src/renderer-transcript-dom.ts +1 -1
- package/src/native-ui/renderer-extension/src/renderer-trigger-chip-style.ts +2 -2
- package/src/native-ui/renderer-extension/src/renderer-usage-control.ts +4 -4
- package/src/native-ui/renderer-extension/src/settings/accounts-list.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/accounts-page.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/accounts-usage.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/connections-page.ts +7 -7
- package/src/native-ui/renderer-extension/src/settings/harness-accounts.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/icons.ts +2 -2
- package/src/native-ui/renderer-extension/src/settings/pages.ts +11 -11
- package/src/native-ui/renderer-extension/src/settings/pet-market.css +33 -0
- package/src/native-ui/renderer-extension/src/settings/pet-market.ts +173 -91
- package/src/native-ui/renderer-extension/src/settings/pets-client.ts +5 -5
- package/src/native-ui/renderer-extension/src/settings/release-notes.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/session-import-list-controls.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/session-import-page.ts +1 -1
- package/src/native-ui/renderer-extension/src/settings/shell.css +15 -15
- package/src/native-ui/renderer-extension/src/settings/shell.ts +11 -11
- package/src/native-ui/renderer-extension/src/settings/skin-runtime.ts +17 -17
- package/src/native-ui/renderer-extension/src/settings/trigger.ts +1 -1
- package/src/native-ui/renderer-extension/src/versioned-renderer-adapter.ts +20 -20
- package/src/native-ui/renderer-extension/test/agent-selection-state.test.ts +60 -1
- package/src/native-ui/renderer-extension/test/codebuddy-migration.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-agent-picker.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-binding-probe-host-catalog.test.ts +15 -9
- package/src/native-ui/renderer-extension/test/renderer-binding-probe.test.ts +15 -15
- package/src/native-ui/renderer-extension/test/renderer-codex-account-state.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-composer-permissions.test.ts +4 -4
- package/src/native-ui/renderer-extension/test/renderer-external-steering-rpc.test.ts +2 -2
- package/src/native-ui/renderer-extension/test/renderer-external-steering.test.ts +3 -3
- package/src/native-ui/renderer-extension/test/renderer-fork-control.test.ts +4 -4
- package/src/native-ui/renderer-extension/test/renderer-harness-command-claim.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-harness-command-control.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +12 -11
- package/src/native-ui/renderer-extension/test/renderer-model-picker.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-native-thread-ownership.test.ts +6 -6
- package/src/native-ui/renderer-extension/test/renderer-new-thread-preference.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-permission-mode-picker.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-permission-mode-preference.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/renderer-request-timeout.test.ts +80 -0
- package/src/native-ui/renderer-extension/test/renderer-settings-lifecycle.test.ts +2 -2
- package/src/native-ui/renderer-extension/test/renderer-sidebar-agent-icons.test.ts +10 -3
- package/src/native-ui/renderer-extension/test/renderer-unsupported-methods.test.ts +1 -1
- package/src/native-ui/renderer-extension/test/settings/pages.test.ts +5 -5
- package/src/native-ui/renderer-extension/test/settings/release-notes.test.ts +9 -9
- package/src/native-ui/renderer-extension/test/versioned-renderer-adapter.test.ts +3 -3
- package/src/native-ui/shared-contracts/dist/errors.d.ts +2 -2
- package/src/native-ui/shared-contracts/dist/errors.d.ts.map +1 -1
- package/src/native-ui/shared-contracts/dist/errors.js +1 -1
- package/src/native-ui/shared-contracts/dist/errors.js.map +1 -1
- package/src/native-ui/shared-contracts/dist/harness-models.d.ts +40 -0
- package/src/native-ui/shared-contracts/dist/harness-models.d.ts.map +1 -1
- package/src/native-ui/shared-contracts/dist/harness-models.js +23 -2
- package/src/native-ui/shared-contracts/dist/harness-models.js.map +1 -1
- package/src/native-ui/shared-contracts/dist/harness-route.d.ts +1 -1
- package/src/native-ui/shared-contracts/dist/harness-route.d.ts.map +1 -1
- package/src/native-ui/shared-contracts/dist/harness-route.js +1 -1
- package/src/native-ui/shared-contracts/dist/harness-route.js.map +1 -1
- package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts +1 -1
- package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts.map +1 -1
- package/src/native-ui/shared-contracts/dist/harness-session-import.js +1 -1
- package/src/native-ui/shared-contracts/dist/harness-session-import.js.map +1 -1
- package/src/native-ui/shared-contracts/dist/index.d.ts +3 -3
- package/src/native-ui/shared-contracts/dist/index.d.ts.map +1 -1
- package/src/native-ui/shared-contracts/dist/index.js +2 -2
- package/src/native-ui/shared-contracts/dist/index.js.map +1 -1
- package/src/native-ui/shared-contracts/dist/tsconfig.tsbuildinfo +1 -1
- package/src/native-ui/shared-contracts/dist/updates.js +1 -1
- package/src/native-ui/shared-contracts/dist/updates.js.map +1 -1
- package/src/native-ui/shared-contracts/package.json +1 -1
- package/src/native-ui/shared-contracts/src/errors.ts +3 -3
- package/src/native-ui/shared-contracts/src/harness-models.ts +23 -2
- package/src/native-ui/shared-contracts/src/harness-route.ts +1 -1
- package/src/native-ui/shared-contracts/src/harness-session-import.ts +1 -1
- package/src/native-ui/shared-contracts/src/index.ts +3 -3
- package/src/native-ui/shared-contracts/src/updates.ts +1 -1
- package/src/native-ui/shared-contracts/test/browser-bundle.test.ts +3 -3
- package/src/native-ui/shared-contracts/test/deepseek-modern-sessions.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/errors.test.ts +9 -9
- package/src/native-ui/shared-contracts/test/harness-commands.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/harness-models.test.ts +3 -3
- package/src/native-ui/shared-contracts/test/harness-permission-modes.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/harness-plugins.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/harness-session-import.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/index.test.ts +3 -3
- package/src/native-ui/shared-contracts/test/json-rpc.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/thread-usage.test.ts +1 -1
- package/src/native-ui/shared-contracts/test/updates.test.ts +4 -4
- /package/licenses/{codex-host-MIT.txt → bytepioneer-MIT.txt} +0 -0
package/scripts/pets-test.cjs
CHANGED
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
const assert = require('node:assert/strict');
|
|
4
4
|
const fs = require('node:fs');
|
|
5
|
+
const http = require('node:http');
|
|
5
6
|
const os = require('node:os');
|
|
6
7
|
const path = require('node:path');
|
|
7
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
createPetMarket,
|
|
10
|
+
readAsarHeader,
|
|
11
|
+
isWebpBuffer,
|
|
12
|
+
validatePetMetadata,
|
|
13
|
+
} = require('../src/main/native/pets');
|
|
8
14
|
|
|
9
15
|
function buildSyntheticAsar(targetPath, petName, blobContent) {
|
|
10
16
|
const tree = {
|
|
@@ -36,6 +42,16 @@ function buildSyntheticAsar(targetPath, petName, blobContent) {
|
|
|
36
42
|
fs.writeFileSync(targetPath, asarBuf);
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
// 合法 WebP 容器头:RIFF + size + WEBP + VP8 块
|
|
46
|
+
function webpPayload(label) {
|
|
47
|
+
return Buffer.concat([
|
|
48
|
+
Buffer.from('RIFF', 'latin1'),
|
|
49
|
+
Buffer.from([0x20, 0x00, 0x00, 0x00]),
|
|
50
|
+
Buffer.from('WEBPVP8 ', 'latin1'),
|
|
51
|
+
Buffer.from(`--${label}--`, 'latin1'),
|
|
52
|
+
]);
|
|
53
|
+
}
|
|
54
|
+
|
|
39
55
|
(async () => {
|
|
40
56
|
const testRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-mix-pets-test-'));
|
|
41
57
|
const fakeAsarDir = path.join(testRoot, 'resources');
|
|
@@ -51,10 +67,61 @@ function buildSyntheticAsar(targetPath, petName, blobContent) {
|
|
|
51
67
|
fs.mkdirSync(petsDir, { recursive: true });
|
|
52
68
|
|
|
53
69
|
const env = {
|
|
54
|
-
|
|
70
|
+
HARNESSMIX_STOCK_CODEX_PATH: fakeCodexBin,
|
|
55
71
|
HARNESS_MIX_PETS_DIR: petsDir,
|
|
56
72
|
};
|
|
57
73
|
|
|
74
|
+
// 本地 HTTP 服务器模拟社区下载源,覆盖 成功/500/坏签名/超大/截断/慢响应 场景
|
|
75
|
+
const server = http.createServer((req, res) => {
|
|
76
|
+
const url = new URL(req.url, 'http://127.0.0.1');
|
|
77
|
+
if (url.pathname === '/ok.webp') {
|
|
78
|
+
const body = webpPayload('community');
|
|
79
|
+
res.writeHead(200, { 'content-type': 'image/webp', 'content-length': body.length });
|
|
80
|
+
res.end(body);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (url.pathname === '/bad-sig.webp') {
|
|
84
|
+
const body = Buffer.from('NOT-A-REAL-WEBP-PAYLOAD', 'latin1');
|
|
85
|
+
res.writeHead(200, { 'content-type': 'image/webp', 'content-length': body.length });
|
|
86
|
+
res.end(body);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (url.pathname === '/huge.webp') {
|
|
90
|
+
// 声明 64MB,应在读取 body 前被 content-length 预检拦截
|
|
91
|
+
res.writeHead(200, { 'content-type': 'image/webp', 'content-length': 64 * 1024 * 1024 });
|
|
92
|
+
res.end(webpPayload('huge'));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (url.pathname === '/truncated.webp') {
|
|
96
|
+
// 声明长度大于实际发送:客户端应下载失败
|
|
97
|
+
res.writeHead(200, { 'content-type': 'image/webp', 'content-length': 1000 });
|
|
98
|
+
try {
|
|
99
|
+
res.end(Buffer.from('RIFF....WEBP', 'latin1'));
|
|
100
|
+
} catch {
|
|
101
|
+
res.destroy();
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (url.pathname === '/slow.webp') {
|
|
106
|
+
setTimeout(() => {
|
|
107
|
+
const body = webpPayload('slow');
|
|
108
|
+
res.writeHead(200, { 'content-type': 'image/webp', 'content-length': body.length });
|
|
109
|
+
res.end(body);
|
|
110
|
+
}, 300);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
res.writeHead(500);
|
|
114
|
+
res.end('boom');
|
|
115
|
+
});
|
|
116
|
+
await new Promise((resolve, reject) => {
|
|
117
|
+
server.once('error', reject);
|
|
118
|
+
server.listen(0, '127.0.0.1', resolve);
|
|
119
|
+
});
|
|
120
|
+
const baseUrl = `http://127.0.0.1:${server.address().port}`;
|
|
121
|
+
|
|
122
|
+
const leftoverArtifacts = () =>
|
|
123
|
+
fs.readdirSync(petsDir).filter(name => name.startsWith('.tmp-') || name.startsWith('.bak-'));
|
|
124
|
+
|
|
58
125
|
try {
|
|
59
126
|
// 1. Verify readAsarHeader
|
|
60
127
|
const asarInfo = readAsarHeader(fakeAsarPath);
|
|
@@ -90,7 +157,7 @@ function buildSyntheticAsar(targetPath, petName, blobContent) {
|
|
|
90
157
|
assert.throws(() => market.preview({ id: '../bad-pet' }), /Invalid pet id/);
|
|
91
158
|
assert.throws(() => market.preview({ id: 'non-existent-pet' }), /Unknown pet/);
|
|
92
159
|
|
|
93
|
-
// 4. Test install() of official pet
|
|
160
|
+
// 4. Test install() of official pet(原子流程:临时目录 -> 校验 -> 切换)
|
|
94
161
|
const installRes = await market.install({ id: 'synthetic-buddy' });
|
|
95
162
|
assert.equal(installRes.id, 'synthetic-buddy');
|
|
96
163
|
assert.equal(installRes.installed, true);
|
|
@@ -102,6 +169,7 @@ function buildSyntheticAsar(targetPath, petName, blobContent) {
|
|
|
102
169
|
const petSpritePath = path.join(installedDir, 'spritesheet.webp');
|
|
103
170
|
assert.ok(fs.existsSync(petJsonPath), 'pet.json exists');
|
|
104
171
|
assert.ok(fs.existsSync(petSpritePath), 'spritesheet.webp exists');
|
|
172
|
+
assert.deepEqual(leftoverArtifacts(), [], 'no staging/backup dirs left after official install');
|
|
105
173
|
|
|
106
174
|
const meta = JSON.parse(fs.readFileSync(petJsonPath, 'utf8'));
|
|
107
175
|
assert.equal(meta.id, 'synthetic-buddy');
|
|
@@ -139,8 +207,160 @@ function buildSyntheticAsar(targetPath, petName, blobContent) {
|
|
|
139
207
|
const uninstalledEntry = catalogAfterUninstall.data.find(p => p.id === 'synthetic-buddy');
|
|
140
208
|
assert.equal(uninstalledEntry.installed, false);
|
|
141
209
|
|
|
210
|
+
// 7. 社区下载安装成功路径(本地 HTTP 源),安装后无临时/备份目录残留
|
|
211
|
+
const communityInstall = await market.install({
|
|
212
|
+
id: 'community-pet',
|
|
213
|
+
displayName: 'Community Pet',
|
|
214
|
+
spritesheetUrl: `${baseUrl}/ok.webp`,
|
|
215
|
+
});
|
|
216
|
+
assert.equal(communityInstall.installed, true);
|
|
217
|
+
assert.equal(communityInstall.alreadyInstalled, false);
|
|
218
|
+
const communityDir = path.join(petsDir, 'community-pet');
|
|
219
|
+
assert.ok(fs.existsSync(path.join(communityDir, 'pet.json')));
|
|
220
|
+
assert.ok(fs.existsSync(path.join(communityDir, 'spritesheet.webp')));
|
|
221
|
+
const communityMeta = JSON.parse(fs.readFileSync(path.join(communityDir, 'pet.json'), 'utf8'));
|
|
222
|
+
assert.equal(communityMeta.displayName, 'Community Pet');
|
|
223
|
+
assert.equal(communityMeta.spriteVersionNumber, 1);
|
|
224
|
+
assert.deepEqual(leftoverArtifacts(), [], 'no staging/backup dirs left after community install');
|
|
225
|
+
|
|
226
|
+
// 8. 下载失败(HTTP 500):拒绝安装且不留下任何目录
|
|
227
|
+
await assert.rejects(
|
|
228
|
+
market.install({ id: 'dl-fail-pet', spritesheetUrl: `${baseUrl}/missing.webp` }),
|
|
229
|
+
/Download failed \(500\)/,
|
|
230
|
+
);
|
|
231
|
+
assert.ok(!fs.existsSync(path.join(petsDir, 'dl-fail-pet')), 'failed install must not leave a pet dir');
|
|
232
|
+
assert.deepEqual(leftoverArtifacts(), [], 'download failure must not leave staging dirs');
|
|
233
|
+
|
|
234
|
+
// 9. 校验失败:坏 WebP 签名
|
|
235
|
+
await assert.rejects(
|
|
236
|
+
market.install({ id: 'bad-sig-pet', spritesheetUrl: `${baseUrl}/bad-sig.webp` }),
|
|
237
|
+
/RIFF\/WEBP signature/,
|
|
238
|
+
);
|
|
239
|
+
assert.ok(!fs.existsSync(path.join(petsDir, 'bad-sig-pet')));
|
|
240
|
+
assert.deepEqual(leftoverArtifacts(), [], 'signature failure must not leave staging dirs');
|
|
241
|
+
|
|
242
|
+
// 10. 校验失败:content-length 超过大小上限(预检拦截)
|
|
243
|
+
await assert.rejects(
|
|
244
|
+
market.install({ id: 'huge-pet', spritesheetUrl: `${baseUrl}/huge.webp` }),
|
|
245
|
+
/too large/,
|
|
246
|
+
);
|
|
247
|
+
assert.ok(!fs.existsSync(path.join(petsDir, 'huge-pet')));
|
|
248
|
+
assert.deepEqual(leftoverArtifacts(), []);
|
|
249
|
+
|
|
250
|
+
// 11. 下载截断(声明长度与实际不符):拒绝安装且清理
|
|
251
|
+
await assert.rejects(
|
|
252
|
+
market.install({ id: 'truncated-pet', spritesheetUrl: `${baseUrl}/truncated.webp` }),
|
|
253
|
+
);
|
|
254
|
+
assert.ok(!fs.existsSync(path.join(petsDir, 'truncated-pet')));
|
|
255
|
+
assert.deepEqual(leftoverArtifacts(), []);
|
|
256
|
+
|
|
257
|
+
// 12. pet.json 必填字段校验:displayName 非法时在下载前拒绝,不创建目录
|
|
258
|
+
await assert.rejects(
|
|
259
|
+
market.install({ id: 'meta-bad-pet', displayName: 123, spritesheetUrl: `${baseUrl}/ok.webp` }),
|
|
260
|
+
/displayName/,
|
|
261
|
+
);
|
|
262
|
+
assert.ok(!fs.existsSync(path.join(petsDir, 'meta-bad-pet')));
|
|
263
|
+
assert.deepEqual(leftoverArtifacts(), []);
|
|
264
|
+
|
|
265
|
+
// 13. 路径安全:目录穿越 / 斜杠注入 / 大写 id 一律拒绝
|
|
266
|
+
await assert.rejects(market.install({ id: '../escape' }), /Invalid pet id/);
|
|
267
|
+
await assert.rejects(market.install({ id: 'a/b' }), /Invalid pet id/);
|
|
268
|
+
await assert.rejects(market.install({ id: 'a\\b' }), /Invalid pet id/);
|
|
269
|
+
await assert.rejects(market.install({ id: 'UPPERCASE' }), /Invalid pet id/);
|
|
270
|
+
assert.throws(() => market.uninstall({ id: '..\\evil' }), /Invalid pet id/);
|
|
271
|
+
assert.throws(() => market.uninstall({ id: '../evil' }), /Invalid pet id/);
|
|
272
|
+
assert.deepEqual(leftoverArtifacts(), []);
|
|
273
|
+
assert.ok(!fs.existsSync(path.join(testRoot, 'escape')), 'nothing written outside pets root');
|
|
274
|
+
|
|
275
|
+
// 14. 并发防护:同一 pet 安装进行中,第二个安装与卸载都被拒绝
|
|
276
|
+
const slowInstall = market.install({ id: 'conc-pet', spritesheetUrl: `${baseUrl}/slow.webp` });
|
|
277
|
+
await assert.rejects(
|
|
278
|
+
market.install({ id: 'conc-pet', spritesheetUrl: `${baseUrl}/slow.webp` }),
|
|
279
|
+
/in progress/,
|
|
280
|
+
);
|
|
281
|
+
assert.throws(() => market.uninstall({ id: 'conc-pet' }), /in progress/);
|
|
282
|
+
const slowResult = await slowInstall;
|
|
283
|
+
assert.equal(slowResult.installed, true);
|
|
284
|
+
assert.deepEqual(leftoverArtifacts(), []);
|
|
285
|
+
// 操作释放后可以正常卸载
|
|
286
|
+
const concUninstall = market.uninstall({ id: 'conc-pet' });
|
|
287
|
+
assert.equal(concUninstall.removed, true);
|
|
288
|
+
|
|
289
|
+
// 15. 修复损坏目录:已有目录缺少精灵图时,走 备份->切换 流程完成安装且不残留 .bak
|
|
290
|
+
const brokenDir = path.join(petsDir, 'broken-pet');
|
|
291
|
+
fs.mkdirSync(brokenDir, { recursive: true });
|
|
292
|
+
fs.writeFileSync(path.join(brokenDir, 'pet.json'), '{"id":"broken-pet"}');
|
|
293
|
+
const fixRes = await market.install({
|
|
294
|
+
id: 'broken-pet',
|
|
295
|
+
displayName: 'Broken Pet',
|
|
296
|
+
spritesheetUrl: `${baseUrl}/ok.webp`,
|
|
297
|
+
});
|
|
298
|
+
assert.equal(fixRes.alreadyInstalled, false);
|
|
299
|
+
assert.ok(fs.existsSync(path.join(brokenDir, 'spritesheet.webp')), 'spritesheet repaired');
|
|
300
|
+
const fixedMeta = JSON.parse(fs.readFileSync(path.join(brokenDir, 'pet.json'), 'utf8'));
|
|
301
|
+
assert.equal(fixedMeta.displayName, 'Broken Pet');
|
|
302
|
+
assert.deepEqual(leftoverArtifacts(), [], 'swap with existing dir must not leave backup dirs');
|
|
303
|
+
|
|
304
|
+
// 16. 已安装列表不容忍损坏目录:pet.json 无法解析或缺少精灵图的目录不出现
|
|
305
|
+
const badJsonDir = path.join(petsDir, 'bad-json-pet');
|
|
306
|
+
fs.mkdirSync(badJsonDir);
|
|
307
|
+
fs.writeFileSync(path.join(badJsonDir, 'pet.json'), '{not json');
|
|
308
|
+
fs.writeFileSync(path.join(badJsonDir, 'spritesheet.webp'), webpPayload('x'));
|
|
309
|
+
const noSheetDir = path.join(petsDir, 'no-sheet-pet');
|
|
310
|
+
fs.mkdirSync(noSheetDir);
|
|
311
|
+
fs.writeFileSync(path.join(noSheetDir, 'pet.json'), JSON.stringify({ id: 'no-sheet-pet' }));
|
|
312
|
+
const robustCatalogIds = market.catalog().data.map(p => p.id);
|
|
313
|
+
assert.ok(!robustCatalogIds.includes('bad-json-pet'), 'unparseable pet.json excluded');
|
|
314
|
+
assert.ok(!robustCatalogIds.includes('no-sheet-pet'), 'missing spritesheet excluded');
|
|
315
|
+
assert.ok(robustCatalogIds.includes('community-pet'), 'healthy install still listed');
|
|
316
|
+
assert.ok(robustCatalogIds.includes('broken-pet'), 'repaired install now listed');
|
|
317
|
+
|
|
318
|
+
// 17. 崩溃残留清扫:超过年龄的 .tmp-* / .bak-* 在下一次安装/卸载时被清理
|
|
319
|
+
const staleTmp = path.join(petsDir, '.tmp-stale-pet-0-0-aaaaaa');
|
|
320
|
+
const staleBak = path.join(petsDir, '.bak-stale-pet-0-0-bbbbbb');
|
|
321
|
+
fs.mkdirSync(staleTmp);
|
|
322
|
+
fs.mkdirSync(staleBak);
|
|
323
|
+
const oldTime = new Date(Date.now() - 60 * 60 * 1000);
|
|
324
|
+
fs.utimesSync(staleTmp, oldTime, oldTime);
|
|
325
|
+
fs.utimesSync(staleBak, oldTime, oldTime);
|
|
326
|
+
market.uninstall({ id: 'no-such-pet' });
|
|
327
|
+
assert.ok(!fs.existsSync(staleTmp), 'stale .tmp dir swept');
|
|
328
|
+
assert.ok(!fs.existsSync(staleBak), 'stale .bak dir swept');
|
|
329
|
+
|
|
330
|
+
// 18. 校验辅助函数单元测试
|
|
331
|
+
assert.equal(isWebpBuffer(webpPayload('t')), true);
|
|
332
|
+
assert.equal(isWebpBuffer(Buffer.from('RIFF....WEBP', 'latin1')), true);
|
|
333
|
+
assert.equal(isWebpBuffer(Buffer.from('RIFF....AVIF', 'latin1')), false);
|
|
334
|
+
assert.equal(isWebpBuffer(Buffer.from('WEBP....RIFF', 'latin1')), false);
|
|
335
|
+
assert.equal(isWebpBuffer(Buffer.from('RIFF', 'latin1')), false);
|
|
336
|
+
assert.equal(isWebpBuffer(Buffer.alloc(0)), false);
|
|
337
|
+
|
|
338
|
+
assert.throws(() => validatePetMetadata(null, 'x'), /must be an object/);
|
|
339
|
+
assert.throws(
|
|
340
|
+
() => validatePetMetadata({ id: 'y', displayName: 'A', spriteVersionNumber: 1, spritesheetPath: 'spritesheet.webp' }, 'x'),
|
|
341
|
+
/id mismatch/,
|
|
342
|
+
);
|
|
343
|
+
assert.throws(
|
|
344
|
+
() => validatePetMetadata({ id: 'x', displayName: ' ', spriteVersionNumber: 1, spritesheetPath: 'spritesheet.webp' }, 'x'),
|
|
345
|
+
/displayName/,
|
|
346
|
+
);
|
|
347
|
+
assert.throws(
|
|
348
|
+
() => validatePetMetadata({ id: 'x', displayName: 'A', spriteVersionNumber: 0, spritesheetPath: 'spritesheet.webp' }, 'x'),
|
|
349
|
+
/spriteVersionNumber/,
|
|
350
|
+
);
|
|
351
|
+
assert.throws(
|
|
352
|
+
() => validatePetMetadata({ id: 'x', displayName: 'A', spriteVersionNumber: 1, spritesheetPath: '../evil.webp' }, 'x'),
|
|
353
|
+
/spritesheetPath/,
|
|
354
|
+
);
|
|
355
|
+
assert.equal(
|
|
356
|
+
validatePetMetadata({ id: 'x', displayName: 'A', spriteVersionNumber: 2, spritesheetPath: 'spritesheet.webp' }, 'x').id,
|
|
357
|
+
'x',
|
|
358
|
+
);
|
|
359
|
+
|
|
142
360
|
console.log('Pets market native tests passed successfully!');
|
|
143
361
|
} finally {
|
|
362
|
+
try { server.closeAllConnections(); } catch { /* Node < 18.2 无此 API */ }
|
|
363
|
+
server.close();
|
|
144
364
|
fs.rmSync(testRoot, { recursive: true, force: true });
|
|
145
365
|
}
|
|
146
366
|
})();
|
|
@@ -10,12 +10,12 @@ const { evaluateDesktopCompatibility, enforceDesktopCompatibility } = require('.
|
|
|
10
10
|
|
|
11
11
|
async function main() {
|
|
12
12
|
const home = path.resolve(os.tmpdir(), 'hm-home');
|
|
13
|
-
assert.equal(dataDirectory({}, 'darwin', home), path.join(home, 'Library/Application Support/
|
|
14
|
-
assert.equal(dataDirectory({}, 'linux', home), path.join(home, '.local/share/
|
|
15
|
-
assert.equal(dataDirectory({ XDG_DATA_HOME: home }, 'linux', '/ignored'), path.join(home, '
|
|
13
|
+
assert.equal(dataDirectory({}, 'darwin', home), path.join(home, 'Library/Application Support/harnessmix'));
|
|
14
|
+
assert.equal(dataDirectory({}, 'linux', home), path.join(home, '.local/share/harnessmix'));
|
|
15
|
+
assert.equal(dataDirectory({ XDG_DATA_HOME: home }, 'linux', '/ignored'), path.join(home, 'harnessmix'));
|
|
16
16
|
assert.equal(dataDirectory({ XDG_DATA_HOME: 'relative' }, 'linux', home), dataDirectory({}, 'linux', home));
|
|
17
|
-
assert.equal(dataDirectory({
|
|
18
|
-
assert.equal(dataDirectory({ APPDATA: home }, 'win32'), path.join(home, '
|
|
17
|
+
assert.equal(dataDirectory({ HARNESSMIX_DATA_DIR: home }, 'darwin'), home);
|
|
18
|
+
assert.equal(dataDirectory({ APPDATA: home }, 'win32'), path.join(home, 'harnessmix'));
|
|
19
19
|
for (const platform of ['win32', 'darwin', 'linux']) {
|
|
20
20
|
assert.equal(path.basename(nativePaths(platform).shim), executableName('harness-mix-shim', platform));
|
|
21
21
|
assert.equal('activation' in nativePaths(platform), platform === 'win32');
|
|
@@ -24,7 +24,7 @@ async function main() {
|
|
|
24
24
|
assert.throws(() => enforceDesktopCompatibility(result, { HARNESS_MIX_STRICT_COMPATIBILITY: '1' }));
|
|
25
25
|
}
|
|
26
26
|
assert.equal(evaluateDesktopCompatibility('1.2.3', undefined, 'darwin').state, 'unverified');
|
|
27
|
-
const env = { HARNESS_MIX_DESKTOP_EXECUTABLE: process.execPath,
|
|
27
|
+
const env = { HARNESS_MIX_DESKTOP_EXECUTABLE: process.execPath, HARNESSMIX_STOCK_CODEX_PATH: process.execPath };
|
|
28
28
|
assert.equal(inspectPosix(env, 'linux').version, 'unknown');
|
|
29
29
|
assert.equal(inspectPosix({ ...env, HARNESS_MIX_DESKTOP_VERSION: '1.2.3' }, 'linux').stock, fs.realpathSync(process.execPath));
|
|
30
30
|
assert.throws(() => inspectPosix({}, 'linux'), /Install Codex Desktop/);
|
|
@@ -24,7 +24,7 @@ if (!sourceOnly) {
|
|
|
24
24
|
}
|
|
25
25
|
fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify({
|
|
26
26
|
name: `@harness-mix/native-${key}`, version, description: `Harness Mix native runtime for ${key}${sourceOnly ? ' (source-only; build locally)' : ''}`,
|
|
27
|
-
license: 'Apache-2.0', os: [platform], cpu: [arch], files: ['bin'], publishConfig: { access: 'public' },
|
|
27
|
+
license: '(Apache-2.0 OR MIT)', os: [platform], cpu: [arch], files: ['bin'], publishConfig: { access: 'public' },
|
|
28
28
|
}, null, 2) + '\n');
|
|
29
29
|
fs.writeFileSync(path.join(pkg, 'README.md'), `# @harness-mix/native-${key}\n\nNative runtime selected automatically by @harness-mix/cli.\n`);
|
|
30
30
|
const publish = flags.includes('--publish');
|
|
@@ -43,14 +43,14 @@ async function main() {
|
|
|
43
43
|
console.log('Waiting for probe to mount...');
|
|
44
44
|
await evaluate(`(async () => {
|
|
45
45
|
for (let i = 0; i < 50; i++) {
|
|
46
|
-
if (window.
|
|
46
|
+
if (window.__harnessmixRendererBindingProbeV1 && document.querySelector('.ProseMirror')) break;
|
|
47
47
|
await new Promise(r => setTimeout(r, 100));
|
|
48
48
|
}
|
|
49
49
|
})()`);
|
|
50
50
|
|
|
51
51
|
const directClientTest = await evaluate(`(async () => {
|
|
52
52
|
try {
|
|
53
|
-
const probe = window.
|
|
53
|
+
const probe = window.__harnessmixRendererBindingProbeV1;
|
|
54
54
|
return {
|
|
55
55
|
hasProbe: !!probe,
|
|
56
56
|
probeKeys: probe ? Object.keys(probe) : []
|
|
@@ -54,7 +54,9 @@ const { HostRuntime } = require('../src/main/host/runtime');
|
|
|
54
54
|
rt.subscribe(e => { if (e.type === 'turn/diff/updated') updates.push(e); });
|
|
55
55
|
await rt.store.load();
|
|
56
56
|
rt.adapters.set('test', {
|
|
57
|
-
|
|
57
|
+
// Even a Harness that advertises nativePatch may omit a native file event.
|
|
58
|
+
// Host final Diff must still close the gap from its authoritative snapshot.
|
|
59
|
+
manifest: { id: 'test', name: 'Test', capabilities: { nativeDiff: true, nativePatch: true } },
|
|
58
60
|
open: async () => ({}), close: async () => {},
|
|
59
61
|
send: async (_session, _text, { emit }) => {
|
|
60
62
|
emit({ kind: 'text-delta', text: 'progress' });
|
|
@@ -73,7 +75,7 @@ const { HostRuntime } = require('../src/main/host/runtime');
|
|
|
73
75
|
assert.equal(t.status, 'ready');
|
|
74
76
|
const answer = t.messages.at(-1);
|
|
75
77
|
assert.deepEqual(answer.coreItems.filter(i => ['agent_message', 'tool_call'].includes(i.type)).map(i => i.type), ['agent_message', 'tool_call', 'agent_message']);
|
|
76
|
-
assert.equal(answer.review.files.length, 1);
|
|
78
|
+
assert.equal(answer.review.files.length, 1, 'Host final Diff supplements a missing native patch');
|
|
77
79
|
assert.equal(answer.review.files[0].path, 'dirty.js');
|
|
78
80
|
assert.ok(updates.some(e => e.turnId === answer.id && e.review?.live && e.review.files.some(f => f.path === 'dirty.js')), 'Runtime pushes live diff without Renderer polling');
|
|
79
81
|
assert.ok(updates.some(e => e.turnId === answer.id && e.review?.live === false), 'Runtime pushes final diff');
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Icon provenance
|
|
2
|
+
|
|
3
|
+
33 brand marks are bundled in this directory and read by `src/main/native/icons.js`.
|
|
4
|
+
They exist so the UI can label the harnesses and models this project integrates with.
|
|
5
|
+
Every mark remains a trademark of its owner; see the trademark note at the end.
|
|
6
|
+
|
|
7
|
+
## Redistributed from lobehub/lobe-icons — 24 of 33 (MIT)
|
|
8
|
+
|
|
9
|
+
`@lobehub/icons-static-svg` v1.95.0, `Copyright (c) 2023 LobeHub`.
|
|
10
|
+
Source: https://github.com/lobehub/lobe-icons
|
|
11
|
+
License text: `licenses/lobe-icons-MIT.txt`
|
|
12
|
+
|
|
13
|
+
Fifteen files are byte-identical to the upstream package:
|
|
14
|
+
|
|
15
|
+
| local | upstream |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `claude-color.svg` | `claude-color.svg` |
|
|
18
|
+
| `cline-color.svg` | `cline.svg` |
|
|
19
|
+
| `cursor-cli-color.svg` | `cursor.svg` |
|
|
20
|
+
| `deepseek-color.svg` | `deepseek-color.svg` |
|
|
21
|
+
| `grok-color.svg` | `grok.svg` |
|
|
22
|
+
| `model-claude.svg` | `claude.svg` |
|
|
23
|
+
| `model-deepseek.svg` | `deepseek.svg` |
|
|
24
|
+
| `model-kimi.svg` | `kimi.svg` |
|
|
25
|
+
| `model-minimax.svg` | `minimax.svg` |
|
|
26
|
+
| `model-openai.svg` | `openai.svg` |
|
|
27
|
+
| `model-qwen-color.svg` | `qwen-color.svg` |
|
|
28
|
+
| `model-xiaomimimo.svg` | `xiaomimimo.svg` |
|
|
29
|
+
| `openclaw-color.svg` | `openclaw-color.svg` |
|
|
30
|
+
| `opencode-color.svg` | `opencode.svg` |
|
|
31
|
+
| `pi.svg` | `pi.svg` |
|
|
32
|
+
|
|
33
|
+
Nine more carry the same artwork (identical `path` data) behind a slightly different
|
|
34
|
+
export wrapper, so they come from the same set:
|
|
35
|
+
|
|
36
|
+
| local | upstream |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `antigravity-color.svg` | `antigravity-color.svg` |
|
|
39
|
+
| `cursor.svg` | `cursor.svg` |
|
|
40
|
+
| `model-gemini.svg` | `gemini.svg` |
|
|
41
|
+
| `model-grok.svg` | `grok.svg` |
|
|
42
|
+
| `model-zai.svg` | `zai.svg` |
|
|
43
|
+
| `qoder-color.svg` | `qoder-color.svg` |
|
|
44
|
+
| `trae-color.svg` | `trae-color.svg` |
|
|
45
|
+
| `workbuddy-color.svg` | `yuanbao-color.svg` |
|
|
46
|
+
| `zcode-color.svg` | `zai.svg` |
|
|
47
|
+
|
|
48
|
+
Note that two local file names do not match the mark they contain: `workbuddy-color.svg`
|
|
49
|
+
is the upstream *Yuanbao* mark, and `zcode-color.svg` is the upstream *Z.ai* mark.
|
|
50
|
+
The upstream `<title>` element in those files still carries the original names.
|
|
51
|
+
|
|
52
|
+
## Bundled from product brand marks — 8 of 33
|
|
53
|
+
|
|
54
|
+
| local | known origin |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| `kiro-cli-color.svg` | Official Kiro icon, `https://kiro.dev/icon.svg`. Byte-identical to `src/native-ui/renderer-extension/src/assets/kiro-agent.svg`, whose provenance is recorded in that directory's `README.md`. |
|
|
57
|
+
| `codex-color.svg`, `codex-harness.svg` | The Codex mark. Both names hold the same bytes and both are referenced (`adapters/codex.js` uses `codex-color.svg`, `native/icons.js` and `README.md` use `codex-harness.svg`). |
|
|
58
|
+
| `codebuddy-color.svg` | CodeBuddy harness mark. Source record not kept. |
|
|
59
|
+
| `hermes-color.svg` | Hermes harness mark. Source record not kept. |
|
|
60
|
+
| `omp-color.svg` | Oh My Pi harness mark whose source record was not kept. It is **not** the official mark: `omp-agent.svg` in the renderer assets has identical path data to the official Oh My Pi favicon (`packages/collab-web/public/favicon.svg`), while this file is a different, simpler shape. |
|
|
61
|
+
| `model-astra.svg` | Drawn in this repository (gradient disc), not third-party artwork. |
|
|
62
|
+
| `model-hunyuan.svg` | Drawn in this repository (rounded plate with a glyph), not third-party artwork. |
|
|
63
|
+
|
|
64
|
+
## Unknown provenance — 1 of 33
|
|
65
|
+
|
|
66
|
+
`pinumber1_80899.svg` is a pi glyph exported by Adobe Illustrator 18.1.1; the file name
|
|
67
|
+
matches the download naming of free icon sites. It is used as the Pi harness icon
|
|
68
|
+
(`src/main/adapters/pi.js`). The exact source and its license could not be established,
|
|
69
|
+
so it should be replaced with original artwork or have its source recorded.
|
|
70
|
+
|
|
71
|
+
## Usage
|
|
72
|
+
|
|
73
|
+
`src/main/native/icons.js` resolves icons through an explicit file list and nothing globs
|
|
74
|
+
this directory, so three files are currently referenced by no code path:
|
|
75
|
+
|
|
76
|
+
| file | why it is unused |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `cursor-cli-color.svg` | Both the `cursor` and `cursor-cli` entries resolve to `cursor.svg`. |
|
|
79
|
+
| `model-grok.svg` | The `grok` model family resolves to `grok-color.svg`. The other eleven model families all use `model-*.svg`, so this is the convention-consistent file — either it should be wired up or the duplicate dropped. |
|
|
80
|
+
| `workbuddy-color.svg` | Every alias map resolves `workbuddy` to `codebuddy`, which uses `codebuddy-color.svg`. |
|
|
81
|
+
|
|
82
|
+
`grok-color.svg` and `model-grok.svg` carry identical path data, so despite the names they
|
|
83
|
+
are the same artwork under two file names.
|
|
84
|
+
|
|
85
|
+
Everything in this directory is published: `package.json` lists `src` in `files`.
|
|
86
|
+
|
|
87
|
+
## Trademarks
|
|
88
|
+
|
|
89
|
+
These marks are the property of their respective owners and are bundled only to identify
|
|
90
|
+
the harnesses and models this project integrates with. No trademark right, endorsement or
|
|
91
|
+
affiliation is claimed. Copyright licenses covering a mark (such as the MIT license above)
|
|
92
|
+
do not grant any trademark right.
|