create-walle 0.9.21 → 0.9.23
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 +27 -5
- package/package.json +2 -2
- package/template/CLAUDE.md +2 -2
- package/template/LICENSE +1 -1
- package/template/bin/ctm-dev-cleanup.js +24 -3
- package/template/bin/ctm-launch.sh +13 -0
- package/template/bin/dev.sh +156 -18
- package/template/bin/node-bin.sh +84 -0
- package/template/bin/pin-node.sh +51 -0
- package/template/claude-task-manager/api-prompts.js +1203 -182
- package/template/claude-task-manager/api-reviews.js +109 -15
- package/template/claude-task-manager/approval-agent.js +1360 -280
- package/template/claude-task-manager/bin/restart-ctm.sh +64 -23
- package/template/claude-task-manager/bin/storage-migration-supervisor.js +338 -0
- package/template/claude-task-manager/db.js +4417 -295
- package/template/claude-task-manager/docs/app-update-refresh-protocol.md +69 -0
- package/template/claude-task-manager/docs/approval-ai-refinement.md +138 -0
- package/template/claude-task-manager/docs/approval-rescue-loop.md +74 -0
- package/template/claude-task-manager/docs/codex-operational-warning-health.md +107 -0
- package/template/claude-task-manager/docs/codex-resume-state-guard-design.md +17 -12
- package/template/claude-task-manager/docs/codex-terminal-render-controller-handoff.md +311 -0
- package/template/claude-task-manager/docs/coding-agent-hooks-architecture.md +418 -0
- package/template/claude-task-manager/docs/conversation-import-freshness.md +20 -0
- package/template/claude-task-manager/docs/google-workspace-auth-health.md +77 -0
- package/template/claude-task-manager/docs/image-paste-ux.md +13 -0
- package/template/claude-task-manager/docs/ipad-web-preview.md +88 -0
- package/template/claude-task-manager/docs/main-loop-offload-architecture.md +66 -0
- package/template/claude-task-manager/docs/microsoft-dev-tunnel-phone-access-design.md +274 -519
- package/template/claude-task-manager/docs/mobile-live-streaming.md +27 -5
- package/template/claude-task-manager/docs/mobile-remote-submission-lifecycle.md +69 -0
- package/template/claude-task-manager/docs/phone-access-design.md +53 -15
- package/template/claude-task-manager/docs/phone-passkey-identity.md +122 -0
- package/template/claude-task-manager/docs/phone-setup.md +3 -0
- package/template/claude-task-manager/docs/prompt-editing-tree-design.md +25 -1
- package/template/claude-task-manager/docs/remote-desktop-access-design.md +268 -0
- package/template/claude-task-manager/docs/restart-lifecycle-architecture.md +95 -0
- package/template/claude-task-manager/docs/runtime-work-control-plane.md +53 -0
- package/template/claude-task-manager/docs/session-interactive-wait-surfaces.md +38 -0
- package/template/claude-task-manager/docs/session-needs-you-dismissal.md +84 -0
- package/template/claude-task-manager/docs/session-render-state-management-design.md +91 -3
- package/template/claude-task-manager/docs/session-standup-command-center-design.md +25 -1
- package/template/claude-task-manager/docs/session-title-authority.md +32 -0
- package/template/claude-task-manager/docs/session-workspace-binding.md +33 -0
- package/template/claude-task-manager/docs/skill-intent-resolution-design.md +72 -0
- package/template/claude-task-manager/docs/walle-mcp-supervisor-health.md +86 -0
- package/template/claude-task-manager/docs/walle-relay-phone-access-design.md +24 -15
- package/template/claude-task-manager/docs/walle-session-history-hydration.md +114 -0
- package/template/claude-task-manager/docs/walle-session-input-queue.md +104 -0
- package/template/claude-task-manager/docs/walle-session-model-catalog.md +90 -0
- package/template/claude-task-manager/docs/walle-session-model-preferences.md +15 -6
- package/template/claude-task-manager/git-utils.js +897 -27
- package/template/claude-task-manager/lib/agent-capabilities.js +33 -0
- package/template/claude-task-manager/lib/agent-cli-cache.js +37 -7
- package/template/claude-task-manager/lib/agent-hooks-installer.js +26 -2
- package/template/claude-task-manager/lib/agent-presets.js +17 -1
- package/template/claude-task-manager/lib/all-sessions-query.js +108 -0
- package/template/claude-task-manager/lib/approval-ai-refinement.js +488 -0
- package/template/claude-task-manager/lib/approval-self-adapt.js +168 -0
- package/template/claude-task-manager/lib/async-semaphore.js +44 -0
- package/template/claude-task-manager/lib/auth-context.js +5 -0
- package/template/claude-task-manager/lib/auth-rate-limit.js +47 -4
- package/template/claude-task-manager/lib/auth-rules.js +29 -2
- package/template/claude-task-manager/lib/auto-approval-verifier.js +129 -16
- package/template/claude-task-manager/lib/background-llm.js +144 -17
- package/template/claude-task-manager/lib/branch-inventory.js +212 -0
- package/template/claude-task-manager/lib/claude-desktop-sessions.js +15 -3
- package/template/claude-task-manager/lib/coalesce-sync-frames.js +151 -0
- package/template/claude-task-manager/lib/codex-launch-health.js +762 -0
- package/template/claude-task-manager/lib/codex-transcript-pager.js +51 -0
- package/template/claude-task-manager/lib/codex-zst.js +124 -0
- package/template/claude-task-manager/lib/coding-agent-models.js +233 -30
- package/template/claude-task-manager/lib/connection-health.js +232 -0
- package/template/claude-task-manager/lib/conversation-blob-parser.js +42 -0
- package/template/claude-task-manager/lib/conversation-tail-merge.js +89 -26
- package/template/claude-task-manager/lib/ctm-session-context-api.js +39 -10
- package/template/claude-task-manager/lib/cursor-conversation-store.js +354 -0
- package/template/claude-task-manager/lib/db-owner-worker-client.js +315 -0
- package/template/claude-task-manager/lib/document-review.js +141 -6
- package/template/claude-task-manager/lib/escalation-review.js +152 -0
- package/template/claude-task-manager/lib/graceful-shutdown.js +159 -0
- package/template/claude-task-manager/lib/headless-term-service.js +678 -0
- package/template/claude-task-manager/lib/heavy-worker-fallback.js +38 -0
- package/template/claude-task-manager/lib/jsonl-conversation-parser.js +542 -0
- package/template/claude-task-manager/lib/jsonl-range-reader.js +112 -0
- package/template/claude-task-manager/lib/main-db-census.js +216 -0
- package/template/claude-task-manager/lib/message-pagination.js +106 -4
- package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +750 -26
- package/template/claude-task-manager/lib/mobile-auth-api.js +274 -7
- package/template/claude-task-manager/lib/mobile-auth-store.js +592 -10
- package/template/claude-task-manager/lib/mobile-notification-dispatcher.js +15 -0
- package/template/claude-task-manager/lib/model-overview-brain-fallback.js +311 -0
- package/template/claude-task-manager/lib/model-overview-cache.js +141 -0
- package/template/claude-task-manager/lib/models-health-routing-notice.js +126 -0
- package/template/claude-task-manager/lib/node-pin-guard.js +93 -0
- package/template/claude-task-manager/lib/perf-tracker.js +242 -6
- package/template/claude-task-manager/lib/permission-match.js +76 -0
- package/template/claude-task-manager/lib/permission-sync.js +133 -20
- package/template/claude-task-manager/lib/process-title.js +35 -0
- package/template/claude-task-manager/lib/prompt-executions-query.js +25 -0
- package/template/claude-task-manager/lib/prompt-index-disk-cache.js +44 -0
- package/template/claude-task-manager/lib/prompt-intent.js +132 -0
- package/template/claude-task-manager/lib/provider-user-context.js +34 -0
- package/template/claude-task-manager/lib/read-pool-client.js +313 -0
- package/template/claude-task-manager/lib/readpool-breaker.js +31 -0
- package/template/claude-task-manager/lib/recent-sessions-breaker.js +12 -0
- package/template/claude-task-manager/lib/remote-feedback-client.js +72 -0
- package/template/claude-task-manager/lib/remote-relay-protocol.js +37 -4
- package/template/claude-task-manager/lib/remote-relay-store.js +159 -0
- package/template/claude-task-manager/lib/remote-submission-observer.js +278 -0
- package/template/claude-task-manager/lib/restart-guard.js +109 -0
- package/template/claude-task-manager/lib/restore-interruption-detector.js +439 -0
- package/template/claude-task-manager/lib/restore-policy.js +13 -0
- package/template/claude-task-manager/lib/restore-resume-batch.js +74 -0
- package/template/claude-task-manager/lib/restore-runtime.js +68 -0
- package/template/claude-task-manager/lib/restore-storm.js +34 -0
- package/template/claude-task-manager/lib/resume-cwd.js +36 -0
- package/template/claude-task-manager/lib/resume-preflight.js +313 -0
- package/template/claude-task-manager/lib/runtime-work-registry.js +444 -0
- package/template/claude-task-manager/lib/sanitize-openai-auth.js +31 -0
- package/template/claude-task-manager/lib/scheduler.js +21 -1
- package/template/claude-task-manager/lib/scrollback-snapshot-store.js +159 -0
- package/template/claude-task-manager/lib/serial-task-queue.js +64 -0
- package/template/claude-task-manager/lib/server-listeners.js +239 -0
- package/template/claude-task-manager/lib/session-capture.js +42 -7
- package/template/claude-task-manager/lib/session-content-backfill.js +131 -0
- package/template/claude-task-manager/lib/session-history.js +388 -43
- package/template/claude-task-manager/lib/session-host-manager.js +287 -0
- package/template/claude-task-manager/lib/session-image-refs.js +209 -0
- package/template/claude-task-manager/lib/session-jobs.js +399 -59
- package/template/claude-task-manager/lib/session-prompt-index.js +137 -0
- package/template/claude-task-manager/lib/session-restore.js +53 -0
- package/template/claude-task-manager/lib/session-standup.js +123 -23
- package/template/claude-task-manager/lib/session-state-bus.js +14 -0
- package/template/claude-task-manager/lib/session-stream.js +64 -16
- package/template/claude-task-manager/lib/session-timeline-summary.js +260 -0
- package/template/claude-task-manager/lib/session-token-usage.js +494 -0
- package/template/claude-task-manager/lib/session-workspace-binding.js +356 -0
- package/template/claude-task-manager/lib/setup-network-config.js +9 -0
- package/template/claude-task-manager/lib/size-cap.js +45 -0
- package/template/claude-task-manager/lib/size-cap.test.js +62 -0
- package/template/claude-task-manager/lib/skill-autocomplete.js +180 -1
- package/template/claude-task-manager/lib/skill-intent-resolver.js +304 -0
- package/template/claude-task-manager/lib/sqlite-driver.js +19 -3
- package/template/claude-task-manager/lib/standup-attention.js +7 -3
- package/template/claude-task-manager/lib/status-authority.js +39 -0
- package/template/claude-task-manager/lib/status-hooks.js +4 -0
- package/template/claude-task-manager/lib/storage-migration.js +235 -0
- package/template/claude-task-manager/lib/structured-capture.js +298 -0
- package/template/claude-task-manager/lib/sync-io-census.js +163 -0
- package/template/claude-task-manager/lib/tailscale-setup.js +6 -0
- package/template/claude-task-manager/lib/terminal-activity-evidence.js +33 -0
- package/template/claude-task-manager/lib/terminal-choice.js +364 -0
- package/template/claude-task-manager/lib/terminal-control-sanitize.js +17 -0
- package/template/claude-task-manager/lib/terminal-fingerprint.js +48 -0
- package/template/claude-task-manager/lib/terminal-output-flush.js +84 -0
- package/template/claude-task-manager/lib/timeline-order.js +122 -0
- package/template/claude-task-manager/lib/transcript-store.js +348 -43
- package/template/claude-task-manager/lib/transport-security.js +84 -1
- package/template/claude-task-manager/lib/wait-state.js +184 -0
- package/template/claude-task-manager/lib/walle-client.js +47 -5
- package/template/claude-task-manager/lib/walle-ctm-history.js +564 -4
- package/template/claude-task-manager/lib/walle-external-actions.js +135 -16
- package/template/claude-task-manager/lib/walle-history-hydration.js +46 -0
- package/template/claude-task-manager/lib/walle-native-health.js +403 -0
- package/template/claude-task-manager/lib/walle-repair.js +701 -0
- package/template/claude-task-manager/lib/walle-session-cache.js +109 -0
- package/template/claude-task-manager/lib/walle-session-context.js +57 -21
- package/template/claude-task-manager/lib/walle-session-model-catalog.js +34 -0
- package/template/claude-task-manager/lib/walle-supervisor.js +539 -63
- package/template/claude-task-manager/lib/walle-transcript.js +52 -0
- package/template/claude-task-manager/lib/worktree-active-sync.js +11 -7
- package/template/claude-task-manager/lib/worktree-cwd.js +32 -1
- package/template/claude-task-manager/package.json +1 -1
- package/template/claude-task-manager/prompt-harvest.js +89 -66
- package/template/claude-task-manager/providers/claude-code.js +51 -3
- package/template/claude-task-manager/providers/cursor.js +140 -45
- package/template/claude-task-manager/public/css/reviews.css +551 -61
- package/template/claude-task-manager/public/css/setup.css +191 -0
- package/template/claude-task-manager/public/css/walle-session.css +865 -10
- package/template/claude-task-manager/public/css/walle.css +154 -0
- package/template/claude-task-manager/public/designs/ai-providers-consolidation-v2.html +830 -0
- package/template/claude-task-manager/public/index.html +18516 -2058
- package/template/claude-task-manager/public/ipad.html +363 -0
- package/template/claude-task-manager/public/js/document-review-links.js +301 -0
- package/template/claude-task-manager/public/js/image-normalize.js +69 -36
- package/template/claude-task-manager/public/js/message-renderer.js +1265 -77
- package/template/claude-task-manager/public/js/prompts.js +66 -29
- package/template/claude-task-manager/public/js/reviews.js +901 -133
- package/template/claude-task-manager/public/js/session-activity-utils.js +11 -1
- package/template/claude-task-manager/public/js/session-search-utils.js +94 -10
- package/template/claude-task-manager/public/js/session-status-precedence.js +23 -5
- package/template/claude-task-manager/public/js/setup.js +1273 -176
- package/template/claude-task-manager/public/js/stream-view.js +691 -73
- package/template/claude-task-manager/public/js/terminal-reconciler.js +210 -0
- package/template/claude-task-manager/public/js/walle-session.js +2455 -158
- package/template/claude-task-manager/public/js/walle.js +455 -28
- package/template/claude-task-manager/public/m/app.css +2909 -262
- package/template/claude-task-manager/public/m/app.js +6601 -398
- package/template/claude-task-manager/public/m/claim.html +224 -17
- package/template/claude-task-manager/public/m/index.html +117 -21
- package/template/claude-task-manager/public/m/sw.js +3 -1
- package/template/claude-task-manager/public/manifest.json +2 -2
- package/template/claude-task-manager/public/prompts.html +30 -14
- package/template/claude-task-manager/queue-engine.js +507 -28
- package/template/claude-task-manager/scripts/repair-claude-session-images.js +27 -8
- package/template/claude-task-manager/server.js +14341 -2197
- package/template/claude-task-manager/session-integrity.js +160 -18
- package/template/claude-task-manager/session-search-ranking.js +1 -0
- package/template/claude-task-manager/session-utils.js +25 -5
- package/template/claude-task-manager/workers/approval-blocklist.js +96 -6
- package/template/claude-task-manager/workers/approval-widget-validator.js +14 -8
- package/template/claude-task-manager/workers/conversation-import-worker.js +11 -50
- package/template/claude-task-manager/workers/db-owner-worker.js +386 -0
- package/template/claude-task-manager/workers/harvest-worker.js +9 -55
- package/template/claude-task-manager/workers/headless-term-worker.js +9 -530
- package/template/claude-task-manager/workers/read-pool-worker.js +387 -0
- package/template/claude-task-manager/workers/scrollback-worker.js +11 -72
- package/template/claude-task-manager/workers/session-host-process.js +146 -0
- package/template/claude-task-manager/workers/session-integrity-worker.js +10 -54
- package/template/claude-task-manager/workers/state-detectors/base.js +18 -1
- package/template/claude-task-manager/workers/state-detectors/claude-code.js +182 -9
- package/template/claude-task-manager/workers/state-detectors/codex.js +150 -2
- package/template/claude-task-manager/workers/state-detectors/cursor.js +127 -0
- package/template/claude-task-manager/workers/state-detectors/gemini.js +21 -0
- package/template/claude-task-manager/workers/state-detectors/index.js +29 -0
- package/template/claude-task-manager/workers/state-detectors/opencode.js +103 -0
- package/template/docs/design/markdown-review-pane.md +206 -0
- package/template/docs/designs/2026-05-17-portkey-gateway-provider-ux.md +129 -38
- package/template/docs/designs/2026-05-20-mobile-worktree-finish-command.md +27 -0
- package/template/docs/designs/2026-05-22-ai-configuration-consolidation.md +248 -0
- package/template/docs/designs/ai-configuration-consolidation-mock.html +812 -0
- package/template/docs/private-memory-and-pii-policy.md +69 -0
- package/template/package.json +2 -1
- package/template/scripts/check-private-data.js +201 -0
- package/template/shared/sqlite-owner-guard.js +30 -0
- package/template/shared/sqlite-owner-write-queue.js +225 -0
- package/template/shared/sqlite-storage-policy.js +111 -0
- package/template/shared/sqlite-write-lock.js +428 -0
- package/template/wall-e/agent-runners/claude-code.js +5 -0
- package/template/wall-e/agent.js +166 -22
- package/template/wall-e/api-walle.js +524 -70
- package/template/wall-e/auth/provider-flows.js +11 -1
- package/template/wall-e/bin/walle-mcp-stdio.js +341 -17
- package/template/wall-e/brain.js +1614 -141
- package/template/wall-e/chat/attachment-blocks.js +96 -0
- package/template/wall-e/chat/attachments.js +2 -1
- package/template/wall-e/chat/capability-resolver.js +7 -7
- package/template/wall-e/chat/context-messages.js +28 -0
- package/template/wall-e/chat/conversation-frame.js +630 -0
- package/template/wall-e/chat/provider-messages.js +125 -0
- package/template/wall-e/chat.js +1002 -233
- package/template/wall-e/coding/acceptance-contract.js +170 -0
- package/template/wall-e/coding/acp-adapter.js +1 -1
- package/template/wall-e/coding/agent-catalog.js +3 -0
- package/template/wall-e/coding/artifact-store.js +93 -0
- package/template/wall-e/coding/capability-router.js +120 -0
- package/template/wall-e/coding/coding-run-controller.js +423 -0
- package/template/wall-e/coding/compaction-service.js +157 -12
- package/template/wall-e/coding/frontend-verification.js +258 -0
- package/template/wall-e/coding/lifecycle-hooks.js +75 -0
- package/template/wall-e/coding/local-preview-contract.js +157 -0
- package/template/wall-e/coding/permission-service.js +57 -13
- package/template/wall-e/coding/prompt-bundle.js +19 -1
- package/template/wall-e/coding/prompt-section-registry.js +227 -0
- package/template/wall-e/coding/provider-compat.js +15 -0
- package/template/wall-e/coding/runtime-events.js +224 -0
- package/template/wall-e/coding/runtime-mode.js +3 -0
- package/template/wall-e/coding/side-git-snapshot.js +160 -4
- package/template/wall-e/coding/snapshot-service.js +143 -1
- package/template/wall-e/coding/stream-processor.js +388 -34
- package/template/wall-e/coding/task-tool.js +141 -4
- package/template/wall-e/coding/tool-execution-controller.js +365 -0
- package/template/wall-e/coding/tool-registry.js +43 -5
- package/template/wall-e/coding/user-hooks.js +217 -0
- package/template/wall-e/coding-orchestrator.js +1330 -221
- package/template/wall-e/coding-prompts.js +20 -4
- package/template/wall-e/context/context-builder.js +15 -2
- package/template/wall-e/decision/confidence.js +1 -1
- package/template/wall-e/docs/coding-acceptance-contract.md +41 -0
- package/template/wall-e/docs/external-action-controller.md +26 -6
- package/template/wall-e/docs/telemetry-lifecycle.md +8 -2
- package/template/wall-e/embeddings.js +591 -53
- package/template/wall-e/external-action-controller.js +12 -0
- package/template/wall-e/http/auth.js +1 -0
- package/template/wall-e/http/chat-api.js +46 -11
- package/template/wall-e/http/model-admin.js +836 -34
- package/template/wall-e/lib/boot-profile.js +88 -0
- package/template/wall-e/lib/event-loop-monitor.js +93 -0
- package/template/wall-e/lib/service-health.js +194 -0
- package/template/wall-e/llm/anthropic.js +130 -5
- package/template/wall-e/llm/client.js +266 -63
- package/template/wall-e/llm/default-fallback.js +382 -0
- package/template/wall-e/llm/health.js +19 -0
- package/template/wall-e/llm/message-guard.js +78 -0
- package/template/wall-e/llm/model-catalog.js +252 -1
- package/template/wall-e/llm/openai.js +26 -4
- package/template/wall-e/llm/portkey-sync.js +654 -0
- package/template/wall-e/llm/provider-error.js +30 -2
- package/template/wall-e/llm/registry.js +5 -1
- package/template/wall-e/llm/request-compat.js +67 -0
- package/template/wall-e/loops/backfill.js +79 -23
- package/template/wall-e/loops/brain-optimize.js +67 -0
- package/template/wall-e/loops/ingest.js +25 -10
- package/template/wall-e/loops/question-digest.js +160 -0
- package/template/wall-e/loops/reflect.js +6 -4
- package/template/wall-e/loops/think.js +39 -12
- package/template/wall-e/mcp-server.js +318 -36
- package/template/wall-e/memory/ctm-context-client.js +52 -14
- package/template/wall-e/memory/ctm-operational-context.js +237 -0
- package/template/wall-e/memory/ctm-prompt-executions-client.js +128 -0
- package/template/wall-e/memory/ctm-session-context.js +111 -63
- package/template/wall-e/prompts/coding/deepseek.txt +3 -0
- package/template/wall-e/prompts/coding/gemini.txt +6 -0
- package/template/wall-e/prompts/coding/gpt.txt +6 -0
- package/template/wall-e/prompts/coding/local.txt +7 -0
- package/template/wall-e/runtime/decision-hooks.js +115 -0
- package/template/wall-e/runtime/devbox-gateway.js +82 -8
- package/template/wall-e/runtime/prompt-manifest.js +86 -0
- package/template/wall-e/runtime/tool-executor.js +269 -0
- package/template/wall-e/runtime/tool-result-envelope.js +138 -0
- package/template/wall-e/runtime/transcript-projection.js +60 -0
- package/template/wall-e/runtime/walle-runtime.js +224 -0
- package/template/wall-e/scripts/db-optimize/migrate.js +162 -0
- package/template/wall-e/scripts/db-optimize/recall-eval.js +117 -0
- package/template/wall-e/server.js +15 -0
- package/template/wall-e/session-files.js +9 -0
- package/template/wall-e/skills/_bundled/google-calendar/run.js +1 -1
- package/template/wall-e/skills/_bundled/gws-workspace/run.js +1 -1
- package/template/wall-e/skills/_bundled/slack-mentions/run.js +76 -6
- package/template/wall-e/skills/claude-code-reader.js +7 -3
- package/template/wall-e/skills/script-skill-runner.js +10 -0
- package/template/wall-e/skills/skill-planner.js +38 -0
- package/template/wall-e/tools/builtin-middleware.js +19 -9
- package/template/wall-e/tools/local-tools.js +1428 -16
- package/template/wall-e/tools/permission-checker.js +73 -5
- package/template/wall-e/tools/question-manager.js +117 -7
- package/template/wall-e/training/harvester.js +12 -28
- package/template/wall-e/training/replay.js +25 -80
- package/template/website/index.html +10 -10
- package/template/wall-e/eval/ab-test.js +0 -203
- package/template/wall-e/eval/agent-runner.js +0 -772
- package/template/wall-e/eval/agent-scorer.js +0 -461
- package/template/wall-e/eval/aggregator.js +0 -414
- package/template/wall-e/eval/allowed-test-commands.js +0 -34
- package/template/wall-e/eval/benchmark-generator.js +0 -113
- package/template/wall-e/eval/benchmarks/chat-eval.json +0 -1662
- package/template/wall-e/eval/benchmarks/chat.json +0 -82
- package/template/wall-e/eval/benchmarks/coding-agent-real.json +0 -1
- package/template/wall-e/eval/benchmarks/coding-agent.json +0 -1581
- package/template/wall-e/eval/benchmarks/coding.json +0 -122
- package/template/wall-e/eval/benchmarks/memory-retrieval.json +0 -234
- package/template/wall-e/eval/benchmarks/reasoning.json +0 -82
- package/template/wall-e/eval/benchmarks/swebench-lite-30.json +0 -212
- package/template/wall-e/eval/benchmarks.js +0 -669
- package/template/wall-e/eval/cc-replay.js +0 -719
- package/template/wall-e/eval/chat-eval.js +0 -525
- package/template/wall-e/eval/check-keys.js +0 -15
- package/template/wall-e/eval/check-providers.js +0 -42
- package/template/wall-e/eval/codex-cli-baseline.js +0 -669
- package/template/wall-e/eval/coding-agent-real.js +0 -570
- package/template/wall-e/eval/context-compactor.js +0 -251
- package/template/wall-e/eval/debug-agent003.js +0 -68
- package/template/wall-e/eval/diagnostics.js +0 -216
- package/template/wall-e/eval/eval-orchestrator.js +0 -642
- package/template/wall-e/eval/evaluate.js +0 -202
- package/template/wall-e/eval/evaluator.js +0 -373
- package/template/wall-e/eval/exporter.js +0 -212
- package/template/wall-e/eval/fixtures/express-basic/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-basic/server.js +0 -115
- package/template/wall-e/eval/fixtures/express-basic/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-buggy/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-buggy/server.js +0 -113
- package/template/wall-e/eval/fixtures/express-buggy/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-buggy-items/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-buggy-items/server.js +0 -112
- package/template/wall-e/eval/fixtures/express-buggy-items/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-buggy-search/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-buggy-search/server.js +0 -121
- package/template/wall-e/eval/fixtures/express-buggy-search/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-rename-data/data.js +0 -34
- package/template/wall-e/eval/fixtures/express-rename-data/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-rename-data/server.js +0 -97
- package/template/wall-e/eval/fixtures/express-rename-data/test.js +0 -88
- package/template/wall-e/eval/fixtures/express-xss/package.json +0 -12
- package/template/wall-e/eval/fixtures/express-xss/server.js +0 -90
- package/template/wall-e/eval/fixtures/express-xss/test.js +0 -67
- package/template/wall-e/eval/fixtures/express-xss/views/profile.ejs +0 -9
- package/template/wall-e/eval/fixtures/fullstack-app/config/default.js +0 -9
- package/template/wall-e/eval/fixtures/fullstack-app/config/test.js +0 -13
- package/template/wall-e/eval/fixtures/fullstack-app/package.json +0 -11
- package/template/wall-e/eval/fixtures/fullstack-app/public/css/style.css +0 -137
- package/template/wall-e/eval/fixtures/fullstack-app/public/index.html +0 -46
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/app.js +0 -121
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/auth.js +0 -71
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/items.js +0 -80
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/users.js +0 -46
- package/template/wall-e/eval/fixtures/fullstack-app/public/login.html +0 -45
- package/template/wall-e/eval/fixtures/fullstack-app/public/register.html +0 -38
- package/template/wall-e/eval/fixtures/fullstack-app/scripts/migrate.js +0 -23
- package/template/wall-e/eval/fixtures/fullstack-app/scripts/seed.js +0 -46
- package/template/wall-e/eval/fixtures/fullstack-app/server/db.js +0 -99
- package/template/wall-e/eval/fixtures/fullstack-app/server/index.js +0 -94
- package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/auth.js +0 -19
- package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/logger.js +0 -19
- package/template/wall-e/eval/fixtures/fullstack-app/server/router.js +0 -50
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/auth.js +0 -69
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/health.js +0 -23
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/items.js +0 -88
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/users.js +0 -75
- package/template/wall-e/eval/fixtures/fullstack-app/server/test.js +0 -198
- package/template/wall-e/eval/fixtures/fullstack-app/server/utils/response.js +0 -34
- package/template/wall-e/eval/fixtures/fullstack-app/server/utils/validate.js +0 -26
- package/template/wall-e/eval/fixtures/fullstack-app/server.js +0 -8
- package/template/wall-e/eval/fixtures/fullstack-app/test.js +0 -12
- package/template/wall-e/eval/fixtures/monorepo-basic/package.json +0 -8
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/data.js +0 -58
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/middleware.js +0 -46
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/package.json +0 -8
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/routes.js +0 -64
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/server.js +0 -56
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/test.js +0 -116
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/commands.js +0 -61
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/index.js +0 -62
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/output.js +0 -43
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/package.json +0 -11
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/test.js +0 -44
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/formatters.js +0 -43
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/index.js +0 -12
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/package.json +0 -5
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/test.js +0 -55
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/validators.js +0 -29
- package/template/wall-e/eval/fixtures/monorepo-basic/test.js +0 -46
- package/template/wall-e/eval/fixtures/node-cli/index.js +0 -78
- package/template/wall-e/eval/fixtures/node-cli/package.json +0 -10
- package/template/wall-e/eval/fixtures/node-cli/test.js +0 -57
- package/template/wall-e/eval/fixtures/node-typed/package.json +0 -8
- package/template/wall-e/eval/fixtures/node-typed/src/handlers.js +0 -31
- package/template/wall-e/eval/fixtures/node-typed/src/utils.js +0 -33
- package/template/wall-e/eval/fixtures/node-typed/test.js +0 -36
- package/template/wall-e/eval/fixtures/python-flask/app.py +0 -14
- package/template/wall-e/eval/fixtures/python-flask/requirements.txt +0 -2
- package/template/wall-e/eval/fixtures/python-flask/test_app.py +0 -25
- package/template/wall-e/eval/fixtures/wall-e-subset/brain.js +0 -105
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/aggregator.js +0 -101
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/chat.json +0 -20
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/coding.json +0 -32
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks.js +0 -64
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/package.json +0 -6
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/server.js +0 -31
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/test.js +0 -18
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/utils.js +0 -34
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/runner.js +0 -104
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/scorer.js +0 -73
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/test.js +0 -134
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/client.js +0 -99
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/providers.js +0 -63
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/test.js +0 -70
- package/template/wall-e/eval/fixtures/wall-e-subset/package.json +0 -10
- package/template/wall-e/eval/fixtures/wall-e-subset/test.js +0 -86
- package/template/wall-e/eval/harvester.js +0 -685
- package/template/wall-e/eval/head-to-head.js +0 -388
- package/template/wall-e/eval/humaneval-adapter.js +0 -321
- package/template/wall-e/eval/list-models.js +0 -31
- package/template/wall-e/eval/livecodebench-adapter.js +0 -291
- package/template/wall-e/eval/mail-integration.js +0 -443
- package/template/wall-e/eval/manifest.js +0 -186
- package/template/wall-e/eval/meta-harness/adapters/coding-agent.js +0 -57
- package/template/wall-e/eval/meta-harness/bootstrap-snapshot.js +0 -149
- package/template/wall-e/eval/meta-harness/candidate-store.js +0 -117
- package/template/wall-e/eval/meta-harness/cli.js +0 -86
- package/template/wall-e/eval/meta-harness/domain-spec.js +0 -154
- package/template/wall-e/eval/meta-harness/domains/coding-agent.domain.json +0 -84
- package/template/wall-e/eval/meta-harness/examples/env-bootstrap-candidate.js +0 -29
- package/template/wall-e/eval/meta-harness/experience-store.js +0 -174
- package/template/wall-e/eval/meta-harness/frontier.js +0 -96
- package/template/wall-e/eval/meta-harness/harness-interface.js +0 -90
- package/template/wall-e/eval/meta-harness/leakage-guard.js +0 -80
- package/template/wall-e/eval/meta-harness/optimizer.js +0 -207
- package/template/wall-e/eval/meta-harness/proposer-runner.js +0 -110
- package/template/wall-e/eval/meta-harness/reporting.js +0 -58
- package/template/wall-e/eval/meta-harness/telemetry.js +0 -27
- package/template/wall-e/eval/meta-harness/validation.js +0 -81
- package/template/wall-e/eval/promoter.js +0 -228
- package/template/wall-e/eval/provider-normalizer.js +0 -33
- package/template/wall-e/eval/replay.js +0 -395
- package/template/wall-e/eval/run-agent-benchmarks.js +0 -386
- package/template/wall-e/eval/run-codex-cli-baseline.js +0 -177
- package/template/wall-e/eval/run-coding-agent-real.js +0 -187
- package/template/wall-e/eval/run-eval.js +0 -435
- package/template/wall-e/eval/run-model-comparison.js +0 -142
- package/template/wall-e/eval/session-evaluator.js +0 -187
- package/template/wall-e/eval/session-miner.js +0 -207
- package/template/wall-e/eval/session-retrieval-benchmark.js +0 -150
- package/template/wall-e/eval/session-transcripts.js +0 -509
- package/template/wall-e/eval/shadow.js +0 -161
- package/template/wall-e/eval/swebench-adapter.js +0 -345
- package/template/wall-e/eval/swebench-docker.js +0 -192
- package/template/wall-e/eval/train.py +0 -320
- package/template/wall-e/eval/trainer.js +0 -232
- package/template/wall-e/eval/weekly-eval-loop.js +0 -241
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# Coding Agent Hooks Architecture
|
|
2
|
+
|
|
3
|
+
Date: 2026-05-28
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
CTM runs several external coding agents as terminal sessions: Claude Code,
|
|
8
|
+
Codex, and Gemini CLI. Those agents own their terminal UI and provider runtime,
|
|
9
|
+
but CTM needs reliable lifecycle signals to render status, drive mobile status
|
|
10
|
+
lanes, preserve session context, and eventually trigger memory capture at the
|
|
11
|
+
right boundaries.
|
|
12
|
+
|
|
13
|
+
Hooks are the bridge. They are small user-approved entries in each agent's own
|
|
14
|
+
configuration that call back into CTM when an agent starts, stops, waits, or
|
|
15
|
+
uses tools. They complement, but do not replace, transcripts, PTY activity,
|
|
16
|
+
OpenTelemetry, and CTM's own session database.
|
|
17
|
+
|
|
18
|
+
## External Contracts
|
|
19
|
+
|
|
20
|
+
### Claude Code
|
|
21
|
+
|
|
22
|
+
Claude Code supports hooks in JSON settings files. Its docs describe a
|
|
23
|
+
read-only `/hooks` browser, user/project/local/plugin/session/built-in hook
|
|
24
|
+
sources, and command hooks that receive JSON on stdin. Common input fields
|
|
25
|
+
include `session_id`, `transcript_path`, `cwd`, and `permission_mode`.
|
|
26
|
+
|
|
27
|
+
CTM uses user-level `~/.claude/settings.json` so the integration applies to
|
|
28
|
+
Claude Code sessions launched through CTM without requiring project files to be
|
|
29
|
+
modified.
|
|
30
|
+
|
|
31
|
+
Source: https://code.claude.com/docs/en/hooks
|
|
32
|
+
|
|
33
|
+
### Codex
|
|
34
|
+
|
|
35
|
+
Codex has a different contract. CTM uses two surfaces:
|
|
36
|
+
|
|
37
|
+
- OTLP log export, configured through an `[otel]` block.
|
|
38
|
+
- The top-level `notify = [...]` command array, which Codex invokes on agent
|
|
39
|
+
turn completion.
|
|
40
|
+
|
|
41
|
+
The Codex source defines `notify` as an optional command vector and shows it
|
|
42
|
+
invoked with an `agent-turn-complete` JSON payload. Current Codex config docs
|
|
43
|
+
also expose lifecycle-hook policy controls such as `allow_managed_hooks_only`
|
|
44
|
+
for managed environments.
|
|
45
|
+
|
|
46
|
+
Sources:
|
|
47
|
+
|
|
48
|
+
- https://github.com/openai/codex/blob/main/codex-rs/core/src/config/mod.rs
|
|
49
|
+
- https://github.com/openai/codex/blob/main/docs/config.md
|
|
50
|
+
|
|
51
|
+
### Gemini CLI
|
|
52
|
+
|
|
53
|
+
Gemini CLI uses JSON settings files, with user-level config at
|
|
54
|
+
`~/.gemini/settings.json` and project-level config at `.gemini/settings.json`.
|
|
55
|
+
Its hook settings include events such as `BeforeAgent`, `AfterAgent`,
|
|
56
|
+
`Notification`, `SessionStart`, `SessionEnd`, `BeforeTool`, and `AfterTool`.
|
|
57
|
+
The hook-writing guide emphasizes the same basic execution model CTM relies on:
|
|
58
|
+
hooks receive JSON on stdin, should log to stderr, and should reserve stdout for
|
|
59
|
+
JSON hook output.
|
|
60
|
+
|
|
61
|
+
Sources:
|
|
62
|
+
|
|
63
|
+
- https://github.com/google-gemini/gemini-cli/blob/main/docs/reference/configuration.md
|
|
64
|
+
- https://github.com/google-gemini/gemini-cli/blob/main/docs/hooks/writing-hooks.md
|
|
65
|
+
|
|
66
|
+
### OpenTelemetry
|
|
67
|
+
|
|
68
|
+
OpenTelemetry OTLP defines HTTP endpoints such as `/v1/logs` for log export.
|
|
69
|
+
The OTLP exporter configuration supports environment variables including
|
|
70
|
+
`OTEL_EXPORTER_OTLP_ENDPOINT` and `OTEL_EXPORTER_OTLP_PROTOCOL`; `http/json` is
|
|
71
|
+
a valid protocol value.
|
|
72
|
+
|
|
73
|
+
CTM uses this for low-latency agent status when an agent supports OTLP logs.
|
|
74
|
+
|
|
75
|
+
Sources:
|
|
76
|
+
|
|
77
|
+
- https://opentelemetry.io/docs/specs/otlp/
|
|
78
|
+
- https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/
|
|
79
|
+
|
|
80
|
+
## Current CTM Implementation
|
|
81
|
+
|
|
82
|
+
### UI
|
|
83
|
+
|
|
84
|
+
The AI Providers page has a **Coding Agents** tab. It checks:
|
|
85
|
+
|
|
86
|
+
- CLI availability through `/api/models/available-agents`.
|
|
87
|
+
- Hook install status through `/api/otel/status`.
|
|
88
|
+
|
|
89
|
+
The card state is derived in `public/index.html`:
|
|
90
|
+
|
|
91
|
+
- `Ready`: CLI detected and CTM hooks installed.
|
|
92
|
+
- `Enable live status`: CLI detected but CTM has not found the integration for
|
|
93
|
+
the current CTM port.
|
|
94
|
+
- `Not found`: CLI is not on PATH.
|
|
95
|
+
- `Path changed` or `Config needs attention`: cached path or config inspection
|
|
96
|
+
failed.
|
|
97
|
+
|
|
98
|
+
When coding agents are detected but hooks are missing, CTM shows one
|
|
99
|
+
**Enable live status** prompt for every detected runtime that needs the current
|
|
100
|
+
CTM port. The modal shows each target config path and a sanitized change
|
|
101
|
+
summary from `/api/otel/plan-install`, then applies the idempotent installer
|
|
102
|
+
only after the user approves. When hooks are already present, the card offers
|
|
103
|
+
**Refresh live status** for the same idempotent repair path.
|
|
104
|
+
|
|
105
|
+
The proactive prompt is allowed when the user opens the Coding Agents tab or
|
|
106
|
+
when a fresh coding-agent session emits `session.needsSetup`. Passive page load
|
|
107
|
+
still must not write config or install hooks.
|
|
108
|
+
|
|
109
|
+
Relevant code:
|
|
110
|
+
|
|
111
|
+
- `claude-task-manager/public/index.html`
|
|
112
|
+
- `_modelsCodingAgentStatusFor`
|
|
113
|
+
- `_ensureModelsAgentStatus`
|
|
114
|
+
- `installCodingAgentHooks`
|
|
115
|
+
- `renderModelsCodingAgentRoutes`
|
|
116
|
+
|
|
117
|
+
### Installer
|
|
118
|
+
|
|
119
|
+
`claude-task-manager/lib/agent-hooks-installer.js` is the local authority for
|
|
120
|
+
config writes. It has a plan/apply split:
|
|
121
|
+
|
|
122
|
+
- `planInstall(agent, port)` reads the user's config and builds the proposed
|
|
123
|
+
next text.
|
|
124
|
+
- `install(agent, port)` applies the plan.
|
|
125
|
+
- `planUninstall(agent, port)` removes CTM-owned entries.
|
|
126
|
+
- `isInstalled(agent, port)` checks whether the current CTM integration marker
|
|
127
|
+
is present.
|
|
128
|
+
|
|
129
|
+
The installer is deliberately idempotent. Re-running install should avoid
|
|
130
|
+
duplicates, and uninstall should remove only CTM-owned entries while preserving
|
|
131
|
+
user-owned config.
|
|
132
|
+
|
|
133
|
+
Current target files:
|
|
134
|
+
|
|
135
|
+
- Claude Code: `~/.claude/settings.json`
|
|
136
|
+
- Codex: `~/.codex/config.toml`
|
|
137
|
+
- Gemini CLI: `~/.gemini/settings.json`
|
|
138
|
+
|
|
139
|
+
Current hook commands point at CTM scripts under `claude-task-manager/bin`:
|
|
140
|
+
|
|
141
|
+
- `claude-hook.js`
|
|
142
|
+
- `codex-notify.js`
|
|
143
|
+
- `gemini-hook.js`
|
|
144
|
+
|
|
145
|
+
### Agent Presets
|
|
146
|
+
|
|
147
|
+
`claude-task-manager/lib/agent-presets.js` is the source of truth for each
|
|
148
|
+
agent's lifecycle events:
|
|
149
|
+
|
|
150
|
+
Claude Code:
|
|
151
|
+
|
|
152
|
+
- `SessionStart` -> `claude-hook start`
|
|
153
|
+
- `UserPromptSubmit` -> `claude-hook start`
|
|
154
|
+
- `Stop` -> `claude-hook stop`
|
|
155
|
+
- `Notification` -> `claude-hook idle`
|
|
156
|
+
- `PreToolUse` -> `claude-hook menu`
|
|
157
|
+
|
|
158
|
+
Codex:
|
|
159
|
+
|
|
160
|
+
- `notify` -> `codex-notify stop`
|
|
161
|
+
- OTLP env vars point logs at the CTM port.
|
|
162
|
+
|
|
163
|
+
Gemini CLI:
|
|
164
|
+
|
|
165
|
+
- `BeforeAgent` -> `gemini-hook start`
|
|
166
|
+
- `AfterAgent` -> `gemini-hook stop`
|
|
167
|
+
- `SessionEnd` -> `gemini-hook stop`
|
|
168
|
+
- `BeforeTool` -> `gemini-hook menu`
|
|
169
|
+
|
|
170
|
+
The same file also builds per-session environment variables, including
|
|
171
|
+
`CTM_SESSION_ID`, `CTM_PORT`, and, where supported, OTLP endpoint settings.
|
|
172
|
+
|
|
173
|
+
### Server Ingress
|
|
174
|
+
|
|
175
|
+
CTM only accepts hook/OTLP ingress from loopback. The local server handles:
|
|
176
|
+
|
|
177
|
+
- `/v1/logs` and `/api/otlp/v1/logs` -> `telemetryReceiver.handleLogs`
|
|
178
|
+
- `/hook/claude/{start|stop|idle|menu}` -> `telemetryReceiver.hookClaude`
|
|
179
|
+
- `/hook/codex/stop` -> `telemetryReceiver.hookCodexStop`
|
|
180
|
+
- `/hook/gemini/{start|stop|menu}` -> `telemetryReceiver.hookGemini`
|
|
181
|
+
|
|
182
|
+
The same receiver then broadcasts `session.status` over CTM's existing websocket
|
|
183
|
+
fan-out. This is important: hooks enter through a small local ingress, but they
|
|
184
|
+
reuse the normal session status contract instead of creating a parallel UI
|
|
185
|
+
state model.
|
|
186
|
+
|
|
187
|
+
Relevant code:
|
|
188
|
+
|
|
189
|
+
- `claude-task-manager/server.js`
|
|
190
|
+
- hook/OTLP ingress near the local-only hook server block
|
|
191
|
+
- `/api/otel/status`, `/api/otel/plan-install`, `/api/otel/install`,
|
|
192
|
+
`/api/otel/uninstall`
|
|
193
|
+
- session creation watchdog that prompts setup only when hooks are missing
|
|
194
|
+
and the spawn is not a resume
|
|
195
|
+
|
|
196
|
+
### Tests
|
|
197
|
+
|
|
198
|
+
Existing tests cover the safety properties that matter most:
|
|
199
|
+
|
|
200
|
+
- `claude-task-manager/tests/agent-hooks-installer.test.js`
|
|
201
|
+
- writes plausible Claude/Gemini settings
|
|
202
|
+
- writes Codex `[otel]` plus top-level `notify = [...]`
|
|
203
|
+
- install is idempotent
|
|
204
|
+
- uninstall preserves user-owned config
|
|
205
|
+
- legacy Codex `[notify]` section is repaired to the top-level array shape
|
|
206
|
+
|
|
207
|
+
- `claude-task-manager/tests/agent-presets.test.js`
|
|
208
|
+
- agent detection
|
|
209
|
+
- OTLP/env construction
|
|
210
|
+
- inherited session identity sanitation
|
|
211
|
+
|
|
212
|
+
## End-to-End Flow
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
User opens AI Providers -> Coding Agents
|
|
216
|
+
|
|
|
217
|
+
+-- UI GET /api/models/available-agents
|
|
218
|
+
| -> CTM discovers claude/codex/gemini binaries
|
|
219
|
+
|
|
|
220
|
+
+-- UI GET /api/otel/status
|
|
221
|
+
-> CTM checks whether the relevant config contains CTM's current hook marker
|
|
222
|
+
|
|
223
|
+
User clicks Enable live status in the consent modal
|
|
224
|
+
|
|
|
225
|
+
+-- UI POST /api/otel/install?agent=<id>
|
|
226
|
+
-> agent-hooks-installer reads user config
|
|
227
|
+
-> patches only CTM-owned entries
|
|
228
|
+
-> writes the agent config file
|
|
229
|
+
|
|
230
|
+
User launches an agent through CTM
|
|
231
|
+
|
|
|
232
|
+
+-- server builds env with CTM_SESSION_ID and CTM_PORT
|
|
233
|
+
+-- for OTLP-capable agents, server injects OTLP endpoint env
|
|
234
|
+
+-- agent runs normally in its terminal
|
|
235
|
+
|
|
236
|
+
Agent lifecycle event happens
|
|
237
|
+
|
|
|
238
|
+
+-- provider hook invokes CTM script
|
|
239
|
+
+-- script posts JSON to localhost CTM hook endpoint
|
|
240
|
+
+-- telemetry-receiver maps event to CTM session status
|
|
241
|
+
+-- websocket broadcasts session.status
|
|
242
|
+
+-- desktop/mobile UI updates lanes, badges, and attention state
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Architectural Benefits
|
|
246
|
+
|
|
247
|
+
### 1. Reliable Status Without Scraping Terminal Text
|
|
248
|
+
|
|
249
|
+
Terminal text is a weak status source. It changes with provider UI versions,
|
|
250
|
+
color themes, redraw timing, and terminal width. Hooks give CTM structured
|
|
251
|
+
signals at the lifecycle boundary: start, stop, idle, tool/menu, and agent
|
|
252
|
+
turn-complete.
|
|
253
|
+
|
|
254
|
+
CTM should still keep PTY and transcript fallbacks, but hooks reduce the amount
|
|
255
|
+
of brittle regex parsing needed for high-level state.
|
|
256
|
+
|
|
257
|
+
### 2. Provider-Neutral Session State
|
|
258
|
+
|
|
259
|
+
Claude, Codex, and Gemini expose different mechanics. CTM normalizes them into
|
|
260
|
+
one internal contract: `session.status`. This lets the web UI, mobile UI,
|
|
261
|
+
queue, notifications, and future Wall-E memory capture depend on one local CTM
|
|
262
|
+
event stream instead of three provider-specific contracts.
|
|
263
|
+
|
|
264
|
+
### 3. Low-Latency Mobile and Remote UX
|
|
265
|
+
|
|
266
|
+
The phone status page and desktop session list need to know when an agent is
|
|
267
|
+
actually running, waiting, or done. Hooks provide low-latency transitions that
|
|
268
|
+
do not require polling large transcripts or waiting for terminal text to settle.
|
|
269
|
+
|
|
270
|
+
This matters especially on mobile, where noisy lane movement and stale
|
|
271
|
+
`Running` badges are high-friction.
|
|
272
|
+
|
|
273
|
+
### 4. Correct Ownership Boundary
|
|
274
|
+
|
|
275
|
+
The provider still owns execution, tool calls, permissions, and terminal UI.
|
|
276
|
+
CTM only receives lifecycle facts and local telemetry. That keeps CTM from
|
|
277
|
+
pretending it is the agent runtime, while still giving CTM enough signals to be
|
|
278
|
+
a good control plane.
|
|
279
|
+
|
|
280
|
+
### 5. Future Memory Capture Boundary
|
|
281
|
+
|
|
282
|
+
Hooks are the natural point to trigger durable capture:
|
|
283
|
+
|
|
284
|
+
- `SessionStart`: link provider session ID to CTM session ID.
|
|
285
|
+
- `UserPromptSubmit` / `BeforeAgent`: mark a new work unit.
|
|
286
|
+
- `Stop` / `AfterAgent`: flush final transcript tail and summarize.
|
|
287
|
+
- `PreToolUse` / `BeforeTool`: detect approval/tool attention.
|
|
288
|
+
- Future compaction hooks: preserve memory before context disappears.
|
|
289
|
+
|
|
290
|
+
The existing `session-capture-foundation-design.md` already says hooks are
|
|
291
|
+
strong status signals but should not be the only source of truth. The better
|
|
292
|
+
architecture is "hooks as timing/evidence, transcripts as content, PTY as
|
|
293
|
+
fallback."
|
|
294
|
+
|
|
295
|
+
## Hooks-Optional Runtime Contract
|
|
296
|
+
|
|
297
|
+
Coding-agent hooks are not required for a CTM session to work. They improve the
|
|
298
|
+
status signal, but the baseline runtime path is still the PTY/session stream:
|
|
299
|
+
|
|
300
|
+
- CTM creates the PTY and renders terminal output regardless of hook status.
|
|
301
|
+
- `statusHooks` tracks meaningful PTY activity through the internal
|
|
302
|
+
`SessionStateBus`, even when no project or global `.ctm-hooks.json` command is
|
|
303
|
+
configured.
|
|
304
|
+
- `waiting-for-input` and `session-resumed` websocket messages continue to
|
|
305
|
+
project running/waiting state through `SessionCapture` without a prior
|
|
306
|
+
`session.status` hook frame.
|
|
307
|
+
- The missing-hook watchdog only emits `session.needsSetup` onboarding. It does
|
|
308
|
+
not fabricate runtime status and does not block the session.
|
|
309
|
+
|
|
310
|
+
The intended degradation is therefore:
|
|
311
|
+
|
|
312
|
+
```text
|
|
313
|
+
With hooks: provider hook/OTLP -> authoritative session.status -> UI
|
|
314
|
+
Without hooks: PTY/session stream -> state bus + terminal fallback -> UI
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
If either path disappears, that is a regression. Keep regression coverage for
|
|
318
|
+
both so hook improvements never turn into a hard runtime dependency.
|
|
319
|
+
|
|
320
|
+
## Consent and Safety Model
|
|
321
|
+
|
|
322
|
+
Installing hooks mutates persistent user-level files under the user's home
|
|
323
|
+
directory. That means the integration can affect future CLI sessions outside
|
|
324
|
+
the current CTM tab. It is useful, but it is also a trust boundary.
|
|
325
|
+
|
|
326
|
+
Therefore CTM should keep hook install user-approved. CTM can proactively
|
|
327
|
+
detect a missing integration and open the setup modal, but the persistent
|
|
328
|
+
config write still needs an explicit user action.
|
|
329
|
+
|
|
330
|
+
Required safety properties:
|
|
331
|
+
|
|
332
|
+
1. Preview before write for advanced users.
|
|
333
|
+
2. Idempotent install; no duplicate entries.
|
|
334
|
+
3. CTM-owned marker for uninstall/repair.
|
|
335
|
+
4. Preserve user-owned config and hooks.
|
|
336
|
+
5. Localhost-only ingress.
|
|
337
|
+
6. Clear "installed for this CTM port" semantics.
|
|
338
|
+
7. Visible uninstall/disable path.
|
|
339
|
+
8. No hook install during passive page load.
|
|
340
|
+
9. Do not expose raw config contents through preview APIs.
|
|
341
|
+
|
|
342
|
+
## Why CTM Should Not Auto-Install Hooks
|
|
343
|
+
|
|
344
|
+
There are three separate reasons.
|
|
345
|
+
|
|
346
|
+
First, it is a side effect outside the app workspace. The files are user-level
|
|
347
|
+
agent configs, not CTM-owned project files. Silent edits would violate the same
|
|
348
|
+
trust model that Claude/Codex/Gemini use for project trust and hook execution.
|
|
349
|
+
|
|
350
|
+
Second, hooks are executable persistence. A hook entry runs a command in future
|
|
351
|
+
agent sessions. CTM's entries are benign and local, but the class of action is
|
|
352
|
+
still security-sensitive. The UI should make the write explicit.
|
|
353
|
+
|
|
354
|
+
Third, the correct hook endpoint includes the CTM port. If a user runs multiple
|
|
355
|
+
CTM instances, auto-install on page load could race ports and rewrite a working
|
|
356
|
+
config for the wrong instance. User-initiated install gives the user control
|
|
357
|
+
over which CTM instance owns the integration.
|
|
358
|
+
|
|
359
|
+
## UX Recommendations
|
|
360
|
+
|
|
361
|
+
1. Use **Enable live status** for missing integrations and
|
|
362
|
+
**Refresh live status** for installed integrations.
|
|
363
|
+
- "Repair" implies breakage.
|
|
364
|
+
- Both actions use an idempotent reinstall for the current CTM port.
|
|
365
|
+
|
|
366
|
+
2. Keep the setup preview in a consent modal.
|
|
367
|
+
- Use existing `/api/otel/plan-install`.
|
|
368
|
+
- Show target file path and a sanitized CTM-owned change summary.
|
|
369
|
+
- Do not send or render raw current/next config text in the browser.
|
|
370
|
+
|
|
371
|
+
3. Add **Remove integration** when hooks are installed.
|
|
372
|
+
- Use existing `/api/otel/uninstall`.
|
|
373
|
+
- This makes the trust boundary reversible.
|
|
374
|
+
|
|
375
|
+
4. Explain the status in product terms:
|
|
376
|
+
- CLI: "Can CTM launch this runtime?"
|
|
377
|
+
- Hooks: "Can this runtime report live state back to CTM?"
|
|
378
|
+
- Provider link: "Which model provider powers this runtime?"
|
|
379
|
+
|
|
380
|
+
5. Keep provider config separate.
|
|
381
|
+
- Hooks do not configure API keys or default models.
|
|
382
|
+
- Provider cards configure model access.
|
|
383
|
+
- Coding Agent cards configure session runtime observability.
|
|
384
|
+
|
|
385
|
+
6. Prefer user-level config by default, but expose the target.
|
|
386
|
+
- The current code writes user-level config.
|
|
387
|
+
- If project-scoped hooks are added later, the UI must make scope explicit.
|
|
388
|
+
|
|
389
|
+
## Open Questions
|
|
390
|
+
|
|
391
|
+
1. Should CTM support project-scoped hook installs for teams that do not want
|
|
392
|
+
user-level global hooks?
|
|
393
|
+
2. Should "Ready" require both hooks and a successful live test event, or is
|
|
394
|
+
config presence enough?
|
|
395
|
+
3. Should Codex move from `notify`-only completion hooks to newer managed
|
|
396
|
+
lifecycle hook config if/when the CLI exposes a stable user-level contract?
|
|
397
|
+
4. Should Wall-E memory capture become a first-class hook subscriber, or should
|
|
398
|
+
it continue consuming normalized CTM session events?
|
|
399
|
+
|
|
400
|
+
## Proposed North Star
|
|
401
|
+
|
|
402
|
+
Hooks should be treated as a local, consented observability layer for coding
|
|
403
|
+
agents. The architecture should stay provider-neutral:
|
|
404
|
+
|
|
405
|
+
```text
|
|
406
|
+
Provider-specific hook/telemetry inputs
|
|
407
|
+
-> CTM local ingress
|
|
408
|
+
-> telemetry-receiver normalization
|
|
409
|
+
-> session.status + capture events
|
|
410
|
+
-> desktop/mobile UI, notifications, Wall-E memory, queues
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
This keeps the model clean:
|
|
414
|
+
|
|
415
|
+
- Coding agents own execution.
|
|
416
|
+
- AI Providers own model access.
|
|
417
|
+
- CTM owns orchestration, status, mobile/desktop control surfaces, and durable
|
|
418
|
+
session evidence.
|
|
@@ -52,6 +52,26 @@ This filter belongs at the parser and `/api/session/messages` boundaries. UI
|
|
|
52
52
|
surfaces can keep a defensive check for already-cached old rows, but desktop and
|
|
53
53
|
phone should both converge on the normalized API result.
|
|
54
54
|
|
|
55
|
+
## Codex User Echo Dedupe
|
|
56
|
+
|
|
57
|
+
Codex can record the same human prompt twice for one turn: once as a
|
|
58
|
+
`response_item` user message and again as an `event_msg.user_message`. CTM must
|
|
59
|
+
collapse that provider echo so Conversation, Review, search, and phone timelines
|
|
60
|
+
do not show duplicate user turns.
|
|
61
|
+
|
|
62
|
+
The dedupe key is **not** globally unique text. Long-lived Codex sessions often
|
|
63
|
+
repeat the same prompt days later, for example rerunning the same research skill
|
|
64
|
+
after follow-up design work. Those later prompts are distinct human turns and
|
|
65
|
+
must remain visible. The importer therefore dedupes only same-text user events
|
|
66
|
+
inside a short timestamp window. If the timestamp is missing, CTM falls back to
|
|
67
|
+
conservative same-text dedupe because it cannot prove the events are separate.
|
|
68
|
+
|
|
69
|
+
The Codex conversation importer records a parser version on
|
|
70
|
+
`session_conversations`. When this semantic contract changes, same-size Codex
|
|
71
|
+
caches with an older parser version must be eligible for full re-import; file
|
|
72
|
+
size alone is not enough to prove a cache is fresh. This avoids one-off DB edits
|
|
73
|
+
for historical sessions whose raw rollout still contains the correct prompt.
|
|
74
|
+
|
|
55
75
|
## Non-Starving Scheduling
|
|
56
76
|
|
|
57
77
|
Background DB work can defer briefly while the user is actively interacting
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Google Workspace Auth Health
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Google sign-in happens outside the CTM browser tab. After OAuth completes, the
|
|
6
|
+
setup page can still show an old "Google account needs reconnection" banner if
|
|
7
|
+
the page does not refresh its Wall-E credential state. The browser's Google
|
|
8
|
+
login state is not a valid source of truth for CTM; Wall-E must verify the
|
|
9
|
+
stored `gws` credentials and then update both setup UI and service alerts from
|
|
10
|
+
that verified state.
|
|
11
|
+
|
|
12
|
+
## Source Of Truth
|
|
13
|
+
|
|
14
|
+
`/api/wall-e/gws/accounts` is the authoritative health endpoint for connected
|
|
15
|
+
Google accounts. It derives each account state by asking the bundled
|
|
16
|
+
`gws-workspace` setup module for usable credentials:
|
|
17
|
+
|
|
18
|
+
- `tokenValid: true` means Wall-E has a usable access token for that account.
|
|
19
|
+
- `reauthRequired: true` means the saved refresh credential is missing, expired,
|
|
20
|
+
or revoked.
|
|
21
|
+
- `authIssue` is a user-facing explanation of the credential problem.
|
|
22
|
+
|
|
23
|
+
The setup page must render the reconnection banner only from this endpoint. It
|
|
24
|
+
must not infer success from a browser Google cookie or from returning to the CTM
|
|
25
|
+
tab after OAuth.
|
|
26
|
+
|
|
27
|
+
## Alert Reconciliation
|
|
28
|
+
|
|
29
|
+
Service alerts are persisted in Wall-E's `service_alerts` KV entry and surfaced
|
|
30
|
+
on the Wall-E panel and session pages. Google Workspace account alerts use this
|
|
31
|
+
stable service key:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
google_workspace:<profile-id-or-default>:<lowercase-email>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Whenever Wall-E proves an account is usable, it should clear only resolved
|
|
38
|
+
Google Workspace auth alerts for that same account. This mirrors the existing
|
|
39
|
+
Slack health model while keeping unrelated alerts, disabled-skill alerts, and
|
|
40
|
+
other providers intact.
|
|
41
|
+
|
|
42
|
+
Reconciliation happens at two boundaries:
|
|
43
|
+
|
|
44
|
+
1. OAuth completion: `completeGoogleAuthFlow()` only completes after
|
|
45
|
+
`gwsSetup.getCredentials()` returns a usable access token, then clears the
|
|
46
|
+
account's stale `gws_reauth` alert.
|
|
47
|
+
2. Health reads: `/api/wall-e/gws/accounts` opportunistically clears stale
|
|
48
|
+
auth alerts for every account it reports as usable, so any setup page refresh
|
|
49
|
+
self-heals old alert state.
|
|
50
|
+
|
|
51
|
+
## Browser Refresh Contract
|
|
52
|
+
|
|
53
|
+
Setup should refresh connected services when the user returns from an external
|
|
54
|
+
OAuth window:
|
|
55
|
+
|
|
56
|
+
- `pageshow`
|
|
57
|
+
- `focus`
|
|
58
|
+
- visible `visibilitychange`
|
|
59
|
+
- `online`
|
|
60
|
+
|
|
61
|
+
These events only trigger a small debounced `/api/wall-e/gws/accounts` refresh.
|
|
62
|
+
The page still uses explicit OAuth flow polling while CTM owns the flow, but it
|
|
63
|
+
does not rely on blind background polling to repair stale UI.
|
|
64
|
+
|
|
65
|
+
The endpoint and browser fetch should use no-store/no-cache semantics because
|
|
66
|
+
credential health is live operational state, not a static catalog.
|
|
67
|
+
|
|
68
|
+
## Tests
|
|
69
|
+
|
|
70
|
+
Coverage should prove:
|
|
71
|
+
|
|
72
|
+
- Google auth completion clears stale account-specific `gws_reauth` alerts only
|
|
73
|
+
after credentials are usable.
|
|
74
|
+
- Google alert clearing does not remove unrelated Google, Slack, or disabled
|
|
75
|
+
skill alerts.
|
|
76
|
+
- The setup page removes the reconnection banner when a foreground lifecycle
|
|
77
|
+
refresh sees the account become healthy.
|
|
@@ -12,6 +12,7 @@ CTM treats pasted screenshots as first-class attachments and shows compact promp
|
|
|
12
12
|
|
|
13
13
|
- Terminal sessions: paste events and the macOS `Ctrl+V` compatibility path upload images and insert the compact token, for example `[Image #1]`. The token is what the user sees and edits in both Claude and Codex sessions. `Cmd+Shift+V` on macOS and `Ctrl+Shift+V` elsewhere intentionally paste the raw local path reference. The terminal context menu can copy all pasted image paths or URLs for the active session.
|
|
14
14
|
- Terminal sessions backed by Claude Code or Codex use provider-native image handoff. CTM uploads and normalizes the browser clipboard image, then sends the normalized local image path as a bracketed paste to the PTY. The provider creates the real image attachment and renders its own compact `[Image #n]` chip, so the model receives image context while the terminal does not show raw paths.
|
|
15
|
+
- Terminal sessions backed by Claude Code or Codex also append durable image metadata when the prompt is submitted. CTM does not change the paste behavior: paste still inserts the compact token and keeps provider-native path handoff intact. At Enter/submit time, any unsent image attachments from the active input are appended once as `[Attached image: "..."]` or `[Attached images: "...", "..."]` before the newline reaches the PTY. This makes future Conversation/Review import able to resolve the image path even if the provider transcript only preserves terminal text.
|
|
15
16
|
- Terminal text paste also normalizes CTM image references. If the clipboard contains `[Image #1: "/path/to/file.png"]`, a raw local image path, or an `/api/images/file/...` URL, default paste deduplicates repeated references and hands each local image path to provider-native attachment paste when possible.
|
|
16
17
|
- Terminal image paste accepts browser clipboard files by `image/*` MIME type or by common image filename extension when the OS leaves the MIME type empty.
|
|
17
18
|
- Wall-E sessions: pasted images become structured message attachments. The composer inserts `[Image #n]`; sending preserves the compact token in the message text and sends image data separately.
|
|
@@ -20,3 +21,15 @@ CTM treats pasted screenshots as first-class attachments and shows compact promp
|
|
|
20
21
|
## Provider Contract
|
|
21
22
|
|
|
22
23
|
Compact tokens are UI references, not raw file paths. CTM keeps attachment metadata, normalized uploads, and copyable path/URL references beside the visible token. Provider adapters must not send only `[Image #n]` to a raw PTY. They should either send structured attachments, or, for Claude Code and Codex terminal sessions, trigger native image attachment by bracket-pasting the normalized local image path. Explicit path paste remains available for CLIs that require a visible local filesystem reference in the prompt text.
|
|
24
|
+
|
|
25
|
+
Submit-time metadata is a transcript durability layer, not a replacement for native provider image attachment. It must not run during paste, path-copy, or path-paste handling, and it must mark attachments as submitted or discarded so later prompts do not inherit stale image references.
|
|
26
|
+
|
|
27
|
+
## Performance Contract
|
|
28
|
+
|
|
29
|
+
Image storage must not do large synchronous work on CTM's primary Node.js event loop.
|
|
30
|
+
|
|
31
|
+
- Browser uploads may arrive as buffers, but hashing must process large buffers in bounded chunks and yield between chunks.
|
|
32
|
+
- Screenshot capture must store the captured file through a streaming file path, then rename or copy it into the content-addressed image store. Do not synchronously read the screenshot back into a full buffer after `screencapture` exits.
|
|
33
|
+
- The shared image-store helpers are the boundary for this behavior: `saveImage()` handles in-memory uploads, while `saveImageFromFile()` handles captured or already-on-disk images.
|
|
34
|
+
|
|
35
|
+
This keeps terminal typing, WebSocket output flushes, and screenshot preview rendering responsive while large Retina screenshots are being stored.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# CTM iPad Web Preview
|
|
2
|
+
|
|
3
|
+
Status: implemented for local and staging checks
|
|
4
|
+
Date: 2026-05-19
|
|
5
|
+
|
|
6
|
+
## Goal
|
|
7
|
+
|
|
8
|
+
Use `/ipad.html` to run the CTM mobile app inside an iPad-sized frame from any CTM server. This is a fast desktop-browser check for the iPad layout before testing on a physical iPad.
|
|
9
|
+
|
|
10
|
+
The preview is intentionally same-origin by default:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
http://localhost:3456/ipad.html
|
|
14
|
+
frames
|
|
15
|
+
http://localhost:3456/m/
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
When testing a staging/tunnel server, open that server's own preview page:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
https://<staging-host>/ipad.html
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
That keeps CTM cookies, device tokens, service worker scope, and API calls on the same origin as the mobile app.
|
|
25
|
+
|
|
26
|
+
## Run A Safe Local Staging Instance
|
|
27
|
+
|
|
28
|
+
Use `bin/dev.sh --refresh` with a separate port and data directory so iPad testing has copied CTM/Wall-E data without mutating the primary CTM state:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
WALLE_DEV_DIR=/tmp/walle-dev-4456 \
|
|
32
|
+
DEV_CTM_PORT=4456 \
|
|
33
|
+
DEV_WALLE_PORT=4457 \
|
|
34
|
+
bash bin/dev.sh --refresh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Open:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
http://localhost:4456/ipad.html
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The source field defaults to `/m/`. Keep it there for normal testing. If the preview loads but has no sessions, restart with `--refresh`; that copies the current CTM and Wall-E databases into the staging data directory.
|
|
44
|
+
|
|
45
|
+
## Preview Modes
|
|
46
|
+
|
|
47
|
+
`/ipad.html` includes four device presets:
|
|
48
|
+
|
|
49
|
+
- `Test Portrait`: `768 x 1024`, matching the automated tablet regression test.
|
|
50
|
+
- `Test Landscape`: `1024 x 768`, matching the automated split-workspace regression test.
|
|
51
|
+
- `11 Portrait`: `834 x 1194`, close to an 11-inch iPad CSS viewport.
|
|
52
|
+
- `11 Landscape`: `1194 x 834`, close to an 11-inch iPad landscape viewport.
|
|
53
|
+
|
|
54
|
+
Use `Reload` to reload only the framed mobile app. Use `Open` to launch the framed URL directly.
|
|
55
|
+
|
|
56
|
+
## What This Catches
|
|
57
|
+
|
|
58
|
+
- Tablet breakpoint regressions.
|
|
59
|
+
- Horizontal overflow.
|
|
60
|
+
- Portrait single-column sizing.
|
|
61
|
+
- Landscape list/detail split layout.
|
|
62
|
+
- Detail pane modal-vs-region behavior.
|
|
63
|
+
- Composer and bottom navigation placement.
|
|
64
|
+
- Search and session-card density at iPad widths.
|
|
65
|
+
|
|
66
|
+
## What Still Requires A Real iPad
|
|
67
|
+
|
|
68
|
+
The preview does not replace Safari-on-iPad validation. Always do one physical-device pass before shipping high-risk mobile changes because desktop browser framing does not fully emulate:
|
|
69
|
+
|
|
70
|
+
- iPad Safari viewport height changes when the software keyboard opens.
|
|
71
|
+
- PWA standalone mode.
|
|
72
|
+
- touch momentum scrolling and rubber-band edges.
|
|
73
|
+
- safe-area inset differences.
|
|
74
|
+
- iOS third-party cookie and passkey behavior.
|
|
75
|
+
- real camera/file-picker attachment flows.
|
|
76
|
+
|
|
77
|
+
## Automated Companion Test
|
|
78
|
+
|
|
79
|
+
The existing mobile render suite covers the same core tablet breakpoints:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npm --prefix claude-task-manager exec playwright test -- \
|
|
83
|
+
--config tests/rendering/playwright.config.js \
|
|
84
|
+
scenarios/mobile-pwa.spec.js \
|
|
85
|
+
-g "iPad|tablet|iPad preview"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use the automated test for regression gates and `/ipad.html` for quick visual inspection.
|