You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by wy...@apache.org on 2026/09/01 14:15:58 UTC
(maka) branch feat/maka-browser-recovery-dialogs updated (b98013202f -> 3441f46cbb)
This is an automated email from the ASF dual-hosted git repository.
M4n5ter pushed a change to branch feat/maka-browser-recovery-dialogs
in repository https://gitbox.apache.org/repos/asf/maka.git
from b98013202f test(desktop): keep dialog assertions behavioral
new bcaf080a67 fix(desktop): close remaining recovery gaps
add 920d7142d0 fix(cli): localize remaining TUI copy (#4422)
add 49858c4f0d refactor(runtime-host): make the Host the authority for the model catalog (#4411)
add a5ede6b357 refactor(desktop): move Goal controller ownership below AppShell (#4316)
add 0d3265eaf4 fix(runtime-host): separate the persisted grant record from the authority it derives (#4427)
add 5c1bbe3445 refactor(runtime-host): derive dispatcher operation groups from spec objects (#4402)
add dfe457eac9 refactor(desktop): retire dead Task Ledger CSS and align it with SessionTodoPanel (#4396)
add 6668af3f55 ci: allocate a runner only when its inputs changed (#4461)
new 3441f46cbb Merge remote-tracking branch 'origin/main' into feat/maka-browser-recovery-dialogs
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.asf.yaml | 14 +-
.github/workflows/ci.yml | 219 +++---
.github/workflows/cli-package-validation.yml | 211 +++---
.github/workflows/release-windows-check.yml | 38 +-
.github/workflows/windows-recovery.yml | 120 ++-
apps/desktop/e2e/goal-dialog-budget.spec.ts | 16 +
apps/desktop/renderer-architecture.json | 11 +-
.../scripts/check-renderer-architecture.test.mjs | 46 ++
.../app-shell-session-settings-actions.test.ts | 12 +-
.../src/main/__tests__/goal-provider-scope.test.ts | 216 ++++++
.../src/main/__tests__/goals-boundary.test.ts | 171 ++++-
.../__tests__/main-renderer-process-gone.test.ts | 20 +-
...tions.test.ts => main-startup-lifetime.test.ts} | 21 +-
.../main/__tests__/model-catalog-choices.test.ts | 94 ++-
.../main/__tests__/provider-add-submission.test.ts | 8 +-
.../provider-endpoint-presentation.test.ts | 14 +-
.../runtime-host-account-connection.test.ts | 8 +-
.../__tests__/runtime-host-config-ipc-main.test.ts | 7 +-
.../runtime-host-connections-ipc-main.test.ts | 37 +-
.../__tests__/runtime-host-desktop-manager.test.ts | 43 +-
.../runtime-host-github-copilot-ipc-main.test.ts | 9 +-
.../__tests__/runtime-host-oauth-ipc-main.test.ts | 30 +-
.../__tests__/runtime-host-upgrade-dialog.test.ts | 47 +-
.../__tests__/session-health-recovery-flow.test.ts | 5 +-
.../task-submission-readiness-main.test.ts | 23 +-
.../desktop/src/main/connections-ipc-validation.ts | 12 +-
.../desktop/src/main/main-renderer-process-gone.ts | 9 +
apps/desktop/src/main/onboarding-service.ts | 9 +-
.../src/main/runtime-host-account-connection.ts | 11 +-
apps/desktop/src/main/runtime-host-boot.ts | 6 +-
apps/desktop/src/main/runtime-host-client.ts | 4 +-
.../src/main/runtime-host-config-ipc-main.ts | 4 +-
.../src/main/runtime-host-connections-ipc-main.ts | 27 +-
.../src/main/runtime-host-desktop-manager.ts | 12 +-
apps/desktop/src/main/runtime-host-upgrade-copy.ts | 33 +-
.../src/main/runtime-host-upgrade-dialog.ts | 7 +-
.../src/main/task-submission-readiness-main.ts | 16 -
apps/desktop/src/preload/bridge-contract.d.ts | 4 +-
apps/desktop/src/preload/preload.ts | 2 +-
.../renderer/app-shell-session-settings-actions.ts | 9 +-
apps/desktop/src/renderer/app-shell.tsx | 26 +-
apps/desktop/src/renderer/chat-composer-region.tsx | 56 +-
apps/desktop/src/renderer/chat-message-surface.tsx | 50 +-
apps/desktop/src/renderer/features/goals/README.md | 36 +-
apps/desktop/src/renderer/features/goals/index.ts | 8 +-
.../desktop/src/renderer/features/goals/testing.ts | 1 +
.../src/renderer/features/goals/ui/goal-host.tsx | 8 +-
.../renderer/features/goals/ui/goal-provider.tsx | 121 +++
apps/desktop/src/renderer/maka-tokens.css | 5 +-
apps/desktop/src/renderer/model-catalog-choices.ts | 101 +--
.../settings/daily-review-settings-page.tsx | 6 +-
.../renderer/settings/general-settings-page.tsx | 12 +-
.../src/renderer/settings/provider-add-form.tsx | 14 +-
.../renderer/settings/provider-add-submission.ts | 4 +-
.../renderer/settings/provider-catalog-page.tsx | 8 +-
.../settings/provider-connection-detail.tsx | 20 +-
.../settings/provider-enabled-model-manager.tsx | 2 +-
.../settings/provider-endpoint-presentation.ts | 7 +-
.../src/renderer/settings/provider-panel-shared.ts | 8 +-
.../src/renderer/settings/providers-panel.tsx | 8 +-
.../renderer/settings/settings-snapshot-cache.ts | 7 +-
.../src/renderer/settings/settings-surface.tsx | 8 +-
.../renderer/settings/subagent-settings-page.tsx | 49 +-
.../src/renderer/settings/use-connection-detail.ts | 59 +-
apps/desktop/src/renderer/styles.css | 2 +-
.../src/renderer/styles/session-todo-panel.css | 94 +++
apps/desktop/src/renderer/styles/task-ledger.css | 135 ----
apps/desktop/src/renderer/use-shell-chat-model.ts | 7 +-
.../src/shared/desktop-connection-snapshot.ts | 4 +-
apps/desktop/stories/onboarding.stories.tsx | 1 -
.../stories/settings/provider-settings.stories.tsx | 12 +-
.../stories/settings/settings-pages.stories.tsx | 16 +-
docs/architecture/runtime-host-architecture.md | 3 +-
docs/astryx-surface-file-inventory.md | 5 +-
docs/astryx-surface-file-inventory.paths | 3 +-
docs/model-metadata-firstscreen-optimization.md | 16 +-
package.json | 2 +-
packages/cli/src/__tests__/pi-transcript.test.ts | 8 +-
.../cli/src/__tests__/pi-tui-mcp-status.test.ts | 273 ++++++-
packages/cli/src/__tests__/pi-tui-runner.test.ts | 266 +++++--
.../src/__tests__/runtime-host-onboarding.test.ts | 58 +-
.../src/__tests__/runtime-host-run-command.test.ts | 2 +
.../cli/src/__tests__/tui-copy-catalog.test.ts | 30 +
packages/cli/src/onboarding-catalog.ts | 8 +-
packages/cli/src/pi-transcript.ts | 29 +-
packages/cli/src/pi-tui-contracts.ts | 21 +-
packages/cli/src/pi-tui-layout.ts | 8 +-
packages/cli/src/pi-tui-mcp-status.ts | 213 ++----
packages/cli/src/pi-tui-pickers.ts | 20 +-
packages/cli/src/pi-tui-runner.ts | 225 +++---
packages/cli/src/runtime-host-cli-context.ts | 5 +-
packages/cli/src/runtime-host-onboarding.ts | 29 +-
packages/cli/src/runtime-host-task-readiness.ts | 5 +-
packages/cli/src/runtime-host-tui-command.ts | 1 -
packages/cli/src/runtime-host-tui-context.ts | 20 +-
packages/cli/src/tui-copy-catalog.ts | 237 ++++++
.../core/src/__tests__/llm-connections.test.ts | 72 +-
packages/core/src/__tests__/model-catalog.test.ts | 222 +++---
packages/core/src/__tests__/model-metadata.test.ts | 21 +-
packages/core/src/__tests__/model-thinking.test.ts | 1 -
packages/core/src/__tests__/provider-auth.test.ts | 123 +---
.../__tests__/provider-catalog-contract.test.ts | 31 +-
packages/core/src/chat-model-choice.ts | 61 +-
packages/core/src/connection-readiness.ts | 37 +-
packages/core/src/llm-connections.ts | 214 +++---
packages/core/src/model-catalog.ts | 808 ++++++++-------------
packages/core/src/model-facts.ts | 24 +-
packages/core/src/model-metadata.ts | 67 +-
packages/core/src/model-thinking.ts | 4 +-
packages/core/src/onboarding.ts | 7 +-
packages/core/src/provider-auth.ts | 400 ++--------
packages/core/src/provider-registry.ts | 469 +++---------
packages/core/src/runtime-policy.ts | 2 +
.../src/runtime-policy/connection-catalog-codec.ts | 23 +-
.../runtime-policy/model-catalog-entry-codec.ts | 82 +++
packages/core/src/session-send-projection.ts | 7 +-
packages/core/src/task-submission-readiness.ts | 7 +-
.../access-credential-grant-migration.test.ts | 186 +++++
.../__tests__/access-credential-metadata.test.ts | 4 +-
.../src/__tests__/bootstrap-runtime-policy.test.ts | 28 +-
.../src/__tests__/catalog-reader.test.ts | 2 +
.../__tests__/execution-model-composition.test.ts | 4 +-
.../src/__tests__/hosted-execution-client.test.ts | 3 +
.../src/__tests__/hosted-execution-target.test.ts | 3 +
.../__tests__/runtime-policy-coordinator.test.ts | 34 +-
packages/runtime-host/src/client/catalog-reader.ts | 29 +-
packages/runtime-host/src/client/index.ts | 2 +
packages/runtime-host/src/protocol/index.ts | 9 +-
.../runtime-host/src/protocol/runtime-policy.ts | 152 ++--
.../runtime-host/src/server/access-authority.ts | 27 +-
.../src/server/access-credential-metadata.ts | 10 +-
.../src/server/access-credential-store.ts | 215 ++++--
.../src/server/bootstrap-runtime-policy.ts | 16 +-
.../src/server/connection-effect-coordinator.ts | 10 +-
.../src/server/execution-composition.ts | 11 +
.../src/server/execution-model-authority.ts | 4 +-
.../src/server/operation-dispatcher.ts | 329 +++------
.../src/server/runtime-policy-coordinator.ts | 33 +-
.../src/__tests__/model-factory-thinking.test.ts | 8 +-
.../src/__tests__/provider-conformance.test.ts | 8 +-
.../src/__tests__/provider-contract-matrix.test.ts | 6 +-
.../src/__tests__/provider-contract-matrix.ts | 34 +-
packages/runtime/src/model-fetcher.ts | 24 +-
packages/runtime/src/model-runtime.ts | 4 +-
packages/runtime/src/test-connection.ts | 21 +-
.../src/__tests__/runtime-policy-stores.test.ts | 14 +-
packages/storage/src/runtime-policy-stores.ts | 1 -
.../runtime-policy/connection-catalog-document.ts | 44 +-
packages/storage/src/runtime-policy/coordinator.ts | 52 +-
.../src/runtime-policy/onboarding-transaction.ts | 4 +-
packages/storage/src/runtime-policy/operations.ts | 15 +-
packages/ui/src/chat-view.tsx | 23 +-
packages/ui/src/components.tsx | 12 +
packages/ui/src/composer.tsx | 29 +-
packages/ui/src/goal-projection-context.ts | 63 ++
packages/ui/src/session-todo-panel.tsx | 14 +-
packages/ui/src/styles.css | 2 +-
scripts/asf-source-workflow-policy.test.mjs | 2 +-
scripts/check-app-shell-hooks.mjs | 1 -
scripts/ci-test-plan.mjs | 56 +-
scripts/ci-test-plan.test.mjs | 643 +---------------
...t-plan.test.mjs => ci-workflow-policy.test.mjs} | 664 ++++++-----------
scripts/prepare-windows-upgrade-baseline.mjs | 23 +-
scripts/prepare-windows-upgrade-baseline.test.mjs | 136 ++++
scripts/qualify-released-cli-state-root.mjs | 147 +++-
scripts/qualify-released-cli-state-root.test.mjs | 60 +-
scripts/release-cli-workflow-policy.test.mjs | 65 +-
scripts/released-cli-state-root-fixture.mjs | 74 ++
scripts/update-test-feed-wiring.test.mjs | 67 ++
scripts/windows-package-source-closure.mjs | 23 +-
scripts/windows-package-source-closure.test.mjs | 82 ++-
171 files changed, 5505 insertions(+), 4696 deletions(-)
create mode 100644 apps/desktop/src/main/__tests__/goal-provider-scope.test.ts
copy apps/desktop/src/main/__tests__/{cursor-overlay-window-options.test.ts => main-startup-lifetime.test.ts} (58%)
create mode 100644 apps/desktop/src/renderer/features/goals/ui/goal-provider.tsx
create mode 100644 apps/desktop/src/renderer/styles/session-todo-panel.css
delete mode 100644 apps/desktop/src/renderer/styles/task-ledger.css
create mode 100644 packages/core/src/runtime-policy/model-catalog-entry-codec.ts
create mode 100644 packages/runtime-host/src/__tests__/access-credential-grant-migration.test.ts
create mode 100644 packages/ui/src/goal-projection-context.ts
copy scripts/{ci-test-plan.test.mjs => ci-workflow-policy.test.mjs} (56%)
create mode 100644 scripts/prepare-windows-upgrade-baseline.test.mjs
create mode 100644 scripts/update-test-feed-wiring.test.mjs
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
(maka) 02/02: Merge remote-tracking branch 'origin/main' into feat/maka-browser-recovery-dialogs
Posted by wy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
M4n5ter pushed a commit to branch feat/maka-browser-recovery-dialogs
in repository https://gitbox.apache.org/repos/asf/maka.git
commit 3441f46cbb97af39f8379fc1213428e7889841b0
Merge: bcaf080a67 6668af3f55
Author: Wang <m4...@gmail.com>
AuthorDate: Tue Sep 1 22:13:41 2026 +0800
Merge remote-tracking branch 'origin/main' into feat/maka-browser-recovery-dialogs
.asf.yaml | 14 +-
.github/workflows/ci.yml | 219 +++---
.github/workflows/cli-package-validation.yml | 211 +++---
.github/workflows/release-windows-check.yml | 38 +-
.github/workflows/windows-recovery.yml | 120 ++-
apps/desktop/e2e/goal-dialog-budget.spec.ts | 16 +
apps/desktop/renderer-architecture.json | 11 +-
.../scripts/check-renderer-architecture.test.mjs | 46 ++
.../app-shell-session-settings-actions.test.ts | 12 +-
.../src/main/__tests__/goal-provider-scope.test.ts | 216 ++++++
.../src/main/__tests__/goals-boundary.test.ts | 171 ++++-
.../main/__tests__/model-catalog-choices.test.ts | 94 ++-
.../main/__tests__/provider-add-submission.test.ts | 8 +-
.../provider-endpoint-presentation.test.ts | 14 +-
.../runtime-host-account-connection.test.ts | 8 +-
.../__tests__/runtime-host-config-ipc-main.test.ts | 7 +-
.../runtime-host-connections-ipc-main.test.ts | 37 +-
.../runtime-host-github-copilot-ipc-main.test.ts | 9 +-
.../__tests__/runtime-host-oauth-ipc-main.test.ts | 30 +-
.../__tests__/session-health-recovery-flow.test.ts | 5 +-
.../task-submission-readiness-main.test.ts | 23 +-
.../desktop/src/main/connections-ipc-validation.ts | 12 +-
apps/desktop/src/main/onboarding-service.ts | 9 +-
.../src/main/runtime-host-account-connection.ts | 11 +-
apps/desktop/src/main/runtime-host-boot.ts | 6 +-
apps/desktop/src/main/runtime-host-client.ts | 4 +-
.../src/main/runtime-host-config-ipc-main.ts | 4 +-
.../src/main/runtime-host-connections-ipc-main.ts | 27 +-
.../src/main/task-submission-readiness-main.ts | 16 -
apps/desktop/src/preload/bridge-contract.d.ts | 4 +-
apps/desktop/src/preload/preload.ts | 2 +-
.../renderer/app-shell-session-settings-actions.ts | 9 +-
apps/desktop/src/renderer/app-shell.tsx | 26 +-
apps/desktop/src/renderer/chat-composer-region.tsx | 56 +-
apps/desktop/src/renderer/chat-message-surface.tsx | 50 +-
apps/desktop/src/renderer/features/goals/README.md | 36 +-
apps/desktop/src/renderer/features/goals/index.ts | 8 +-
.../desktop/src/renderer/features/goals/testing.ts | 1 +
.../src/renderer/features/goals/ui/goal-host.tsx | 8 +-
.../renderer/features/goals/ui/goal-provider.tsx | 121 +++
apps/desktop/src/renderer/maka-tokens.css | 5 +-
apps/desktop/src/renderer/model-catalog-choices.ts | 101 +--
.../settings/daily-review-settings-page.tsx | 6 +-
.../renderer/settings/general-settings-page.tsx | 12 +-
.../src/renderer/settings/provider-add-form.tsx | 14 +-
.../renderer/settings/provider-add-submission.ts | 4 +-
.../renderer/settings/provider-catalog-page.tsx | 8 +-
.../settings/provider-connection-detail.tsx | 20 +-
.../settings/provider-enabled-model-manager.tsx | 2 +-
.../settings/provider-endpoint-presentation.ts | 7 +-
.../src/renderer/settings/provider-panel-shared.ts | 8 +-
.../src/renderer/settings/providers-panel.tsx | 8 +-
.../renderer/settings/settings-snapshot-cache.ts | 7 +-
.../src/renderer/settings/settings-surface.tsx | 8 +-
.../renderer/settings/subagent-settings-page.tsx | 49 +-
.../src/renderer/settings/use-connection-detail.ts | 59 +-
apps/desktop/src/renderer/styles.css | 2 +-
.../src/renderer/styles/session-todo-panel.css | 94 +++
apps/desktop/src/renderer/styles/task-ledger.css | 135 ----
apps/desktop/src/renderer/use-shell-chat-model.ts | 7 +-
.../src/shared/desktop-connection-snapshot.ts | 4 +-
apps/desktop/stories/onboarding.stories.tsx | 1 -
.../stories/settings/provider-settings.stories.tsx | 12 +-
.../stories/settings/settings-pages.stories.tsx | 16 +-
docs/architecture/runtime-host-architecture.md | 3 +-
docs/astryx-surface-file-inventory.md | 5 +-
docs/astryx-surface-file-inventory.paths | 3 +-
docs/model-metadata-firstscreen-optimization.md | 16 +-
package.json | 2 +-
packages/cli/src/__tests__/pi-transcript.test.ts | 8 +-
.../cli/src/__tests__/pi-tui-mcp-status.test.ts | 273 ++++++-
packages/cli/src/__tests__/pi-tui-runner.test.ts | 266 +++++--
.../src/__tests__/runtime-host-onboarding.test.ts | 58 +-
.../src/__tests__/runtime-host-run-command.test.ts | 2 +
.../cli/src/__tests__/tui-copy-catalog.test.ts | 30 +
packages/cli/src/onboarding-catalog.ts | 8 +-
packages/cli/src/pi-transcript.ts | 29 +-
packages/cli/src/pi-tui-contracts.ts | 21 +-
packages/cli/src/pi-tui-layout.ts | 8 +-
packages/cli/src/pi-tui-mcp-status.ts | 213 ++----
packages/cli/src/pi-tui-pickers.ts | 20 +-
packages/cli/src/pi-tui-runner.ts | 225 +++---
packages/cli/src/runtime-host-cli-context.ts | 5 +-
packages/cli/src/runtime-host-onboarding.ts | 29 +-
packages/cli/src/runtime-host-task-readiness.ts | 5 +-
packages/cli/src/runtime-host-tui-command.ts | 1 -
packages/cli/src/runtime-host-tui-context.ts | 20 +-
packages/cli/src/tui-copy-catalog.ts | 237 ++++++
.../core/src/__tests__/llm-connections.test.ts | 72 +-
packages/core/src/__tests__/model-catalog.test.ts | 222 +++---
packages/core/src/__tests__/model-metadata.test.ts | 21 +-
packages/core/src/__tests__/model-thinking.test.ts | 1 -
packages/core/src/__tests__/provider-auth.test.ts | 123 +---
.../__tests__/provider-catalog-contract.test.ts | 31 +-
packages/core/src/chat-model-choice.ts | 61 +-
packages/core/src/connection-readiness.ts | 37 +-
packages/core/src/llm-connections.ts | 214 +++---
packages/core/src/model-catalog.ts | 808 ++++++++-------------
packages/core/src/model-facts.ts | 24 +-
packages/core/src/model-metadata.ts | 67 +-
packages/core/src/model-thinking.ts | 4 +-
packages/core/src/onboarding.ts | 7 +-
packages/core/src/provider-auth.ts | 400 ++--------
packages/core/src/provider-registry.ts | 469 +++---------
packages/core/src/runtime-policy.ts | 2 +
.../src/runtime-policy/connection-catalog-codec.ts | 23 +-
.../runtime-policy/model-catalog-entry-codec.ts | 82 +++
packages/core/src/session-send-projection.ts | 7 +-
packages/core/src/task-submission-readiness.ts | 7 +-
.../access-credential-grant-migration.test.ts | 186 +++++
.../__tests__/access-credential-metadata.test.ts | 4 +-
.../src/__tests__/bootstrap-runtime-policy.test.ts | 28 +-
.../src/__tests__/catalog-reader.test.ts | 2 +
.../__tests__/execution-model-composition.test.ts | 4 +-
.../src/__tests__/hosted-execution-client.test.ts | 3 +
.../src/__tests__/hosted-execution-target.test.ts | 3 +
.../__tests__/runtime-policy-coordinator.test.ts | 34 +-
packages/runtime-host/src/client/catalog-reader.ts | 29 +-
packages/runtime-host/src/client/index.ts | 2 +
packages/runtime-host/src/protocol/index.ts | 9 +-
.../runtime-host/src/protocol/runtime-policy.ts | 152 ++--
.../runtime-host/src/server/access-authority.ts | 27 +-
.../src/server/access-credential-metadata.ts | 10 +-
.../src/server/access-credential-store.ts | 215 ++++--
.../src/server/bootstrap-runtime-policy.ts | 16 +-
.../src/server/connection-effect-coordinator.ts | 10 +-
.../src/server/execution-composition.ts | 11 +
.../src/server/execution-model-authority.ts | 4 +-
.../src/server/operation-dispatcher.ts | 329 +++------
.../src/server/runtime-policy-coordinator.ts | 33 +-
.../src/__tests__/model-factory-thinking.test.ts | 8 +-
.../src/__tests__/provider-conformance.test.ts | 8 +-
.../src/__tests__/provider-contract-matrix.test.ts | 6 +-
.../src/__tests__/provider-contract-matrix.ts | 34 +-
packages/runtime/src/model-fetcher.ts | 24 +-
packages/runtime/src/model-runtime.ts | 4 +-
packages/runtime/src/test-connection.ts | 21 +-
.../src/__tests__/runtime-policy-stores.test.ts | 14 +-
packages/storage/src/runtime-policy-stores.ts | 1 -
.../runtime-policy/connection-catalog-document.ts | 44 +-
packages/storage/src/runtime-policy/coordinator.ts | 52 +-
.../src/runtime-policy/onboarding-transaction.ts | 4 +-
packages/storage/src/runtime-policy/operations.ts | 15 +-
packages/ui/src/chat-view.tsx | 23 +-
packages/ui/src/components.tsx | 12 +
packages/ui/src/composer.tsx | 29 +-
packages/ui/src/goal-projection-context.ts | 63 ++
packages/ui/src/session-todo-panel.tsx | 14 +-
packages/ui/src/styles.css | 2 +-
scripts/asf-source-workflow-policy.test.mjs | 2 +-
scripts/check-app-shell-hooks.mjs | 1 -
scripts/ci-test-plan.mjs | 56 +-
scripts/ci-test-plan.test.mjs | 643 +---------------
...t-plan.test.mjs => ci-workflow-policy.test.mjs} | 664 ++++++-----------
scripts/prepare-windows-upgrade-baseline.mjs | 23 +-
scripts/prepare-windows-upgrade-baseline.test.mjs | 136 ++++
scripts/qualify-released-cli-state-root.mjs | 147 +++-
scripts/qualify-released-cli-state-root.test.mjs | 60 +-
scripts/release-cli-workflow-policy.test.mjs | 65 +-
scripts/released-cli-state-root-fixture.mjs | 74 ++
scripts/update-test-feed-wiring.test.mjs | 67 ++
scripts/windows-package-source-closure.mjs | 23 +-
scripts/windows-package-source-closure.test.mjs | 82 ++-
163 files changed, 5365 insertions(+), 4644 deletions(-)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
(maka) 01/02: fix(desktop): close remaining recovery gaps
Posted by wy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
M4n5ter pushed a commit to branch feat/maka-browser-recovery-dialogs
in repository https://gitbox.apache.org/repos/asf/maka.git
commit bcaf080a6702cfb084519c5532e659c4fc8df916
Author: Wang <m4...@gmail.com>
AuthorDate: Tue Sep 1 22:13:32 2026 +0800
fix(desktop): close remaining recovery gaps
---
.../__tests__/main-renderer-process-gone.test.ts | 20 ++++++++-
.../main/__tests__/main-startup-lifetime.test.ts | 39 ++++++++++++++++++
.../__tests__/runtime-host-desktop-manager.test.ts | 43 ++++++++++++++++++--
.../__tests__/runtime-host-upgrade-dialog.test.ts | 47 +++++++++++++++-------
.../desktop/src/main/main-renderer-process-gone.ts | 9 +++++
.../src/main/runtime-host-desktop-manager.ts | 12 +++---
apps/desktop/src/main/runtime-host-upgrade-copy.ts | 33 +++++++--------
.../src/main/runtime-host-upgrade-dialog.ts | 7 +---
8 files changed, 165 insertions(+), 45 deletions(-)
diff --git a/apps/desktop/src/main/__tests__/main-renderer-process-gone.test.ts b/apps/desktop/src/main/__tests__/main-renderer-process-gone.test.ts
index 1e261ce6b4..44cbc12a0b 100644
--- a/apps/desktop/src/main/__tests__/main-renderer-process-gone.test.ts
+++ b/apps/desktop/src/main/__tests__/main-renderer-process-gone.test.ts
@@ -83,12 +83,13 @@ test('reports reload success only after the main document finishes loading', asy
assert.equal(source.listenerCount('render-process-gone'), 0);
});
-test('keeps recovery active when a Renderer reload fails or exits', async () => {
+test('keeps recovery active when a Renderer reload fails, exits, or stops responding', async () => {
for (const fail of [
(source: ReturnType<typeof reloadSource>) =>
source.emit('did-fail-load', {}, -105, 'name not resolved', 'https://bad.test', true, 1, 2),
(source: ReturnType<typeof reloadSource>) =>
source.emit('render-process-gone', {}, { reason: 'crashed', exitCode: 11 }),
+ (source: ReturnType<typeof reloadSource>) => source.emit('unresponsive'),
]) {
const source = reloadSource();
let observed = false;
@@ -104,9 +105,26 @@ test('keeps recovery active when a Renderer reload fails or exits', async () =>
assert.equal(await result, false);
assert.equal(observed, false);
assert.equal(source.listenerCount('did-finish-load'), 0);
+ assert.equal(source.listenerCount('unresponsive'), 0);
}
});
+test('bounds a Renderer reload that emits no terminal event', async () => {
+ const source = reloadSource();
+ const result = reloadMainRendererProcess({
+ source,
+ shutdownSignal: new AbortController().signal,
+ onLoaded: () => assert.fail('timed-out reload must not report success'),
+ timeoutMs: 1,
+ });
+
+ assert.equal(await result, false);
+ assert.equal(source.listenerCount('did-finish-load'), 0);
+ assert.equal(source.listenerCount('did-fail-load'), 0);
+ assert.equal(source.listenerCount('unresponsive'), 0);
+ assert.equal(source.listenerCount('render-process-gone'), 0);
+});
+
function reloadSource(): EventEmitter & {
reloadCalls: number;
reload(): void;
diff --git a/apps/desktop/src/main/__tests__/main-startup-lifetime.test.ts b/apps/desktop/src/main/__tests__/main-startup-lifetime.test.ts
new file mode 100644
index 0000000000..0a26fff7d8
--- /dev/null
+++ b/apps/desktop/src/main/__tests__/main-startup-lifetime.test.ts
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import assert from 'node:assert/strict';
+import { readFileSync } from 'node:fs';
+import { test } from 'node:test';
+import { fileURLToPath } from 'node:url';
+
+const mainSource = readFileSync(
+ fileURLToPath(new URL('../../../src/main/main.ts', import.meta.url)),
+ 'utf8',
+);
+
+test('retains process lifetime before a standalone startup dialog can close', () => {
+ const retentionPolicy = mainSource.search(
+ /app\.on\(['"]window-all-closed['"],\s*\(\)\s*=>\s*\{\s*\}\);/u,
+ );
+ const singleInstanceDecision = mainSource.indexOf('app.requestSingleInstanceLock()');
+
+ assert.notEqual(retentionPolicy, -1);
+ assert.notEqual(singleInstanceDecision, -1);
+ assert.ok(retentionPolicy < singleInstanceDecision);
+});
diff --git a/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts b/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts
index e6c71b0f15..9d56a61936 100644
--- a/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts
+++ b/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts
@@ -562,6 +562,36 @@ test('keeps Local and remote Hosts active and routes work by owning Host', async
await manager.close();
});
+test('does not poll a remote service PID when the Host cannot be replaced', async () => {
+ const local = candidateHarness({ hostId: 'host-local' });
+ const observed = upgradeRequired(false);
+ const conflict = {
+ ...observed,
+ registration: { ...observed.registration, lifecycleMode: 'service' as const },
+ };
+ const manager = await startRuntimeHostDesktopManager(
+ {} as DesktopRuntimeHostCandidateStartInput,
+ {
+ startCandidate: async (input) =>
+ input.profileTarget ? conflict : ready(local.candidate),
+ upgradePrompts: {
+ restartable: async () => assert.fail('non-restartable conflict used restart prompt'),
+ nonRestartable: async (_conflict, action) => {
+ assert.equal(action, 'cancel_only');
+ return 'cancel';
+ },
+ },
+ waitForHostRetirement: async () => assert.fail('remote PID must not be polled locally'),
+ },
+ );
+
+ await assert.rejects(
+ manager.enable(remoteTarget('legacy-service')),
+ RuntimeHostUpgradeCancelledError,
+ );
+ await manager.close();
+});
+
test('keeps independent shared-session credentials active for the same Host', async () => {
const candidates = [
candidateHarness({ hostId: 'host-local' }).candidate,
@@ -1206,7 +1236,11 @@ test('prompts when a restartable Host has no activity snapshot', async () => {
});
test('waits passively for a Host that cannot be taken over', async () => {
- const conflict = upgradeRequired(false);
+ const observed = upgradeRequired(false);
+ const conflict = {
+ ...observed,
+ registration: { ...observed.registration, lifecycleMode: 'service' as const },
+ };
let starts = 0;
let finishRetirement!: () => void;
const retirement = new Promise<void>((resolve) => {
@@ -1220,7 +1254,10 @@ test('waits passively for a Host that cannot be taken over', async () => {
},
upgradePrompts: {
restartable: async () => assert.fail('wait-only conflict used restart prompt'),
- nonRestartable: async () => 'wait',
+ nonRestartable: async (_conflict, action) => {
+ assert.equal(action, 'wait');
+ return 'wait';
+ },
},
waitForHostRetirement: async (registration) => {
assert.equal(registration.hostEpoch, conflict.registration.hostEpoch);
@@ -1292,7 +1329,7 @@ test('prompts only after a non-restartable Local Host reports active tasks', asy
restartable: async () => assert.fail('non-restartable conflict used restart prompt'),
nonRestartable: async (_conflict, action) => {
prompts += 1;
- assert.equal(action, 'replace_active_work');
+ assert.equal(action, 'replace_may_interrupt_work');
return 'replace';
},
},
diff --git a/apps/desktop/src/main/__tests__/runtime-host-upgrade-dialog.test.ts b/apps/desktop/src/main/__tests__/runtime-host-upgrade-dialog.test.ts
index ae3590b834..7a75eadb71 100644
--- a/apps/desktop/src/main/__tests__/runtime-host-upgrade-dialog.test.ts
+++ b/apps/desktop/src/main/__tests__/runtime-host-upgrade-dialog.test.ts
@@ -25,7 +25,7 @@ import { createRuntimeHostUpgradePrompts } from '../runtime-host-upgrade-dialog.
const conflict = {
kind: 'upgrade_required',
restartable: true,
- registration: {},
+ registration: { pid: 42, lifecycleMode: 'ephemeral' },
handshake: {
activity: {
connections: 2,
@@ -37,17 +37,17 @@ const conflict = {
],
},
},
-} as never;
+} as unknown as Parameters<typeof buildRuntimeHostUpgradeDialog>[0];
test('localizes upgrade activity without changing decision indexes', () => {
const en = buildRuntimeHostUpgradeDialog(
conflict,
- 'restart_or_wait',
+ 'restart',
'en',
).options;
const zh = buildRuntimeHostUpgradeDialog(
conflict,
- 'restart_or_wait',
+ 'restart',
'zh',
).options;
assert.deepEqual(en.buttons, ['Restart Runtime Host', 'Wait', 'Cancel Startup']);
@@ -79,13 +79,13 @@ test('maps the non-default replacement choice to the replace decision', async ()
restartable: false,
registration: { pid: 42 },
} as never,
- 'replace_active_work',
+ 'replace_may_interrupt_work',
),
'replace',
);
});
-test('does not offer passive waiting for a supervised Host', async () => {
+test('offers only cancellation when the target cannot wait or replace the Host', async () => {
const conflict = {
kind: 'upgrade_required',
restartable: false,
@@ -94,20 +94,39 @@ test('does not offer passive waiting for a supervised Host', async () => {
const prompts = createRuntimeHostUpgradePrompts(
async () => 'en',
async (options) => {
- assert.deepEqual(options.buttons, ['Stop Host and Continue', 'Cancel Startup']);
- assert.equal(options.defaultId, 1);
- assert.equal(options.cancelId, 1);
+ assert.deepEqual(options.buttons, ['Cancel Startup']);
+ assert.equal(options.defaultId, 0);
+ assert.equal(options.cancelId, 0);
assert.doesNotMatch(options.detail ?? '', /If you wait/u);
- return { response: 1, checkboxChecked: false };
+ return { response: 0, checkboxChecked: false };
},
);
assert.equal(
- await prompts.nonRestartable(conflict, 'replace_active_work'),
+ await prompts.nonRestartable(conflict, 'cancel_only'),
'cancel',
);
});
-test('explains when the safe replacement check found active background work', () => {
+test('does not offer passive waiting when a supervised Host can restart', async () => {
+ const prompts = createRuntimeHostUpgradePrompts(
+ async () => 'en',
+ async (options) => {
+ assert.deepEqual(options.buttons, ['Restart Runtime Host', 'Cancel Startup']);
+ assert.doesNotMatch(options.detail ?? '', /If you wait/u);
+ return { response: 0, checkboxChecked: false };
+ },
+ );
+
+ assert.equal(
+ await prompts.restartable({
+ ...conflict,
+ registration: { pid: 42, lifecycleMode: 'service' },
+ } as never),
+ 'restart',
+ );
+});
+
+test('explains when the safe replacement check could not verify idle state', () => {
const conflict = {
kind: 'upgrade_required' as const,
restartable: false as const,
@@ -115,11 +134,11 @@ test('explains when the safe replacement check found active background work', ()
} as Parameters<typeof buildRuntimeHostUpgradeDialog>[0];
const dialog = buildRuntimeHostUpgradeDialog(
conflict,
- 'replace_active_work',
+ 'replace_may_interrupt_work',
'zh',
);
- assert.match(dialog.options.detail ?? '', /仍有后台任务在运行/u);
+ assert.match(dialog.options.detail ?? '', /无法确认此 Host 是否处于空闲状态/u);
assert.doesNotMatch(dialog.options.detail ?? '', /无法报告后台活动/u);
assert.equal(dialog.options.defaultId, dialog.options.cancelId);
});
diff --git a/apps/desktop/src/main/main-renderer-process-gone.ts b/apps/desktop/src/main/main-renderer-process-gone.ts
index 3f6f240111..2ddd3eae1f 100644
--- a/apps/desktop/src/main/main-renderer-process-gone.ts
+++ b/apps/desktop/src/main/main-renderer-process-gone.ts
@@ -28,6 +28,7 @@ interface RenderProcessGoneSource {
interface MainRendererReloadSource {
once(event: 'did-finish-load', listener: () => void): void;
+ once(event: 'unresponsive', listener: () => void): void;
once(
event: 'render-process-gone',
listener: (event: Event, details: RenderProcessGoneDetails) => void,
@@ -46,6 +47,7 @@ interface MainRendererReloadSource {
) => void,
): void;
off(event: 'did-finish-load', listener: () => void): void;
+ off(event: 'unresponsive', listener: () => void): void;
off(
event: 'render-process-gone',
listener: (event: Event, details: RenderProcessGoneDetails) => void,
@@ -87,15 +89,19 @@ export function reloadMainRendererProcess(deps: {
readonly source: MainRendererReloadSource;
readonly shutdownSignal: AbortSignal;
readonly onLoaded: () => void;
+ readonly timeoutMs?: number;
}): Promise<boolean> {
if (deps.shutdownSignal.aborted || deps.source.isDestroyed()) {
return Promise.resolve(false);
}
return new Promise<boolean>((resolve) => {
let settled = false;
+ let timeout: ReturnType<typeof setTimeout> | undefined;
const cleanup = (): void => {
+ if (timeout) clearTimeout(timeout);
deps.source.off('did-finish-load', onLoaded);
deps.source.off('did-fail-load', onFailed);
+ deps.source.off('unresponsive', onUnresponsive);
deps.source.off('render-process-gone', onGone);
deps.source.off('destroyed', onDestroyed);
deps.shutdownSignal.removeEventListener('abort', onAborted);
@@ -123,15 +129,18 @@ export function reloadMainRendererProcess(deps: {
): void => {
if (isMainFrame) settle(false);
};
+ const onUnresponsive = (): void => settle(false);
const onGone = (_event: Event, _details: RenderProcessGoneDetails): void => settle(false);
const onDestroyed = (): void => settle(false);
const onAborted = (): void => settle(false);
deps.source.once('did-finish-load', onLoaded);
deps.source.on('did-fail-load', onFailed);
+ deps.source.once('unresponsive', onUnresponsive);
deps.source.once('render-process-gone', onGone);
deps.source.once('destroyed', onDestroyed);
deps.shutdownSignal.addEventListener('abort', onAborted, { once: true });
+ timeout = setTimeout(() => settle(false), deps.timeoutMs ?? 30_000);
try {
deps.source.reload();
} catch {
diff --git a/apps/desktop/src/main/runtime-host-desktop-manager.ts b/apps/desktop/src/main/runtime-host-desktop-manager.ts
index 29fb3b55d2..a6247756bb 100644
--- a/apps/desktop/src/main/runtime-host-desktop-manager.ts
+++ b/apps/desktop/src/main/runtime-host-desktop-manager.ts
@@ -147,7 +147,7 @@ export class DesktopLocalHostRetirementError extends Error {
export type RuntimeHostRestartDecision = 'restart' | 'wait' | 'cancel';
export type RuntimeHostNonRestartableDecision = 'replace' | 'wait' | 'cancel';
export type RuntimeHostNonRestartableAction =
- | 'replace_active_work'
+ | 'replace_may_interrupt_work'
| 'wait'
| 'cancel_only';
@@ -952,11 +952,13 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
continue;
}
}
+ // The retirement waiter observes a local PID. Remote targets cannot
+ // use it to prove that a Host on another machine has exited.
const action: RuntimeHostNonRestartableAction = replacement
- ? 'replace_active_work'
- : result.registration.lifecycleMode !== 'service'
- ? 'wait'
- : 'cancel_only';
+ ? 'replace_may_interrupt_work'
+ : target.input.profileTarget
+ ? 'cancel_only'
+ : 'wait';
const decision = await this.#resolveNonRestartable(result, action);
if (decision === 'cancel') throw new RuntimeHostUpgradeCancelledError();
if (decision === 'replace') {
diff --git a/apps/desktop/src/main/runtime-host-upgrade-copy.ts b/apps/desktop/src/main/runtime-host-upgrade-copy.ts
index 209c05d95f..ab9654f931 100644
--- a/apps/desktop/src/main/runtime-host-upgrade-copy.ts
+++ b/apps/desktop/src/main/runtime-host-upgrade-copy.ts
@@ -28,10 +28,7 @@ import type {
type Conflict = RuntimeHostRestartableConflict | RuntimeHostWaitConflict;
export type RuntimeHostUpgradeDialogDecision = 'restart' | 'replace' | 'wait' | 'cancel';
-type RuntimeHostUpgradeAvailability =
- | RuntimeHostNonRestartableAction
- | 'restart'
- | 'restart_or_wait';
+type RuntimeHostUpgradeAvailability = RuntimeHostNonRestartableAction | 'restart';
export interface RuntimeHostUpgradeDialog {
readonly options: MessageBoxOptions;
@@ -53,19 +50,21 @@ export function buildRuntimeHostUpgradeDialog(
): RuntimeHostUpgradeDialog {
const activity = conflict.handshake?.activity;
const hasWork =
- availability === 'replace_active_work' ||
+ availability === 'replace_may_interrupt_work' ||
(activity?.activeOperations ?? 0) > 0 ||
(activity?.residencies.length ?? 0) > 0;
const copy = UPGRADE_COPY[locale];
const choices: { readonly label: string; readonly decision: RuntimeHostUpgradeDialogDecision }[] =
[];
const action =
- availability === 'restart' || availability === 'restart_or_wait'
+ availability === 'restart'
? 'restart'
- : availability === 'replace_active_work'
+ : availability === 'replace_may_interrupt_work'
? 'replace'
: undefined;
- const canWait = availability === 'restart_or_wait' || availability === 'wait';
+ const canWait =
+ availability === 'wait' ||
+ (availability === 'restart' && conflict.registration.lifecycleMode !== 'service');
if (action) {
choices.push({
label: action === 'restart' ? copy.restart : copy.replace,
@@ -85,7 +84,7 @@ export function buildRuntimeHostUpgradeDialog(
type: 'warning',
title: copy.title,
message: copy.message,
- detail: formatActivity(conflict, availability, locale),
+ detail: formatActivity(conflict, availability, canWait, locale),
buttons: choices.map((choice) => choice.label),
defaultId: choices.findIndex((choice) => choice.decision === defaultDecision),
cancelId: choices.findIndex((choice) => choice.decision === 'cancel'),
@@ -98,6 +97,7 @@ export function buildRuntimeHostUpgradeDialog(
function formatActivity(
conflict: Conflict,
availability: RuntimeHostUpgradeAvailability,
+ canWait: boolean,
locale: UiLocale,
): string {
const activity = conflict.handshake?.activity;
@@ -112,17 +112,18 @@ function formatActivity(
for (const residency of activity.residencies) {
lines.push(`${copy.activity[activityKey(residency.label)]}: ${residency.count}`);
}
- } else if (availability === 'replace_active_work') lines.push(copy.activeTasksDetected);
- else lines.push(copy.unknownActivity);
- if (availability === 'replace_active_work') {
+ } else if (availability === 'replace_may_interrupt_work') {
+ lines.push(copy.idleNotVerified);
+ } else lines.push(copy.unknownActivity);
+ if (availability === 'replace_may_interrupt_work') {
lines.push('', copy.replaceWarning, copy.replaceExplanation);
- } else if (availability === 'restart' || availability === 'restart_or_wait') {
+ } else if (availability === 'restart') {
lines.push('', copy.restartWarning);
} else if (conflict.kind !== 'upgrade_required' || !conflict.restartable) {
lines.push('');
lines.push(copy.exitOwner(conflict.registration.pid));
}
- if (availability === 'restart_or_wait' || availability === 'wait') {
+ if (canWait) {
lines.push(copy.waitExplanation);
}
return lines.join('\n');
@@ -152,7 +153,7 @@ const UPGRADE_COPY = {
uptime: (n: number) => `Running for about ${n} ${n === 1 ? 'minute' : 'minutes'}`,
connections: (n: number) => `${n} other client(s) are still connected`,
operations: (n: number) => `${n} operation(s) are running`,
- activeTasksDetected: 'This Host reported active background work during the safe replacement check.',
+ idleNotVerified: 'Maka could not verify that this Host is idle during the safe replacement check.',
unknownActivity: 'This Host version cannot report its background activity.',
processId: (pid: number) => `Process ID (PID): ${pid}`,
restartWarning:
@@ -179,7 +180,7 @@ const UPGRADE_COPY = {
uptime: (n: number) => `已运行约 ${n} 分钟`,
connections: (n: number) => `仍有 ${n} 个其他客户端连接`,
operations: (n: number) => `有 ${n} 个操作正在运行`,
- activeTasksDetected: '安全替换检查发现此 Host 仍有后台任务在运行。',
+ idleNotVerified: '安全替换检查无法确认此 Host 是否处于空闲状态。',
unknownActivity: '此 Host 版本无法报告后台活动。',
processId: (pid: number) => `进程 ID (PID):${pid}`,
restartWarning: '重启会保留持久化状态,但可能中断正在进行的外部工作。',
diff --git a/apps/desktop/src/main/runtime-host-upgrade-dialog.ts b/apps/desktop/src/main/runtime-host-upgrade-dialog.ts
index 9c4f6fe91a..488307dc13 100644
--- a/apps/desktop/src/main/runtime-host-upgrade-dialog.ts
+++ b/apps/desktop/src/main/runtime-host-upgrade-dialog.ts
@@ -36,12 +36,7 @@ export function createRuntimeHostUpgradePrompts(
return {
restartable: async (conflict): Promise<RuntimeHostRestartDecision> => {
const locale = await resolveLocale();
- const canWait = conflict.registration.lifecycleMode !== 'service';
- const dialog = buildRuntimeHostUpgradeDialog(
- conflict,
- canWait ? 'restart_or_wait' : 'restart',
- locale,
- );
+ const dialog = buildRuntimeHostUpgradeDialog(conflict, 'restart', locale);
const { response } = await showDialog(
dialog.options,
locale,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org