@wjarka/cezarion 0.15.1 → 0.16.0
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 +167 -46
- package/dist/agent-config/catalog.d.ts +6 -2
- package/dist/agent-config/catalog.js +78 -3
- package/dist/agent-config/catalog.js.map +1 -1
- package/dist/agent-config/model-settings/shared.js +6 -3
- package/dist/agent-config/model-settings/shared.js.map +1 -1
- package/dist/agent-config/models.js +4 -0
- package/dist/agent-config/models.js.map +1 -1
- package/dist/agent-config/validate.js +6 -0
- package/dist/agent-config/validate.js.map +1 -1
- package/dist/artifacts/cli.js +10 -2
- package/dist/artifacts/cli.js.map +1 -1
- package/dist/automations/coordinator.d.ts +7 -0
- package/dist/automations/coordinator.js +22 -2
- package/dist/automations/coordinator.js.map +1 -1
- package/dist/automations/github-poller.d.ts +4 -4
- package/dist/automations/github-poller.js.map +1 -1
- package/dist/automations/schedule-runner.d.ts +130 -0
- package/dist/automations/schedule-runner.js +326 -0
- package/dist/automations/schedule-runner.js.map +1 -0
- package/dist/automations/scheduler.d.ts +38 -7
- package/dist/automations/scheduler.js +90 -22
- package/dist/automations/scheduler.js.map +1 -1
- package/dist/automations/store.d.ts +80 -3
- package/dist/automations/store.js +208 -16
- package/dist/automations/store.js.map +1 -1
- package/dist/automations/task-template.d.ts +42 -6
- package/dist/automations/task-template.js +152 -24
- package/dist/automations/task-template.js.map +1 -1
- package/dist/automations/types.d.ts +142 -6
- package/dist/automations/types.js +64 -6
- package/dist/automations/types.js.map +1 -1
- package/dist/autosave-holders.js +8 -12
- package/dist/autosave-holders.js.map +1 -1
- package/dist/ci-wait/client.d.ts +8 -1
- package/dist/ci-wait/client.js +43 -1
- package/dist/ci-wait/client.js.map +1 -1
- package/dist/ci-wait/controller.d.ts +83 -4
- package/dist/ci-wait/controller.js +76 -11
- package/dist/ci-wait/controller.js.map +1 -1
- package/dist/ci-wait/errors.d.ts +7 -1
- package/dist/ci-wait/errors.js +36 -0
- package/dist/ci-wait/errors.js.map +1 -1
- package/dist/ci-wait/github.d.ts +2 -0
- package/dist/ci-wait/github.js +3 -1
- package/dist/ci-wait/github.js.map +1 -1
- package/dist/ci-wait/mcp.d.ts +2 -98
- package/dist/ci-wait/mcp.js +11 -25
- package/dist/ci-wait/mcp.js.map +1 -1
- package/dist/ci-wait/supervisor.d.ts +2 -1
- package/dist/ci-wait/supervisor.js +2 -1
- package/dist/ci-wait/supervisor.js.map +1 -1
- package/dist/ci-wait/tools.d.ts +307 -0
- package/dist/ci-wait/tools.js +63 -0
- package/dist/ci-wait/tools.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/contract/agent-config.d.ts +5 -0
- package/dist/contract/agent-profiles.d.ts +15 -0
- package/dist/contract/automation-schedule.d.ts +60 -0
- package/dist/contract/automations.d.ts +208 -36
- package/dist/contract/delegation.d.ts +96 -0
- package/dist/contract/discovery.d.ts +7 -0
- package/dist/contract/github.d.ts +1 -0
- package/dist/contract/health.d.ts +6 -0
- package/dist/contract/index.d.ts +3 -0
- package/dist/contract/index.js +1445 -745
- package/dist/contract/preview.d.ts +508 -0
- package/dist/contract/runs.d.ts +716 -15
- package/dist/contract/skills.d.ts +39 -0
- package/dist/contract/workflows.d.ts +6 -0
- package/dist/contract/workspace.d.ts +65 -0
- package/dist/contract/zoned-time.d.ts +35 -0
- package/dist/core/agent-env.d.ts +11 -0
- package/dist/core/agent-env.js +27 -5
- package/dist/core/agent-env.js.map +1 -1
- package/dist/core/agent-profiles.js +7 -0
- package/dist/core/agent-profiles.js.map +1 -1
- package/dist/core/agent-runner.d.ts +49 -1
- package/dist/core/agent-runner.js +2 -1
- package/dist/core/agent-runner.js.map +1 -1
- package/dist/core/backend-detect.d.ts +3 -2
- package/dist/core/backend-detect.js +27 -1
- package/dist/core/backend-detect.js.map +1 -1
- package/dist/core/claude-cli-runner.d.ts +1 -0
- package/dist/core/claude-cli-runner.js +69 -19
- package/dist/core/claude-cli-runner.js.map +1 -1
- package/dist/core/codex-app-server-runner.d.ts +1 -0
- package/dist/core/codex-app-server-runner.js +200 -25
- package/dist/core/codex-app-server-runner.js.map +1 -1
- package/dist/core/codex-app-server-transport.d.ts +7 -3
- package/dist/core/codex-app-server-transport.js +11 -9
- package/dist/core/codex-app-server-transport.js.map +1 -1
- package/dist/core/cursor-acp-runner.d.ts +1 -0
- package/dist/core/cursor-acp-runner.js +24 -9
- package/dist/core/cursor-acp-runner.js.map +1 -1
- package/dist/core/host-model-catalog.js +2 -0
- package/dist/core/host-model-catalog.js.map +1 -1
- package/dist/core/managed-session.js +2 -0
- package/dist/core/managed-session.js.map +1 -1
- package/dist/core/model-identity.js +2 -0
- package/dist/core/model-identity.js.map +1 -1
- package/dist/core/model-presets.js +3 -0
- package/dist/core/model-presets.js.map +1 -1
- package/dist/core/omp-model-catalog.d.ts +43 -0
- package/dist/core/omp-model-catalog.js +205 -0
- package/dist/core/omp-model-catalog.js.map +1 -0
- package/dist/core/omp-runner.d.ts +73 -0
- package/dist/core/omp-runner.js +990 -0
- package/dist/core/omp-runner.js.map +1 -0
- package/dist/core/omp-ui-mapper.d.ts +106 -0
- package/dist/core/omp-ui-mapper.js +882 -0
- package/dist/core/omp-ui-mapper.js.map +1 -0
- package/dist/core/opencode-server-runner.d.ts +18 -4
- package/dist/core/opencode-server-runner.js +337 -96
- package/dist/core/opencode-server-runner.js.map +1 -1
- package/dist/core/opencode-session-error.d.ts +11 -0
- package/dist/core/opencode-session-error.js +26 -0
- package/dist/core/opencode-session-error.js.map +1 -0
- package/dist/core/opencode-ui-mapper.js +4 -36
- package/dist/core/opencode-ui-mapper.js.map +1 -1
- package/dist/core/pi-runner.d.ts +1 -0
- package/dist/core/pi-runner.js +75 -12
- package/dist/core/pi-runner.js.map +1 -1
- package/dist/core/provider-auth.d.ts +9 -2
- package/dist/core/provider-auth.js +43 -6
- package/dist/core/provider-auth.js.map +1 -1
- package/dist/core/runner-factory.js +3 -0
- package/dist/core/runner-factory.js.map +1 -1
- package/dist/core/runner-model-catalog.js +1 -0
- package/dist/core/runner-model-catalog.js.map +1 -1
- package/dist/core/runner-stderr.d.ts +2 -0
- package/dist/core/runner-stderr.js +20 -0
- package/dist/core/runner-stderr.js.map +1 -0
- package/dist/core/session-process.d.ts +22 -0
- package/dist/core/session-process.js +202 -0
- package/dist/core/session-process.js.map +1 -0
- package/dist/core/ui-events.d.ts +1 -1
- package/dist/core/usage-limit.js +3 -60
- package/dist/core/usage-limit.js.map +1 -1
- package/dist/data-gitignore.d.ts +6 -0
- package/dist/data-gitignore.js +57 -0
- package/dist/data-gitignore.js.map +1 -0
- package/dist/delegation/capacity.d.ts +19 -0
- package/dist/delegation/capacity.js +34 -0
- package/dist/delegation/capacity.js.map +1 -0
- package/dist/delegation/cli.js +13 -4
- package/dist/delegation/cli.js.map +1 -1
- package/dist/delegation/conversations.d.ts +4 -2
- package/dist/delegation/conversations.js +8 -12
- package/dist/delegation/conversations.js.map +1 -1
- package/dist/delegation/credentials.d.ts +2 -0
- package/dist/delegation/credentials.js +10 -0
- package/dist/delegation/credentials.js.map +1 -1
- package/dist/delegation/destroy-observation.d.ts +42 -0
- package/dist/delegation/destroy-observation.js +115 -0
- package/dist/delegation/destroy-observation.js.map +1 -0
- package/dist/delegation/execution-identity.d.ts +6 -0
- package/dist/delegation/execution-identity.js +1 -1
- package/dist/delegation/execution-identity.js.map +1 -1
- package/dist/delegation/policy.d.ts +3 -2
- package/dist/delegation/policy.js +7 -5
- package/dist/delegation/policy.js.map +1 -1
- package/dist/delegation/process-liveness.d.ts +57 -20
- package/dist/delegation/process-liveness.js +114 -92
- package/dist/delegation/process-liveness.js.map +1 -1
- package/dist/delegation/provision.js +6 -6
- package/dist/delegation/provision.js.map +1 -1
- package/dist/delegation/results.js +4 -2
- package/dist/delegation/results.js.map +1 -1
- package/dist/delegation/retry-backoff.d.ts +23 -0
- package/dist/delegation/retry-backoff.js +18 -0
- package/dist/delegation/retry-backoff.js.map +1 -0
- package/dist/delegation/routes.d.ts +64 -58
- package/dist/delegation/scratch-cleanup.d.ts +29 -0
- package/dist/delegation/scratch-cleanup.js +143 -0
- package/dist/delegation/scratch-cleanup.js.map +1 -0
- package/dist/delegation/service.d.ts +20 -1
- package/dist/delegation/service.js +233 -70
- package/dist/delegation/service.js.map +1 -1
- package/dist/delegation/transport.d.ts +12 -6
- package/dist/delegation/workspace.d.ts +23 -4
- package/dist/delegation/workspace.js +147 -31
- package/dist/delegation/workspace.js.map +1 -1
- package/dist/git-worktree-lock-helper.js +8 -3
- package/dist/git-worktree-lock-helper.js.map +1 -1
- package/dist/git-worktree-lock.d.ts +6 -1
- package/dist/git-worktree-lock.js +10 -4
- package/dist/git-worktree-lock.js.map +1 -1
- package/dist/git-worktree-release.d.ts +20 -0
- package/dist/git-worktree-release.js +27 -0
- package/dist/git-worktree-release.js.map +1 -0
- package/dist/git-worktree.d.ts +8 -2
- package/dist/git-worktree.js +19 -2
- package/dist/git-worktree.js.map +1 -1
- package/dist/handoff.d.ts +2 -2
- package/dist/handoff.js +1 -1
- package/dist/index.js +109 -76
- package/dist/index.js.map +1 -1
- package/dist/paths.d.ts +1 -1
- package/dist/paths.js +5 -1
- package/dist/paths.js.map +1 -1
- package/dist/preview/cdp.d.ts +13 -0
- package/dist/preview/cdp.js +69 -0
- package/dist/preview/cdp.js.map +1 -0
- package/dist/preview/chromium.d.ts +75 -0
- package/dist/preview/chromium.js +394 -0
- package/dist/preview/chromium.js.map +1 -0
- package/dist/preview/dev-server.d.ts +68 -0
- package/dist/preview/dev-server.js +341 -0
- package/dist/preview/dev-server.js.map +1 -0
- package/dist/preview/host.d.ts +154 -0
- package/dist/preview/host.js +681 -0
- package/dist/preview/host.js.map +1 -0
- package/dist/preview/registration.d.ts +63 -0
- package/dist/preview/registration.js +109 -0
- package/dist/preview/registration.js.map +1 -0
- package/dist/preview/session.d.ts +73 -0
- package/dist/preview/session.js +347 -0
- package/dist/preview/session.js.map +1 -0
- package/dist/preview/url.d.ts +6 -0
- package/dist/preview/url.js +17 -0
- package/dist/preview/url.js.map +1 -0
- package/dist/runs/agent-tmpdir-removal.d.ts +15 -0
- package/dist/runs/agent-tmpdir-removal.js +60 -0
- package/dist/runs/agent-tmpdir-removal.js.map +1 -0
- package/dist/runs/agent-tmpdir.d.ts +12 -1
- package/dist/runs/agent-tmpdir.js +123 -34
- package/dist/runs/agent-tmpdir.js.map +1 -1
- package/dist/runs/delegation-state.d.ts +5 -1
- package/dist/runs/delegation-state.js +9 -0
- package/dist/runs/delegation-state.js.map +1 -1
- package/dist/runs/event-history.d.ts +4 -4
- package/dist/runs/event-history.js +97 -117
- package/dist/runs/event-history.js.map +1 -1
- package/dist/runs/history-compressor.d.ts +29 -0
- package/dist/runs/history-compressor.js +116 -0
- package/dist/runs/history-compressor.js.map +1 -0
- package/dist/runs/history-file.d.ts +36 -0
- package/dist/runs/history-file.js +463 -0
- package/dist/runs/history-file.js.map +1 -0
- package/dist/runs/human-ask-summary.js +18 -13
- package/dist/runs/human-ask-summary.js.map +1 -1
- package/dist/runs/legacy-index.d.ts +62 -0
- package/dist/runs/legacy-index.js +168 -0
- package/dist/runs/legacy-index.js.map +1 -0
- package/dist/runs/raw-record.d.ts +52 -0
- package/dist/runs/raw-record.js +145 -0
- package/dist/runs/raw-record.js.map +1 -0
- package/dist/runs/retention.d.ts +13 -6
- package/dist/runs/retention.js +42 -13
- package/dist/runs/retention.js.map +1 -1
- package/dist/runs/run-claims.d.ts +23 -0
- package/dist/runs/run-claims.js +24 -0
- package/dist/runs/run-claims.js.map +1 -0
- package/dist/runs/run-database.d.ts +385 -0
- package/dist/runs/run-database.js +930 -0
- package/dist/runs/run-database.js.map +1 -0
- package/dist/runs/run-index.d.ts +35 -9
- package/dist/runs/run-index.js +200 -25
- package/dist/runs/run-index.js.map +1 -1
- package/dist/runs/run-row.d.ts +44 -0
- package/dist/runs/run-row.js +84 -0
- package/dist/runs/run-row.js.map +1 -0
- package/dist/runs/run-search.d.ts +29 -0
- package/dist/runs/run-search.js +63 -0
- package/dist/runs/run-search.js.map +1 -0
- package/dist/runs/store-open-error.d.ts +24 -0
- package/dist/runs/store-open-error.js +61 -0
- package/dist/runs/store-open-error.js.map +1 -0
- package/dist/runs/store.d.ts +667 -32
- package/dist/runs/store.js +2153 -324
- package/dist/runs/store.js.map +1 -1
- package/dist/runs/transcript-facts.d.ts +77 -0
- package/dist/runs/transcript-facts.js +302 -0
- package/dist/runs/transcript-facts.js.map +1 -0
- package/dist/runs/webhook.js +5 -4
- package/dist/runs/webhook.js.map +1 -1
- package/dist/runs/worker-execution.d.ts +22 -0
- package/dist/runs/worker-execution.js +30 -0
- package/dist/runs/worker-execution.js.map +1 -0
- package/dist/server/capabilities.d.ts +1 -0
- package/dist/server/capabilities.js +2 -0
- package/dist/server/capabilities.js.map +1 -1
- package/dist/server/cockpit-ownership.d.ts +8 -0
- package/dist/server/cockpit-ownership.js +19 -0
- package/dist/server/cockpit-ownership.js.map +1 -1
- package/dist/server/forge/github.d.ts +1 -4
- package/dist/server/forge/github.js +47 -23
- package/dist/server/forge/github.js.map +1 -1
- package/dist/server/git.js +1 -1
- package/dist/server/git.js.map +1 -1
- package/dist/server/open-in-app.js +1 -0
- package/dist/server/open-in-app.js.map +1 -1
- package/dist/server/preview-socket.d.ts +36 -0
- package/dist/server/preview-socket.js +126 -0
- package/dist/server/preview-socket.js.map +1 -0
- package/dist/server/project-context.d.ts +31 -4
- package/dist/server/project-context.js +73 -9
- package/dist/server/project-context.js.map +1 -1
- package/dist/server/provider-action-gate.js +1 -0
- package/dist/server/provider-action-gate.js.map +1 -1
- package/dist/server/repo-branches.d.ts +4 -3
- package/dist/server/repo-branches.js +5 -4
- package/dist/server/repo-branches.js.map +1 -1
- package/dist/server/server.d.ts +4500 -2727
- package/dist/server/server.js +651 -202
- package/dist/server/server.js.map +1 -1
- package/dist/server/upgrade-router.d.ts +23 -0
- package/dist/server/upgrade-router.js +53 -0
- package/dist/server/upgrade-router.js.map +1 -0
- package/dist/server/validators.d.ts +6 -1
- package/dist/server/validators.js +4 -4
- package/dist/server/validators.js.map +1 -1
- package/dist/server/ws.d.ts +16 -16
- package/dist/server/ws.js +56 -54
- package/dist/server/ws.js.map +1 -1
- package/dist/skills-remote.d.ts +14 -0
- package/dist/skills-remote.js +91 -15
- package/dist/skills-remote.js.map +1 -1
- package/dist/task-cli/cli.js +40 -16
- package/dist/task-cli/cli.js.map +1 -1
- package/dist/task-cli/discovery.d.ts +4 -3
- package/dist/task-cli/discovery.js +4 -3
- package/dist/task-cli/discovery.js.map +1 -1
- package/dist/task-cli/http.d.ts +2 -0
- package/dist/task-cli/http.js +10 -4
- package/dist/task-cli/http.js.map +1 -1
- package/dist/task-cli/projections.d.ts +5 -2
- package/dist/task-cli/projections.js +13 -0
- package/dist/task-cli/projections.js.map +1 -1
- package/dist/task-cli/watch.d.ts +15 -2
- package/dist/task-cli/watch.js +31 -9
- package/dist/task-cli/watch.js.map +1 -1
- package/dist/ui-state.d.ts +4 -3
- package/dist/ui-state.js +8 -3
- package/dist/ui-state.js.map +1 -1
- package/dist/workflows/grouped-command.d.ts +31 -0
- package/dist/workflows/grouped-command.js +143 -0
- package/dist/workflows/grouped-command.js.map +1 -0
- package/dist/workflows/run.d.ts +223 -42
- package/dist/workflows/run.js +1316 -398
- package/dist/workflows/run.js.map +1 -1
- package/dist/workflows/types.d.ts +12 -0
- package/dist/workflows/types.js +20 -0
- package/dist/workflows/types.js.map +1 -1
- package/dist/workspace/agent-accounts.d.ts +5 -1
- package/dist/workspace/agent-accounts.js +1 -0
- package/dist/workspace/agent-accounts.js.map +1 -1
- package/dist/workspace/agent-profiles.js +1 -1
- package/dist/workspace/agent-profiles.js.map +1 -1
- package/dist/workspace/config.d.ts +3 -1
- package/dist/workspace/config.js +1 -0
- package/dist/workspace/config.js.map +1 -1
- package/dist/worktree-setup.d.ts +85 -0
- package/dist/worktree-setup.js +164 -0
- package/dist/worktree-setup.js.map +1 -0
- package/package.json +7 -5
- package/scripts/benchmark-run-store-fixture.ts +428 -0
- package/scripts/benchmark-run-store.ts +743 -0
- package/scripts/benchmark-stuck-destroys.ts +143 -0
- package/scripts/mock-autonomous.mjs +11 -0
- package/scripts/mock-ci-tool.mjs +20 -5
- package/scripts/mock-claude.mjs +110 -1
- package/scripts/mock-codex-app-server.mjs +117 -2
- package/scripts/mock-codex-coalesce-steer.mjs +59 -0
- package/scripts/mock-codex-reverse-steer.mjs +130 -0
- package/scripts/mock-cursor-acp.mjs +75 -1
- package/scripts/mock-omp-rpc.mjs +605 -0
- package/scripts/mock-opencode-serve.mjs +312 -22
- package/scripts/mock-pi-rpc.mjs +109 -3
- package/scripts/mock-runner-crash.mjs +42 -0
- package/scripts/mock-silent-tail.mjs +78 -0
- package/scripts/mock-turn-messages.mjs +5 -0
- package/scripts/omp-ci-wait.mjs +29 -0
- package/scripts/omp-restrict-delegation.yml +4 -0
- package/scripts/pi-ci-wait.mjs +12 -9
- package/scripts/seed-archive-profile.ts +3 -3
- package/web/dist/assets/agent-accounts-CFOBMVHc.js +1 -0
- package/web/dist/assets/alert-dialog-BrpNUwMt.js +1 -0
- package/web/dist/assets/app-window-CSHwDX9N.js +1 -0
- package/web/dist/assets/button-C_rd7CPp.js +43 -0
- package/web/dist/assets/compare-variants-D6WXhvXA.js +1 -0
- package/web/dist/assets/diff-DrEARXTV.js +3 -0
- package/web/dist/assets/diff-controls-B1-j7nFg.js +1 -0
- package/web/dist/assets/{diff-view-DPn6bQ5W.js → diff-view-DvGLjdTk.js} +3 -3
- package/web/dist/assets/dropdown-menu-BegOZFrj.js +1 -0
- package/web/dist/assets/format-DpNe3S0A.js +1 -0
- package/web/dist/assets/git-toolbar-Cw4ljmhB.js +1 -0
- package/web/dist/assets/github-CfV5sqL0.js +1 -0
- package/web/dist/assets/{image-preview-DJ8cgb1Z.js → image-preview-FOEfqpZP.js} +1 -1
- package/web/dist/assets/index-DgWWlOLy.js +13 -0
- package/web/dist/assets/index-fBFnuvxu.css +1 -0
- package/web/dist/assets/{nav-row-styles-3j64kH5s.js → nav-row-styles-vp2JbhuJ.js} +1 -1
- package/web/dist/assets/play-CmVAj_fu.js +1 -0
- package/web/dist/assets/popover-BohP6WTx.js +1 -0
- package/web/dist/assets/preview-pane-connected-qTA5KNoJ.js +3 -0
- package/web/dist/assets/preview-state-vuMviq6q.js +1 -0
- package/web/dist/assets/prompt-templates-Cubdut_C.js +15 -0
- package/web/dist/assets/repo-git-Cf4t5PD0.js +1 -0
- package/web/dist/assets/{run-diff-5-RRdcVz.js → run-diff-BpkUW37Z.js} +3 -3
- package/web/dist/assets/run-header-68WHf9wV.js +1 -0
- package/web/dist/assets/skills-DiVIgKeU.js +1 -0
- package/web/dist/assets/square-terminal-B6RYYieR.js +1 -0
- package/web/dist/assets/status-dot-CqTJHSP9.js +1 -0
- package/web/dist/assets/{tab-link-K0hjzEXR.js → tab-link-B07Hu4QX.js} +1 -1
- package/web/dist/assets/task-changes--lQF6EYf.js +1 -0
- package/web/dist/assets/task-commits-Cx0qy4DN.js +1 -0
- package/web/dist/assets/task-files-D50s-gKW.js +2 -0
- package/web/dist/assets/task-github-item-DaqmSwYT.js +1 -0
- package/web/dist/assets/task-thread-BPQ64lui.js +7 -0
- package/web/dist/assets/{task-thread-Bw_nQuTx.css → task-thread-zNE2Q9E-.css} +1 -1
- package/web/dist/assets/textarea-D20O4Pw0.js +1 -0
- package/web/dist/assets/thread-state-DWcFMrvb.js +4 -0
- package/web/dist/assets/use-hand-to-agent-state-BLIGmwbd.css +1 -0
- package/web/dist/assets/use-hand-to-agent-state-Cy9eyyfL.js +1 -0
- package/web/dist/assets/{utils-fzNfbPzA.js → utils-JsL3ZsJf.js} +1 -1
- package/web/dist/assets/workflows-jwG7uxqi.js +11 -0
- package/web/dist/assets/{zoomable-image-CDmZ_Rtl.js → zoomable-image-BJJ64KGc.js} +1 -1
- package/web/dist/cezarion-lockup-dark.svg +1 -13
- package/web/dist/cezarion-lockup-light.svg +1 -13
- package/web/dist/cezarion-mark-dark.svg +1 -12
- package/web/dist/cezarion-mark-light.svg +1 -12
- package/web/dist/index.html +16 -21
- package/web/dist/assets/agent-accounts-CU2ZDv24.js +0 -1
- package/web/dist/assets/alert-dialog-C-xYE_dg.js +0 -43
- package/web/dist/assets/chevron-right-BENZ-1ZN.js +0 -1
- package/web/dist/assets/collapsible-DD9J91Iv.js +0 -1
- package/web/dist/assets/compare-variants-5FmqpFSN.js +0 -1
- package/web/dist/assets/diff-controls-Bj0YrioE.js +0 -1
- package/web/dist/assets/diff-rE8rm75J2.js +0 -3
- package/web/dist/assets/diff-stat-BKDCSVfJ.js +0 -1
- package/web/dist/assets/dropdown-menu-Ch5BYQh_.js +0 -1
- package/web/dist/assets/format-dBiNDNVe.js +0 -1
- package/web/dist/assets/git-toolbar-ClVvf5iF.js +0 -1
- package/web/dist/assets/github-BkNOyour.css +0 -1
- package/web/dist/assets/github-DeZMeMwJ.js +0 -1
- package/web/dist/assets/github-item-detail-W5F6GVjF.js +0 -1
- package/web/dist/assets/github-sidebar-model-DcMu-IK2.js +0 -1
- package/web/dist/assets/highlighter-CdHqIwFr.js +0 -3
- package/web/dist/assets/index-CatemBEL.js +0 -8
- package/web/dist/assets/index-MvfD8bZJ.css +0 -1
- package/web/dist/assets/markdown-zdKeLIYA.js +0 -2
- package/web/dist/assets/mobile-run-bar-BCfmFi8V.js +0 -1
- package/web/dist/assets/prompt-templates-CBPp39IU.js +0 -15
- package/web/dist/assets/reference-chip-D6owncJT.js +0 -1
- package/web/dist/assets/repo-git-CtdkZFey.js +0 -1
- package/web/dist/assets/run-header-BcjoDi0W.js +0 -1
- package/web/dist/assets/sheet-ChnYVrp1.js +0 -1
- package/web/dist/assets/skills-C8YKp2vr.js +0 -1
- package/web/dist/assets/task-changes-BW8YdWG8.js +0 -1
- package/web/dist/assets/task-commits-q2kB2y6L.js +0 -1
- package/web/dist/assets/task-files-pPL6_3Cr.js +0 -2
- package/web/dist/assets/task-github-item-BXF5R52U.js +0 -1
- package/web/dist/assets/task-thread-DtkFL3EC.js +0 -10
- package/web/dist/assets/textarea-DxlkE-Yd.js +0 -1
- package/web/dist/assets/token-metrics-DIAjrPlM.js +0 -1
- package/web/dist/assets/use-desktop-CrDny2uG.js +0 -1
- package/web/dist/assets/use-submit-shortcut-KWJsC906.js +0 -1
- package/web/dist/assets/workflows-TmcPEj2K.js +0 -11
- /package/web/dist/assets/{lib-BQXq3kEf2.js → lib-BQXq3kEf.js} +0 -0
|
@@ -14,6 +14,13 @@ function watchdogStall(prompt) {
|
|
|
14
14
|
if (prompt.includes('held-pipe')) {
|
|
15
15
|
watchdogSpawn(process.execPath, ['-e', 'setTimeout(() => {}, 5000)'], { stdio: ['ignore', process.stdout, process.stderr] });
|
|
16
16
|
}
|
|
17
|
+
if (prompt.includes('leftover')) {
|
|
18
|
+
// hearsay-tools/cezarion#890: one child stays in the session's process group and ignores
|
|
19
|
+
// SIGTERM; one leaves the group with setsid. Both exit on their own as a cleanup backstop.
|
|
20
|
+
const leftover = (file) => `process.on('SIGTERM',()=>{}); require('fs').writeFileSync(${JSON.stringify(file)}, String(process.pid)); setTimeout(()=>{},20000)`;
|
|
21
|
+
watchdogSpawn(process.execPath, ['-e', leftover('leftover-group.pid')], { stdio: 'ignore' });
|
|
22
|
+
watchdogSpawn(process.execPath, ['-e', leftover('leftover-session.pid')], { stdio: 'ignore', detached: true }).unref();
|
|
23
|
+
}
|
|
17
24
|
return true;
|
|
18
25
|
}
|
|
19
26
|
|
|
@@ -24,8 +31,30 @@ function watchdogStall(prompt) {
|
|
|
24
31
|
// response resolves immediately — every part and the closing `session.idle`
|
|
25
32
|
// arrive over SSE afterwards, so a correct stream (v1 and v2 alike) must
|
|
26
33
|
// take its turn-end from `session.idle`, never from the HTTP response.
|
|
27
|
-
import {
|
|
34
|
+
import { createHash } from 'node:crypto';
|
|
35
|
+
// Aliased: owned-input-delivery.testkit.ts prepends its own `existsSync`/`writeFileSync` import,
|
|
36
|
+
// and a second import of the same name is a SyntaxError.
|
|
37
|
+
import { appendFileSync, existsSync as sessionStoreExists, mkdirSync, readFileSync, writeFileSync as sessionStoreWrite } from 'node:fs';
|
|
28
38
|
import { createServer } from 'node:http';
|
|
39
|
+
import { tmpdir } from 'node:os';
|
|
40
|
+
import { dirname, join } from 'node:path';
|
|
41
|
+
|
|
42
|
+
// #872: the first N starts die before listening, the way opencode 1.18.33 did
|
|
43
|
+
// when started within ~2 s of SIGTERM to the previous server on the same DB.
|
|
44
|
+
// Starts are counted across processes in a file, so start N+1 listens normally.
|
|
45
|
+
const failStarts = Number(process.env.CEZ_MOCK_OPENCODE_SERVE_FAIL_STARTS ?? 0);
|
|
46
|
+
if (failStarts > 0) {
|
|
47
|
+
const counter = process.env.CEZ_MOCK_OPENCODE_SERVE_FAIL_FILE
|
|
48
|
+
|| (process.env.CEZ_MOCK_ARGS_FILE ? `${process.env.CEZ_MOCK_ARGS_FILE}.opencode-serve-starts`
|
|
49
|
+
: join(tmpdir(), `cez-mock-opencode-serve-starts-${createHash('sha256').update(process.cwd()).digest('hex')}`));
|
|
50
|
+
const start = (sessionStoreExists(counter) ? Number(readFileSync(counter, 'utf8')) || 0 : 0) + 1;
|
|
51
|
+
sessionStoreWrite(counter, String(start));
|
|
52
|
+
if (start <= failStarts) {
|
|
53
|
+
// Pipe writes to stderr are synchronous on POSIX, so exiting right away loses nothing.
|
|
54
|
+
process.stderr.write(`Error: Unexpected error (start ${start})\nServeError\n`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
29
58
|
|
|
30
59
|
if (process.env.CEZ_MOCK_ARGS_FILE && process.env.OPENCODE_CONFIG_CONTENT) appendFileSync(process.env.CEZ_MOCK_ARGS_FILE, JSON.stringify({ type: 'runtime-config', config: JSON.parse(process.env.OPENCODE_CONFIG_CONTENT) }) + '\n');
|
|
31
60
|
if (process.env.CEZ_MOCK_CI_PR) { const { probeCiTool } = await import('./mock-ci-tool.mjs'); await probeCiTool('opencode', JSON.parse(process.env.OPENCODE_CONFIG_CONTENT ?? '{}')); }
|
|
@@ -37,6 +66,15 @@ async function afterParityPark(prompt) {
|
|
|
37
66
|
if (!gate) throw new Error('post-park scenario requires a release path');
|
|
38
67
|
while (!parityGateFs.existsSync(gate)) await new Promise(resolve => setTimeout(resolve, 10));
|
|
39
68
|
}
|
|
69
|
+
async function waitForMockRelease(fallbackMs) {
|
|
70
|
+
const file = process.env.CEZ_MOCK_RELEASE_FILE;
|
|
71
|
+
if (!file) { if (fallbackMs) await new Promise(r => setTimeout(r, fallbackMs)); return; }
|
|
72
|
+
const deadline = Date.now() + 15_000;
|
|
73
|
+
while (!parityGateFs.existsSync(file)) {
|
|
74
|
+
if (Date.now() > deadline) throw new Error('CEZ_MOCK_RELEASE_FILE was not created');
|
|
75
|
+
await new Promise(r => setTimeout(r, 10));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
40
78
|
|
|
41
79
|
const args = process.argv.slice(2);
|
|
42
80
|
const arg = (flag, fallback) => {
|
|
@@ -45,9 +83,81 @@ const arg = (flag, fallback) => {
|
|
|
45
83
|
};
|
|
46
84
|
const hostname = arg('--hostname', '127.0.0.1');
|
|
47
85
|
|
|
48
|
-
const
|
|
86
|
+
const DEFAULT_SESSION_ID = 'ses_mock_1';
|
|
87
|
+
let SESSION_ID = DEFAULT_SESSION_ID;
|
|
49
88
|
const MESSAGE_ID = 'msg_mock_1';
|
|
50
89
|
|
|
90
|
+
function sessionStorePath() {
|
|
91
|
+
if (process.env.CEZ_MOCK_OPENCODE_SESSIONS_FILE) return process.env.CEZ_MOCK_OPENCODE_SESSIONS_FILE;
|
|
92
|
+
// Keyed on the args file, not its directory: spec-support probes and D1 share a
|
|
93
|
+
// cwd and would otherwise increment ses_mock_N across unrelated launches.
|
|
94
|
+
if (process.env.CEZ_MOCK_ARGS_FILE) return `${process.env.CEZ_MOCK_ARGS_FILE}.opencode-sessions.json`;
|
|
95
|
+
// Dry-run Continue (no args file) must resume in the same worktree: persist by cwd.
|
|
96
|
+
const key = createHash('sha256').update(process.cwd()).digest('hex');
|
|
97
|
+
return join(tmpdir(), `cez-mock-opencode-sessions-${key}.json`);
|
|
98
|
+
}
|
|
99
|
+
function emptySessionStore() {
|
|
100
|
+
return { seq: 0, sessions: {} };
|
|
101
|
+
}
|
|
102
|
+
function readPersistedSessionStore() {
|
|
103
|
+
const path = sessionStorePath();
|
|
104
|
+
if (!path || !sessionStoreExists(path)) return null;
|
|
105
|
+
try {
|
|
106
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
107
|
+
if (parsed && typeof parsed === 'object' && parsed.sessions && typeof parsed.sessions === 'object') return parsed;
|
|
108
|
+
} catch {
|
|
109
|
+
// A corrupt store is treated as missing so a later POST can mint a session.
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
let memorySessionStore = readPersistedSessionStore() ?? emptySessionStore();
|
|
114
|
+
function loadSessionStore() {
|
|
115
|
+
return readPersistedSessionStore() ?? memorySessionStore;
|
|
116
|
+
}
|
|
117
|
+
function saveSessionStore(store) {
|
|
118
|
+
memorySessionStore = store;
|
|
119
|
+
const path = sessionStorePath();
|
|
120
|
+
if (!path) return;
|
|
121
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
122
|
+
sessionStoreWrite(path, JSON.stringify(store));
|
|
123
|
+
}
|
|
124
|
+
function getSession(id) {
|
|
125
|
+
return loadSessionStore().sessions[id] ?? null;
|
|
126
|
+
}
|
|
127
|
+
function createSession(body = {}) {
|
|
128
|
+
const store = loadSessionStore();
|
|
129
|
+
store.seq += 1;
|
|
130
|
+
const id = store.seq === 1 ? DEFAULT_SESSION_ID : `ses_mock_${store.seq}`;
|
|
131
|
+
store.sessions[id] = {
|
|
132
|
+
id,
|
|
133
|
+
title: typeof body.title === 'string' ? body.title : 'cezar task',
|
|
134
|
+
prompts: [],
|
|
135
|
+
...(Array.isArray(body.permission) ? { permission: [...body.permission] } : {}),
|
|
136
|
+
};
|
|
137
|
+
saveSessionStore(store);
|
|
138
|
+
return id;
|
|
139
|
+
}
|
|
140
|
+
function addPrompt(id, text) {
|
|
141
|
+
const store = loadSessionStore();
|
|
142
|
+
if (!store.sessions[id]) return;
|
|
143
|
+
store.sessions[id].prompts = [...(store.sessions[id].prompts ?? []), text];
|
|
144
|
+
saveSessionStore(store);
|
|
145
|
+
}
|
|
146
|
+
function patchSession(id, body) {
|
|
147
|
+
const store = loadSessionStore();
|
|
148
|
+
if (!store.sessions[id]) return null;
|
|
149
|
+
// OpenCode 1.18.33: PATCH permission APPENDS (no replace, no dedupe); a
|
|
150
|
+
// title-only PATCH leaves permission alone.
|
|
151
|
+
const next = { ...store.sessions[id], ...body, id };
|
|
152
|
+
if (Array.isArray(body.permission)) {
|
|
153
|
+
const existing = Array.isArray(store.sessions[id].permission) ? store.sessions[id].permission : [];
|
|
154
|
+
next.permission = [...existing, ...body.permission];
|
|
155
|
+
}
|
|
156
|
+
store.sessions[id] = next;
|
|
157
|
+
saveSessionStore(store);
|
|
158
|
+
return store.sessions[id];
|
|
159
|
+
}
|
|
160
|
+
|
|
51
161
|
let sse = null;
|
|
52
162
|
const write = (event) => {
|
|
53
163
|
if (sse) sse.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
@@ -117,6 +227,9 @@ const info = (extra) => ({
|
|
|
117
227
|
...extra,
|
|
118
228
|
});
|
|
119
229
|
|
|
230
|
+
let autonomousTurn = 0;
|
|
231
|
+
let autonomousCap = false;
|
|
232
|
+
let autonomousReadinessIdle = false;
|
|
120
233
|
const server = createServer((req, res) => {
|
|
121
234
|
const url = req.url ?? '';
|
|
122
235
|
if (req.method === 'GET' && url === '/question') {
|
|
@@ -151,15 +264,63 @@ const server = createServer((req, res) => {
|
|
|
151
264
|
else acknowledge();
|
|
152
265
|
return;
|
|
153
266
|
}
|
|
267
|
+
const sessionGet = req.method === 'GET' && /^\/session\/([^/]+)$/.exec(url);
|
|
268
|
+
if (sessionGet) {
|
|
269
|
+
const session = getSession(sessionGet[1]);
|
|
270
|
+
if (!session) {
|
|
271
|
+
res.writeHead(404, { 'content-type': 'application/json' });
|
|
272
|
+
res.end(JSON.stringify({ error: 'NotFoundError' }));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
res.writeHead(200, { 'content-type': 'application/json' });
|
|
276
|
+
res.end(JSON.stringify({
|
|
277
|
+
id: session.id,
|
|
278
|
+
title: session.title,
|
|
279
|
+
...(Array.isArray(session.permission) ? { permission: session.permission } : {}),
|
|
280
|
+
}));
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const sessionPatch = req.method === 'PATCH' && /^\/session\/([^/]+)$/.exec(url);
|
|
284
|
+
if (sessionPatch) {
|
|
285
|
+
const session = patchSession(sessionPatch[1], body ? JSON.parse(body) : {});
|
|
286
|
+
if (!session) {
|
|
287
|
+
res.writeHead(404, { 'content-type': 'application/json' });
|
|
288
|
+
res.end(JSON.stringify({ error: 'NotFoundError' }));
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
res.writeHead(200, { 'content-type': 'application/json' });
|
|
292
|
+
res.end(JSON.stringify({
|
|
293
|
+
id: session.id,
|
|
294
|
+
title: session.title,
|
|
295
|
+
...(Array.isArray(session.permission) ? { permission: session.permission } : {}),
|
|
296
|
+
}));
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
154
299
|
if (req.method === 'POST' && url === '/session') {
|
|
300
|
+
const parsed = body ? JSON.parse(body) : {};
|
|
301
|
+
SESSION_ID = createSession(parsed);
|
|
155
302
|
res.writeHead(200, { 'content-type': 'application/json' });
|
|
156
|
-
res.end(JSON.stringify({
|
|
303
|
+
res.end(JSON.stringify({
|
|
304
|
+
id: SESSION_ID,
|
|
305
|
+
title: parsed.title ?? 'cezar task',
|
|
306
|
+
...(Array.isArray(parsed.permission) ? { permission: parsed.permission } : {}),
|
|
307
|
+
}));
|
|
157
308
|
return;
|
|
158
309
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
310
|
+
const sessionPrompt = req.method === 'POST' && /^\/session\/([^/]+)\/(prompt_async|message)$/.exec(url);
|
|
311
|
+
if (sessionPrompt && getSession(sessionPrompt[1])) {
|
|
312
|
+
SESSION_ID = sessionPrompt[1];
|
|
313
|
+
try {
|
|
314
|
+
const text = body ? JSON.parse(body).parts?.map(part => part.text ?? '').join('\n') ?? '' : '';
|
|
315
|
+
if (text) addPrompt(SESSION_ID, text);
|
|
316
|
+
} catch {
|
|
317
|
+
// Keep the scripted turn even when the body is not JSON.
|
|
318
|
+
}
|
|
319
|
+
if (body.includes('mock:crash-stderr-pre-ack')) {
|
|
320
|
+
const { crashWithStderr } = await import('./mock-runner-crash.mjs');
|
|
321
|
+
crashWithStderr(body);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
163
324
|
if (body.includes('mock:reject-agent-post')) {
|
|
164
325
|
res.writeHead(503, { 'content-type': 'application/json' });
|
|
165
326
|
res.end(JSON.stringify({ error: 'agent prompt rejected' }));
|
|
@@ -180,13 +341,42 @@ const server = createServer((req, res) => {
|
|
|
180
341
|
turnActive = true;
|
|
181
342
|
// `prompt_async` semantics: acknowledge now, stream the turn over SSE.
|
|
182
343
|
res.writeHead(200, { 'content-type': 'application/json' });
|
|
344
|
+
// #426: a nudged turn can finish on SSE before its HTTP acceptance arrives.
|
|
345
|
+
// Force that ordering in the cap scenario; the first opening stays ordinary.
|
|
346
|
+
if (autonomousReadinessIdle && body.includes('Continue working autonomously until the task is fully complete.')) {
|
|
347
|
+
// Keep the portable answer HTTP request unacknowledged while its SSE turn finishes.
|
|
348
|
+
} else if (autonomousCap && body.includes('Continue working autonomously until the task is fully complete.')) {
|
|
349
|
+
setTimeout(() => res.end(JSON.stringify({ info: info({}), parts: [] })), 100);
|
|
350
|
+
} else if (body.includes('f7-delay-ack')) {
|
|
351
|
+
// F7: SSE turn-end before HTTP ACK so parkAfterAck applies the silent-tail nudge.
|
|
352
|
+
setTimeout(() => res.end(JSON.stringify({ info: info({}), parts: [] })), 250);
|
|
353
|
+
} else {
|
|
183
354
|
res.end(JSON.stringify({ info: info({}), parts: [] }));
|
|
355
|
+
}
|
|
356
|
+
if (body.includes('mock:autonomous-readiness-idle')) autonomousReadinessIdle = true;
|
|
357
|
+
if (body.includes('mock:autonomous-cap') || body.includes('mock:autonomous-ask-cap')) autonomousCap = true;
|
|
358
|
+
if (body.includes('mock:silent-tail') || body.includes('Your last turn ended without a message to the user.')) {
|
|
359
|
+
const silent = await import('./mock-silent-tail.mjs');
|
|
360
|
+
const prompt = (() => { try { return JSON.parse(body).parts.map(part => part.text ?? '').join('\n'); } catch { return body; } })();
|
|
361
|
+
silent.noteSilentTailPrompt(prompt);
|
|
362
|
+
if (silent.isAckOnlyNudge(prompt)) {
|
|
363
|
+
const beats = setInterval(() => { if (sse) sse.write(': heartbeat\n\n'); }, 50);
|
|
364
|
+
beats.unref?.();
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (silent.isLateNudge(prompt)) await silent.sleep(silent.LATE_REPLY_MS);
|
|
368
|
+
}
|
|
184
369
|
if (url.endsWith('/prompt_async')) {
|
|
185
370
|
currentUserId = `msg_user_${++steerSerial}`;
|
|
186
371
|
const text = JSON.parse(body).parts.map(part => part.text ?? '').join('\n');
|
|
187
372
|
send({ type: 'message.updated', properties: { info: { id: currentUserId, sessionID: SESSION_ID, role: 'user', time: { created: Date.now() } } } });
|
|
188
373
|
send({ type: 'message.part.updated', properties: { part: { id: `prt_${currentUserId}`, messageID: currentUserId, sessionID: SESSION_ID, type: 'text', text } } });
|
|
189
374
|
}
|
|
375
|
+
if (body.includes('mock:crash-stderr')) {
|
|
376
|
+
const { crashWithStderr } = await import('./mock-runner-crash.mjs');
|
|
377
|
+
if (body.includes('mock:crash-stderr-clean')) crashWithStderr(body);
|
|
378
|
+
else { setTimeout(() => crashWithStderr(body), 30); return; }
|
|
379
|
+
}
|
|
190
380
|
if (body.includes('mock:steer-tool')) {
|
|
191
381
|
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
192
382
|
send({ type: 'message.part.updated', properties: { part: { id: 'prt_steer_tool', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'tool', callID: 'call_steer', tool: 'bash', state: { status: 'running', input: { command: 'wait' } } } } });
|
|
@@ -212,6 +402,15 @@ const server = createServer((req, res) => {
|
|
|
212
402
|
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
213
403
|
return;
|
|
214
404
|
}
|
|
405
|
+
if (body.includes('mock:turn-messages:')) {
|
|
406
|
+
const { turnMessages } = await import('./mock-turn-messages.mjs');
|
|
407
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
408
|
+
for (const text of turnMessages(JSON.parse(body).parts.map(part => part.text ?? '').join('\n'))) {
|
|
409
|
+
send({ type: 'message.part.updated', properties: { part: { id: `prt_multi_${++echoSerial}`, messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text, time: { start: 1, end: 2 } } } });
|
|
410
|
+
}
|
|
411
|
+
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
215
414
|
if (body.includes('mock:agent-echo')) {
|
|
216
415
|
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
217
416
|
send({ type: 'message.part.updated', properties: { part: {
|
|
@@ -288,6 +487,22 @@ const server = createServer((req, res) => {
|
|
|
288
487
|
}, 60);
|
|
289
488
|
return;
|
|
290
489
|
}
|
|
490
|
+
// #723: native GET /skill diagnostic captured on 1.18.33; upstream
|
|
491
|
+
// packages/opencode/src/skill/index.ts:96-111 skips the unreadable skill.
|
|
492
|
+
if (body.includes('mock:skill-warning')) {
|
|
493
|
+
for (const root of ['.claude', '.agents']) send({ type: 'session.error', properties: {
|
|
494
|
+
error: { name: 'UnknownError', data: { message: `Failed to parse skill /home/agent/${root}/skills/pen-design/SKILL.md` } },
|
|
495
|
+
} });
|
|
496
|
+
}
|
|
497
|
+
if (body.includes('mock:unscoped-provider-failure') || body.includes('mock:scoped-skill-failure')) {
|
|
498
|
+
send({ type: 'session.error', properties: {
|
|
499
|
+
...(body.includes('mock:scoped-skill-failure') ? { sessionID: SESSION_ID } : {}),
|
|
500
|
+
error: { name: 'UnknownError', data: { message: body.includes('mock:scoped-skill-failure')
|
|
501
|
+
? 'Failed to parse skill /skills/required/SKILL.md' : 'provider unavailable — retry after restoring service' } },
|
|
502
|
+
} });
|
|
503
|
+
setTimeout(() => send({ type: 'session.idle', properties: { sessionID: SESSION_ID } }), 30);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
291
506
|
if (body.includes('mock:provider-error-early')) {
|
|
292
507
|
// #505 review: the provider rejects before any assistant message exists.
|
|
293
508
|
send({ type: 'session.error', properties: { sessionID: SESSION_ID, error: { name: 'ProviderAuthError', data: { message: 'API key expired' } } } });
|
|
@@ -331,10 +546,53 @@ const server = createServer((req, res) => {
|
|
|
331
546
|
setTimeout(() => send({ type: 'session.idle', properties: { sessionID: SESSION_ID } }), 30);
|
|
332
547
|
return;
|
|
333
548
|
}
|
|
549
|
+
if (body.includes('mock:autonomous') || body.includes('Continue working autonomously until the task is fully complete.')) {
|
|
550
|
+
const { autonomousReply } = await import('./mock-autonomous.mjs');
|
|
551
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
552
|
+
send({ type: 'message.part.updated', properties: { part: { id: `autonomous-${++autonomousTurn}`, messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: autonomousReply(JSON.parse(body).parts.map(part => part.text ?? '').join('\n')), time: { start: 1, end: 2 } } } });
|
|
553
|
+
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
if (body.includes('mock:silent-tail') || body.includes('mock:tool-tail') || body.includes('Your last turn ended without a message to the user.')) {
|
|
557
|
+
const silent = await import('./mock-silent-tail.mjs');
|
|
558
|
+
const prompt = (() => { try { return JSON.parse(body).parts.map(part => part.text ?? '').join('\n'); } catch { return body; } })();
|
|
559
|
+
silent.noteSilentTailPrompt(prompt);
|
|
560
|
+
if (silent.isFinalMessageNudge(prompt)) {
|
|
561
|
+
const kind = silent.finalMessageNudgeKind();
|
|
562
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
563
|
+
if (kind === 'silent') {
|
|
564
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'silent-nudge-rsn', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'reasoning', text: silent.SILENT_TAIL_REASONING, time: { start: 1, end: 2 } } } });
|
|
565
|
+
} else {
|
|
566
|
+
if (kind === 'slow-done') {
|
|
567
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'silent-nudge-prefix', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: silent.SLOW_DONE_PREFIX, time: { start: 1, end: 2 } } } });
|
|
568
|
+
await silent.sleep(silent.SLOW_DONE_TAIL_MS);
|
|
569
|
+
}
|
|
570
|
+
const text = kind === 'standing' ? silent.FINAL_MESSAGE_STANDING : silent.SILENT_TAIL_DONE;
|
|
571
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'silent-nudge-done', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text, time: { start: 1, end: 2 } } } });
|
|
572
|
+
}
|
|
573
|
+
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
if (silent.isSilentTailScenario(prompt)) {
|
|
577
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
578
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'silent-open', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: silent.SILENT_TAIL_OPENING, time: { start: 1, end: 2 } } } });
|
|
579
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'silent-gh', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'tool', callID: 'call_silent_gh', tool: 'bash', state: { status: 'completed', input: { command: 'gh issue create' }, output: 'created', time: { start: 1, end: 2 } } } } });
|
|
580
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'silent-rsn', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'reasoning', text: silent.SILENT_TAIL_REASONING, time: { start: 1, end: 2 } } } });
|
|
581
|
+
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (silent.isToolTailScenario(prompt)) {
|
|
585
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
586
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'tool-tail-open', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: silent.TOOL_TAIL_OPENING, time: { start: 1, end: 2 } } } });
|
|
587
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'tool-tail-git', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'tool', callID: 'call_tool_tail', tool: 'bash', state: { status: 'completed', input: { command: 'git status --short' }, output: ' M src/example.ts', time: { start: 1, end: 2 } } } } });
|
|
588
|
+
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
334
592
|
// #401: one completed text snapshot, without an earlier streaming part.
|
|
335
593
|
if (body.includes('mock:ask-snapshot')) {
|
|
336
594
|
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
337
|
-
send({ type: 'message.part.updated', properties: { part: { id: 'ask-snapshot', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: 'Using the CEZ:ASK structured question format instead:\n\nCEZ:ASK {"questions":[{"header":"Library","question":"Which test library?","options":[{"label":"Vitest"},{"label":"Node test"}]}]}', time: { start: 1, end: 2 } } } });
|
|
595
|
+
send({ type: 'message.part.updated', properties: { part: { id: 'ask-snapshot', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: body.includes('mock:ask-snapshot-bad') ? 'CEZ:ASK {not valid json' : 'Using the CEZ:ASK structured question format instead:\n\nCEZ:ASK {"questions":[{"header":"Library","question":"Which test library?","options":[{"label":"Vitest"},{"label":"Node test"}]}]}', time: { start: 1, end: 2 } } } });
|
|
338
596
|
send({ type: 'session.idle', properties: { sessionID: SESSION_ID } });
|
|
339
597
|
return;
|
|
340
598
|
}
|
|
@@ -371,6 +629,22 @@ const server = createServer((req, res) => {
|
|
|
371
629
|
}] });
|
|
372
630
|
return;
|
|
373
631
|
}
|
|
632
|
+
if (body.includes('mock:hold-done')) {
|
|
633
|
+
// Pause, then CEZ:DONE, so a mid-turn sendMessage can queue behind the
|
|
634
|
+
// running turn and race the close (#486).
|
|
635
|
+
await waitForMockRelease(400);
|
|
636
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
637
|
+
send({ type: 'message.part.updated', properties: { part: {
|
|
638
|
+
id: 'prt_mock_hold_done', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text',
|
|
639
|
+
text: 'parity hold-done: content after the pause\n\nCEZ:DONE',
|
|
640
|
+
time: { start: 1760000000500, end: 1760000000600 },
|
|
641
|
+
} } });
|
|
642
|
+
send({ type: 'message.updated', properties: { info: info({
|
|
643
|
+
cost: 0.0001, tokens: { input: 20, output: 10, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
644
|
+
}) } });
|
|
645
|
+
setTimeout(() => send({ type: 'session.idle', properties: { sessionID: SESSION_ID } }), 30);
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
374
648
|
if (body.includes('mock:done')) {
|
|
375
649
|
// Declares the task complete so the run reaches cezar's review gate; a
|
|
376
650
|
// markerless turn-end correctly parks as `waiting` instead (harness
|
|
@@ -390,19 +664,18 @@ const server = createServer((req, res) => {
|
|
|
390
664
|
if (body.includes('mock:hold-ask')) {
|
|
391
665
|
// Portable CEZ:ASK after a pause, so a mid-turn sendMessage can queue
|
|
392
666
|
// and then race the park (run.ts must discard that waiter).
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}, 250);
|
|
667
|
+
await waitForMockRelease(250);
|
|
668
|
+
const ask = 'Pick one.\n\nCEZ:ASK {"questions":[{"header":"Library","question":"Which date library should I standardize on?","options":[{"label":"date-fns","description":"Tree-shakeable, functional"},{"label":"Luxon","description":"Immutable, tz-aware"}]}]}';
|
|
669
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
670
|
+
send({ type: 'message.part.updated', properties: { part: {
|
|
671
|
+
id: 'prt_mock_hold_ask', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text',
|
|
672
|
+
text: ask,
|
|
673
|
+
time: { start: 1760000000500, end: 1760000000600 },
|
|
674
|
+
} } });
|
|
675
|
+
send({ type: 'message.updated', properties: { info: info({
|
|
676
|
+
cost: 0.0001, tokens: { input: 20, output: 10, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
677
|
+
}) } });
|
|
678
|
+
setTimeout(() => send({ type: 'session.idle', properties: { sessionID: SESSION_ID } }), 30);
|
|
406
679
|
return;
|
|
407
680
|
}
|
|
408
681
|
if (watchdogStall(body)) return;
|
|
@@ -414,6 +687,19 @@ const server = createServer((req, res) => {
|
|
|
414
687
|
}, 100);
|
|
415
688
|
return;
|
|
416
689
|
}
|
|
690
|
+
if (body.includes('mock:hold-gated')) {
|
|
691
|
+
await waitForMockRelease(250);
|
|
692
|
+
const gated = 'parity hold-gated: content after the pause';
|
|
693
|
+
send({ type: 'message.updated', properties: { info: info({}) } });
|
|
694
|
+
send({ type: 'message.part.updated', properties: { part: {
|
|
695
|
+
id: 'prt_mock_hold_gated', messageID: MESSAGE_ID, sessionID: SESSION_ID, type: 'text', text: gated,
|
|
696
|
+
} } });
|
|
697
|
+
send({ type: 'message.updated', properties: { info: info({
|
|
698
|
+
cost: 0.0001, tokens: { input: 20, output: 10, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
699
|
+
}) } });
|
|
700
|
+
setTimeout(() => send({ type: 'session.idle', properties: { sessionID: SESSION_ID } }), 30);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
417
703
|
if (body.includes('mock:hold')) {
|
|
418
704
|
// The response above is the ack (this is the #4 wire: `prompt_async`
|
|
419
705
|
// resolves immediately, the turn arrives over SSE afterwards). Holding
|
|
@@ -522,4 +808,8 @@ server.listen(0, hostname, () => {
|
|
|
522
808
|
// The runner reads the bound URL back from stdout, like the real server.
|
|
523
809
|
console.log(`opencode server listening on http://${hostname}:${server.address().port}`);
|
|
524
810
|
});
|
|
525
|
-
process.on('SIGTERM', () =>
|
|
811
|
+
process.on('SIGTERM', () => {
|
|
812
|
+
// Expose the end-request/process-exit interval to the root idle regression.
|
|
813
|
+
if (autonomousReadinessIdle) setTimeout(() => process.exit(0), 250);
|
|
814
|
+
else process.exit(0);
|
|
815
|
+
});
|
package/scripts/mock-pi-rpc.mjs
CHANGED
|
@@ -14,11 +14,28 @@ function watchdogStall(prompt) {
|
|
|
14
14
|
if (prompt.includes('held-pipe')) {
|
|
15
15
|
watchdogSpawn(process.execPath, ['-e', 'setTimeout(() => {}, 5000)'], { stdio: ['ignore', process.stdout, process.stderr] });
|
|
16
16
|
}
|
|
17
|
+
if (prompt.includes('leftover')) {
|
|
18
|
+
// hearsay-tools/cezarion#890: one child stays in the session's process group and ignores
|
|
19
|
+
// SIGTERM; one leaves the group with setsid. Both exit on their own as a cleanup backstop.
|
|
20
|
+
const leftover = (file) => `process.on('SIGTERM',()=>{}); require('fs').writeFileSync(${JSON.stringify(file)}, String(process.pid)); setTimeout(()=>{},20000)`;
|
|
21
|
+
watchdogSpawn(process.execPath, ['-e', leftover('leftover-group.pid')], { stdio: 'ignore' });
|
|
22
|
+
watchdogSpawn(process.execPath, ['-e', leftover('leftover-session.pid')], { stdio: 'ignore', detached: true }).unref();
|
|
23
|
+
}
|
|
17
24
|
return true;
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
import readline from 'node:readline';
|
|
21
|
-
import { appendFileSync } from 'node:fs';
|
|
28
|
+
import { appendFileSync, existsSync as mockReleaseExists } from 'node:fs';
|
|
29
|
+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
30
|
+
async function waitForMockRelease(fallbackMs) {
|
|
31
|
+
const file = process.env.CEZ_MOCK_RELEASE_FILE;
|
|
32
|
+
if (!file) { if (fallbackMs) await sleep(fallbackMs); return; }
|
|
33
|
+
const deadline = Date.now() + 15_000;
|
|
34
|
+
while (!mockReleaseExists(file)) {
|
|
35
|
+
if (Date.now() > deadline) throw new Error('CEZ_MOCK_RELEASE_FILE was not created');
|
|
36
|
+
await sleep(10);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
22
39
|
if (process.env.CEZ_MOCK_ARGS_FILE) appendFileSync(process.env.CEZ_MOCK_ARGS_FILE, `${JSON.stringify(process.argv.slice(2))}\n`);
|
|
23
40
|
|
|
24
41
|
// Pi handles SIGTERM and reports 128 + signal, rather than a null exit code.
|
|
@@ -66,7 +83,6 @@ const send = (value) => {
|
|
|
66
83
|
}
|
|
67
84
|
write(value);
|
|
68
85
|
};
|
|
69
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
70
86
|
|
|
71
87
|
/** One valid CEZ:ASK payload (spec #473), used by the `mock:ask` scenario. */
|
|
72
88
|
const ASK_MARKER_BODY = "{\"questions\":[{\"header\":\"Library\",\"question\":\"Which test library?\",\"multiSelect\":false,\"options\":[{\"label\":\"Vitest\",\"description\":\"Use the existing test runner\"},{\"label\":\"Node test\",\"description\":\"Use node:test\"}]}]}";
|
|
@@ -81,6 +97,13 @@ function sendText(deltas) {
|
|
|
81
97
|
send({ type: 'message_update', message: {}, assistantMessageEvent: { type: 'text_end', contentIndex: 0, content, partial: {} } });
|
|
82
98
|
}
|
|
83
99
|
|
|
100
|
+
/** Native thinking block — contentIndex 1 when a text block already occupied 0. */
|
|
101
|
+
function sendThinking(text, contentIndex = 0) {
|
|
102
|
+
send({ type: 'message_update', message: {}, assistantMessageEvent: { type: 'thinking_start', contentIndex, partial: {} } });
|
|
103
|
+
send({ type: 'message_update', message: {}, assistantMessageEvent: { type: 'thinking_delta', contentIndex, delta: text, partial: {} } });
|
|
104
|
+
send({ type: 'message_update', message: {}, assistantMessageEvent: { type: 'thinking_end', contentIndex, content: text, partial: {} } });
|
|
105
|
+
}
|
|
106
|
+
|
|
84
107
|
/** The terminal quartet: usage-bearing message_end, then turn/agent settle. */
|
|
85
108
|
function sendTurnEnd(usage = { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, cost: { total: 0.001 } }) {
|
|
86
109
|
send({ type: 'message_end', message: { role: 'assistant', usage } });
|
|
@@ -104,6 +127,60 @@ rl.on('line', (line) => {
|
|
|
104
127
|
rl.on('close', () => { queue.then(() => process.exit(0)); });
|
|
105
128
|
|
|
106
129
|
async function handle(command) {
|
|
130
|
+
if (command.type === 'prompt' && (command.message.includes('mock:autonomous') || command.message.startsWith('Continue working autonomously until the task is fully complete.'))) {
|
|
131
|
+
const { autonomousReply } = await import('./mock-autonomous.mjs');
|
|
132
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
133
|
+
send({ type: 'agent_start' });
|
|
134
|
+
send({ type: 'turn_start' });
|
|
135
|
+
sendText([autonomousReply(command.message)]);
|
|
136
|
+
sendTurnEnd();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (command.type === 'prompt' && (command.message.includes('mock:silent-tail') || command.message.includes('mock:tool-tail') || command.message.includes('Your last turn ended without a message to the user.'))) {
|
|
140
|
+
const silent = await import('./mock-silent-tail.mjs');
|
|
141
|
+
silent.noteSilentTailPrompt(command.message);
|
|
142
|
+
if (silent.isFinalMessageNudge(command.message)) {
|
|
143
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
144
|
+
const kind = silent.finalMessageNudgeKind();
|
|
145
|
+
if (kind === 'ack-only') return;
|
|
146
|
+
if (kind === 'late') await silent.sleep(silent.LATE_REPLY_MS);
|
|
147
|
+
send({ type: 'agent_start' });
|
|
148
|
+
send({ type: 'turn_start' });
|
|
149
|
+
if (kind === 'silent') sendThinking(silent.SILENT_TAIL_REASONING);
|
|
150
|
+
else if (kind === 'slow-done') {
|
|
151
|
+
sendText([silent.SLOW_DONE_PREFIX]);
|
|
152
|
+
await silent.sleep(silent.SLOW_DONE_TAIL_MS);
|
|
153
|
+
sendText([silent.SILENT_TAIL_DONE]);
|
|
154
|
+
} else sendText([kind === 'standing' ? silent.FINAL_MESSAGE_STANDING : silent.SILENT_TAIL_DONE]);
|
|
155
|
+
sendTurnEnd();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (silent.isSilentTailScenario(command.message)) {
|
|
159
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
160
|
+
send({ type: 'agent_start' });
|
|
161
|
+
send({ type: 'turn_start' });
|
|
162
|
+
sendText([silent.SILENT_TAIL_OPENING]);
|
|
163
|
+
send({ type: 'tool_execution_start', toolCallId: 'tool-silent-gh', toolName: 'bash', args: { command: 'gh issue create' } });
|
|
164
|
+
send({ type: 'tool_execution_end', toolCallId: 'tool-silent-gh', toolName: 'bash', result: { content: [{ type: 'text', text: 'created' }] }, isError: false });
|
|
165
|
+
sendThinking(silent.SILENT_TAIL_REASONING, 1);
|
|
166
|
+
sendTurnEnd();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (silent.isToolTailScenario(command.message)) {
|
|
170
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
171
|
+
send({ type: 'agent_start' });
|
|
172
|
+
send({ type: 'turn_start' });
|
|
173
|
+
sendText([silent.TOOL_TAIL_OPENING]);
|
|
174
|
+
send({ type: 'tool_execution_start', toolCallId: 'tool-tail-git', toolName: 'bash', args: { command: 'git status --short' } });
|
|
175
|
+
send({ type: 'tool_execution_end', toolCallId: 'tool-tail-git', toolName: 'bash', result: { content: [{ type: 'text', text: ' M src/example.ts' }] }, isError: false });
|
|
176
|
+
sendTurnEnd();
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (command.type === 'prompt' && command.message.includes('mock:crash-stderr')) {
|
|
181
|
+
const { crashWithStderr } = await import('./mock-runner-crash.mjs');
|
|
182
|
+
if (crashWithStderr(command.message, '{"type":"tool_execution_update","toolCallId":"truncated')) return;
|
|
183
|
+
}
|
|
107
184
|
// Testability hook, mirroring mock-claude: CEZ_MOCK_STDIN_FILE=<path> appends
|
|
108
185
|
// each inbound prompt's text and image count, so tests can assert what the
|
|
109
186
|
// runner actually wrote onto the RPC (harness parity's AgentRunSpec probes).
|
|
@@ -153,6 +230,12 @@ async function handle(command) {
|
|
|
153
230
|
activeTurn.late = true;
|
|
154
231
|
await sleep(300);
|
|
155
232
|
sendTurnEnd();
|
|
233
|
+
} else if (command.type === 'prompt' && command.message.includes('mock:turn-messages:')) {
|
|
234
|
+
const { turnMessages } = await import('./mock-turn-messages.mjs');
|
|
235
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
236
|
+
send({ type: 'agent_start' }); send({ type: 'turn_start' });
|
|
237
|
+
for (const text of turnMessages(command.message)) sendText([text]);
|
|
238
|
+
sendTurnEnd();
|
|
156
239
|
} else if (command.type === 'prompt' && command.message.includes('mock:agent-echo')) {
|
|
157
240
|
// rpc-lifecycle.ndjson's normal prompt/assistant/settled sequence.
|
|
158
241
|
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
@@ -191,6 +274,20 @@ async function handle(command) {
|
|
|
191
274
|
errorMessage: 'Not Found',
|
|
192
275
|
} });
|
|
193
276
|
send({ type: 'agent_settled' });
|
|
277
|
+
} else if (command.type === 'prompt' && command.message.includes('mock:hold-done')) {
|
|
278
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
279
|
+
send({ type: 'agent_start' });
|
|
280
|
+
send({ type: 'turn_start' });
|
|
281
|
+
await waitForMockRelease(400);
|
|
282
|
+
sendText(['parity hold-done: content after the pause\n\nCEZ:DONE']);
|
|
283
|
+
sendTurnEnd();
|
|
284
|
+
} else if (command.type === 'prompt' && command.message.includes('mock:hold-ask')) {
|
|
285
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
286
|
+
send({ type: 'agent_start' });
|
|
287
|
+
send({ type: 'turn_start' });
|
|
288
|
+
await waitForMockRelease(400);
|
|
289
|
+
sendText(['Pick one.\n\nCEZ:ASK {"questions":[{"header":"Library","question":"Which test library?","options":[{"label":"Vitest"},{"label":"Node test"}]}]}']);
|
|
290
|
+
sendTurnEnd();
|
|
194
291
|
} else if (command.type === 'prompt' && (command.message.includes('mock:done') || (resumeAfterAsk && command.message.trim() === 'Library: Vitest'))) {
|
|
195
292
|
resumeAfterAsk = false;
|
|
196
293
|
// Declares the task complete so the run reaches cezar's review gate; a
|
|
@@ -206,7 +303,7 @@ async function handle(command) {
|
|
|
206
303
|
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
207
304
|
send({ type: 'agent_start' });
|
|
208
305
|
send({ type: 'turn_start' });
|
|
209
|
-
send({ type: 'message_update', message: {}, assistantMessageEvent: { type: 'text_end', contentIndex: 0, content: 'Using the CEZ:ASK structured question format instead:\n\nCEZ:ASK {"questions":[{"header":"Library","question":"Which test library?","options":[{"label":"Vitest"},{"label":"Node test"}]}]}', partial: {} } });
|
|
306
|
+
send({ type: 'message_update', message: {}, assistantMessageEvent: { type: 'text_end', contentIndex: 0, content: command.message.includes('mock:ask-snapshot-bad') ? 'CEZ:ASK {not valid json' : 'Using the CEZ:ASK structured question format instead:\n\nCEZ:ASK {"questions":[{"header":"Library","question":"Which test library?","options":[{"label":"Vitest"},{"label":"Node test"}]}]}', partial: {} } });
|
|
210
307
|
sendTurnEnd();
|
|
211
308
|
} else if (command.type === 'prompt' && command.message.includes('mock:ask-prose')) {
|
|
212
309
|
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
@@ -241,6 +338,14 @@ async function handle(command) {
|
|
|
241
338
|
for (let i = 0; i < 24; i++) { send({ type: 'tool_execution_update', toolCallId: 'busy', toolName: 'bash', partialResult: { content: [{ type: 'text', text: 'working' }] } }); await sleep(100); }
|
|
242
339
|
sendTurnEnd();
|
|
243
340
|
}
|
|
341
|
+
} else if (command.type === 'prompt' && command.message.includes('mock:hold-gated')) {
|
|
342
|
+
send({ id: command.id, type: 'response', command: 'prompt', success: true });
|
|
343
|
+
send({ type: 'agent_start' });
|
|
344
|
+
send({ type: 'turn_start' });
|
|
345
|
+
await waitForMockRelease(250);
|
|
346
|
+
sendText(['parity hold-gated: content after the pause']);
|
|
347
|
+
await sleep(250);
|
|
348
|
+
sendTurnEnd();
|
|
244
349
|
} else if (command.type === 'prompt' && command.message.includes('mock:hold')) {
|
|
245
350
|
// The `response` below is the ack. Holding the content AND the terminal
|
|
246
351
|
// quartet behind it is what makes harness parity S2 meaningful: a runner
|
|
@@ -292,6 +397,7 @@ async function handle(command) {
|
|
|
292
397
|
result: { content: [{ type: 'text', text: 'mock file' }] },
|
|
293
398
|
isError: false,
|
|
294
399
|
});
|
|
400
|
+
if (!monitoringMarker) sendText(['Done with the first pass.']);
|
|
295
401
|
send({
|
|
296
402
|
type: 'message_end',
|
|
297
403
|
message: {
|