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,395 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-3 of docs/deepseek-harness-acp-agent-2026-10-28.html (§5 D-8, §5 D-10, §6.4; §9 S-27; §10 T-7, T-9).
|
|
4
|
+
//
|
|
5
|
+
// CTM owns the dsh (DeepSeek Harness) transcript. Every user prompt and every flushed ACP
|
|
6
|
+
// `session/update` becomes ONE Claude-shaped JSONL row with `provider:'dsh'` under
|
|
7
|
+
// `<dataDir>/dsh-transcripts/<acpSessionId>.jsonl`, and that file is then the session's transcript for
|
|
8
|
+
// live Conv, history, search and export — dsh's own zstd log is never read by CTM.
|
|
9
|
+
//
|
|
10
|
+
// Two row-shape rules the code below encodes (§6.4):
|
|
11
|
+
// * chunk deltas are ACCUMULATED. `agent_thought_chunk` / `agent_message_chunk` group by `messageId`
|
|
12
|
+
// and kind and become one row when the kind changes, the messageId changes, a `tool_call` arrives or
|
|
13
|
+
// `flush()` is called — so ten delta chunks for one message are one row (T-7), while a bridge that
|
|
14
|
+
// sends one chunk per block is unaffected (D-6).
|
|
15
|
+
// * `usage_update` and `config_option_update` are NOT rows.
|
|
16
|
+
//
|
|
17
|
+
// I/O: the public API stays synchronous-to-call (it returns the row it built), but the writer never does
|
|
18
|
+
// sync fs I/O on CTM's main event loop. Each call builds its row synchronously — uuid / parentUuid /
|
|
19
|
+
// timestamp are assigned in call order — serializes it, and ENQUEUES the line on ONE per-writer promise
|
|
20
|
+
// chain: the first link `fs.promises.mkdir(dir, {recursive:true})`, every later link
|
|
21
|
+
// `fs.promises.appendFile(path, line)`. Order on disk is exactly call order; nothing is ever truncated,
|
|
22
|
+
// renamed or unlinked (D-10, T-9). `whenIdle()` resolves once every queued write has landed (WP-4/WP-5
|
|
23
|
+
// and the tests await it); a failed write is reported once through the injected `log` and never breaks
|
|
24
|
+
// the chain for later rows. `fs` (promises-shaped), `now`, `uuid` and `log` are deps so a test never
|
|
25
|
+
// writes a real transcript (H-7).
|
|
26
|
+
|
|
27
|
+
const crypto = require('node:crypto');
|
|
28
|
+
const fsPromisesDefault = require('node:fs').promises;
|
|
29
|
+
const path = require('node:path');
|
|
30
|
+
|
|
31
|
+
const transcriptSource = require('../transcript-source');
|
|
32
|
+
|
|
33
|
+
const DSH_ROW_VERSION = 'dsh-acp-jsonl-v1';
|
|
34
|
+
const DSH_TURN_INTERRUPTED_TEXT = 'Turn interrupted by CTM restart';
|
|
35
|
+
const TRANSCRIPT_DIR_NAME = 'dsh-transcripts';
|
|
36
|
+
// Enough to hold the last row of any update we write; the tail read only needs its closing line.
|
|
37
|
+
const TAIL_BYTES = 64 * 1024;
|
|
38
|
+
|
|
39
|
+
// §6.4: the two streaming kinds, and the content type each one flushes to.
|
|
40
|
+
const CHUNK_KINDS = Object.freeze({
|
|
41
|
+
agent_thought_chunk: 'thinking',
|
|
42
|
+
agent_message_chunk: 'text',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/** The directory a dsh session's transcript lives in (`<dataDir>/dsh-transcripts`). */
|
|
46
|
+
function dshTranscriptDir(dataDir) {
|
|
47
|
+
return path.join(String(dataDir || ''), TRANSCRIPT_DIR_NAME);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function _stringOr(value, fallback) {
|
|
51
|
+
return typeof value === 'string' && value ? value : fallback;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// `content` is `{type:'text', text}` on a chunk and may be a bare string on an exotic bridge.
|
|
55
|
+
function _chunkText(content) {
|
|
56
|
+
if (typeof content === 'string') return content;
|
|
57
|
+
if (content && typeof content.text === 'string') return content.text;
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// WP-11 (D-20): an image the user attached to a prompt, carried on the user row in the SAME shape a
|
|
62
|
+
// Claude Code JSONL user row encodes one — `{type:'image', source:{type:'base64', media_type, data}}`.
|
|
63
|
+
// That is the shape lib/jsonl-conversation-parser.js / lib/session-stream.js already understand: their
|
|
64
|
+
// `_jsonlContentText` turns it into the compact `[Image #N]` token (the join key
|
|
65
|
+
// lib/session-image-refs.js matches a recorded manifest against) and `stripBase64Blobs` reduces it to a
|
|
66
|
+
// metadata-only `image_ref` block for live Conv. The base64 is what the provider itself was given.
|
|
67
|
+
function _imageContentBlocks(images) {
|
|
68
|
+
const blocks = [];
|
|
69
|
+
for (const image of Array.isArray(images) ? images : []) {
|
|
70
|
+
if (!image || typeof image !== 'object') continue;
|
|
71
|
+
const data = typeof image.data === 'string' ? image.data : '';
|
|
72
|
+
if (!data) continue;
|
|
73
|
+
blocks.push({
|
|
74
|
+
type: 'image',
|
|
75
|
+
source: {
|
|
76
|
+
type: 'base64',
|
|
77
|
+
media_type: _stringOr(image.mimeType || image.media_type, 'image/png'),
|
|
78
|
+
data,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return blocks;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// A `tool_call_update`'s content is an array of ACP content blocks
|
|
86
|
+
// (`{type:'content', content:{type:'text', text}}`); join every text it carries into ONE string.
|
|
87
|
+
function _joinedContentText(content) {
|
|
88
|
+
const parts = [];
|
|
89
|
+
const walk = (item) => {
|
|
90
|
+
if (typeof item === 'string') {
|
|
91
|
+
parts.push(item);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!item || typeof item !== 'object') return;
|
|
95
|
+
if (typeof item.text === 'string') {
|
|
96
|
+
parts.push(item.text);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (item.content !== undefined && item.content !== null) {
|
|
100
|
+
if (Array.isArray(item.content)) item.content.forEach(walk);
|
|
101
|
+
else walk(item.content);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
if (Array.isArray(content)) content.forEach(walk);
|
|
105
|
+
else walk(content);
|
|
106
|
+
return parts.join('\n');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// The uuid of the file's last row, read through lib/transcript-source.js (the one transcript reader) so
|
|
110
|
+
// a writer that reopens an existing transcript keeps its parentUuid chain unbroken. This seed stays
|
|
111
|
+
// synchronous on purpose: every row's parentUuid must be known the moment the row is BUILT (calls are in
|
|
112
|
+
// order), so an async seed could not feed the synchronous row builders. (The read is a bounded tail read
|
|
113
|
+
// through the transcript-source seam, not a raw fs call.)
|
|
114
|
+
function _lastRowUuid(filePath) {
|
|
115
|
+
try {
|
|
116
|
+
const view = transcriptSource.statTranscriptSync(filePath);
|
|
117
|
+
if (!view || !view.exists || !view.size) return null;
|
|
118
|
+
const start = Math.max(0, view.size - TAIL_BYTES);
|
|
119
|
+
const tail = transcriptSource.readTranscriptRangeSync(filePath, start, view.size).toString('utf8');
|
|
120
|
+
const lines = tail.split('\n').filter((line) => line.trim() !== '');
|
|
121
|
+
if (!lines.length) return null;
|
|
122
|
+
const row = JSON.parse(lines[lines.length - 1]);
|
|
123
|
+
return _stringOr(row && row.uuid, null);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
// expected: a missing, unreadable or half-written tail — a fresh chain is the safe answer and the
|
|
126
|
+
// append itself will surface a real write problem.
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* WP-5 (§9 S-42, D-9). Is this transcript's last turn still OPEN?
|
|
133
|
+
*
|
|
134
|
+
* The row shapes (§6.4) make this a one-line question: a turn is open exactly when the LAST
|
|
135
|
+
* turn-bearing row is a `user` row — either a prompt whose assistant never answered, or a
|
|
136
|
+
* `tool_result` whose follow-up assistant row never came. Every terminal row closes it: an ordinary
|
|
137
|
+
* `assistant` row, the WP-7d `dsh_turn_failed` / `dsh_turn_interrupted` rows (now also `assistant`
|
|
138
|
+
* rows), and — for transcripts written before WP-7d — the older `system`-typed variant of those two
|
|
139
|
+
* rows. PURE: it reads no file and writes none; the caller passes the already-parsed rows (or raw
|
|
140
|
+
* JSON lines) it read off-thread.
|
|
141
|
+
*
|
|
142
|
+
* @param {Array<object|string>} rows parsed rows, or raw JSON lines (malformed ones are skipped)
|
|
143
|
+
* @returns {{open: true, uuid: string|null, clientMessageId: string|null, timestamp: string|null}|null}
|
|
144
|
+
*/
|
|
145
|
+
function findOpenDshTurn(rows) {
|
|
146
|
+
if (!Array.isArray(rows) || !rows.length) return null;
|
|
147
|
+
for (let i = rows.length - 1; i >= 0; i -= 1) {
|
|
148
|
+
let row = rows[i];
|
|
149
|
+
if (typeof row === 'string') {
|
|
150
|
+
try { row = JSON.parse(row); } catch (error) { void error; continue; } // expected: a half-written tail line is not a row
|
|
151
|
+
}
|
|
152
|
+
if (!row || typeof row !== 'object') continue;
|
|
153
|
+
if (row.type === 'user') {
|
|
154
|
+
return {
|
|
155
|
+
open: true,
|
|
156
|
+
uuid: _stringOr(row.uuid, null),
|
|
157
|
+
clientMessageId: _stringOr(row.clientMessageId, null),
|
|
158
|
+
timestamp: _stringOr(row.timestamp, null),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// An assistant row (including the WP-7d `dsh_turn_failed` / `dsh_turn_interrupted` rows) or a
|
|
162
|
+
// legacy `system` row is terminal: the turn that preceded it is closed.
|
|
163
|
+
if (row.type === 'assistant' || row.type === 'system') return null;
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* One writer per CTM dsh session (D-2: one child, one transcript).
|
|
170
|
+
*
|
|
171
|
+
* @param {object} opts
|
|
172
|
+
* @param {string} opts.dataDir // lib/data-dir.js's getDataDir()
|
|
173
|
+
* @param {string} opts.acpSessionId // the ACP session id (the file's name)
|
|
174
|
+
* @param {string} [opts.cwd]
|
|
175
|
+
* @param {() => string} [opts.now] // timestamp for a row
|
|
176
|
+
* @param {() => string} [opts.uuid] // row uuid
|
|
177
|
+
* @param {{mkdir: Function, appendFile: Function}} [opts.fs] // promises-shaped fs for tests
|
|
178
|
+
* @param {(message: string) => void} [opts.log] // write-failure sink (default no-op)
|
|
179
|
+
* @returns {{
|
|
180
|
+
* path: string,
|
|
181
|
+
* appendUserPrompt: (prompt: {text?: string, clientMessageId?: string}) => object,
|
|
182
|
+
* onUpdate: (update: object) => object|null,
|
|
183
|
+
* flush: () => object|null,
|
|
184
|
+
* appendTurnFailed: (message?: string) => object,
|
|
185
|
+
* appendTurnInterrupted: () => object,
|
|
186
|
+
* setModel: (id?: string|null) => string|null,
|
|
187
|
+
* whenIdle: () => Promise<void>,
|
|
188
|
+
* }}
|
|
189
|
+
*/
|
|
190
|
+
function createDshTranscriptWriter(opts = {}) {
|
|
191
|
+
const dataDir = String(opts.dataDir || '');
|
|
192
|
+
const acpSessionId = String(opts.acpSessionId || '');
|
|
193
|
+
if (!dataDir || !acpSessionId) {
|
|
194
|
+
throw new TypeError('createDshTranscriptWriter requires dataDir and acpSessionId');
|
|
195
|
+
}
|
|
196
|
+
const cwd = opts.cwd || '';
|
|
197
|
+
const now = typeof opts.now === 'function' ? opts.now : () => new Date().toISOString();
|
|
198
|
+
const uuid = typeof opts.uuid === 'function' ? opts.uuid : () => crypto.randomUUID();
|
|
199
|
+
const fs = opts.fs || fsPromisesDefault;
|
|
200
|
+
const log = typeof opts.log === 'function' ? opts.log : () => {};
|
|
201
|
+
const dirPath = dshTranscriptDir(dataDir);
|
|
202
|
+
const filePath = path.join(dirPath, `${acpSessionId}.jsonl`);
|
|
203
|
+
|
|
204
|
+
let parentUuid = _lastRowUuid(filePath);
|
|
205
|
+
let model = null;
|
|
206
|
+
let pending = null; // { kind: 'thinking'|'text', messageId, text }
|
|
207
|
+
let dirEnsured = false;
|
|
208
|
+
// Serialized async write chain: one link per appended line, executed in call order. `tail` is always a
|
|
209
|
+
// settled-or-pending promise that never rejects (a failed write is logged, then swallowed) so a single
|
|
210
|
+
// bad append cannot stall or break the rows that follow it.
|
|
211
|
+
let tail = Promise.resolve();
|
|
212
|
+
|
|
213
|
+
async function _appendLine(line) {
|
|
214
|
+
if (!dirEnsured) {
|
|
215
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
216
|
+
dirEnsured = true;
|
|
217
|
+
}
|
|
218
|
+
await fs.appendFile(filePath, line);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Build the row synchronously (uuid/parentUuid/timestamp in call order) and enqueue its serialized line.
|
|
222
|
+
function _write(row) {
|
|
223
|
+
const rowUuid = uuid();
|
|
224
|
+
const line = {
|
|
225
|
+
...row,
|
|
226
|
+
provider: 'dsh',
|
|
227
|
+
version: DSH_ROW_VERSION,
|
|
228
|
+
sessionId: acpSessionId,
|
|
229
|
+
uuid: rowUuid,
|
|
230
|
+
parentUuid,
|
|
231
|
+
cwd,
|
|
232
|
+
timestamp: now(),
|
|
233
|
+
};
|
|
234
|
+
parentUuid = rowUuid;
|
|
235
|
+
tail = tail.then(() => _appendLine(`${JSON.stringify(line)}\n`)).catch((error) => {
|
|
236
|
+
log(`[dsh-transcript] write failed: ${error && error.message ? error.message : error}`);
|
|
237
|
+
});
|
|
238
|
+
return line;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function _flushPending() {
|
|
242
|
+
if (!pending) return null;
|
|
243
|
+
const { kind, messageId, text } = pending;
|
|
244
|
+
pending = null;
|
|
245
|
+
const content = kind === 'thinking'
|
|
246
|
+
? [{ type: 'thinking', thinking: text }]
|
|
247
|
+
: [{ type: 'text', text }];
|
|
248
|
+
return _write({ type: 'assistant', message: { id: messageId, role: 'assistant', model, content } });
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function _chunk(kind, update) {
|
|
252
|
+
const messageId = _stringOr(update.messageId, '');
|
|
253
|
+
if (!messageId) return null;
|
|
254
|
+
if (pending && (pending.kind !== kind || pending.messageId !== messageId)) _flushPending();
|
|
255
|
+
if (!pending) pending = { kind, messageId, text: '' };
|
|
256
|
+
pending.text += _chunkText(update.content);
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function _toolCall(update) {
|
|
261
|
+
// A tool call ends the chunk group that precedes it (§6.4/D-6).
|
|
262
|
+
_flushPending();
|
|
263
|
+
const toolCallId = _stringOr(update.toolCallId, '');
|
|
264
|
+
if (!toolCallId) return null;
|
|
265
|
+
const rawInput = update.rawInput && typeof update.rawInput === 'object' && !Array.isArray(update.rawInput)
|
|
266
|
+
? update.rawInput
|
|
267
|
+
: {};
|
|
268
|
+
return _write({
|
|
269
|
+
type: 'assistant',
|
|
270
|
+
message: {
|
|
271
|
+
id: `tool-${toolCallId}`,
|
|
272
|
+
role: 'assistant',
|
|
273
|
+
model,
|
|
274
|
+
content: [{ type: 'tool_use', id: toolCallId, name: _stringOr(update.title, ''), input: rawInput }],
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function _toolCallUpdate(update) {
|
|
280
|
+
const status = _stringOr(update.status, '');
|
|
281
|
+
if (status !== 'completed' && status !== 'failed') return null; // in_progress/pending are not rows
|
|
282
|
+
const toolCallId = _stringOr(update.toolCallId, '');
|
|
283
|
+
if (!toolCallId) return null;
|
|
284
|
+
return _write({
|
|
285
|
+
type: 'user',
|
|
286
|
+
message: {
|
|
287
|
+
role: 'user',
|
|
288
|
+
content: [{
|
|
289
|
+
type: 'tool_result',
|
|
290
|
+
tool_use_id: toolCallId,
|
|
291
|
+
content: _joinedContentText(update.content),
|
|
292
|
+
is_error: status === 'failed',
|
|
293
|
+
}],
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
path: filePath,
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* CTM sent `session/prompt` (§6.4 row 1). WP-4 calls this; the writer never prompts itself.
|
|
303
|
+
*
|
|
304
|
+
* WP-11 (D-20): `images` are the images the prompt carried (`{mimeType, data}`), written as the
|
|
305
|
+
* Claude-shaped content blocks below the text block — exactly how a Claude user row encodes its
|
|
306
|
+
* images — so the EXISTING Conv parsers and the manifest join work on a dsh row unchanged and a
|
|
307
|
+
* reload shows the same thumbnails a Claude session would.
|
|
308
|
+
*/
|
|
309
|
+
appendUserPrompt(prompt = {}) {
|
|
310
|
+
_flushPending();
|
|
311
|
+
const content = [{ type: 'text', text: typeof prompt.text === 'string' ? prompt.text : '' }];
|
|
312
|
+
content.push(..._imageContentBlocks(prompt.images));
|
|
313
|
+
return _write({
|
|
314
|
+
type: 'user',
|
|
315
|
+
clientMessageId: _stringOr(prompt.clientMessageId, null),
|
|
316
|
+
message: { role: 'user', content },
|
|
317
|
+
});
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
/** One ACP `session/update` `update` object. Returns null for updates that are not rows. */
|
|
321
|
+
onUpdate(update) {
|
|
322
|
+
if (!update || typeof update !== 'object') return null;
|
|
323
|
+
const kind = CHUNK_KINDS[update.sessionUpdate];
|
|
324
|
+
if (kind) return _chunk(kind, update);
|
|
325
|
+
if (update.sessionUpdate === 'tool_call') return _toolCall(update);
|
|
326
|
+
if (update.sessionUpdate === 'tool_call_update') return _toolCallUpdate(update);
|
|
327
|
+
return null; // usage_update, config_option_update, plan, diff, … are not rows
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
/** Turn end: flush the chunk group still open. WP-4 calls this when the prompt settles. */
|
|
331
|
+
flush() {
|
|
332
|
+
return _flushPending();
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* A rejected prompt (§6.4 row 6), e.g. "Insufficient Balance".
|
|
337
|
+
*
|
|
338
|
+
* WP-7d: this row is written in the shape Claude Code itself writes for a failed turn — an
|
|
339
|
+
* `assistant` row with `isApiErrorMessage` — because that is the only shape both Conv lanes
|
|
340
|
+
* (`lib/transcript-store.js` ingest, `lib/jsonl-conversation-parser.js`) already render as an
|
|
341
|
+
* assistant message. A `system` row would be invisible in Conv.
|
|
342
|
+
*/
|
|
343
|
+
appendTurnFailed(message) {
|
|
344
|
+
_flushPending();
|
|
345
|
+
const text = typeof message === 'string' ? message : String(message === undefined || message === null ? '' : message);
|
|
346
|
+
return _write({
|
|
347
|
+
type: 'assistant',
|
|
348
|
+
isApiErrorMessage: true,
|
|
349
|
+
error: 'dsh_turn_failed',
|
|
350
|
+
message: {
|
|
351
|
+
role: 'assistant',
|
|
352
|
+
model: '<synthetic>',
|
|
353
|
+
content: [{ type: 'text', text: `API Error: ${text || 'turn failed'}` }],
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
/** The boot sweep's one row for a turn that died with the CTM process (D-9). WP-7d: assistant-shaped so Conv renders it. */
|
|
359
|
+
appendTurnInterrupted() {
|
|
360
|
+
_flushPending();
|
|
361
|
+
return _write({
|
|
362
|
+
type: 'assistant',
|
|
363
|
+
isApiErrorMessage: true,
|
|
364
|
+
error: 'dsh_turn_interrupted',
|
|
365
|
+
message: {
|
|
366
|
+
role: 'assistant',
|
|
367
|
+
model: '<synthetic>',
|
|
368
|
+
content: [{ type: 'text', text: DSH_TURN_INTERRUPTED_TEXT }],
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
/** D-12: the session's current model id, stamped on every assistant row from here on (default null). */
|
|
374
|
+
setModel(id) {
|
|
375
|
+
model = _stringOr(id, null);
|
|
376
|
+
return model;
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Resolves once every write queued so far has landed on disk (in call order). Never rejects: a
|
|
381
|
+
* failed write is reported through `log` and swallowed, so the chain always drains.
|
|
382
|
+
*/
|
|
383
|
+
whenIdle() {
|
|
384
|
+
return tail;
|
|
385
|
+
},
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
module.exports = {
|
|
390
|
+
createDshTranscriptWriter,
|
|
391
|
+
findOpenDshTurn,
|
|
392
|
+
dshTranscriptDir,
|
|
393
|
+
DSH_ROW_VERSION,
|
|
394
|
+
DSH_TURN_INTERRUPTED_TEXT,
|
|
395
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-9 step 2 — the DeepSeek Harness per-request usage rows (design
|
|
4
|
+
// docs/deepseek-harness-acp-agent-2026-10-28.html §5 D-19, §6.7 `appendDshUsageRow`, §9b L-1/L-2,
|
|
5
|
+
// T-20).
|
|
6
|
+
//
|
|
7
|
+
// A dsh session talks to its model through CTM's model proxy with a per-session LEAD token minted by
|
|
8
|
+
// `prepareDshRoute` (lib/acp/dsh-route-patch.js). ACP carries no per-request token usage — the wire has
|
|
9
|
+
// `usage_update {used,size}` only (context occupancy, not billed tokens) — so CTM's usage ledger, which
|
|
10
|
+
// is fed by transcript ingest, never saw dsh spend. The proxy is the one place that sees every
|
|
11
|
+
// response's `usage` block, so it appends ONE row per completed request here.
|
|
12
|
+
//
|
|
13
|
+
// Contract (the seam with the ledger-side parser, lib/usage-ledger/dsh-parse.js — do NOT change it):
|
|
14
|
+
//
|
|
15
|
+
// <dataDir>/dsh-usage/<ctmSessionId>.jsonl
|
|
16
|
+
// {"ts":"<ISO-8601 UTC>","requestId":"…","model":"…","input_tokens":N,"output_tokens":N,
|
|
17
|
+
// "cache_read_input_tokens":N,"cache_creation_input_tokens":N}
|
|
18
|
+
//
|
|
19
|
+
// * one JSON object per line, UTF-8, `\n`-terminated;
|
|
20
|
+
// * exactly those seven fields — never a token, key, header, prompt or response text;
|
|
21
|
+
// * all four counts are non-negative integers, 0 when the upstream omitted one;
|
|
22
|
+
// * directory 0700 (created on first write), file 0600;
|
|
23
|
+
// * `ctmSessionId` is validated against `/^[A-Za-z0-9_-]{1,128}$/` BEFORE it becomes a file name, so
|
|
24
|
+
// no caller value can traverse out of the directory.
|
|
25
|
+
//
|
|
26
|
+
// Async fs only (the main-thread lint forbids sync fs under lib/), one append per call, and appends are
|
|
27
|
+
// serialized per file through an in-process promise chain so two concurrent requests can never
|
|
28
|
+
// interleave partial lines.
|
|
29
|
+
|
|
30
|
+
const fs = require('node:fs');
|
|
31
|
+
const path = require('node:path');
|
|
32
|
+
|
|
33
|
+
// The exact file-name grammar. A `/`, `.` or NUL can never reach path.join.
|
|
34
|
+
const CTM_SESSION_ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
|
|
35
|
+
const USAGE_DIR_NAME = 'dsh-usage';
|
|
36
|
+
const DIR_MODE = 0o700;
|
|
37
|
+
const FILE_MODE = 0o600;
|
|
38
|
+
// A bounded opaque string (the proxy's own request id, or the downstream id it was answered with).
|
|
39
|
+
const MAX_OPAQUE_LEN = 200;
|
|
40
|
+
// The row's wire model id is a deployment id; the proxy's grammar caps it well below this.
|
|
41
|
+
const MAX_MODEL_LEN = 200;
|
|
42
|
+
|
|
43
|
+
/** @type {Map<string, Promise<void>>} one serialization chain per absolute file path */
|
|
44
|
+
const _chains = new Map();
|
|
45
|
+
|
|
46
|
+
function _count(value) {
|
|
47
|
+
const n = Number(value);
|
|
48
|
+
if (!Number.isFinite(n) || n < 0) return 0;
|
|
49
|
+
return Math.round(n);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function _boundedString(value, max) {
|
|
53
|
+
return typeof value === 'string' ? value.slice(0, max) : '';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function _message(error) {
|
|
57
|
+
return String((error && error.message) || error || '').slice(0, 200);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The directory a dsh session's usage rows live in: `<dataDir>/dsh-usage`.
|
|
62
|
+
* @param {string} dataDir
|
|
63
|
+
* @returns {string}
|
|
64
|
+
*/
|
|
65
|
+
function dshUsageDir(dataDir) {
|
|
66
|
+
return path.join(dataDir, USAGE_DIR_NAME);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The ONE file a dsh session's usage rows live in: `<dataDir>/dsh-usage/<ctmSessionId>.jsonl`.
|
|
71
|
+
* `ctmSessionId` must already have passed the file-name grammar.
|
|
72
|
+
* @param {string} dataDir
|
|
73
|
+
* @param {string} ctmSessionId
|
|
74
|
+
* @returns {string}
|
|
75
|
+
*/
|
|
76
|
+
function dshUsagePath(dataDir, ctmSessionId) {
|
|
77
|
+
return path.join(dshUsageDir(dataDir), `${ctmSessionId}.jsonl`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Build the exact contract row from a caller's (possibly richer) row object. Every field is
|
|
82
|
+
* whitelisted and coerced here: an extra key on the input can never reach the file, and a missing or
|
|
83
|
+
* malformed count becomes 0 rather than surfacing as `null`/`undefined`/NaN on the line.
|
|
84
|
+
*
|
|
85
|
+
* @param {object} row
|
|
86
|
+
* @returns {{ts:string, requestId:string, model:string, input_tokens:number, output_tokens:number,
|
|
87
|
+
* cache_read_input_tokens:number, cache_creation_input_tokens:number}}
|
|
88
|
+
*/
|
|
89
|
+
function buildDshUsageRow(row) {
|
|
90
|
+
const input = row && typeof row === 'object' && !Array.isArray(row) ? row : {};
|
|
91
|
+
return {
|
|
92
|
+
ts: typeof input.ts === 'string' && input.ts ? input.ts : new Date().toISOString(),
|
|
93
|
+
requestId: _boundedString(input.requestId, MAX_OPAQUE_LEN),
|
|
94
|
+
model: _boundedString(input.model, MAX_MODEL_LEN),
|
|
95
|
+
input_tokens: _count(input.input_tokens),
|
|
96
|
+
output_tokens: _count(input.output_tokens),
|
|
97
|
+
cache_read_input_tokens: _count(input.cache_read_input_tokens),
|
|
98
|
+
cache_creation_input_tokens: _count(input.cache_creation_input_tokens),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Serialize per file: the previous append for this path always settles before the next one starts, so
|
|
103
|
+
// two concurrent calls produce two whole lines in call order. The stored chain never rejects (the
|
|
104
|
+
// caller's own promise is `next`, below), so a failed append cannot poison the ones that follow.
|
|
105
|
+
function _serialize(filePath, task) {
|
|
106
|
+
const previous = _chains.get(filePath) || Promise.resolve();
|
|
107
|
+
const next = previous.then(task, task);
|
|
108
|
+
const guard = next.then(() => {}, () => {});
|
|
109
|
+
_chains.set(filePath, guard);
|
|
110
|
+
guard.then(() => {
|
|
111
|
+
if (_chains.get(filePath) === guard) _chains.delete(filePath);
|
|
112
|
+
});
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function _appendLine(filePath, line) {
|
|
117
|
+
const dir = path.dirname(filePath);
|
|
118
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: DIR_MODE });
|
|
119
|
+
// `mode` applies only at CREATION (and is masked by umask), so re-assert both bits: the directory
|
|
120
|
+
// holds a session's spend and the file is never group/world readable.
|
|
121
|
+
await fs.promises.chmod(dir, DIR_MODE);
|
|
122
|
+
await fs.promises.appendFile(filePath, line, { encoding: 'utf8', mode: FILE_MODE });
|
|
123
|
+
await fs.promises.chmod(filePath, FILE_MODE);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Append ONE contract row for a completed dsh lead request. Never throws: every failure is returned as
|
|
128
|
+
* `{ok:false, reason}` so the proxy can report it without breaking a response that has already gone out.
|
|
129
|
+
*
|
|
130
|
+
* @param {{ dataDir: string, ctmSessionId: string, row: object }} opts
|
|
131
|
+
* @returns {Promise<{ok:true}|{ok:false, reason:string, error?:string}>}
|
|
132
|
+
*/
|
|
133
|
+
function appendDshUsageRow({ dataDir, ctmSessionId, row } = {}) {
|
|
134
|
+
if (typeof dataDir !== 'string' || !dataDir) return Promise.resolve({ ok: false, reason: 'data_dir_required' });
|
|
135
|
+
if (typeof ctmSessionId !== 'string' || !CTM_SESSION_ID_RE.test(ctmSessionId)) {
|
|
136
|
+
// Refuse BEFORE the id is ever joined into a path: `../x`, an empty string, a 200-character id and
|
|
137
|
+
// anything else outside the grammar write NOTHING.
|
|
138
|
+
return Promise.resolve({ ok: false, reason: 'invalid_ctm_session_id' });
|
|
139
|
+
}
|
|
140
|
+
if (!row || typeof row !== 'object' || Array.isArray(row)) return Promise.resolve({ ok: false, reason: 'invalid_row' });
|
|
141
|
+
const filePath = dshUsagePath(dataDir, ctmSessionId);
|
|
142
|
+
const line = `${JSON.stringify(buildDshUsageRow(row))}\n`;
|
|
143
|
+
return _serialize(filePath, async () => {
|
|
144
|
+
try {
|
|
145
|
+
await _appendLine(filePath, line);
|
|
146
|
+
return { ok: true };
|
|
147
|
+
} catch (error) {
|
|
148
|
+
// REPORT: the caller surfaces the bounded reason through the proxy's own log line; the module
|
|
149
|
+
// itself stays silent and never throws into a response path.
|
|
150
|
+
return { ok: false, reason: 'write_failed', error: _message(error) };
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
module.exports = {
|
|
156
|
+
CTM_SESSION_ID_RE,
|
|
157
|
+
USAGE_DIR_NAME,
|
|
158
|
+
dshUsageDir,
|
|
159
|
+
dshUsagePath,
|
|
160
|
+
buildDshUsageRow,
|
|
161
|
+
appendDshUsageRow,
|
|
162
|
+
};
|