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
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Landing-throughput WP-6 shard S14 (design doc §5 D-10 "move-only", §6 "Shard module
|
|
4
|
+
// seam"): the conversation-freshness diagnostics pair (_conversationFreshnessDiagnostics plus its
|
|
5
|
+
// private helper _conversationPermanentStaleSnapshot) moves out of server.js VERBATIM into this
|
|
6
|
+
// module behind the same configure(deps) seam as lib/api/session-attach.js and
|
|
7
|
+
// lib/terminal-attach-geometry.js (S6), lib/walle-history-serve.js (S8),
|
|
8
|
+
// lib/codex-rollout-history.js (S9), lib/terminal-input-prepared.js (S10), lib/idle-notify.js
|
|
9
|
+
// (S11), lib/session-park.js (S12) and lib/terminal-draft-operation.js (S13). It registers NO
|
|
10
|
+
// route and NO socket handler: server.js keeps the one pass-through call site as
|
|
11
|
+
// conversationFreshnessDiagnostics._conversationFreshnessDiagnostics(id) (inside
|
|
12
|
+
// apiDiagnosticsConversationFreshness) and this configure() seam. Bodies are identical to the
|
|
13
|
+
// server.js declarations except for the `_deps.` prefix on every identifier that used to resolve
|
|
14
|
+
// to a server.js top-level binding (D-10 rule 1), proven by `node bin/move-only-check.js`.
|
|
15
|
+
// Two inline `require('./lib/...')` calls are rebased to this module's own `require('./...')`
|
|
16
|
+
// (S8 precedent: one move-only DIFF per rebased require -- the remainder is proven by re-running
|
|
17
|
+
// against a copy with `sed "s#require('\./#require('./lib/#g"` applied).
|
|
18
|
+
//
|
|
19
|
+
// The module deliberately lives at lib/conversation-freshness-diagnostics.js and NOT under lib/ws/:
|
|
20
|
+
// this is the read-only /api/diagnostics/conversation-freshness view, not a ws-router handler.
|
|
21
|
+
//
|
|
22
|
+
// Injected deps, per function:
|
|
23
|
+
// _conversationFreshnessDiagnostics: _conversationFreshnessDebtSnapshot, _coopScheduler, _ctmDbWorker, _jsonlWatcher, _resolveCanonicalRowSources, _sessionMessageRowsHwm, _sessionRowsFreshnessForSource, crypto, dbModule, getConversationImportConvergenceStats, historySourceSupport, listSelfLinkedConversationPartitions, path, providerAdapterKind
|
|
24
|
+
// _conversationPermanentStaleSnapshot: _conversationPermanentStale, _conversationPermanentStaleCount
|
|
25
|
+
//
|
|
26
|
+
// Mutable module state (D-10 rule 2 / S9 lesson 7): _coopScheduler, _ctmDbWorker, _jsonlWatcher and
|
|
27
|
+
// _conversationPermanentStaleCount are server.js `let`s, so each is injected as a GETTER -- never a
|
|
28
|
+
// copy. No moved body ASSIGNS a server.js top-level binding, so this seam carries no get/set pair.
|
|
29
|
+
// _conversationPermanentStale (a `const` Map) and every function dep are by-value references.
|
|
30
|
+
// Calls between the two moved functions stay direct (no `_deps.`).
|
|
31
|
+
|
|
32
|
+
let _deps = null;
|
|
33
|
+
|
|
34
|
+
function configure(deps = {}) {
|
|
35
|
+
_deps = deps;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function _conversationFreshnessDiagnostics(requestedId) {
|
|
39
|
+
const id = String(requestedId || '').trim();
|
|
40
|
+
const resolution = _deps._resolveCanonicalRowSources(id);
|
|
41
|
+
const sourceIds = [
|
|
42
|
+
id,
|
|
43
|
+
resolution?.canonicalSessionId,
|
|
44
|
+
...(Array.isArray(resolution?.sources) ? resolution.sources.map(s => s.id) : []),
|
|
45
|
+
].filter(Boolean);
|
|
46
|
+
const uniqueSourceIds = [...new Set(sourceIds)];
|
|
47
|
+
const db = _deps.dbModule.getDb();
|
|
48
|
+
const sources = (Array.isArray(resolution?.sources) ? resolution.sources : []).map((source) => {
|
|
49
|
+
const rowHwm = _deps._sessionMessageRowsHwm(source.id);
|
|
50
|
+
let freshness = null;
|
|
51
|
+
try { freshness = _deps._sessionRowsFreshnessForSource(id, source.id, { knownRowCount: rowHwm.rowCount }); } catch {}
|
|
52
|
+
return {
|
|
53
|
+
id: source.id,
|
|
54
|
+
rank: source.rank || 0,
|
|
55
|
+
reason: source.reason || '',
|
|
56
|
+
resolverRowCount: source.rowCount || 0,
|
|
57
|
+
resolverRowMaxTimestamp: source.rowMaxTimestamp || '',
|
|
58
|
+
rowHwm,
|
|
59
|
+
freshness,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const transcriptFiles = [];
|
|
64
|
+
const seenFiles = new Set();
|
|
65
|
+
for (const sourceId of uniqueSourceIds) {
|
|
66
|
+
let rows = [];
|
|
67
|
+
try {
|
|
68
|
+
rows = db.prepare(`
|
|
69
|
+
SELECT jsonl_path, agent_session_id, ctm_session_id, provider, size, offset, mtime_ms, status, last_error, updated_at
|
|
70
|
+
FROM transcript_files
|
|
71
|
+
WHERE ctm_session_id = ? OR agent_session_id = ?
|
|
72
|
+
ORDER BY updated_at DESC, jsonl_path
|
|
73
|
+
LIMIT 50
|
|
74
|
+
`).all(sourceId, sourceId);
|
|
75
|
+
} catch {}
|
|
76
|
+
for (const row of rows) {
|
|
77
|
+
const key = String(row.jsonl_path || '');
|
|
78
|
+
if (!key || seenFiles.has(key)) continue;
|
|
79
|
+
seenFiles.add(key);
|
|
80
|
+
const size = Number(row.size || 0);
|
|
81
|
+
const offset = Number(row.offset || 0);
|
|
82
|
+
transcriptFiles.push({
|
|
83
|
+
locatorBasename: _deps.path.basename(key),
|
|
84
|
+
locatorHash: _deps.crypto.createHash('sha256').update(key).digest('hex'),
|
|
85
|
+
agentSessionId: row.agent_session_id || '',
|
|
86
|
+
ctmSessionId: row.ctm_session_id || '',
|
|
87
|
+
provider: row.provider || '',
|
|
88
|
+
size,
|
|
89
|
+
offset,
|
|
90
|
+
lagBytes: Math.max(0, size - offset),
|
|
91
|
+
mtimeMs: Number(row.mtime_ms || 0),
|
|
92
|
+
status: row.status || '',
|
|
93
|
+
lastError: row.last_error || '',
|
|
94
|
+
updatedAt: row.updated_at || '',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let rowBackfillCursor = null;
|
|
100
|
+
try {
|
|
101
|
+
rowBackfillCursor = db.prepare(`
|
|
102
|
+
SELECT ctm_session_id, max_event_id, updated_at, last_scanned, last_inserted, last_error
|
|
103
|
+
FROM transcript_row_backfill_cursors
|
|
104
|
+
WHERE ctm_session_id = ?
|
|
105
|
+
`).get(resolution?.canonicalSessionId || id) || null;
|
|
106
|
+
} catch {}
|
|
107
|
+
|
|
108
|
+
let worker = null;
|
|
109
|
+
try { worker = _deps._ctmDbWorker ? _deps._ctmDbWorker.getStatus?.() : null; } catch {}
|
|
110
|
+
let publicationDebt = { pending: 0, oldestCommittedAt: '', oldestAgeMs: 0 };
|
|
111
|
+
try {
|
|
112
|
+
const debt = db.prepare(`
|
|
113
|
+
SELECT COUNT(*) AS pending, MIN(committed_at) AS oldest_committed_at
|
|
114
|
+
FROM conversation_update_outbox
|
|
115
|
+
WHERE published_at IS NULL
|
|
116
|
+
`).get();
|
|
117
|
+
const oldestCommittedAt = String(debt?.oldest_committed_at || '');
|
|
118
|
+
publicationDebt = {
|
|
119
|
+
pending: Number(debt?.pending || 0),
|
|
120
|
+
oldestCommittedAt,
|
|
121
|
+
oldestAgeMs: oldestCommittedAt ? Math.max(0, Date.now() - Date.parse(`${oldestCommittedAt}Z`)) : 0,
|
|
122
|
+
};
|
|
123
|
+
} catch {}
|
|
124
|
+
let kernelSources = [];
|
|
125
|
+
let projection = null;
|
|
126
|
+
let migration = null;
|
|
127
|
+
let rangeProtocol = null;
|
|
128
|
+
try {
|
|
129
|
+
const canonicalId = resolution?.canonicalSessionId || id;
|
|
130
|
+
const sourceRows = db.prepare(`
|
|
131
|
+
SELECT source_id, provider, adapter_kind, generation, source_version,
|
|
132
|
+
observed_hwm, committed_hwm, continuation_json, parser_version, state, last_error
|
|
133
|
+
FROM conversation_sources WHERE canonical_session_id=? ORDER BY source_id
|
|
134
|
+
`).all(canonicalId);
|
|
135
|
+
const memberQuery = db.prepare(`
|
|
136
|
+
SELECT member_id, locator_hash, locator_basename, fingerprint, member_role,
|
|
137
|
+
generation, byte_cursor, partial_line, observed_size, observed_mtime_ms, committed_hwm
|
|
138
|
+
FROM conversation_source_members WHERE source_id=? ORDER BY member_id
|
|
139
|
+
`);
|
|
140
|
+
kernelSources = sourceRows.map((row) => ({
|
|
141
|
+
sourceId: row.source_id,
|
|
142
|
+
provider: row.provider,
|
|
143
|
+
adapter: row.adapter_kind,
|
|
144
|
+
writer: 'conversation-commit-kernel',
|
|
145
|
+
generation: Number(row.generation || 0),
|
|
146
|
+
sourceVersion: Number(row.source_version || 0),
|
|
147
|
+
observedHwm: (() => { try { return JSON.parse(row.observed_hwm || '{}'); } catch { return {}; } })(),
|
|
148
|
+
committedHwm: (() => { try { return JSON.parse(row.committed_hwm || '{}'); } catch { return {}; } })(),
|
|
149
|
+
continuationPending: !!row.continuation_json,
|
|
150
|
+
parserVersion: Number(row.parser_version || 0),
|
|
151
|
+
state: row.state,
|
|
152
|
+
lastError: row.last_error || '',
|
|
153
|
+
members: memberQuery.all(row.source_id).map((member) => ({
|
|
154
|
+
memberId: member.member_id,
|
|
155
|
+
locatorHash: member.locator_hash,
|
|
156
|
+
locatorBasename: member.locator_basename,
|
|
157
|
+
fingerprint: member.fingerprint,
|
|
158
|
+
role: member.member_role,
|
|
159
|
+
generation: Number(member.generation || 0),
|
|
160
|
+
byteCursor: Number(member.byte_cursor || 0),
|
|
161
|
+
observedSize: Number(member.observed_size || 0),
|
|
162
|
+
observedMtimeMs: Number(member.observed_mtime_ms || 0),
|
|
163
|
+
partialLinePending: !!member.partial_line,
|
|
164
|
+
committedHwm: (() => { try { return JSON.parse(member.committed_hwm || '{}'); } catch { return {}; } })(),
|
|
165
|
+
})),
|
|
166
|
+
}));
|
|
167
|
+
projection = db.prepare('SELECT * FROM conversation_projection_state WHERE ctm_session_id=?').get(canonicalId) || null;
|
|
168
|
+
migration = db.prepare('SELECT * FROM conversation_migration_state WHERE provider=?').get('provider-source-enrollment') || null;
|
|
169
|
+
rangeProtocol = require('./conversation-page-v3')
|
|
170
|
+
.readConversationV3Diagnostics(db, canonicalId);
|
|
171
|
+
rangeProtocol.metrics = require('./conversation-range-metrics').snapshot(canonicalId);
|
|
172
|
+
} catch {}
|
|
173
|
+
const sourceComplete = (source) => {
|
|
174
|
+
if (!source || source.state !== 'active' || source.continuationPending) return false;
|
|
175
|
+
if (JSON.stringify(source.observedHwm || {}) !== JSON.stringify(source.committedHwm || {})) return false;
|
|
176
|
+
if (source.adapter !== 'append-log' && source.adapter !== 'compound-log') return true;
|
|
177
|
+
const currentMembers = source.members.filter((member) => member.generation === source.generation);
|
|
178
|
+
return currentMembers.length > 0 && currentMembers.every((member) => (
|
|
179
|
+
!member.partialLinePending && member.byteCursor >= member.observedSize
|
|
180
|
+
));
|
|
181
|
+
};
|
|
182
|
+
let aliasPartitions = [];
|
|
183
|
+
try {
|
|
184
|
+
// One predicate: the adoption module owns "which agent ids hold a stranded v2 partition".
|
|
185
|
+
aliasPartitions = _deps.listSelfLinkedConversationPartitions(db, _deps.dbModule.getDomainDb('core'), { limit: 100 })
|
|
186
|
+
.map((p) => ({ agentSessionId: p.agentSessionId, ownerCtmSessionId: p.ownerCtmSessionId, rowCount: p.placements }));
|
|
187
|
+
} catch {}
|
|
188
|
+
let detectedProvider = '';
|
|
189
|
+
try {
|
|
190
|
+
const canonicalId = resolution?.canonicalSessionId || id;
|
|
191
|
+
// ctm_sessions + agent_sessions are both core.
|
|
192
|
+
detectedProvider = String(_deps.dbModule.getDomainDb('core').prepare(`
|
|
193
|
+
SELECT provider FROM ctm_sessions WHERE id=?
|
|
194
|
+
UNION ALL
|
|
195
|
+
SELECT provider FROM agent_sessions WHERE ctm_session_id=? OR agent_session_id=?
|
|
196
|
+
LIMIT 1
|
|
197
|
+
`).get(canonicalId, canonicalId, id)?.provider || '').trim().toLowerCase();
|
|
198
|
+
} catch {}
|
|
199
|
+
// S-19: pass the SAME adapterKind the runtime ingest path would derive
|
|
200
|
+
// (providerAdapterKind) rather than leaving adapterKind blank — a blank
|
|
201
|
+
// adapterKind makes historySourceSupport accept ANY registered adapter for
|
|
202
|
+
// the provider, which can report "supported" for a provider/adapter
|
|
203
|
+
// combination the runtime path would actually reject, making this
|
|
204
|
+
// diagnostic disagree with reality.
|
|
205
|
+
const sourceSupport = kernelSources.length > 0
|
|
206
|
+
? _deps.historySourceSupport(kernelSources[0].provider, kernelSources[0].adapter)
|
|
207
|
+
: (detectedProvider
|
|
208
|
+
? _deps.historySourceSupport(detectedProvider, _deps.providerAdapterKind(detectedProvider))
|
|
209
|
+
: { provider: '', status: 'history_source_unclassified', supported: false });
|
|
210
|
+
const sourceSetVersion = kernelSources.reduce((total, source) => total + Number(source.sourceVersion || 0), 0);
|
|
211
|
+
const migrationComplete = !migration || !!migration.completed_at;
|
|
212
|
+
const projectionComplete = !!projection
|
|
213
|
+
&& projection.state === 'ready'
|
|
214
|
+
&& Number(projection.source_set_version || 0) === sourceSetVersion
|
|
215
|
+
&& kernelSources.length > 0
|
|
216
|
+
&& kernelSources.every(sourceComplete)
|
|
217
|
+
&& migrationComplete
|
|
218
|
+
&& aliasPartitions.length === 0;
|
|
219
|
+
return {
|
|
220
|
+
ok: true,
|
|
221
|
+
generatedAt: Date.now(),
|
|
222
|
+
requestedId: id,
|
|
223
|
+
canonicalSessionId: resolution?.canonicalSessionId || id,
|
|
224
|
+
sources,
|
|
225
|
+
transcriptFiles,
|
|
226
|
+
totalLagBytes: transcriptFiles.reduce((n, row) => n + Number(row.lagBytes || 0), 0),
|
|
227
|
+
rowBackfillCursor,
|
|
228
|
+
convergence: {
|
|
229
|
+
main: typeof _deps.getConversationImportConvergenceStats === 'function'
|
|
230
|
+
? _deps.getConversationImportConvergenceStats(id)
|
|
231
|
+
: null,
|
|
232
|
+
worker: null,
|
|
233
|
+
},
|
|
234
|
+
worker,
|
|
235
|
+
watcherRoots: _deps._jsonlWatcher?.rootHealthSnapshot?.() || [],
|
|
236
|
+
render: {
|
|
237
|
+
rowCount: _deps._sessionMessageRowsHwm(resolution?.canonicalSessionId || id).rowCount,
|
|
238
|
+
projectionEpoch: Number(projection?.projection_epoch || 0),
|
|
239
|
+
latestRowHwm: Number(projection?.latest_row_hwm || 0),
|
|
240
|
+
},
|
|
241
|
+
providerSources: kernelSources,
|
|
242
|
+
historySource: sourceSupport,
|
|
243
|
+
projectionComplete,
|
|
244
|
+
projection,
|
|
245
|
+
migration,
|
|
246
|
+
rangeProtocol,
|
|
247
|
+
rowOwnership: {
|
|
248
|
+
writer: 'conversation-commit-kernel',
|
|
249
|
+
aliasPartitionCount: aliasPartitions.length,
|
|
250
|
+
aliasRows: aliasPartitions.reduce((total, row) => total + Number(row.rowCount || 0), 0),
|
|
251
|
+
aliasPartitions,
|
|
252
|
+
},
|
|
253
|
+
publicationDebt,
|
|
254
|
+
coopJobs: _deps._coopScheduler ? _deps._coopScheduler.statusReport() : [],
|
|
255
|
+
freshnessDebt: _deps._conversationFreshnessDebtSnapshot(),
|
|
256
|
+
permanentStaleTripwire: _conversationPermanentStaleSnapshot(),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function _conversationPermanentStaleSnapshot() {
|
|
261
|
+
const items = [];
|
|
262
|
+
for (const [sessionId, item] of _deps._conversationPermanentStale.entries()) {
|
|
263
|
+
items.push({
|
|
264
|
+
sessionId,
|
|
265
|
+
firstAt: item.firstAt || 0,
|
|
266
|
+
loggedAt: item.loggedAt || 0,
|
|
267
|
+
state: item.state || '',
|
|
268
|
+
count: item.count || 0,
|
|
269
|
+
renderableTailBytes: item.renderableTailBytes || 0,
|
|
270
|
+
evidence: item.evidence || null,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
return { count: _deps._conversationPermanentStaleCount, active: items };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
module.exports = {
|
|
277
|
+
configure,
|
|
278
|
+
_conversationFreshnessDiagnostics,
|
|
279
|
+
_conversationPermanentStaleSnapshot,
|
|
280
|
+
};
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-5 (docs/shared-memory-every-machine-2026-10-31.html §5 D-3, §6.8): the per-origin change
|
|
4
|
+
// clock over the conversation store. Every inserted/corrected item gets one clock row carrying
|
|
5
|
+
// (origin_instance_id, origin_seq) — the compacted log lib/conversation-sync.js serves as a
|
|
6
|
+
// version-vector-addressed feed. `conversation_vv` is "seen through"; `conversation_local_seq`
|
|
7
|
+
// is this host's monotonic allocator. Text table untouched (the brief's DDL is additive).
|
|
8
|
+
//
|
|
9
|
+
// HELPERS ONLY — no DDL lives here. The three clock tables are declared by migration v61
|
|
10
|
+
// (lib/migrations/v61-conversation-item-clock.js, the sanctioned lib/migrations/** home), which
|
|
11
|
+
// lib/conversation-store-v2.js reaches through ensureConversationItemClockSchema so a store built
|
|
12
|
+
// outside the ladder (a bare fixture, a fresh boot) still gets them — the same shape
|
|
13
|
+
// lib/conversation-turn-index.js uses for v31's turn index. Keeping the DDL out of that store is
|
|
14
|
+
// what keeps conversation-store-v2.js under its ddl-outside-runner ratchet; keeping it out of HERE
|
|
15
|
+
// is what lets this module sit BELOW db.js without a require cycle.
|
|
16
|
+
//
|
|
17
|
+
// The replica RECEIVER's delete is NOT here: it lives beside purgeConversationV2 in
|
|
18
|
+
// lib/prompt-purge-v2.js, because it is the same "delete items by stable key + record the feed +
|
|
19
|
+
// rebuild the turn index" operation, and that module is already the pinned writer of the
|
|
20
|
+
// conversation item tables (tests/conversation-store-v2.test.js's writer gate). Keeping it there
|
|
21
|
+
// keeps this module DDL-free AND free of raw item-table writes.
|
|
22
|
+
|
|
23
|
+
// WP-5 §6.8: one seed page is at most this many items (the brief's default).
|
|
24
|
+
const CONVERSATION_SEED_PAGE_LIMIT = 5_000;
|
|
25
|
+
|
|
26
|
+
// The seed walk's resumable cursor lives in the host-local `settings` kv (never replicated, D-7).
|
|
27
|
+
const CONVERSATION_SEED_CURSOR_KEY = 'conversation_clock_seed.cursor';
|
|
28
|
+
|
|
29
|
+
// A process-level override for this CTM's instance id. Production leaves it null and the store
|
|
30
|
+
// reads `instance_identity` (the row db.js's boot mint writes); tests set it so a bare in-memory
|
|
31
|
+
// store has a deterministic origin without a boot sequence.
|
|
32
|
+
let _instanceIdOverride = null;
|
|
33
|
+
|
|
34
|
+
// The production seam for the same question: a resolver db.js registers at module scope (it is the
|
|
35
|
+
// one module that owns `getCurrentHostedInstanceIdStrict`, and its handle routing knows where the
|
|
36
|
+
// `instance_identity` row physically lives). Null until then, and '' is a valid answer.
|
|
37
|
+
let _instanceIdResolver = null;
|
|
38
|
+
|
|
39
|
+
function setConversationInstanceIdForTests(instanceId) {
|
|
40
|
+
_instanceIdOverride = instanceId ? String(instanceId).trim() : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// `fn` is a zero-arg function returning this CTM's instance id (or a falsy value); null clears it.
|
|
44
|
+
function setConversationInstanceIdResolver(fn) {
|
|
45
|
+
_instanceIdResolver = typeof fn === 'function' ? fn : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// This CTM's own instance id — the value that addresses everything this node ORIGINATES. Same
|
|
49
|
+
// source the rest of the firehose DB uses for `origin_instance_id` (db.js's boot mint writes the
|
|
50
|
+
// `instance_identity` row); '' means "this host, before the identity was known" (never shipped —
|
|
51
|
+
// D-3), and a caller with no such row can pin one with setConversationInstanceIdForTests.
|
|
52
|
+
//
|
|
53
|
+
// Deliberately NOT falling back to lib/instance-identity-access here: that module sits ABOVE db.js
|
|
54
|
+
// (it reads its identity through `require('../db')`), and db.js requires the conversation store —
|
|
55
|
+
// reaching for it would put this module back above db.js and close a dependency-lint cycle
|
|
56
|
+
// (lib/conversation-item-clock -> lib/instance-identity-access -> db.js -> lib/conversation-store-v2).
|
|
57
|
+
//
|
|
58
|
+
// So the fallback is a RESOLVER SEAM instead of an import. The clock's own tables are read from the
|
|
59
|
+
// same handle as the identity row, so a handle that can read one can read the other — but only on a
|
|
60
|
+
// single-file install. On a DOMAIN-SPLIT install the clock tables are firehose (task-manager.db)
|
|
61
|
+
// while `instance_identity` is core (core.db), so the same-handle read above finds no table and
|
|
62
|
+
// every origin would be ''. db.js (which sits ABOVE this module and already requires the store, so
|
|
63
|
+
// no new edge is created) registers `() => getCurrentHostedInstanceIdStrict()` — the identity
|
|
64
|
+
// accessor lib/instance-identity-access.js itself uses, routed through getDomainDb('core') — and
|
|
65
|
+
// this module calls it only when the same-handle read came up empty. Tests may set the override or
|
|
66
|
+
// the resolver; both are process-wide and must be restored in after().
|
|
67
|
+
function localConversationInstanceId(db) {
|
|
68
|
+
if (_instanceIdOverride) return _instanceIdOverride;
|
|
69
|
+
try {
|
|
70
|
+
const row = db.prepare('SELECT instance_id FROM instance_identity LIMIT 1').get();
|
|
71
|
+
const id = String(row?.instance_id || '').trim();
|
|
72
|
+
if (id) return id;
|
|
73
|
+
} catch { /* expected: a store without the instance_identity table (bare fixture) */ }
|
|
74
|
+
if (_instanceIdResolver) {
|
|
75
|
+
try {
|
|
76
|
+
const resolved = _instanceIdResolver();
|
|
77
|
+
// A non-string (an object, a number, undefined) is NOT an instance id — take nothing from it.
|
|
78
|
+
if (typeof resolved === 'string') {
|
|
79
|
+
const id = resolved.trim();
|
|
80
|
+
if (id) return id;
|
|
81
|
+
}
|
|
82
|
+
} catch { /* expected: identity not readable yet (pre-initDb, or no core handle) — origin stays '' */ }
|
|
83
|
+
}
|
|
84
|
+
return ''; // REPORT: no readable identity — items stay unaddressable (origin '') rather than mislabelled
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function _tableExists(db, name) {
|
|
88
|
+
return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(name);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Allocate `count` consecutive local seqs; seqs start at 1. Caller owns the transaction.
|
|
92
|
+
function _takeLocalSeqs(db, count) {
|
|
93
|
+
const row = db.prepare('SELECT next_seq FROM conversation_local_seq WHERE id=1').get();
|
|
94
|
+
const start = row && Number.isSafeInteger(Number(row.next_seq)) && Number(row.next_seq) > 0
|
|
95
|
+
? Number(row.next_seq) : 1;
|
|
96
|
+
db.prepare(`
|
|
97
|
+
INSERT INTO conversation_local_seq(id, next_seq) VALUES (1, ?)
|
|
98
|
+
ON CONFLICT(id) DO UPDATE SET next_seq=excluded.next_seq
|
|
99
|
+
`).run(start + count);
|
|
100
|
+
return start;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// "Seen through": monotonic per origin, exactly like the brain's _bumpVv.
|
|
104
|
+
function _bumpConversationVv(db, originInstanceId, seq) {
|
|
105
|
+
const origin = String(originInstanceId || '').trim();
|
|
106
|
+
const value = Number(seq);
|
|
107
|
+
if (!origin || !Number.isSafeInteger(value) || value <= 0) return;
|
|
108
|
+
db.prepare(`
|
|
109
|
+
INSERT INTO conversation_vv(origin_instance_id, max_seq) VALUES (?, ?)
|
|
110
|
+
ON CONFLICT(origin_instance_id) DO UPDATE SET max_seq=MAX(max_seq, excluded.max_seq)
|
|
111
|
+
`).run(origin, value);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function _stampConversationClock(db, { stableKey, sessionId, originInstanceId, originSeq, nowMs, deleted }) {
|
|
115
|
+
db.prepare(`
|
|
116
|
+
INSERT INTO conversation_item_clock
|
|
117
|
+
(stable_key, session_id, origin_instance_id, origin_seq, updated_at_ms, deleted)
|
|
118
|
+
VALUES (?,?,?,?,?,?)
|
|
119
|
+
ON CONFLICT(stable_key) DO UPDATE SET
|
|
120
|
+
session_id=excluded.session_id,
|
|
121
|
+
origin_instance_id=excluded.origin_instance_id,
|
|
122
|
+
origin_seq=excluded.origin_seq,
|
|
123
|
+
updated_at_ms=excluded.updated_at_ms,
|
|
124
|
+
deleted=excluded.deleted
|
|
125
|
+
`).run(String(stableKey), String(sessionId), String(originInstanceId || ''),
|
|
126
|
+
Number(originSeq) || 0, Number(nowMs) || 0, deleted ? 1 : 0);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// The receiver's tombstone clock row: the sender's (origin, origin_seq) with deleted=1, so the
|
|
130
|
+
// delete stays addressable in its origin's stream and relays onward (D-3). No local seq is spent.
|
|
131
|
+
function stampIncomingConversationClockV2(db, { stableKey, sessionId, origin, originSeq, nowMs = Date.now() } = {}) {
|
|
132
|
+
const key = String(stableKey || '').trim();
|
|
133
|
+
const originId = String(origin || '').trim();
|
|
134
|
+
const seq = Number(originSeq);
|
|
135
|
+
if (!key || !originId || !Number.isSafeInteger(seq) || seq <= 0) return false;
|
|
136
|
+
_stampConversationClock(db, {
|
|
137
|
+
stableKey: key, sessionId, originInstanceId: originId, originSeq: seq, nowMs, deleted: true,
|
|
138
|
+
});
|
|
139
|
+
_bumpConversationVv(db, originId, seq);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function _readConversationVv(db) {
|
|
144
|
+
const vector = {};
|
|
145
|
+
for (const row of db.prepare('SELECT origin_instance_id, max_seq FROM conversation_vv ORDER BY origin_instance_id ASC').all()) {
|
|
146
|
+
vector[String(row.origin_instance_id)] = Number(row.max_seq) || 0;
|
|
147
|
+
}
|
|
148
|
+
return vector;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// The tombstone half of a purge: a purged key must keep an addressable clock row (deleted=1)
|
|
152
|
+
// under THIS host's origin so peers learn to delete it. Local seqs, local vv bump, one row per key.
|
|
153
|
+
function stampConversationTombstonesV2(db, { sessionId, stableKeys = [], nowMs = Date.now() } = {}) {
|
|
154
|
+
const keys = [...new Set((Array.isArray(stableKeys) ? stableKeys : []).map((k) => String(k)).filter(Boolean))];
|
|
155
|
+
if (!keys.length) return 0;
|
|
156
|
+
const localId = localConversationInstanceId(db);
|
|
157
|
+
// No identity, no stamping (the same rule the ingest path applies — lib/conversation-store-v2.js
|
|
158
|
+
// skips `!origin`): a row at origin '' is unaddressable AND permanently so, because nothing ever
|
|
159
|
+
// revisits a key that already has a clock row. Spend no seq, write no row, say so.
|
|
160
|
+
if (!localId) return 0;
|
|
161
|
+
let start = 1;
|
|
162
|
+
db.transaction(() => {
|
|
163
|
+
start = _takeLocalSeqs(db, keys.length);
|
|
164
|
+
keys.forEach((stableKey, index) => {
|
|
165
|
+
_stampConversationClock(db, {
|
|
166
|
+
stableKey, sessionId, originInstanceId: localId, originSeq: start + index, nowMs, deleted: true,
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
_bumpConversationVv(db, localId, start + keys.length - 1);
|
|
170
|
+
})();
|
|
171
|
+
return keys.length;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function conversationSeedState(db) {
|
|
175
|
+
try {
|
|
176
|
+
const row = db.prepare('SELECT value FROM settings WHERE key=?').get(CONVERSATION_SEED_CURSOR_KEY);
|
|
177
|
+
if (!row || row.value == null) return { done: false, afterItemId: 0 };
|
|
178
|
+
const parsed = JSON.parse(String(row.value));
|
|
179
|
+
return { done: parsed?.done === true, afterItemId: Number(parsed?.afterItemId) || 0 };
|
|
180
|
+
} catch {
|
|
181
|
+
return { done: false, afterItemId: 0 }; // expected: no cursor yet (or a bare fixture without `settings`)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function _writeConversationSeedState(db, state) {
|
|
186
|
+
db.prepare(`
|
|
187
|
+
INSERT INTO settings(key, value) VALUES (?, ?)
|
|
188
|
+
ON CONFLICT(key) DO UPDATE SET value=excluded.value
|
|
189
|
+
`).run(CONVERSATION_SEED_CURSOR_KEY, JSON.stringify(state));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// One bounded, resumable page of the one-time seed for items that predate the clock. Stamps a
|
|
193
|
+
// clock row at THIS host's origin (local seq) for every item that has none, writes NO outbox row
|
|
194
|
+
// (seeding is not a user-visible change — test (g)), and advances the item_id cursor. Never boot
|
|
195
|
+
// work: the hub/member round drives it until done.
|
|
196
|
+
function seedConversationClockPage(db, { limit = CONVERSATION_SEED_PAGE_LIMIT } = {}) {
|
|
197
|
+
if (!_tableExists(db, 'conversation_item_clock') || !_tableExists(db, 'conversation_text_items_v2')) {
|
|
198
|
+
return { seeded: 0, done: true, afterItemId: 0 };
|
|
199
|
+
}
|
|
200
|
+
const budget = Math.max(1, Math.min(CONVERSATION_SEED_PAGE_LIMIT, Number(limit) || CONVERSATION_SEED_PAGE_LIMIT));
|
|
201
|
+
const state = conversationSeedState(db);
|
|
202
|
+
if (state.done) return { seeded: 0, done: true, afterItemId: state.afterItemId };
|
|
203
|
+
const localId = localConversationInstanceId(db);
|
|
204
|
+
// No readable identity ⇒ stamp NOTHING: not the rows, not the cursor. Seeding at origin '' would
|
|
205
|
+
// take seqs and write clock rows for all N items, and the walk never revisits a key that already
|
|
206
|
+
// has one — so a single premature page would make the whole store permanently unaddressable
|
|
207
|
+
// (the live domain-split symptom: 16,482 items, zero clock rows, nothing on the feed). Returning
|
|
208
|
+
// done:false without opening a transaction leaves the cursor untouched, so the very next call
|
|
209
|
+
// after the identity becomes readable seeds the same items at the REAL origin.
|
|
210
|
+
if (!localId) return { seeded: 0, done: false, afterItemId: state.afterItemId };
|
|
211
|
+
const nowMs = Date.now();
|
|
212
|
+
let seeded = 0;
|
|
213
|
+
let afterItemId = state.afterItemId;
|
|
214
|
+
db.transaction(() => {
|
|
215
|
+
const rows = db.prepare(`
|
|
216
|
+
SELECT i.item_id, i.stable_key, i.session_id
|
|
217
|
+
FROM conversation_text_items_v2 i
|
|
218
|
+
LEFT JOIN conversation_item_clock c ON c.stable_key = i.stable_key
|
|
219
|
+
WHERE i.item_id > ? AND c.stable_key IS NULL
|
|
220
|
+
ORDER BY i.item_id ASC
|
|
221
|
+
LIMIT ?
|
|
222
|
+
`).all(afterItemId, budget);
|
|
223
|
+
if (rows.length) {
|
|
224
|
+
const start = _takeLocalSeqs(db, rows.length);
|
|
225
|
+
rows.forEach((row, index) => {
|
|
226
|
+
_stampConversationClock(db, {
|
|
227
|
+
stableKey: row.stable_key, sessionId: row.session_id,
|
|
228
|
+
originInstanceId: localId, originSeq: start + index, nowMs, deleted: false,
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
_bumpConversationVv(db, localId, start + rows.length - 1);
|
|
232
|
+
seeded = rows.length;
|
|
233
|
+
afterItemId = Number(rows[rows.length - 1].item_id);
|
|
234
|
+
}
|
|
235
|
+
// More work remains when this page was full or a later item still lacks a clock.
|
|
236
|
+
const pending = db.prepare(`
|
|
237
|
+
SELECT 1 AS hit FROM conversation_text_items_v2 i
|
|
238
|
+
LEFT JOIN conversation_item_clock c ON c.stable_key = i.stable_key
|
|
239
|
+
WHERE i.item_id > ? AND c.stable_key IS NULL LIMIT 1
|
|
240
|
+
`).get(afterItemId);
|
|
241
|
+
_writeConversationSeedState(db, { done: !pending, afterItemId });
|
|
242
|
+
})();
|
|
243
|
+
return { seeded, done: conversationSeedState(db).done, afterItemId };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
module.exports = {
|
|
247
|
+
CONVERSATION_SEED_PAGE_LIMIT,
|
|
248
|
+
setConversationInstanceIdForTests,
|
|
249
|
+
setConversationInstanceIdResolver,
|
|
250
|
+
localConversationInstanceId,
|
|
251
|
+
readConversationClockVector: _readConversationVv,
|
|
252
|
+
bumpConversationVv: _bumpConversationVv,
|
|
253
|
+
stampIncomingConversationClockV2,
|
|
254
|
+
stampConversationTombstonesV2,
|
|
255
|
+
conversationSeedState,
|
|
256
|
+
seedConversationClockPage,
|
|
257
|
+
// Internal stamping primitives the conversation store's writer calls inside its own transaction.
|
|
258
|
+
_takeLocalSeqs,
|
|
259
|
+
_stampConversationClock,
|
|
260
|
+
_bumpConversationVv,
|
|
261
|
+
};
|
|
@@ -93,6 +93,11 @@ const PROVIDER_ADAPTERS = Object.freeze({
|
|
|
93
93
|
'claude-desktop': Object.freeze(['snapshot']),
|
|
94
94
|
cursor: Object.freeze(['database-snapshot']),
|
|
95
95
|
opencode: Object.freeze(['database-snapshot']),
|
|
96
|
+
// S-25 (docs/deepseek-harness-acp-agent-2026-10-28.html, WP-3 after OQ-2): the DeepSeek Harness's
|
|
97
|
+
// CTM-owned transcript (lib/acp/dsh-transcript.js) is Claude-shaped JSONL, so its history ingest
|
|
98
|
+
// rides the same compound-log lane as claude. Without this entry providerAdapterKind('dsh') is ''
|
|
99
|
+
// and isLogAdapterProvider() rejects the file before it can be parsed.
|
|
100
|
+
dsh: Object.freeze(['compound-log']),
|
|
96
101
|
});
|
|
97
102
|
|
|
98
103
|
function _flagEnabled(name) {
|
|
@@ -17,6 +17,12 @@ const {
|
|
|
17
17
|
const DEFAULT_READ_LIMIT = 500;
|
|
18
18
|
const MAX_READ_LIMIT = 2_000;
|
|
19
19
|
|
|
20
|
+
// WP-5 §6.8: the clock's tables are migration v61's; its helpers are lib/conversation-item-clock.js.
|
|
21
|
+
const {
|
|
22
|
+
localConversationInstanceId, _takeLocalSeqs, _stampConversationClock, _bumpConversationVv, seedConversationClockPage,
|
|
23
|
+
} = require('./conversation-item-clock');
|
|
24
|
+
const { ensureConversationItemClockSchema } = require('./migrations/v61-conversation-item-clock');
|
|
25
|
+
|
|
20
26
|
// These triggers keep the external-content FTS index in sync; table rebuilds recreate them transactionally (v25 migration).
|
|
21
27
|
const CONVERSATION_FTS_TRIGGERS_DDL = `
|
|
22
28
|
CREATE TRIGGER IF NOT EXISTS conversation_text_v2_ai
|
|
@@ -169,6 +175,8 @@ function ensureConversationStoreV2(db) {
|
|
|
169
175
|
|
|
170
176
|
${CONVERSATION_FTS_TRIGGERS_DDL}
|
|
171
177
|
`);
|
|
178
|
+
// WP-5 §6.8: reached here too, so a store built outside the ladder still has the clock tables.
|
|
179
|
+
ensureConversationItemClockSchema({ getDb: () => db });
|
|
172
180
|
ensureTurnIndexSchema(db);
|
|
173
181
|
const textColumns = new Set(db.prepare('PRAGMA table_info(conversation_text_items_v2)').all().map((row) => row.name));
|
|
174
182
|
if (!textColumns.has('source_event_digest')) {
|
|
@@ -436,6 +444,8 @@ function partitionReplacedRemovals(removals, admittedIdentities) {
|
|
|
436
444
|
return { removals: removals.filter((r) => !isReplaced(r)), replaced: removals.filter(isReplaced) };
|
|
437
445
|
}
|
|
438
446
|
|
|
447
|
+
// The receiver's delete (deleteConversationItemsByStableKeyV2) moved to lib/prompt-purge-v2.js.
|
|
448
|
+
|
|
439
449
|
function commitConversationBatchV2(db, batch = {}) {
|
|
440
450
|
if (!db) throw new TypeError('db is required');
|
|
441
451
|
if (!_tableExists(db, 'conversation_text_items_v2')
|
|
@@ -788,6 +798,38 @@ function commitConversationBatchV2(db, batch = {}) {
|
|
|
788
798
|
outboxChanges += 1;
|
|
789
799
|
}
|
|
790
800
|
|
|
801
|
+
// WP-5 §6.8: stamp the per-origin clock for every live/tombstoned key this batch changed. The
|
|
802
|
+
// ordinary writer stamps THIS host's origin with fresh local seqs; the receiver path
|
|
803
|
+
// (`batch.replication = { origin, originSeqByKey }`) keeps the SENDER's origin/seq instead, so a
|
|
804
|
+
// re-served row stays addressable in its origin's stream and this node never re-authors it (no echo).
|
|
805
|
+
if (changed.size) {
|
|
806
|
+
const replication = batch.replication && typeof batch.replication === 'object' ? batch.replication : null;
|
|
807
|
+
const originSeqByKey = replication && replication.originSeqByKey && typeof replication.originSeqByKey === 'object'
|
|
808
|
+
? replication.originSeqByKey : null;
|
|
809
|
+
const keys = [...changed.keys()];
|
|
810
|
+
const localId = localConversationInstanceId(db);
|
|
811
|
+
const localStart = replication ? 0 : _takeLocalSeqs(db, keys.length);
|
|
812
|
+
const ceiling = new Map(); // origin -> highest seq stamped by this batch
|
|
813
|
+
keys.forEach((stableKey, index) => {
|
|
814
|
+
const change = changed.get(stableKey);
|
|
815
|
+
const incoming = originSeqByKey ? Number(originSeqByKey[stableKey]) : NaN;
|
|
816
|
+
const replicated = !!replication && Number.isSafeInteger(incoming) && incoming > 0;
|
|
817
|
+
// A replication batch keeps only the sender's origin/seq; a key with no incoming seq is a
|
|
818
|
+
// local divergence this node already owns, so it is left to its own writer rather than
|
|
819
|
+
// re-authored here under a fabricated origin.
|
|
820
|
+
if (replication && !replicated) return;
|
|
821
|
+
const origin = replicated ? String(replication.origin || '') : localId;
|
|
822
|
+
const seq = replicated ? incoming : localStart + index;
|
|
823
|
+
if (!origin || !(seq > 0)) return;
|
|
824
|
+
_stampConversationClock(db, {
|
|
825
|
+
stableKey, sessionId: change.sessionId, originInstanceId: origin,
|
|
826
|
+
originSeq: seq, nowMs, deleted: change.kind === 'deleted',
|
|
827
|
+
});
|
|
828
|
+
ceiling.set(origin, Math.max(ceiling.get(origin) || 0, seq));
|
|
829
|
+
});
|
|
830
|
+
for (const [origin, seq] of ceiling) _bumpConversationVv(db, origin, seq);
|
|
831
|
+
}
|
|
832
|
+
|
|
791
833
|
const generationSessionIds = new Set(items.map((entry) => entry.item.sessionId));
|
|
792
834
|
for (const removal of removals) generationSessionIds.add(removal.sessionId);
|
|
793
835
|
if (snapshotSessionId) generationSessionIds.add(snapshotSessionId);
|
|
@@ -1043,4 +1085,6 @@ module.exports = {
|
|
|
1043
1085
|
readConversationItemsV2,
|
|
1044
1086
|
searchConversationItemsV2,
|
|
1045
1087
|
verifyConversationFtsV2,
|
|
1088
|
+
// WP-5 §6.8: re-exported for callers that still reach the seed through the store (lib/memory-sync.js).
|
|
1089
|
+
seedConversationClockPage,
|
|
1046
1090
|
};
|