create-walle 0.10.2 → 0.10.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/README.md +3 -1
- package/lib/release-schema.json +2 -2
- package/lib/runtime-closure-policy.json +8 -7
- package/package.json +1 -1
- package/template/coding-task-manager/api-prompts.js +45 -7
- package/template/coding-task-manager/bin/claude-hook.js +55 -1
- package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
- package/template/coding-task-manager/bin/land.js +2069 -0
- package/template/coding-task-manager/bin/memory-census.js +4 -2
- package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
- package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
- package/template/coding-task-manager/db.js +156 -32
- package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
- package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
- package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
- package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
- package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
- package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
- package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
- package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
- package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
- package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
- package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
- package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
- package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
- package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
- package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
- package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
- package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
- package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
- package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
- package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
- package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
- package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
- package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
- package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
- package/template/coding-task-manager/lib/agent-definitions.js +19 -0
- package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
- package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
- package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
- package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
- package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
- package/template/coding-task-manager/lib/agent-presets.js +84 -1
- package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
- package/template/coding-task-manager/lib/agent-version-service.js +74 -11
- package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
- package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
- package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
- package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
- package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
- package/template/coding-task-manager/lib/api/fleet.js +118 -0
- package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
- package/template/coding-task-manager/lib/api/ingress.js +9 -1
- package/template/coding-task-manager/lib/api/landing.js +403 -0
- package/template/coding-task-manager/lib/api/machines.js +691 -2
- package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
- package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
- package/template/coding-task-manager/lib/api/session-attach.js +623 -0
- package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
- package/template/coding-task-manager/lib/api/sessions.js +77 -51
- package/template/coding-task-manager/lib/api/setup-network.js +544 -16
- package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
- package/template/coding-task-manager/lib/api/setup.js +829 -10
- package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
- package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
- package/template/coding-task-manager/lib/auth-rules.js +292 -21
- package/template/coding-task-manager/lib/background-stop.js +369 -0
- package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
- package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
- package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
- package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
- package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
- package/template/coding-task-manager/lib/build-info.js +4 -2
- package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
- package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
- package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
- package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
- package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
- package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
- package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
- package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
- package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
- package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
- package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
- package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
- package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
- package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
- package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
- package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
- package/template/coding-task-manager/lib/conversation-sync.js +355 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
- package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
- package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
- package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
- package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
- package/template/coding-task-manager/lib/db-domains.js +1 -0
- package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
- package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
- package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
- package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
- package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
- package/template/coding-task-manager/lib/feature-manifest.js +4 -0
- package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
- package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
- package/template/coding-task-manager/lib/fleet-hub.js +762 -0
- package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
- package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
- package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
- package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
- package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
- package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
- package/template/coding-task-manager/lib/fleet-update.js +798 -0
- package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
- package/template/coding-task-manager/lib/fs-watcher.js +58 -42
- package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
- package/template/coding-task-manager/lib/headless-term-service.js +84 -8
- package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
- package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
- package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
- package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
- package/template/coding-task-manager/lib/host-handoff.js +16 -19
- package/template/coding-task-manager/lib/host-stats.js +150 -3
- package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
- package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
- package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
- package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
- package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
- package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
- package/template/coding-task-manager/lib/hub-bridge.js +398 -0
- package/template/coding-task-manager/lib/idle-notify.js +491 -0
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
- package/template/coding-task-manager/lib/instance-manifest.js +5 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
- package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
- package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
- package/template/coding-task-manager/lib/landing/config.js +536 -0
- package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
- package/template/coding-task-manager/lib/landing/gate.js +360 -0
- package/template/coding-task-manager/lib/landing/git.js +344 -0
- package/template/coding-task-manager/lib/landing/lease.js +247 -0
- package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
- package/template/coding-task-manager/lib/landing/proof.js +223 -0
- package/template/coding-task-manager/lib/landing/queue.js +998 -0
- package/template/coding-task-manager/lib/landing/radar.js +489 -0
- package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
- package/template/coding-task-manager/lib/landing/state.js +263 -0
- package/template/coding-task-manager/lib/landing/stop.js +49 -0
- package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
- package/template/coding-task-manager/lib/landing/sync.js +456 -0
- package/template/coding-task-manager/lib/landing/train.js +885 -0
- package/template/coding-task-manager/lib/landing/window.js +57 -0
- package/template/coding-task-manager/lib/launch-environment.js +121 -0
- package/template/coding-task-manager/lib/launch-model-override.js +36 -10
- package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
- package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
- package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
- package/template/coding-task-manager/lib/lead-model-options.js +160 -3
- package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
- package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
- package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
- package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
- package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
- package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
- package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
- package/template/coding-task-manager/lib/machine-registry.js +750 -5
- package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
- package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
- package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
- package/template/coding-task-manager/lib/memory-join.js +337 -0
- package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
- package/template/coding-task-manager/lib/memory-sync.js +565 -0
- package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
- package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
- package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
- package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
- package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
- package/template/coding-task-manager/lib/model-availability.js +727 -0
- package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
- package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
- package/template/coding-task-manager/lib/model-id-rule.js +19 -0
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
- package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
- package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
- package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
- package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
- package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
- package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
- package/template/coding-task-manager/lib/native-history-control.js +6 -4
- package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
- package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
- package/template/coding-task-manager/lib/opencode-cli.js +480 -0
- package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
- package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
- package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
- package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
- package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
- package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
- package/template/coding-task-manager/lib/perf-summary.js +7 -0
- package/template/coding-task-manager/lib/perf-tracker.js +63 -2
- package/template/coding-task-manager/lib/project-config.js +7 -0
- package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
- package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
- package/template/coding-task-manager/lib/read-pool-client.js +89 -2
- package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
- package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
- package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
- package/template/coding-task-manager/lib/relay-client.js +57 -3
- package/template/coding-task-manager/lib/relink-audit.js +34 -5
- package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
- package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
- package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
- package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
- package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
- package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
- package/template/coding-task-manager/lib/restart-guard.js +18 -6
- package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
- package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
- package/template/coding-task-manager/lib/resume-admission.js +17 -3
- package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
- package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
- package/template/coding-task-manager/lib/runtime-contract.js +3 -1
- package/template/coding-task-manager/lib/schema-indexes.js +1 -0
- package/template/coding-task-manager/lib/session-context-locator.js +742 -0
- package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
- package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
- package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
- package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
- package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
- package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
- package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
- package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
- package/template/coding-task-manager/lib/session-create/response.js +7 -7
- package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
- package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
- package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
- package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
- package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
- package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
- package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
- package/template/coding-task-manager/lib/session-empty.js +13 -10
- package/template/coding-task-manager/lib/session-host-manager.js +60 -0
- package/template/coding-task-manager/lib/session-jobs.js +3 -1
- package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
- package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
- package/template/coding-task-manager/lib/session-park.js +738 -0
- package/template/coding-task-manager/lib/session-path-grant.js +13 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
- package/template/coding-task-manager/lib/session-transport.js +17 -0
- package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
- package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
- package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
- package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
- package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
- package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
- package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
- package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
- package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
- package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
- package/template/coding-task-manager/lib/submission-ack.js +90 -2
- package/template/coding-task-manager/lib/systemd-scope.js +115 -0
- package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
- package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
- package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
- package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
- package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
- package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
- package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
- package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
- package/template/coding-task-manager/lib/transcript-source.js +36 -4
- package/template/coding-task-manager/lib/transcript-store.js +9 -0
- package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
- package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
- package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
- package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
- package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
- package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
- package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
- package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
- package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
- package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
- package/template/coding-task-manager/lib/walle/turn.js +1 -1
- package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
- package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
- package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
- package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
- package/template/coding-task-manager/lib/walle-row-history.js +495 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
- package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
- package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
- package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
- package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
- package/template/coding-task-manager/lib/ws/misc.js +1 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
- package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
- package/template/coding-task-manager/oauth-proxy.js +112 -115
- package/template/coding-task-manager/package-lock.json +10 -94
- package/template/coding-task-manager/package.json +4 -3
- package/template/coding-task-manager/protocol/message-table.json +10 -0
- package/template/coding-task-manager/protocol/messages.js +10 -0
- package/template/coding-task-manager/protocol/ws-schema.json +20 -0
- package/template/coding-task-manager/protocol/ws-schema.md +2 -0
- package/template/coding-task-manager/public/css/app.css +170 -0
- package/template/coding-task-manager/public/css/walle-session.css +4 -0
- package/template/coding-task-manager/public/index.html +473 -243
- package/template/coding-task-manager/public/js/agent-command.js +86 -0
- package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
- package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
- package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
- package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
- package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
- package/template/coding-task-manager/public/js/background-work.js +196 -27
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
- package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
- package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
- package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
- package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
- package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
- package/template/coding-task-manager/public/js/document-review-links.js +9 -1
- package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
- package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
- package/template/coding-task-manager/public/js/message-renderer.js +4 -3
- package/template/coding-task-manager/public/js/model-picker.js +3 -1
- package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
- package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
- package/template/coding-task-manager/public/js/pasted-content.js +236 -0
- package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
- package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
- package/template/coding-task-manager/public/js/prompts.js +11 -10
- package/template/coding-task-manager/public/js/protocol.js +10 -0
- package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
- package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
- package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
- package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
- package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
- package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
- package/template/coding-task-manager/public/js/stream-view.js +6 -5
- package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
- package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
- package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
- package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
- package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
- package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
- package/template/coding-task-manager/public/js/walle.js +6 -0
- package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
- package/template/coding-task-manager/public/m/app.css +140 -0
- package/template/coding-task-manager/public/m/app.js +507 -68
- package/template/coding-task-manager/public/m/index.html +17 -0
- package/template/coding-task-manager/public/m/machines.js +838 -4
- package/template/coding-task-manager/public/m/private-api.js +31 -1
- package/template/coding-task-manager/public/usage.html +1 -0
- package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
- package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
- package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
- package/template/coding-task-manager/server.js +1950 -11679
- package/template/coding-task-manager/session-integrity.js +64 -4
- package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
- package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
- package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
- package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
- package/template/coding-task-manager/workers/session-host-process.js +5 -5
- package/template/coding-task-manager/workers/watch-worker.js +105 -0
- package/template/coding-task-manager/workers/worktree-worker.js +168 -33
- package/template/ctm-relay/lib/protocol.js +14 -1
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/shared/backup-retention.js +82 -0
- package/template/shared/conversation-admission.js +2 -0
- package/template/shared/conversation-provenance.js +3 -7
- package/template/shared/conversation-storage-v2-contract.js +5 -0
- package/template/shared/linked-worktree.js +51 -0
- package/template/shared/macos-fda-target.js +57 -0
- package/template/shared/orphan-parents.js +55 -0
- package/template/shared/release-schema.json +2 -2
- package/template/shared/storage/contract.js +3 -0
- package/template/wall-e/adapters/imessage.js +12 -0
- package/template/wall-e/agent.js +71 -4
- package/template/wall-e/api-walle.js +21 -1
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
- package/template/wall-e/brain/brain-join.js +859 -0
- package/template/wall-e/brain/brain-sync-membership.js +20 -0
- package/template/wall-e/brain/brain-sync-store.js +131 -77
- package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
- package/template/wall-e/brain/brain-sync-v2.js +578 -0
- package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
- package/template/wall-e/brain/deterministic-id.js +51 -0
- package/template/wall-e/brain/memories.js +2 -2
- package/template/wall-e/brain/migrations.js +40 -6
- package/template/wall-e/brain/model-identity-migration.js +1 -1
- package/template/wall-e/brain/owner-call-whitelist.js +23 -7
- package/template/wall-e/brain/schema.js +45 -85
- package/template/wall-e/brain.js +171 -35
- package/template/wall-e/chat.js +3 -3
- package/template/wall-e/coding/agent-shell-env.js +7 -2
- package/template/wall-e/coding/prompt-bundle.js +66 -21
- package/template/wall-e/config/main-loop-exemptions.json +2 -2
- package/template/wall-e/http/admin-api.js +37 -0
- package/template/wall-e/http/gws-api.js +4 -0
- package/template/wall-e/http/helper-rules-api.js +7 -1
- package/template/wall-e/http/model-admin.js +8 -1
- package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
- package/template/wall-e/http/model-proxy-providers.js +174 -1
- package/template/wall-e/http/model-route-health.js +157 -0
- package/template/wall-e/http/sync-api.js +278 -464
- package/template/wall-e/jobs/job-runner.js +28 -1
- package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
- package/template/wall-e/lib/ctm-data-dir.js +26 -0
- package/template/wall-e/lib/derivation-home.js +147 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
- package/template/wall-e/lib/helper-rules/grade.js +51 -8
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
- package/template/wall-e/lib/helper-rules/store.js +4 -2
- package/template/wall-e/lib/landing-mcp-tools.js +170 -0
- package/template/wall-e/lib/mcp-client-config.js +133 -14
- package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
- package/template/wall-e/lib/mcp-integration.js +58 -13
- package/template/wall-e/lib/parent-death.js +7 -1
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
- package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
- package/template/wall-e/llm/delegate-vendor-default.js +12 -5
- package/template/wall-e/llm/model-roles.js +1 -1
- package/template/wall-e/llm/native-delegate-selection.js +56 -8
- package/template/wall-e/llm/worker-delegate-args.js +72 -7
- package/template/wall-e/llm/worker-mcp-routing.js +66 -17
- package/template/wall-e/loops/brain-custom-writes.js +19 -0
- package/template/wall-e/loops/ingest.js +17 -1
- package/template/wall-e/loops/think.js +19 -4
- package/template/wall-e/mcp-contract.js +222 -6
- package/template/wall-e/mcp-protocol-contract.js +40 -5
- package/template/wall-e/mcp-server.js +128 -29
- package/template/wall-e/mcp-worker-schemas.js +5 -5
- package/template/wall-e/memory/ctm-context-client.js +85 -0
- package/template/wall-e/memory/ctm-session-context.js +9 -3
- package/template/wall-e/memory/hub-bridge-client.js +388 -0
- package/template/wall-e/memory/replica-origin.js +56 -0
- package/template/wall-e/memory/session-pool.js +135 -0
- package/template/wall-e/runtime/live-capabilities.js +8 -3
- package/template/wall-e/server.js +4 -2
- package/template/wall-e/shared/release-schema.json +2 -2
- package/template/wall-e/shared/sqlite-file-set.js +39 -0
- package/template/wall-e/shared/storage/contract.js +3 -0
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
- package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
- package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
- package/template/wall-e/tools/chrome-automation.js +6 -0
- package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
- package/template/wall-e/workers/brain-owner-worker.js +18 -4
- package/template/wall-e/workers/mcp-gateway-process.js +5 -5
|
@@ -364,10 +364,16 @@ function machineFormatPct(value) {
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
// WP-4: a reachable box whose Claude/Codex CLI is signed out says so on its card. Same labels on both
|
|
367
|
-
// surfaces.
|
|
368
|
-
|
|
367
|
+
// surfaces. WP-13b adds the DeepSeek Harness label — it has no CTM sign-in (S-88), so it is listed
|
|
368
|
+
// from the box's own presence verdict instead of a sign-in state.
|
|
369
|
+
var MACHINE_AGENT_LABELS = { claude: 'Claude', codex: 'Codex', dsh: 'DeepSeek Harness' };
|
|
369
370
|
|
|
370
|
-
|
|
371
|
+
// `presence` is the registry row's `agentPresence` ({ dsh: true|false|null }) — the box's own answer
|
|
372
|
+
// to "do you have the DeepSeek Harness" (WP-13b, D-15). dsh has no sign-in state, so it is named
|
|
373
|
+
// ONLY when the box explicitly said it has it (`=== true`); false and null (unknown / never read)
|
|
374
|
+
// add nothing, exactly as an unknown sign-in state adds nothing above. claude/codex output is
|
|
375
|
+
// byte-identical to its pre-WP-13b self whether or not `presence` is passed.
|
|
376
|
+
function machineAgentText(agents, presence) {
|
|
371
377
|
if (!agents || typeof agents !== 'object') return '';
|
|
372
378
|
var parts = [];
|
|
373
379
|
['claude', 'codex'].forEach(function (key) {
|
|
@@ -375,6 +381,7 @@ function machineAgentText(agents) {
|
|
|
375
381
|
if (state === 'signed_in') parts.push(MACHINE_AGENT_LABELS[key] + ' signed in');
|
|
376
382
|
else if (state === 'signed_out') parts.push(MACHINE_AGENT_LABELS[key] + ' signed out');
|
|
377
383
|
});
|
|
384
|
+
if (presence && presence.dsh === true) parts.push(MACHINE_AGENT_LABELS.dsh);
|
|
378
385
|
return parts.join(' · ');
|
|
379
386
|
}
|
|
380
387
|
|
|
@@ -396,6 +403,508 @@ function machineGpuText(gpu) {
|
|
|
396
403
|
return parts.join(' · ');
|
|
397
404
|
}
|
|
398
405
|
|
|
406
|
+
// WP-1 (docs/lid-closed-pool-host-always-on-2026-10-25.html §6/§8): the Power fact — what the kernel
|
|
407
|
+
// actually did. On battery the box WILL sleep when the lid closes, so say so before the count matters;
|
|
408
|
+
// on AC (or an unknown source) report how many DISTINCT times it slept in the last 24 h and how long
|
|
409
|
+
// ago the last one was. history is the oldest-first sample list; now is the caller's clock (never read
|
|
410
|
+
// here, matching machineLoadLine). The 24 h window is half-open on the far edge (> now - 24h) and
|
|
411
|
+
// inclusive of now, so a sleep exactly 24 h ago has aged out.
|
|
412
|
+
function machinePowerText(sample, history, now) {
|
|
413
|
+
if (sample == null || sample.power == null) return '';
|
|
414
|
+
var power = sample.power;
|
|
415
|
+
if (power.onAC === false) return 'On battery — lid close will sleep it';
|
|
416
|
+
var prefix = power.onAC === true ? 'AC · ' : '';
|
|
417
|
+
var nowMs = Number(now);
|
|
418
|
+
var windowStart = nowMs - 24 * 60 * 60 * 1000;
|
|
419
|
+
var rows = machineHistoryRows(history).concat([sample]);
|
|
420
|
+
var seen = {};
|
|
421
|
+
var count = 0;
|
|
422
|
+
var last = null;
|
|
423
|
+
for (var i = 0; i < rows.length; i += 1) {
|
|
424
|
+
var row = rows[i];
|
|
425
|
+
var value = row && row.power ? Number(row.power.lastSleepAt) : NaN;
|
|
426
|
+
if (!Number.isFinite(value) || value <= windowStart || value > nowMs) continue;
|
|
427
|
+
var key = String(value);
|
|
428
|
+
if (seen[key]) continue;
|
|
429
|
+
seen[key] = true;
|
|
430
|
+
count += 1;
|
|
431
|
+
if (last == null || value > last) last = value;
|
|
432
|
+
}
|
|
433
|
+
if (count === 0) return prefix + 'no sleep in 24 h';
|
|
434
|
+
return prefix + 'slept ' + count + '× in 24 h (last ' + machineAgoText(last, nowMs) + ')';
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ── WP-3 fleet line (docs/fleet-auto-update-pooled-machines-2026-10-26.html §8) ─────────────────
|
|
438
|
+
// ONE line per machine row saying what the hub's reconciler last decided about that box. `null` is
|
|
439
|
+
// a real answer — say nothing — when no reconciler pass has run for this instance (`fleet` is null)
|
|
440
|
+
// or when the health line already carries the state (`unreachable`): a status is never invented.
|
|
441
|
+
// The desktop card ("mpc-fleet") and the phone card ("mp-fleet") render these same bytes. Short
|
|
442
|
+
// shas are the first 7 characters; a missing one is the literal "unknown", never an empty string.
|
|
443
|
+
var MACHINE_FLEET_UNKNOWN_SHA = 'unknown';
|
|
444
|
+
|
|
445
|
+
function machineFleetSha7(value) {
|
|
446
|
+
var sha = String(value == null ? '' : value).trim();
|
|
447
|
+
return sha ? sha.slice(0, 7) : MACHINE_FLEET_UNKNOWN_SHA;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// `already_attempted` reads the hub's own record of the attempt it already made on this box.
|
|
451
|
+
// A verdict the hub has not taught us yet is NOT a proven success: it stays muted.
|
|
452
|
+
function machineFleetVerdictLine(lastVerdict, buildSha7) {
|
|
453
|
+
var verdict = String((lastVerdict && lastVerdict.verdict) || '');
|
|
454
|
+
var reason = String((lastVerdict && lastVerdict.reason) || '');
|
|
455
|
+
var suffix = reason ? ': ' + reason : '';
|
|
456
|
+
if (verdict === 'updated') return { text: 'Up to date · ' + buildSha7, tone: 'ok' };
|
|
457
|
+
if (verdict === 'rolled_back') return { text: 'Update rolled back' + suffix, tone: 'warn' };
|
|
458
|
+
if (verdict === 'manual_intervention') return { text: 'Update failed — needs a manual fix' + suffix, tone: 'warn' };
|
|
459
|
+
if (verdict === 'refused') return { text: 'Update refused' + suffix, tone: 'warn' };
|
|
460
|
+
if (verdict === 'timeout') return { text: 'Update timed out', tone: 'warn' };
|
|
461
|
+
return { text: 'Behind — waits for the next hub commit', tone: 'muted' };
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// WP-3 (docs/fleet-origin-main-sync-skill-2026-10-31.html §5 R-1, §6.2): the `origin_sync` line.
|
|
465
|
+
// The box syncs itself from origin (the hub never bundles to it), so the only facts worth showing are
|
|
466
|
+
// the box's OWN: is the new build running yet, and where does its main stand against origin.
|
|
467
|
+
// `n` is printed raw — ahead/behind are integers from `git rev-list --left-right --count`, and the
|
|
468
|
+
// "—" keeps a null (no tracking ref yet) from reading as 0.
|
|
469
|
+
function machineOriginCount(value) {
|
|
470
|
+
return (value === null || value === undefined || value === '') ? '—' : String(value);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// The last sync verdict plus WHEN (relative, via machineAgoText; the ISO string when the stamp is not
|
|
474
|
+
// a time we can read; "never" when the box has never recorded one).
|
|
475
|
+
function machineOriginLastSync(lastSync) {
|
|
476
|
+
if (!lastSync || typeof lastSync !== 'object') return 'never';
|
|
477
|
+
var verdict = String(lastSync.verdict || '') || 'unknown';
|
|
478
|
+
var at = lastSync.at;
|
|
479
|
+
var ms = Date.parse(String(at == null ? '' : at));
|
|
480
|
+
if (Number.isFinite(ms)) return verdict + ' ' + machineAgoText(ms);
|
|
481
|
+
return verdict + ' ' + (at == null || at === '' ? 'never' : String(at));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// `origin_sync` reads the box's own head/runningSha/originSync (the hub row carries them verbatim).
|
|
485
|
+
// First match wins (AC-3d): a new build on disk is a restart, then behind / ahead / level.
|
|
486
|
+
function machineOriginSyncLine(fleet) {
|
|
487
|
+
var runSha7 = machineFleetSha7(fleet.runningSha);
|
|
488
|
+
var os = fleet.originSync && typeof fleet.originSync === 'object' ? fleet.originSync : {};
|
|
489
|
+
var title = 'running ' + runSha7 + ' · origin ahead/behind '
|
|
490
|
+
+ machineOriginCount(os.ahead) + '/' + machineOriginCount(os.behind)
|
|
491
|
+
+ ' · last sync ' + machineOriginLastSync(os.lastSync);
|
|
492
|
+
var head = fleet.head == null ? '' : String(fleet.head);
|
|
493
|
+
var running = fleet.runningSha == null ? '' : String(fleet.runningSha);
|
|
494
|
+
var line;
|
|
495
|
+
if (head && running && head !== running) line = { text: 'New build on disk — restarts when idle', tone: 'pending' };
|
|
496
|
+
else if (Number(os.behind) > 0) line = { text: Number(os.behind) + ' behind origin — pulls within 15 min', tone: 'pending' };
|
|
497
|
+
else if (Number(os.ahead) > 0) line = { text: Number(os.ahead) + ' unpublished — land sync publishes them', tone: 'pending' };
|
|
498
|
+
else line = { text: 'In sync with origin · ' + runSha7, tone: 'ok' };
|
|
499
|
+
return { text: line.text, tone: line.tone, title: title };
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Rules in precedence order, first match wins (FLEET_HUB_REASONS, lib/fleet-hub.js). An unknown
|
|
503
|
+
// reason falls through to null rather than guessing.
|
|
504
|
+
function machineFleetLine(machine) {
|
|
505
|
+
var fleet = machine && machine.fleet;
|
|
506
|
+
if (!fleet || typeof fleet !== 'object') return null;
|
|
507
|
+
var reason = String(fleet.reason || '');
|
|
508
|
+
if (reason === 'unreachable') return null;
|
|
509
|
+
// WP-3: a self-syncing box has its own line (and its own tooltip) — the hub's `target` is not what
|
|
510
|
+
// its card should be comparing against.
|
|
511
|
+
if (reason === 'origin_sync') return machineOriginSyncLine(fleet);
|
|
512
|
+
var buildSha7 = machineFleetSha7(machine.build && machine.build.sha);
|
|
513
|
+
var targetSha7 = machineFleetSha7(fleet.target);
|
|
514
|
+
var title = 'running ' + buildSha7 + ' · hub ' + targetSha7;
|
|
515
|
+
if (fleet.lastVerdict) {
|
|
516
|
+
var lastReason = String(fleet.lastVerdict.reason || '');
|
|
517
|
+
title += ' · last: ' + String(fleet.lastVerdict.verdict || '') + (lastReason ? ' ' + lastReason : '');
|
|
518
|
+
}
|
|
519
|
+
var line;
|
|
520
|
+
if (reason === 'current') line = { text: 'Up to date · ' + buildSha7, tone: 'ok' };
|
|
521
|
+
else if (reason === 'sending' || reason === 'updating' || fleet.inFlight) line = { text: 'Updating to ' + targetSha7 + '…', tone: 'pending' };
|
|
522
|
+
else if (reason === 'restart_pending') line = { text: 'New build on disk — restarts when idle', tone: 'pending' };
|
|
523
|
+
else if (reason === 'busy') line = { text: 'Behind — waits for idle sessions', tone: 'pending' };
|
|
524
|
+
else if (reason === 'cooldown') line = { text: 'Behind — next update after the 3 h cooldown', tone: 'pending' };
|
|
525
|
+
else if (reason === 'behind' || reason === 'another_box_updating') line = { text: 'Behind — queued', tone: 'pending' };
|
|
526
|
+
else if (reason === 'already_attempted') line = machineFleetVerdictLine(fleet.lastVerdict, buildSha7);
|
|
527
|
+
else if (reason === 'not_git') line = { text: 'Not a git checkout — not auto-updated', tone: 'muted' };
|
|
528
|
+
else if (reason === 'not_main') line = { text: 'Not on main — not auto-updated', tone: 'muted' };
|
|
529
|
+
else if (reason === 'dirty') line = { text: 'Local changes — not auto-updated', tone: 'muted' };
|
|
530
|
+
else if (reason === 'diverged') line = { text: 'Has commits the hub lacks — not auto-updated', tone: 'muted' };
|
|
531
|
+
else return null;
|
|
532
|
+
return { text: line.text, tone: line.tone, title: title };
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// ── WP-4 hub-bridge access (docs/remote-session-hub-bridge-2026-10-30.html §6.2 / R-4/R-5/R-9/R-11) ─
|
|
536
|
+
// ONE copy of the Access block's DOM-free half: the effective policy (R-11), the three row texts
|
|
537
|
+
// (grants / open asks / audit), the block and banner markup, and the request bodies the writes send.
|
|
538
|
+
// The desktop Machines page (js/app/machines-page.js) and the phone Machines card (m/app.js) both
|
|
539
|
+
// call these; each passes its own escaper and its own class names, because the two DOM trees have
|
|
540
|
+
// always used different prefixes (`mpc-*` vs `mp-*`) and neither class set is styled anywhere.
|
|
541
|
+
//
|
|
542
|
+
// Everything here is pure: no DOM, no fetch, no clock (every caller passes `now`). The delegated
|
|
543
|
+
// event wiring, the fetches and the toast copy stay in the surface that owns them.
|
|
544
|
+
|
|
545
|
+
var MACHINES_PAGE_AUDIT_LIMIT = 20;
|
|
546
|
+
var MACHINES_PAGE_TRUST_VALUES = ['ask', 'always', 'never'];
|
|
547
|
+
var MACHINES_PAGE_TRUST_DEFAULT = 'ask';
|
|
548
|
+
// R-13's timed grant — the TTL a pending ask's "For 1 hour" buttons are answered with (D-1).
|
|
549
|
+
var MACHINES_PAGE_GRANT_TTL_SEC = 3600;
|
|
550
|
+
var HUB_BRIDGE_DENY_LABEL = 'Deny';
|
|
551
|
+
var HUB_BRIDGE_REVOKE_LABEL = 'Revoke';
|
|
552
|
+
// WP-2 (docs/hub-bridge-approval-scopes-2026-11-01.html §6.3, D-1/D-3): the four answers to an ask are
|
|
553
|
+
// the product of a SCOPE (this session / every session of the asking machine) and a DURATION (1 hour,
|
|
554
|
+
// held in memory / always, persisted in the trust file). The machine scope travels as the `'*'` caller
|
|
555
|
+
// id on the wire, in memory and on disk. No answer writes machine trust, so none changes the mesh.
|
|
556
|
+
var HUB_BRIDGE_ALL_SESSIONS = '*';
|
|
557
|
+
var HUB_BRIDGE_GRANT_GROUPS = [
|
|
558
|
+
{ key: 'hour', label: 'For 1 hour', choices: ['session-hour', 'machine-hour'] },
|
|
559
|
+
{ key: 'always', label: 'Always', choices: ['session-always', 'machine-always'] },
|
|
560
|
+
];
|
|
561
|
+
var HUB_BRIDGE_GRANT_CHOICES = {
|
|
562
|
+
'session-hour': { scope: 'session', always: false, label: 'This session', primary: true },
|
|
563
|
+
'machine-hour': { scope: 'machine', always: false, label: 'All sessions' },
|
|
564
|
+
'session-always': { scope: 'session', always: true, label: 'This session' },
|
|
565
|
+
'machine-always': { scope: 'machine', always: true, label: 'All sessions' },
|
|
566
|
+
};
|
|
567
|
+
var HUB_BRIDGE_TIER_VERBS = { read: 'read files', exec: 'run commands', browser: 'use the browser' };
|
|
568
|
+
var HUB_BRIDGE_FOOT_NOTE = 'Change later on the Machines page';
|
|
569
|
+
// The head's lock: an inline SVG (14 px, stroke currentColor) — no emoji, no external asset.
|
|
570
|
+
var HUB_BRIDGE_LOCK_SVG = '<svg class="hbb-lock" width="14" height="14" viewBox="0 0 24 24" fill="none"'
|
|
571
|
+
+ ' stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"'
|
|
572
|
+
+ ' aria-hidden="true" focusable="false"><rect x="4" y="10" width="16" height="11" rx="2"></rect>'
|
|
573
|
+
+ '<path d="M8 10V7a4 4 0 0 1 8 0v3"></path></svg>';
|
|
574
|
+
|
|
575
|
+
// The desktop's class names. A caller overrides what it needs through `opts.classes`.
|
|
576
|
+
var MACHINE_ACCESS_CLASSES = Object.freeze({
|
|
577
|
+
block: 'mpc-access',
|
|
578
|
+
head: 'mpc-access-head',
|
|
579
|
+
list: 'mpc-access-list',
|
|
580
|
+
rowPending: 'mpc-pending',
|
|
581
|
+
rowGrant: 'mpc-grant',
|
|
582
|
+
rowAudit: 'mpc-audit',
|
|
583
|
+
text: 'mpc-access-text',
|
|
584
|
+
btn: 'mpc-btn mpc-access-btn',
|
|
585
|
+
btnDanger: 'mpc-btn mpc-access-btn mpc-danger',
|
|
586
|
+
trust: 'mpc-trust',
|
|
587
|
+
trustSelect: 'mpc-trust-select',
|
|
588
|
+
trustAll: 'mpc-trust-all',
|
|
589
|
+
// The approval prompt's own structural classes (§6.5). They are `hbb-*` on BOTH surfaces — the two
|
|
590
|
+
// surfaces differ only in the stylesheet that dresses them (public/css/app.css vs public/m/app.css).
|
|
591
|
+
// NOTE: `bannerHead` (not `head`) because `head` above is the Access block's own header row.
|
|
592
|
+
grants: 'hbb-grants',
|
|
593
|
+
grantLabel: 'hbb-label',
|
|
594
|
+
grantSeg: 'hbb-seg',
|
|
595
|
+
grantBtn: 'hbb-btn',
|
|
596
|
+
grantPrimary: 'hbb-primary',
|
|
597
|
+
detail: 'hbb-detail',
|
|
598
|
+
deny: 'hbb-deny',
|
|
599
|
+
foot: 'hbb-foot',
|
|
600
|
+
note: 'hbb-note',
|
|
601
|
+
bannerHead: 'hbb-head',
|
|
602
|
+
icon: 'hbb-icon',
|
|
603
|
+
tier: 'hbb-tier',
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
// The phone's class names (public/m/app.js). Same structure, same hooks, different prefix.
|
|
607
|
+
var MACHINE_ACCESS_CLASSES_PHONE = Object.freeze(Object.assign({}, MACHINE_ACCESS_CLASSES, {
|
|
608
|
+
block: 'mp-access',
|
|
609
|
+
head: 'mp-access-head',
|
|
610
|
+
list: 'mp-access-list',
|
|
611
|
+
rowPending: 'mp-access-row mp-access-pending',
|
|
612
|
+
rowGrant: 'mp-access-row mp-access-grant',
|
|
613
|
+
rowAudit: 'mp-access-row mp-access-audit',
|
|
614
|
+
text: 'mp-access-text',
|
|
615
|
+
btn: 'mp-btn',
|
|
616
|
+
btnDanger: 'mp-btn mp-danger',
|
|
617
|
+
trust: 'mp-access-trust',
|
|
618
|
+
trustSelect: '',
|
|
619
|
+
trustAll: 'mp-access-trust-all',
|
|
620
|
+
}));
|
|
621
|
+
|
|
622
|
+
function machineAccessClasses(overrides) {
|
|
623
|
+
if (!overrides || typeof overrides !== 'object') return MACHINE_ACCESS_CLASSES;
|
|
624
|
+
return Object.assign({}, MACHINE_ACCESS_CLASSES, overrides);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// The escaper a caller hands in is the surface's own (desktop mEsc / phone esc). This fallback is
|
|
628
|
+
// the phone's own map, so a bare vm realm still renders escaped text rather than raw server bytes.
|
|
629
|
+
function machineEscape(value) {
|
|
630
|
+
return String(value == null ? '' : value).replace(/[&<>"']/g, function (ch) {
|
|
631
|
+
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[ch];
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
function machineAccessEsc(opts) {
|
|
636
|
+
return (opts && typeof opts.esc === 'function') ? opts.esc : machineEscape;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/** "45s" / "12m" / "3h" — the age/ttl unit every Access row prints. */
|
|
640
|
+
function machineSpanText(totalSeconds) {
|
|
641
|
+
var secs = Math.max(0, Math.round(Number(totalSeconds) || 0));
|
|
642
|
+
if (secs < 60) return secs + 's';
|
|
643
|
+
if (secs < 3600) return Math.round(secs / 60) + 'm';
|
|
644
|
+
return Math.round(secs / 3600) + 'h';
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/** The session short id every Access row prints (8 chars, like the tab strip). */
|
|
648
|
+
function machineShortId(value) {
|
|
649
|
+
return String(value || '').slice(0, 8);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/** R-11: a machine's effective policy — its own row when it is one of the three values, else the default. */
|
|
653
|
+
function machineEffectiveTrust(trust, instanceId) {
|
|
654
|
+
var id = String(instanceId || '');
|
|
655
|
+
if (trust && trust.machines && Object.prototype.hasOwnProperty.call(trust.machines, id)) {
|
|
656
|
+
var own = String(trust.machines[id]);
|
|
657
|
+
if (MACHINES_PAGE_TRUST_VALUES.indexOf(own) !== -1) return own;
|
|
658
|
+
}
|
|
659
|
+
var dflt = trust && String(trust.default || '');
|
|
660
|
+
return MACHINES_PAGE_TRUST_VALUES.indexOf(dflt) !== -1 ? dflt : MACHINES_PAGE_TRUST_DEFAULT;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function machineTrustOptionsHtml(trust, instanceId, opts) {
|
|
664
|
+
var esc = machineAccessEsc(opts);
|
|
665
|
+
var current = machineEffectiveTrust(trust, instanceId);
|
|
666
|
+
return [['ask', 'Ask'], ['always', 'Always'], ['never', 'Never']].map(function (pair) {
|
|
667
|
+
return '<option value="' + esc(pair[0]) + '"' + (pair[0] === current ? ' selected' : '') + '>' + esc(pair[1]) + '</option>';
|
|
668
|
+
}).join('');
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// R-11's per-machine select. The id rides a data attribute (not an inline handler), so one delegated
|
|
672
|
+
// listener per surface serves every render, and a repaint can never strand a handler.
|
|
673
|
+
function machineTrustSelectHtml(instanceId, trust, opts) {
|
|
674
|
+
var esc = machineAccessEsc(opts);
|
|
675
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
676
|
+
var cls = classes.trustSelect ? ' class="' + esc(classes.trustSelect) + '"' : '';
|
|
677
|
+
return '<label class="' + esc(classes.trust) + '">Can use this Mac:'
|
|
678
|
+
+ '<select' + cls + ' data-hub-bridge-trust="' + esc(String(instanceId || '')) + '"'
|
|
679
|
+
+ ' aria-label="Can use this Mac">'
|
|
680
|
+
+ machineTrustOptionsHtml(trust, instanceId, opts) + '</select></label>';
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/** R-13's page switch: 'always' on, 'ask' off. */
|
|
684
|
+
function machineTrustAllHtml(trust, opts) {
|
|
685
|
+
var esc = machineAccessEsc(opts);
|
|
686
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
687
|
+
var on = !!(trust && String(trust.default || '') === 'always');
|
|
688
|
+
return '<label class="' + esc(classes.trustAll) + '">'
|
|
689
|
+
+ '<input type="checkbox"' + (on ? ' checked' : '') + ' data-hub-bridge-trust-all> Trust all my machines</label>';
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* One active grant: tier, whose session it covers, how long is left, [Revoke]. A machine-scope row is
|
|
694
|
+
* written `'*'` on the wire, so the row says "all sessions"; an `always` row has no ttl at all.
|
|
695
|
+
*/
|
|
696
|
+
function machineGrantRowHtml(row, now, opts) {
|
|
697
|
+
var esc = machineAccessEsc(opts);
|
|
698
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
699
|
+
var r = row || {};
|
|
700
|
+
var left = Math.max(0, Math.round((Number(r.expiresAt || 0) - Number(now || 0)) / 1000));
|
|
701
|
+
var who = String(r.callerSessionId || '') === HUB_BRIDGE_ALL_SESSIONS ? 'all sessions' : machineShortId(r.callerSessionId);
|
|
702
|
+
var when = r.always === true ? 'always' : machineSpanText(left) + ' left';
|
|
703
|
+
var text = String(r.tier || '') + ' · ' + who + ' · ' + when;
|
|
704
|
+
return '<div class="' + esc(classes.rowGrant) + '" data-grant-tier="' + esc(r.tier) + '">'
|
|
705
|
+
+ '<span class="' + esc(classes.text) + '">' + esc(text) + '</span>'
|
|
706
|
+
+ '<button type="button" class="' + esc(classes.btn) + '" data-hub-bridge="revoke"'
|
|
707
|
+
+ ' data-machine-id="' + esc(r.machineId) + '"'
|
|
708
|
+
+ ' data-session-id="' + esc(r.callerSessionId) + '"'
|
|
709
|
+
+ ' data-tier="' + esc(r.tier) + '">' + esc(HUB_BRIDGE_REVOKE_LABEL) + '</button>'
|
|
710
|
+
+ '</div>';
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/** The verb the sentence and every title use for a tier; an unknown tier is shown as its raw word. */
|
|
714
|
+
function hubBridgeTierVerb(tier) {
|
|
715
|
+
var word = String(tier || '');
|
|
716
|
+
return HUB_BRIDGE_TIER_VERBS[word] || word;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/** The asking machine's name, or the same fallback the sentence uses. */
|
|
720
|
+
function hubBridgeMachineName(row) {
|
|
721
|
+
return String((row || {}).machineName || '') || 'another machine';
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* The full answer one grant button spells out (D-7), e.g. "Allow this session to read files on this Mac
|
|
726
|
+
* for 1 hour" / "Allow every session on Box-1 to run commands on this Mac until revoked". An unknown or
|
|
727
|
+
* empty key is the narrowest grant (session + 1 hour), so a stale button can never widen a permission.
|
|
728
|
+
*/
|
|
729
|
+
function hubBridgeGrantTitle(row, key) {
|
|
730
|
+
var r = row || {};
|
|
731
|
+
var choice = HUB_BRIDGE_GRANT_CHOICES[key] || HUB_BRIDGE_GRANT_CHOICES['session-hour'];
|
|
732
|
+
var who = choice.scope === 'machine' ? 'every session on ' + hubBridgeMachineName(r) : 'this session';
|
|
733
|
+
var when = choice.always ? 'until revoked' : 'for 1 hour';
|
|
734
|
+
return 'Allow ' + who + ' to ' + hubBridgeTierVerb(r.tier) + ' on this Mac ' + when;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* The two labelled segmented pairs (D-7, D-10): "For 1 hour" and "Always", each [This session | All
|
|
739
|
+
* sessions]. Only 1 hour · This session is filled. Each pair is a role="group" labelled by the span
|
|
740
|
+
* beside it, whose id is unique per pending row, so a page full of asks still names each pair once.
|
|
741
|
+
*/
|
|
742
|
+
function hubBridgeGrantChoicesHtml(row, opts) {
|
|
743
|
+
var esc = machineAccessEsc(opts);
|
|
744
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
745
|
+
var r = row || {};
|
|
746
|
+
var id = String(r.id || '');
|
|
747
|
+
return '<div class="' + esc(classes.grants) + '">' + HUB_BRIDGE_GRANT_GROUPS.map(function (group) {
|
|
748
|
+
var labelId = 'hbg-' + id + '-' + group.key;
|
|
749
|
+
return '<span class="' + esc(classes.grantLabel) + '" id="' + esc(labelId) + '">' + esc(group.label) + '</span>'
|
|
750
|
+
+ '<div class="' + esc(classes.grantSeg) + '" role="group" aria-labelledby="' + esc(labelId) + '">'
|
|
751
|
+
+ group.choices.map(function (key) {
|
|
752
|
+
var choice = HUB_BRIDGE_GRANT_CHOICES[key];
|
|
753
|
+
var title = hubBridgeGrantTitle(r, key);
|
|
754
|
+
return '<button type="button" class="' + esc(classes.grantBtn) + (choice.primary ? ' ' + esc(classes.grantPrimary) : '') + '"'
|
|
755
|
+
+ ' data-hub-bridge="allow" data-grant="' + esc(key) + '" data-pending-id="' + esc(id) + '"'
|
|
756
|
+
+ ' title="' + esc(title) + '" aria-label="' + esc(title) + '">' + esc(choice.label) + '</button>';
|
|
757
|
+
}).join('')
|
|
758
|
+
+ '</div>';
|
|
759
|
+
}).join('') + '</div>';
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/** One open ask: the text line as before, the two grant groups, and Deny set apart (D-8). */
|
|
763
|
+
function machinePendingRowHtml(row, opts) {
|
|
764
|
+
var esc = machineAccessEsc(opts);
|
|
765
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
766
|
+
var r = row || {};
|
|
767
|
+
var id = String(r.id || '');
|
|
768
|
+
var text = String(r.tier || '') + ' · ' + String(r.op || '') + (r.summary ? ' · ' + String(r.summary) : '');
|
|
769
|
+
return '<div class="' + esc(classes.rowPending) + '" data-pending-id="' + esc(id) + '">'
|
|
770
|
+
+ '<span class="' + esc(classes.text) + '">' + esc(text) + '</span>'
|
|
771
|
+
+ hubBridgeGrantChoicesHtml(r, opts)
|
|
772
|
+
+ '<button type="button" class="' + esc(classes.deny) + '" data-hub-bridge="deny"'
|
|
773
|
+
+ ' data-pending-id="' + esc(id) + '">' + esc(HUB_BRIDGE_DENY_LABEL) + '</button>'
|
|
774
|
+
+ '</div>';
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/** One audit line: op, session short id, ok/code, age. */
|
|
778
|
+
function machineAuditRowHtml(row, now, opts) {
|
|
779
|
+
var esc = machineAccessEsc(opts);
|
|
780
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
781
|
+
var r = row || {};
|
|
782
|
+
var age = machineSpanText((Number(now || 0) - (Number(r.at) || 0)) / 1000);
|
|
783
|
+
var verdict = r.ok === true ? 'ok' : ('fail' + (r.code ? ' ' + String(r.code) : ''));
|
|
784
|
+
var text = String(r.op || '') + ' · ' + machineShortId(r.callerSessionId) + ' · ' + verdict + ' · ' + age + ' ago';
|
|
785
|
+
return '<div class="' + esc(classes.rowAudit) + '" data-audit-ok="' + (r.ok === true ? 'true' : 'false') + '">'
|
|
786
|
+
+ '<span class="' + esc(classes.text) + '">' + esc(text) + '</span>'
|
|
787
|
+
+ '</div>';
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* R-13's Access block. `data` is already-fetched: { trust, grants, pending, audit, now }, all of it
|
|
792
|
+
* filtered to this machine by the caller (or by machineAccessRowsFor below).
|
|
793
|
+
*/
|
|
794
|
+
function machineAccessBlockHtml(machineId, data, opts) {
|
|
795
|
+
var id = String(machineId || '');
|
|
796
|
+
if (!id) return '';
|
|
797
|
+
var esc = machineAccessEsc(opts);
|
|
798
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
799
|
+
var input = data || {};
|
|
800
|
+
var now = Number(input.now || 0);
|
|
801
|
+
var pending = (Array.isArray(input.pending) ? input.pending : []).map(function (row) { return machinePendingRowHtml(row, opts); }).join('');
|
|
802
|
+
var grants = (Array.isArray(input.grants) ? input.grants : []).map(function (row) { return machineGrantRowHtml(row, now, opts); }).join('');
|
|
803
|
+
var audit = (Array.isArray(input.audit) ? input.audit : []).slice(0, MACHINES_PAGE_AUDIT_LIMIT)
|
|
804
|
+
.map(function (row) { return machineAuditRowHtml(row, now, opts); }).join('');
|
|
805
|
+
return '<div class="' + esc(classes.block) + '" data-machine-id="' + esc(id) + '">'
|
|
806
|
+
+ '<div class="' + esc(classes.head) + '">' + machineTrustSelectHtml(id, input.trust, opts) + '</div>'
|
|
807
|
+
+ (pending ? '<div class="' + esc(classes.list) + '">' + pending + '</div>' : '')
|
|
808
|
+
+ (grants ? '<div class="' + esc(classes.list) + '">' + grants + '</div>' : '')
|
|
809
|
+
+ (audit ? '<div class="' + esc(classes.list) + '">' + audit + '</div>' : '')
|
|
810
|
+
+ '</div>';
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/** The rows of one machine out of the hub's whole table (one host's rows, never another's). */
|
|
814
|
+
function machineAccessRowsFor(rows, machineId) {
|
|
815
|
+
var id = String(machineId || '');
|
|
816
|
+
return (Array.isArray(rows) ? rows : []).filter(function (row) {
|
|
817
|
+
return row && String(row.machineId || '') === id;
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// ── AC-2g / D-6: the approval banner ─────────────────────────────────────────────────────────────
|
|
822
|
+
/**
|
|
823
|
+
* "This session on <machineName> wants to <verb> on this Mac" — the ONE banner sentence (D-6). The
|
|
824
|
+
* summary is NOT part of it: the prompt shows it on its own monospace detail line, so the sentence
|
|
825
|
+
* stays readable and nothing has to fit inside parentheses.
|
|
826
|
+
*/
|
|
827
|
+
function hubBridgeBannerText(row) {
|
|
828
|
+
var r = row || {};
|
|
829
|
+
return 'This session on ' + hubBridgeMachineName(r) + ' wants to ' + hubBridgeTierVerb(r.tier) + ' on this Mac';
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function hubBridgeBannerHtml(row, opts) {
|
|
833
|
+
var esc = machineAccessEsc(opts);
|
|
834
|
+
var classes = machineAccessClasses(opts && opts.classes);
|
|
835
|
+
var r = row || {};
|
|
836
|
+
var id = String(r.id || '');
|
|
837
|
+
var summary = String(r.summary || '');
|
|
838
|
+
return '<div class="' + esc(classes.bannerHead) + '">'
|
|
839
|
+
+ '<span class="' + esc(classes.icon) + '">' + HUB_BRIDGE_LOCK_SVG + '</span>'
|
|
840
|
+
+ '<span class="hub-bridge-banner-text">This session on <b>' + esc(hubBridgeMachineName(r)) + '</b>'
|
|
841
|
+
+ ' wants to <b>' + esc(hubBridgeTierVerb(r.tier)) + '</b> on this Mac</span>'
|
|
842
|
+
+ '<span class="' + esc(classes.tier) + '">' + esc(String(r.tier || '')) + '</span>'
|
|
843
|
+
+ '</div>'
|
|
844
|
+
+ (summary ? '<code class="' + esc(classes.detail) + '">' + esc(summary) + '</code>' : '')
|
|
845
|
+
+ hubBridgeGrantChoicesHtml(r, opts)
|
|
846
|
+
+ '<div class="' + esc(classes.foot) + '">'
|
|
847
|
+
+ '<span class="' + esc(classes.note) + '">' + esc(HUB_BRIDGE_FOOT_NOTE) + '</span>'
|
|
848
|
+
+ '<button type="button" class="' + esc(classes.deny) + '" data-hub-bridge="deny"'
|
|
849
|
+
+ ' data-pending-id="' + esc(id) + '">' + esc(HUB_BRIDGE_DENY_LABEL) + '</button>'
|
|
850
|
+
+ '</div>';
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// ── the request bodies (§6.2) ────────────────────────────────────────────────────────────────────
|
|
854
|
+
function hubBridgeTrustBody(instanceId, value) {
|
|
855
|
+
var body = { machines: {} };
|
|
856
|
+
body.machines[String(instanceId || '')] = String(value || '');
|
|
857
|
+
return body;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function hubBridgeTrustAllBody(on) {
|
|
861
|
+
return { default: on ? 'always' : 'ask' };
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* The ask's OWN machine/session/tier is what is granted — never the card's id — and the answer key says
|
|
866
|
+
* which scope and duration (D-1). A machine-scope answer carries `'*'` as the caller session; an
|
|
867
|
+
* `always` answer carries `always: true` and no ttl; the 1 h answers carry the clamped ttl. An unknown
|
|
868
|
+
* or missing key is the narrowest grant, so a stale button can never widen a permission.
|
|
869
|
+
*/
|
|
870
|
+
function hubBridgeGrantBody(row, fallbackMachineId, key) {
|
|
871
|
+
var r = row || {};
|
|
872
|
+
var choice = HUB_BRIDGE_GRANT_CHOICES[key] || HUB_BRIDGE_GRANT_CHOICES['session-hour'];
|
|
873
|
+
var body = {
|
|
874
|
+
machineId: String(r.machineId || fallbackMachineId || ''),
|
|
875
|
+
callerSessionId: choice.scope === 'machine' ? HUB_BRIDGE_ALL_SESSIONS : String(r.callerSessionId || ''),
|
|
876
|
+
tier: String(r.tier || ''),
|
|
877
|
+
};
|
|
878
|
+
if (choice.always) body.always = true;
|
|
879
|
+
else body.ttlSec = MACHINES_PAGE_GRANT_TTL_SEC;
|
|
880
|
+
return body;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* The ONE call that answers an ask, as [path, init]. Every one of the four answers POSTs a grant of the
|
|
885
|
+
* ask's own tier — none writes trust, so none changes the box's policy or its mesh membership (D-2).
|
|
886
|
+
*/
|
|
887
|
+
function hubBridgeAnswerCall(row, fallbackMachineId, key) {
|
|
888
|
+
return ['/api/hub-bridge/grants', { method: 'POST', body: hubBridgeGrantBody(row, fallbackMachineId, key) }];
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
function hubBridgeRevokeBody(instanceId, callerSessionId, tier) {
|
|
892
|
+
return {
|
|
893
|
+
machineId: String(instanceId || ''),
|
|
894
|
+
callerSessionId: String(callerSessionId || ''),
|
|
895
|
+
tier: String(tier || ''),
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
function hubBridgeDenyPath(pendingId) {
|
|
900
|
+
return '/api/hub-bridge/pending/' + encodeURIComponent(String(pendingId || '')) + '/deny';
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// The keys one surface binds for the delegated listeners above: the trust select and the page switch
|
|
904
|
+
// are `change`, the three actions are `click`.
|
|
905
|
+
var HUB_BRIDGE_TRUST_HOOK = '[data-hub-bridge-trust], [data-hub-bridge-trust-all]';
|
|
906
|
+
var HUB_BRIDGE_ACTION_HOOK = '[data-hub-bridge]';
|
|
907
|
+
|
|
399
908
|
if (typeof module === 'object' && module.exports) {
|
|
400
909
|
module.exports = {
|
|
401
910
|
MACHINE_STATS_STALE_MS: MACHINE_STATS_STALE_MS,
|
|
@@ -432,5 +941,51 @@ if (typeof module === 'object' && module.exports) {
|
|
|
432
941
|
machineAgentText: machineAgentText,
|
|
433
942
|
machineTaskLine: machineTaskLine,
|
|
434
943
|
machineGpuText: machineGpuText,
|
|
944
|
+
machinePowerText: machinePowerText,
|
|
945
|
+
MACHINE_FLEET_UNKNOWN_SHA: MACHINE_FLEET_UNKNOWN_SHA,
|
|
946
|
+
machineFleetSha7: machineFleetSha7,
|
|
947
|
+
machineFleetVerdictLine: machineFleetVerdictLine,
|
|
948
|
+
machineFleetLine: machineFleetLine,
|
|
949
|
+
// WP-4 hub-bridge access (R-4/R-5/R-9/R-11/R-13, AC-2g)
|
|
950
|
+
MACHINES_PAGE_AUDIT_LIMIT: MACHINES_PAGE_AUDIT_LIMIT,
|
|
951
|
+
MACHINES_PAGE_TRUST_VALUES: MACHINES_PAGE_TRUST_VALUES,
|
|
952
|
+
MACHINES_PAGE_TRUST_DEFAULT: MACHINES_PAGE_TRUST_DEFAULT,
|
|
953
|
+
MACHINES_PAGE_GRANT_TTL_SEC: MACHINES_PAGE_GRANT_TTL_SEC,
|
|
954
|
+
HUB_BRIDGE_ALL_SESSIONS: HUB_BRIDGE_ALL_SESSIONS,
|
|
955
|
+
HUB_BRIDGE_GRANT_GROUPS: HUB_BRIDGE_GRANT_GROUPS,
|
|
956
|
+
HUB_BRIDGE_GRANT_CHOICES: HUB_BRIDGE_GRANT_CHOICES,
|
|
957
|
+
HUB_BRIDGE_TIER_VERBS: HUB_BRIDGE_TIER_VERBS,
|
|
958
|
+
HUB_BRIDGE_FOOT_NOTE: HUB_BRIDGE_FOOT_NOTE,
|
|
959
|
+
HUB_BRIDGE_DENY_LABEL: HUB_BRIDGE_DENY_LABEL,
|
|
960
|
+
HUB_BRIDGE_REVOKE_LABEL: HUB_BRIDGE_REVOKE_LABEL,
|
|
961
|
+
MACHINE_ACCESS_CLASSES: MACHINE_ACCESS_CLASSES,
|
|
962
|
+
MACHINE_ACCESS_CLASSES_PHONE: MACHINE_ACCESS_CLASSES_PHONE,
|
|
963
|
+
HUB_BRIDGE_TRUST_HOOK: HUB_BRIDGE_TRUST_HOOK,
|
|
964
|
+
HUB_BRIDGE_ACTION_HOOK: HUB_BRIDGE_ACTION_HOOK,
|
|
965
|
+
machineAccessClasses: machineAccessClasses,
|
|
966
|
+
machineEscape: machineEscape,
|
|
967
|
+
machineSpanText: machineSpanText,
|
|
968
|
+
machineShortId: machineShortId,
|
|
969
|
+
machineEffectiveTrust: machineEffectiveTrust,
|
|
970
|
+
machineTrustOptionsHtml: machineTrustOptionsHtml,
|
|
971
|
+
machineTrustSelectHtml: machineTrustSelectHtml,
|
|
972
|
+
machineTrustAllHtml: machineTrustAllHtml,
|
|
973
|
+
machineGrantRowHtml: machineGrantRowHtml,
|
|
974
|
+
machinePendingRowHtml: machinePendingRowHtml,
|
|
975
|
+
machineAuditRowHtml: machineAuditRowHtml,
|
|
976
|
+
machineAccessBlockHtml: machineAccessBlockHtml,
|
|
977
|
+
machineAccessRowsFor: machineAccessRowsFor,
|
|
978
|
+
hubBridgeBannerText: hubBridgeBannerText,
|
|
979
|
+
hubBridgeTierVerb: hubBridgeTierVerb,
|
|
980
|
+
hubBridgeMachineName: hubBridgeMachineName,
|
|
981
|
+
hubBridgeGrantTitle: hubBridgeGrantTitle,
|
|
982
|
+
hubBridgeGrantChoicesHtml: hubBridgeGrantChoicesHtml,
|
|
983
|
+
hubBridgeBannerHtml: hubBridgeBannerHtml,
|
|
984
|
+
hubBridgeTrustBody: hubBridgeTrustBody,
|
|
985
|
+
hubBridgeTrustAllBody: hubBridgeTrustAllBody,
|
|
986
|
+
hubBridgeGrantBody: hubBridgeGrantBody,
|
|
987
|
+
hubBridgeAnswerCall: hubBridgeAnswerCall,
|
|
988
|
+
hubBridgeRevokeBody: hubBridgeRevokeBody,
|
|
989
|
+
hubBridgeDenyPath: hubBridgeDenyPath,
|
|
435
990
|
};
|
|
436
991
|
}
|
|
@@ -324,6 +324,7 @@
|
|
|
324
324
|
return MR.stripImageAttachmentMetadata(text);
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
const _userPromptMarkdown = (t) => (typeof PastedContent !== 'undefined' && PastedContent ? PastedContent.toMarkdown(String(t || '')) : String(t || '')); // D-6 (WP-2): a USER card's paste wrapper → a literal fenced `text` block; typed text around it still renders as markdown, assistant rows never call this
|
|
327
328
|
function _appendReviewAttachmentsHtml(message) {
|
|
328
329
|
const html = MR.renderImageAttachmentsHtml(message);
|
|
329
330
|
return html ? html : '';
|
|
@@ -2524,9 +2525,9 @@
|
|
|
2524
2525
|
const metaCard = MR.renderMetaCardHtml(m, i);
|
|
2525
2526
|
if (metaCard) return metaCard;
|
|
2526
2527
|
const time = m.timestamp ? new Date(m.timestamp).toLocaleString() : '';
|
|
2527
|
-
const displayText = _messageTextForDisplay(m.text || '');
|
|
2528
|
+
const displayText = _messageTextForDisplay(m.role === 'user' ? _userPromptMarkdown(m.text || '') : (m.text || ''));
|
|
2528
2529
|
const attachmentHtml = _appendReviewAttachmentsHtml(Object.assign({}, m, { text: m.text || '' }));
|
|
2529
|
-
const textHtml = _formatDisplayTextHtml(m.text || '', attachmentHtml ? '<span class="msg-empty">(image attachment)</span>' : '');
|
|
2530
|
+
const textHtml = _formatDisplayTextHtml(m.role === 'user' ? _userPromptMarkdown(m.text || '') : (m.text || ''), attachmentHtml ? '<span class="msg-empty">(image attachment)</span>' : '');
|
|
2530
2531
|
const hasRenderedText = !!String(textHtml || '').trim();
|
|
2531
2532
|
const needsCollapse = displayText.length > 1500 || displayText.split('\n').length > 30;
|
|
2532
2533
|
const stripped = displayText.replace(/\[Tool: [^\]]+\]/g, '').trim();
|
|
@@ -3624,7 +3625,7 @@
|
|
|
3624
3625
|
div.className = 'review-msg user';
|
|
3625
3626
|
if (evt.data?.parentUuid) div.dataset.parentUuid = evt.data.parentUuid;
|
|
3626
3627
|
div.appendChild(_makeHeader('You', time, text));
|
|
3627
|
-
if (!_appendTextWithExpand(div, text, evt.data || evt)) return null;
|
|
3628
|
+
if (!_appendTextWithExpand(div, _userPromptMarkdown(text), evt.data || evt)) return null;
|
|
3628
3629
|
return div;
|
|
3629
3630
|
}
|
|
3630
3631
|
|
|
@@ -580,7 +580,9 @@
|
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
582
|
updateRoleValues();
|
|
583
|
-
|
|
583
|
+
// renderActions(): an action whose label depends on the loaded answer (the OpenCode mode verdict)
|
|
584
|
+
// must repaint when the answer lands, not only on open()/switchTab().
|
|
585
|
+
if (activeTab === tab) { renderList(); renderDetail(); position(anchor, popover); renderActions(); }
|
|
584
586
|
}, function(err) {
|
|
585
587
|
if (closed || gen !== st.gen) return;
|
|
586
588
|
st.loading = false;
|