mixdog 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/scripts/build-shipped-history.mjs +125 -33
- package/scripts/gate-local.mjs +220 -63
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +139 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +71 -34
- package/scripts/lib/scoped-temp.mjs +1 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +9 -4
- package/scripts/lib/test-spawn-ledger.mjs +43 -3
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/pptx-kit-index.mjs +5 -6
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/scripts/suite-health.mjs +110 -28
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +38 -2
- package/src/defaults/skills/browser-use/SKILL.md +4 -1
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +12 -2
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +28 -9
- package/src/defaults/skills/setup/references/surfaces.md +5 -2
- package/src/defaults/skills/setup-guide/SKILL.md +11 -3
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +40 -50
- package/src/orchestration/balanced.md +23 -0
- package/src/orchestration/focused.md +22 -0
- package/src/orchestration/none.md +5 -0
- package/src/orchestration/swarm.md +24 -0
- package/src/rules/agent-mode/AGENT_MODE.md +3 -1
- package/src/rules/agent-mode/MIXY.md +2 -2
- package/src/rules/lead/LEAD.md +3 -3
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +4 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
- package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
- package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
- package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
- package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
- package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/attachment-reference.mjs +1 -1
- package/src/runtime/attachments/pdf-extract.mjs +1 -1
- package/src/runtime/attachments/store.d.mts +1 -0
- package/src/runtime/attachments/store.mjs +2 -2
- package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
- package/src/runtime/channels/lib/scheduler.mjs +33 -0
- package/src/runtime/channels/lib/schedules-db.mjs +11 -4
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
- package/src/runtime/channels/lib/whisper-port.mjs +19 -10
- package/src/runtime/channels/lib/whisper-server.mjs +22 -13
- package/src/runtime/channels/lib/worker-main.mjs +9 -31
- package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
- package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
- package/src/runtime/connectors/gmail-app-password.mjs +4 -4
- package/src/runtime/connectors/google-mcp.mjs +1 -1
- package/src/runtime/effort-judge/judge-client.mjs +2 -2
- package/src/runtime/effort-judge/judge-input.mjs +4 -4
- package/src/runtime/explore/explorer.mjs +88 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/hardware.mjs +1 -1
- package/src/runtime/media/adapters/codex-image.mjs +3 -3
- package/src/runtime/media/adapters/gemini-video.mjs +1 -1
- package/src/runtime/media/media-usage.mjs +1 -1
- package/src/runtime/media/store.mjs +1 -1
- package/src/runtime/memory/index.mjs +15 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
- package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
- package/src/runtime/memory/lib/memory-embed.mjs +83 -14
- package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
- package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
- package/src/runtime/memory/lib/memory.mjs +17 -0
- package/src/runtime/memory/lib/pg/process.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
- package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/capabilities.mjs +1 -1
- package/src/runtime/office/core/office-core.mjs +1 -1
- package/src/runtime/office/design/content-model.mjs +3 -3
- package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
- package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
- package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
- package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
- package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +8 -6
- package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
- package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +37 -10
- package/src/runtime/shared/background-wait.mjs +66 -0
- package/src/runtime/shared/child-guardian.mjs +17 -7
- package/src/runtime/shared/config.mjs +313 -16
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +14 -8
- package/src/runtime/shared/connector-catalog.mjs +70 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +21 -18
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/cost.mjs +6 -1
- package/src/runtime/shared/llm/http-agent.mjs +316 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +453 -0
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
- package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
- package/src/runtime/shared/maintenance-schedule.mjs +109 -0
- package/src/runtime/shared/process-runner.mjs +8 -4
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/routine-trigger.d.mts +13 -0
- package/src/runtime/shared/routine-trigger.mjs +34 -0
- package/src/runtime/shared/run-child.d.mts +2 -1
- package/src/runtime/shared/run-child.mjs +70 -18
- package/src/runtime/shared/session-scratch.mjs +14 -2
- package/src/runtime/shared/shipped-definitions.mjs +7 -1
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-surface.mjs +110 -36
- package/src/runtime/shared/tool-work-units.mjs +35 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
- package/src/runtime/shared/worker-requests.mjs +17 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
- package/src/runtime/shared/worktrees/contract.mjs +16 -6
- package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
- package/src/runtime/shared/worktrees/disk.mjs +79 -2
- package/src/runtime/shared/worktrees/git.mjs +97 -7
- package/src/runtime/shared/worktrees/include.mjs +6 -4
- package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
- package/src/runtime/shared/worktrees/manager.mjs +962 -197
- package/src/runtime/shared/worktrees/settings.mjs +33 -7
- package/src/runtime/shared/worktrees/test-support.mjs +5 -1
- package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +9 -5
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +4 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +4 -23
- package/src/runtime/web-search/lib/web-tools.mjs +2 -2
- package/src/runtime/web-search/tool-defs.mjs +17 -26
- package/src/session-runtime/agent-profile-changes.mjs +55 -4
- package/src/session-runtime/agent-task-sessions.mjs +410 -353
- package/src/session-runtime/boot/apis.mjs +27 -4
- package/src/session-runtime/boot/begin.mjs +2 -0
- package/src/session-runtime/boot/config.mjs +10 -1
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/providers.mjs +70 -3
- package/src/session-runtime/boot/session.mjs +2 -0
- package/src/session-runtime/boot/tools.mjs +71 -25
- package/src/session-runtime/bot-status.mjs +103 -103
- package/src/session-runtime/channel-config-api.mjs +1 -0
- package/src/session-runtime/config-change-effects.mjs +179 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
- package/src/session-runtime/config-lifecycle.mjs +160 -24
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/discovery.mjs +245 -47
- package/src/session-runtime/conversation-import/service.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- package/src/session-runtime/handoff-attachments.mjs +1 -1
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
- package/src/session-runtime/internal-tool-executor.mjs +12 -19
- package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
- package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
- package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +40 -7
- package/src/session-runtime/native-web-search/routes.mjs +3 -3
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-auth/refresh.mjs +6 -3
- package/src/session-runtime/provider-auth/setup.mjs +1 -1
- package/src/session-runtime/provider-readiness.mjs +53 -4
- package/src/session-runtime/resource-api.mjs +1 -1
- package/src/session-runtime/resource-extension-sync.mjs +4 -8
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
- package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-plugins-api.mjs +4 -0
- package/src/session-runtime/routine-executor.mjs +152 -0
- package/src/session-runtime/routine-home-turn.mjs +46 -5
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-feature-gates.mjs +2 -11
- package/src/session-runtime/schedule-session-run.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +14 -6
- package/src/session-runtime/services/provider-admin.mjs +281 -10
- package/src/session-runtime/services/seeds.mjs +7 -0
- package/src/session-runtime/services/usage-stats-model.mjs +32 -11
- package/src/session-runtime/session-create/materialize.mjs +4 -2
- package/src/session-runtime/session-create/session-options.mjs +2 -0
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +14 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
- package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
- package/src/session-runtime/tool-policy-refresh.mjs +182 -5
- package/src/session-runtime/tool-surface.mjs +38 -1
- package/src/session-runtime/turn/agent-ops.mjs +33 -2
- package/src/session-runtime/turn/session-ops.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
- package/src/session-runtime/turn/turn-run.mjs +1 -1
- package/src/session-runtime/webhook-session-run.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
- package/src/session-runtime/workflow-agents-api.mjs +2 -0
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/project-branches.mjs +1 -1
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +128 -1070
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +8 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon-session-control.mjs +151 -136
- package/src/standalone/daemon.mjs +61 -2
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +21 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +15 -0
- package/src/standalone/session-service/agent-route-follow.mjs +23 -20
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/quota-resume.mjs +9 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
- package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/tui/App.jsx +162 -164
- package/src/tui/app/app-view/floating-panel.jsx +3 -0
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +22 -11
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/doctor.mjs +2 -2
- package/src/tui/app/panel-signature.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
- package/src/tui/app/provider-setup-picker.mjs +20 -13
- package/src/tui/app/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
- package/src/tui/app/slash-commands.mjs +2 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +5 -4
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +48 -33
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
- package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
- package/src/tui/components/question-panel-model.mjs +4 -4
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/components/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +2205 -1371
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
- package/src/tui/session/agent-job-feed.mjs +2 -0
- package/src/tui/session/context-state.mjs +3 -0
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/quota-resume.mjs +1 -1
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-api/worktree.mjs +13 -1
- package/src/tui/session/session-flow/drain.mjs +11 -14
- package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/tui/session/turn-quiet.mjs +1 -1
- package/src/tui/session/turn.mjs +3 -0
- package/src/tui/session/worktree-setup-notice.mjs +1 -1
- package/src/tui/spinner-meta.mjs +3 -3
- package/src/tui/spinner-verbs.mjs +2 -2
- package/src/defaults/skills/goal-management/SKILL.md +0 -169
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
- package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Test case management
|
|
2
|
+
|
|
3
|
+
Every test has an owner, a single contract and a lane. None of this belongs in a hand-written registry: hand lists
|
|
4
|
+
drift from the code. It is derived from where the file lives, its name and its
|
|
5
|
+
text, and `scripts/inventory.mjs` reports it.
|
|
6
|
+
|
|
7
|
+
## Where a test lives
|
|
8
|
+
|
|
9
|
+
- Beside the code it exercises, in the same area directory; the inventory's
|
|
10
|
+
area is the path below the source root, two levels deep.
|
|
11
|
+
- One domain per file (`suite-design.md`).
|
|
12
|
+
- Cross-area contract suites live in their own directory and still run in CI.
|
|
13
|
+
|
|
14
|
+
## What the inventory reads
|
|
15
|
+
|
|
16
|
+
| Ecosystem | Test files found by | Skip records |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| JS/TS (`node:test`, Vitest, Jest) | `*.test.*`, `*.spec.*`, `*-test.mjs`, `__tests__/` | `skip:` option, `it.skip`, `xit`, `skipIf` |
|
|
19
|
+
| Python (pytest, unittest) | `test_*.py`, `*_test.py` | `pytest.mark.skip/skipif/xfail`, `unittest.skip*`, `pytest.skip` |
|
|
20
|
+
| Go | `*_test.go` | `t.Skip`, `t.Skipf`, `t.SkipNow` |
|
|
21
|
+
| Rust | `tests/` directories, files with `#[test]` or `#[cfg(test)]` | `#[ignore]`, `#[ignore = "…"]`, `cfg_attr(…, ignore)` |
|
|
22
|
+
|
|
23
|
+
Lane comes from a `.slow.`, `.live.`, `.e2e.`, `.integration.` or `.electron.`
|
|
24
|
+
name tag (JS/TS); everything else counts as fast. Vendored, build and cache
|
|
25
|
+
directories are skipped and links are not followed.
|
|
26
|
+
|
|
27
|
+
Skip kinds: `capability` (the reason names a missing platform, tool or
|
|
28
|
+
privilege; a conditional skip with no reason counts here), `tracked` (`#N`),
|
|
29
|
+
`untracked` (a defect-looking skip with no issue) and `expired` (`until
|
|
30
|
+
YYYY-MM-DD` in the past). Every kind but `capability` is a defect skip that
|
|
31
|
+
needs a fix; an issue number does not make it acceptable.
|
|
32
|
+
|
|
33
|
+
## Risk markers
|
|
34
|
+
|
|
35
|
+
| Marker | Meaning | Expected action |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `timer` | Sleep, timeout or ticker in a test | Replace with a signal or fake clock unless time is the subject |
|
|
38
|
+
| `spawn` | Real child process | Keep only when the process is the subject; await exit |
|
|
39
|
+
| `port` | Listener on a fixed port | Bind port 0 |
|
|
40
|
+
| `clock` | Real clock read without a fake clock | Inject or fake the clock when the verdict depends on it |
|
|
41
|
+
| `source-text` | Reads source and matches its text | Rewrite at a runnable interface, or justify in the test |
|
|
42
|
+
|
|
43
|
+
A fake-clock library in the file clears `timer` and `clock`. Markers are
|
|
44
|
+
leads, not verdicts: a timer in a test about timers is correct.
|
|
45
|
+
|
|
46
|
+
## Audit report
|
|
47
|
+
|
|
48
|
+
One table per project: area, files, fast/slow counts, marker counts, defect
|
|
49
|
+
skips. Rank batches by: defect skips, fast-lane
|
|
50
|
+
files with `timer`+`spawn`, then the rest by area. The audit ends at the
|
|
51
|
+
report; fix only the batches the user picks.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Flaky-test policy
|
|
2
|
+
|
|
3
|
+
## Rules
|
|
4
|
+
|
|
5
|
+
1. **Zero flakes.** A test that passes and fails on the same code is a defect.
|
|
6
|
+
CI never retries automatically, and a passing rerun clears nothing.
|
|
7
|
+
2. **Fix, never skip.** Fix the cause, or move a correctly slow test to the
|
|
8
|
+
slow lane. A failure that cannot be fixed now is reported; skipping it is
|
|
9
|
+
the user's decision, never the agent's.
|
|
10
|
+
3. **Capability skips only.** A skip states the capability the platform or
|
|
11
|
+
machine lacks (a tool, an OS feature), never a defect.
|
|
12
|
+
4. **Evidence over memory.** Decide from the failing log and CI history, not
|
|
13
|
+
from "it is always flaky". Keep both the failed and the passing log.
|
|
14
|
+
5. **No local stress.** Reproduction happens through a deterministic trigger
|
|
15
|
+
in the test, or in CI history; never by loading or looping on the user's
|
|
16
|
+
machine.
|
|
17
|
+
|
|
18
|
+
## A flake report
|
|
19
|
+
|
|
20
|
+
When a flake is handed off, one tracked issue carries: the test and file, the
|
|
21
|
+
failing assertion and log, the platform and load conditions, when it first
|
|
22
|
+
appeared, how often in CI history, and the suspected cause with its evidence.
|
|
23
|
+
One issue per test, so ownership stays clear.
|
|
24
|
+
|
|
25
|
+
## Priority
|
|
26
|
+
|
|
27
|
+
Fix in this order:
|
|
28
|
+
|
|
29
|
+
1. Tests that block a release or a push.
|
|
30
|
+
2. Tests failing most often across recent CI runs.
|
|
31
|
+
3. Tests whose cause can also hit users (product races, localized output).
|
|
32
|
+
4. Everything else, batched by area.
|
|
33
|
+
|
|
34
|
+
## What does not count as a fix
|
|
35
|
+
|
|
36
|
+
- Raising a timeout to absorb a sleep, poll or production interval.
|
|
37
|
+
- Adding retries, a rerun-failed CI step, or a serial flag to hide contention.
|
|
38
|
+
- Skipping on a platform that has the capability.
|
|
39
|
+
- Deleting the assertion that failed.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Reliable tests
|
|
2
|
+
|
|
3
|
+
A test must give the same verdict alone, beside other suites, on a busy
|
|
4
|
+
machine, on a localized OS and in CI. Process isolation does not isolate
|
|
5
|
+
ports, paths, child processes, the clock or the host's language.
|
|
6
|
+
|
|
7
|
+
## Cause table
|
|
8
|
+
|
|
9
|
+
| Cause | Signal | Fix |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Timing | Passes alone, fails when other work runs; a sleep or a fixed budget decides the verdict | Wait on the event, promise or state the code produces; fake the clock when time is the subject |
|
|
12
|
+
| Shared resource | Fixed port, fixed temp path, shared data dir, a leftover process | Bind port 0 and read the assigned port; a fresh temp dir per test; per-test data dirs |
|
|
13
|
+
| Unrestored global | Later tests change behaviour; order matters | Restore environment variables, working directory, timers, mocks and locale in a `finally`/fixture teardown right after the change |
|
|
14
|
+
| Platform / locale | Fails on another OS, language or console code page | Query structured sources; never parse localized tool text; remember Windows environment names are case-insensitive |
|
|
15
|
+
| Order | Depends on a previous test's state | Each test creates and removes its own prerequisites |
|
|
16
|
+
| Teardown | Next test sees a live child, open handle or locked file | Await child exit, server close and handle release before the test ends |
|
|
17
|
+
|
|
18
|
+
## Time
|
|
19
|
+
|
|
20
|
+
- A timeout only bounds a wait on a real signal; it never makes the assertion
|
|
21
|
+
true. Keep the outer wait far larger than any deadline under test.
|
|
22
|
+
- When the deadline itself is the subject, inject or fake the clock and
|
|
23
|
+
restore real time in teardown.
|
|
24
|
+
- Do not assert scheduler ordering unless the order is the product contract;
|
|
25
|
+
place races with deferred promises at a chosen point instead.
|
|
26
|
+
|
|
27
|
+
## Processes and ports
|
|
28
|
+
|
|
29
|
+
- Count spawns: a process start costs tens of milliseconds on Windows and much
|
|
30
|
+
more under load. Spawn once per file when the behaviour allows it.
|
|
31
|
+
- A test that starts a process owns its whole tree: kill it and await exit,
|
|
32
|
+
detached children included, before the test ends.
|
|
33
|
+
- Prefer an in-process fake over a real server unless the real process is the
|
|
34
|
+
subject.
|
|
35
|
+
|
|
36
|
+
## Files and environment
|
|
37
|
+
|
|
38
|
+
- Use a private temp root per test and remove it afterwards; never write into
|
|
39
|
+
the user's home configuration or the repository tree.
|
|
40
|
+
- Windows releases handles asynchronously: a rename or delete right after a
|
|
41
|
+
close may need a bounded retry sized to the observed contention.
|
|
42
|
+
- Point every home, data or cache directory variable the code reads at the
|
|
43
|
+
test's own root.
|
|
44
|
+
|
|
45
|
+
## Proof
|
|
46
|
+
|
|
47
|
+
A reliability fix is proven by a deterministic trigger of the named cause
|
|
48
|
+
(held promise, fake clock, localized fixture, pre-bound port) that fails before
|
|
49
|
+
and passes after, not by repeating the test until it stays green.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Suite design
|
|
2
|
+
|
|
3
|
+
How a suite stays small, fast and honest. Apply when writing, placing or
|
|
4
|
+
reviewing tests.
|
|
5
|
+
|
|
6
|
+
## A good test
|
|
7
|
+
|
|
8
|
+
- **Names the break.** Before writing, state the production change that should
|
|
9
|
+
make it fail, and whether that change is a bug or a decision. Cannot name
|
|
10
|
+
one → redesign around an observable behaviour.
|
|
11
|
+
- **Independent expected value.** A literal or hand-checked fixture, never a
|
|
12
|
+
value recomputed with the code under test or its helpers.
|
|
13
|
+
- **No change detectors.** If only intentional decisions can fail it (a
|
|
14
|
+
constant, exact message wording, private structure), test the behaviour that
|
|
15
|
+
depends on the decision instead.
|
|
16
|
+
- **Your code, not the framework's.** Test the contract at your boundaries;
|
|
17
|
+
trivial getters and forwarding earn tests only when they validate,
|
|
18
|
+
normalize, derive or cause side effects.
|
|
19
|
+
- **Through the interface.** Mock only at system boundaries (network, clock,
|
|
20
|
+
randomness, slow or external stores), never your own modules; pass
|
|
21
|
+
dependencies in so a boundary is easy to replace.
|
|
22
|
+
- **One behaviour per test**, small enough that a failure points at one cause.
|
|
23
|
+
Write one test at a time, as needed; never bulk-generate cases.
|
|
24
|
+
|
|
25
|
+
## One invariant, one owning test
|
|
26
|
+
|
|
27
|
+
Two tests asserting the same contract drift apart instead of reinforcing each
|
|
28
|
+
other: when the contract changes, one is updated and the other keeps asserting
|
|
29
|
+
a retired behaviour. Name an owner per contract; every other test covers a
|
|
30
|
+
distinct observable boundary. When an overlap appears, reduce both to what is
|
|
31
|
+
distinct, or keep the owner and move the unique cases into it.
|
|
32
|
+
|
|
33
|
+
## Text matching is a last resort
|
|
34
|
+
|
|
35
|
+
Asserting against source text pins names, spacing and constants instead of
|
|
36
|
+
behaviour. It breaks on harmless refactors and passes on wrong behaviour, so it
|
|
37
|
+
proves neither direction. Reserve it for artifacts with no runnable surface
|
|
38
|
+
(generated scripts, workflow YAML, prompt text) or for ordering invariants in
|
|
39
|
+
code a test cannot import (a guard must precede a send), and say why in the
|
|
40
|
+
test. Keep the list of such files short and known.
|
|
41
|
+
|
|
42
|
+
## A contract suite must run in CI
|
|
43
|
+
|
|
44
|
+
A suite that asserts a contract but runs nowhere automatic is documentation
|
|
45
|
+
with an expiry date: nothing forces it to follow the code, and it fails the
|
|
46
|
+
first time someone runs it. Make it discoverable like every other test and give
|
|
47
|
+
it a CI job. Checks that need a built artifact run after the build step, not
|
|
48
|
+
nowhere. Scripts that are not test files (smoke scripts, harness runners) get a
|
|
49
|
+
scheduled sweep that enumerates them, so new ones join automatically and stale
|
|
50
|
+
exclusions fail closed.
|
|
51
|
+
|
|
52
|
+
## One domain per file
|
|
53
|
+
|
|
54
|
+
A multi-domain test file makes every change pay a whole-file search. Split when
|
|
55
|
+
one change forces a search across domains, not on line count alone; shared
|
|
56
|
+
fixtures move into a helper beside the files. One stateful fixture chain over
|
|
57
|
+
one domain stays one file whatever its length.
|
|
58
|
+
|
|
59
|
+
## Slow work gets its own lane
|
|
60
|
+
|
|
61
|
+
A test over roughly ten seconds alone goes to a slow lane marked by name,
|
|
62
|
+
directory or tag, whichever the runner selects on. It still runs in CI, in a
|
|
63
|
+
parallel job, so the gate takes the longer of the two instead of their sum.
|
|
64
|
+
Tests that need a built artifact or a live system get a live lane. If a file
|
|
65
|
+
is slow only in a full run because processes contend, the cause is contention,
|
|
66
|
+
not a slow file: Diagnose, do not move it.
|
|
67
|
+
|
|
68
|
+
## Selection beats retries
|
|
69
|
+
|
|
70
|
+
During a change run the files that reach the changed code (the project's
|
|
71
|
+
changed-files selection, a path or name filter, a single test id). The full
|
|
72
|
+
lanes gate the push. A suite that takes minutes is a design problem to fix by
|
|
73
|
+
selection and sharding in CI, not by waiting on the user's machine.
|
|
74
|
+
|
|
75
|
+
## Published artifacts carry no tests
|
|
76
|
+
|
|
77
|
+
Check that packaging excludes test sources, and that test-only changes do not
|
|
78
|
+
invalidate caches keyed on the shipped files.
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Read-only inventory of a project's test files across JS/TS, Python, Go and
|
|
3
|
+
// Rust: lane, area, risk markers and skip records. Prints Markdown, or JSON
|
|
4
|
+
// with --json. Never writes files, never follows links, never runs anything.
|
|
5
|
+
import { closeSync, openSync, readSync, readdirSync, statSync } from 'node:fs';
|
|
6
|
+
import { join, relative, sep } from 'node:path';
|
|
7
|
+
import { pathToFileURL } from 'node:url';
|
|
8
|
+
|
|
9
|
+
const SKIP_DIRS = new Set([
|
|
10
|
+
'node_modules',
|
|
11
|
+
'.git',
|
|
12
|
+
'.hg',
|
|
13
|
+
'.svn',
|
|
14
|
+
'dist',
|
|
15
|
+
'out',
|
|
16
|
+
'build',
|
|
17
|
+
'target',
|
|
18
|
+
'vendor',
|
|
19
|
+
'third_party',
|
|
20
|
+
'venv',
|
|
21
|
+
'.venv',
|
|
22
|
+
'site-packages',
|
|
23
|
+
'__pycache__',
|
|
24
|
+
'.tox',
|
|
25
|
+
'.nox',
|
|
26
|
+
'.mypy_cache',
|
|
27
|
+
'.pytest_cache',
|
|
28
|
+
'.ruff_cache',
|
|
29
|
+
'.next',
|
|
30
|
+
'.nuxt',
|
|
31
|
+
'.turbo',
|
|
32
|
+
'.cache',
|
|
33
|
+
'.runtime',
|
|
34
|
+
'coverage',
|
|
35
|
+
'.gradle',
|
|
36
|
+
]);
|
|
37
|
+
const MAX_FILES = 20_000;
|
|
38
|
+
const MAX_DIRS = 50_000;
|
|
39
|
+
const MAX_DEPTH = 40;
|
|
40
|
+
const MAX_BYTES = 1 << 20;
|
|
41
|
+
const LIST_LIMIT = 200;
|
|
42
|
+
|
|
43
|
+
const JS_EXT = '(?:m?[jt]s|c[jt]s|[jt]sx)';
|
|
44
|
+
const JS_TEST = new RegExp(`(?:\\.(?:test|spec)\\.${JS_EXT}|-test\\.m?js)$`);
|
|
45
|
+
const JS_FILE = new RegExp(`\\.${JS_EXT}$`);
|
|
46
|
+
const TYPES_FILE = /\.d\.[cm]?ts$/;
|
|
47
|
+
const RUST_TEST = /#\[\s*(?:cfg\(\s*test\s*\)|test|tokio::test|rstest)\b/;
|
|
48
|
+
|
|
49
|
+
// `skip: cond && 'reason'` keeps the reason after the last `&&`.
|
|
50
|
+
const JS_SKIP_REASON = /\bskip\s*(?::|\()\s*(?:[^\n]*?&&\s*)?(['"`])((?:(?!\1).)*)\1/g;
|
|
51
|
+
const JS_SKIP_BARE = /\b(?:(?:it|test|describe)\.skip|x(?:it|test|describe))\b|\.skip\s*\(\s*\)|\bskip\s*:\s*true\b/;
|
|
52
|
+
const JS_SKIP_IF = /\.skipIf\s*\(/;
|
|
53
|
+
const PY_SKIP =
|
|
54
|
+
/\b(?:pytest\.mark\.(skipif|skip|xfail)|unittest\.(skipIf|skipUnless|skip|expectedFailure)|pytest\.(importorskip|skip))\b/;
|
|
55
|
+
const PY_CONDITIONAL = new Set(['skipif', 'skipIf', 'skipUnless', 'importorskip']);
|
|
56
|
+
const GO_SKIP = /\.Skip(?:f|Now)?\s*\(/;
|
|
57
|
+
const RUST_IGNORE = /#\[\s*ignore\s*(?:=\s*(['"])((?:(?!\1).)*)\1)?\s*(?:\(.*?\))?\s*\]/;
|
|
58
|
+
const RUST_CFG_IGNORE = /#\[\s*cfg_attr\([^\]]*\bignore\b/;
|
|
59
|
+
|
|
60
|
+
const LANGS = {
|
|
61
|
+
js: {
|
|
62
|
+
comment: '//',
|
|
63
|
+
fake: /mock\.timers\.enable|useFakeTimers|installFakeClock|vi\.setSystemTime|jest\.setSystemTime/,
|
|
64
|
+
markers: {
|
|
65
|
+
timer: /\b(setTimeout|setInterval|sleep|delay)\s*\(/,
|
|
66
|
+
spawn: /\b(spawn|spawnSync|execFile|execFileSync|execSync|fork)\s*\(/,
|
|
67
|
+
port: /\.listen\(\s*[1-9]\d{2,4}\b/,
|
|
68
|
+
clock: /Date\.now\(\)|new Date\(\s*\)/,
|
|
69
|
+
'source-text': /readFile(Sync)?\([^)]*\.(m?js|tsx?|jsx)['"`]/,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
python: {
|
|
73
|
+
comment: '#',
|
|
74
|
+
fake: /freezegun|freeze_time|time_machine|time-machine|monkeypatch\.setattr\([^)]*time|mock\.patch\([^)]*time/,
|
|
75
|
+
markers: {
|
|
76
|
+
timer: /\b(?:time|asyncio)\.sleep\(|\bsleep\(/,
|
|
77
|
+
spawn:
|
|
78
|
+
/\bsubprocess\.(?:run|Popen|call|check_output|check_call)\(|\bos\.(?:system|popen)\(|\bmultiprocessing\.Process\(/,
|
|
79
|
+
port: /\.bind\(\s*\([^)]*,\s*[1-9]\d{2,4}\s*\)|\bport\s*=\s*[1-9]\d{3,4}\b/,
|
|
80
|
+
clock: /\bdatetime\.(?:now|utcnow)\(|\bdate\.today\(|\btime\.time\(\)/,
|
|
81
|
+
'source-text': /inspect\.getsource\(|(?:open|Path)\(\s*['"][^'"]*\.(?:py|js|ts)['"]/,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
go: {
|
|
85
|
+
comment: '//',
|
|
86
|
+
fake: /clockwork|benbjohnson\/clock|synctest/,
|
|
87
|
+
markers: {
|
|
88
|
+
timer: /\btime\.(?:Sleep|After|NewTimer|NewTicker|Tick)\(/,
|
|
89
|
+
spawn: /\bexec\.Command(?:Context)?\(/,
|
|
90
|
+
port: /(?:net\.Listen|ListenAndServe)\(\s*(?:"tcp[46]?"\s*,\s*)?"[^"]*:[1-9]\d{2,4}"/,
|
|
91
|
+
clock: /\btime\.Now\(\)/,
|
|
92
|
+
'source-text': /os\.ReadFile\(\s*"[^"]*\.go"|parser\.ParseFile\(/,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
rust: {
|
|
96
|
+
comment: '//',
|
|
97
|
+
fake: /tokio::time::pause|start_paused/,
|
|
98
|
+
markers: {
|
|
99
|
+
timer: /\bsleep\(/,
|
|
100
|
+
spawn: /\b(?:std::)?process::Command\b|\bCommand::new\(/,
|
|
101
|
+
port: /\bbind\(\s*"[^"]*:[1-9]\d{2,4}"/,
|
|
102
|
+
clock: /\b(?:SystemTime|Instant|Utc|Local)::now\(\)/,
|
|
103
|
+
'source-text': /include_str!\([^)]*\.rs"|read_to_string\([^)]*\.rs"/,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// A reason naming a missing capability of the host (platform, privilege,
|
|
109
|
+
// tool, build) is a capability skip; anything else reads as a defect skip.
|
|
110
|
+
const CAPABILITY =
|
|
111
|
+
/\bonly\b|unavailable|unsupported|not (available|permitted|enforced|built|supported|configured|granted|installed)|requires?\b|needs?\b|missing|denied|refused|does not (support|grant|allow)|insensitive|not found|has no|not run on|\bno local\b|\bno display\b|\bposix\b|\bno [\w ]+ (available|configured|is configured|installed)|\bnot on (the )?path\b|\bno [\w-]+ on this (host|machine|platform|runner)|\(\s*(?:e\.g\.|i\.e\.),?\s*running as (?:root|administrator|an? \w+ user)\s*\)|\bskip(?:ped)? (?:when|if|as|under) running as (?:root|administrator|an? \w+ user)\b|\b(?:is|are) an? (?:windows|posix|linux|macos|unix)[- ](?:behaviou?r|feature|semantics)\b/i;
|
|
112
|
+
const TRACKED = /#\d+/;
|
|
113
|
+
const UNTIL = /until (\d{4}-\d{2}-\d{2})/;
|
|
114
|
+
|
|
115
|
+
export function laneOf(file) {
|
|
116
|
+
const tag = /\.(slow|live|electron|e2e|integration)\.(?:test|spec)\./.exec(file);
|
|
117
|
+
return tag ? tag[1] : 'fast';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function areaOf(rel) {
|
|
121
|
+
const dirs = rel.split(sep).join('/').split('/').slice(0, -1);
|
|
122
|
+
if (dirs[0] === 'src') dirs.shift();
|
|
123
|
+
return dirs.slice(0, 2).join('/') || '.';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Returns 'js' | 'python' | 'go' | 'rust' | 'rust?' (a .rs file whose text decides) | null.
|
|
127
|
+
function langOf(rel, name) {
|
|
128
|
+
if (JS_FILE.test(name) && !TYPES_FILE.test(name) && (JS_TEST.test(name) || `/${rel}`.includes('/__tests__/')))
|
|
129
|
+
return 'js';
|
|
130
|
+
if (/^test_.+\.py$|_test\.py$/.test(name)) return 'python';
|
|
131
|
+
if (name.endsWith('_test.go')) return 'go';
|
|
132
|
+
if (name.endsWith('.rs')) return `/${rel}`.includes('/tests/') ? 'rust' : 'rust?';
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Links are never followed: a dangling or looping link cannot break the walk.
|
|
137
|
+
function walk(root) {
|
|
138
|
+
const found = [];
|
|
139
|
+
let dirs = 0;
|
|
140
|
+
const visit = (dir, depth) => {
|
|
141
|
+
if (depth > MAX_DEPTH)
|
|
142
|
+
throw new Error(`directories nested deeper than ${MAX_DEPTH} under ${root}; narrow the root`);
|
|
143
|
+
if (++dirs > MAX_DIRS) throw new Error(`more than ${MAX_DIRS} directories under ${root}; narrow the root`);
|
|
144
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
145
|
+
const full = join(dir, entry.name);
|
|
146
|
+
if (entry.isDirectory()) {
|
|
147
|
+
if (!SKIP_DIRS.has(entry.name)) visit(full, depth + 1);
|
|
148
|
+
} else if (entry.isFile()) {
|
|
149
|
+
const rel = relative(root, full).split(sep).join('/');
|
|
150
|
+
const lang = langOf(rel, entry.name);
|
|
151
|
+
if (!lang) continue;
|
|
152
|
+
found.push({ full, rel, lang });
|
|
153
|
+
if (found.length > MAX_FILES)
|
|
154
|
+
throw new Error(`more than ${MAX_FILES} test files under ${root}; narrow the root`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
visit(root, 0);
|
|
159
|
+
return found;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function readHead(path) {
|
|
163
|
+
const fd = openSync(path, 'r');
|
|
164
|
+
try {
|
|
165
|
+
const buffer = Buffer.alloc(Math.min(statSync(path).size, MAX_BYTES));
|
|
166
|
+
const length = readSync(fd, buffer, 0, buffer.length, 0);
|
|
167
|
+
return buffer.toString('utf8', 0, length);
|
|
168
|
+
} finally {
|
|
169
|
+
closeSync(fd);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// The call's text from `from` to its closing parenthesis, across up to 6 lines.
|
|
174
|
+
function callText(lines, index, from) {
|
|
175
|
+
let text = lines[index].slice(from);
|
|
176
|
+
for (let next = index + 1; next < Math.min(lines.length, index + 6); next += 1) {
|
|
177
|
+
const open = (text.match(/\(/g) || []).length;
|
|
178
|
+
if (open > 0 && (text.match(/\)/g) || []).length >= open) break;
|
|
179
|
+
text += ` ${lines[next].trim()}`;
|
|
180
|
+
}
|
|
181
|
+
return text;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function skipSites(lines, lang) {
|
|
185
|
+
const sites = [];
|
|
186
|
+
lines.forEach((line, index) => {
|
|
187
|
+
const add = (reason, conditional) => sites.push({ index, reason, conditional });
|
|
188
|
+
if (lang === 'js') {
|
|
189
|
+
const reasons = [...line.matchAll(JS_SKIP_REASON)];
|
|
190
|
+
for (const match of reasons) add(match[2], false);
|
|
191
|
+
if (!reasons.length) {
|
|
192
|
+
if (JS_SKIP_IF.test(line)) add('', true);
|
|
193
|
+
else if (JS_SKIP_BARE.test(line)) add('', false);
|
|
194
|
+
}
|
|
195
|
+
} else if (lang === 'python') {
|
|
196
|
+
const match = PY_SKIP.exec(line);
|
|
197
|
+
if (!match || /^\s*#/.test(line)) return;
|
|
198
|
+
const conditional = PY_CONDITIONAL.has(match[1] || match[2] || match[3]);
|
|
199
|
+
const call = callText(lines, index, match.index);
|
|
200
|
+
const keyword = /\breason\s*=\s*(['"])((?:(?!\1).)*)\1/.exec(call);
|
|
201
|
+
const positional = conditional
|
|
202
|
+
? /,\s*(['"])((?:(?!\1).)*)\1\s*\)?\s*$/.exec(call)
|
|
203
|
+
: /\(\s*(['"])((?:(?!\1).)*)\1/.exec(call);
|
|
204
|
+
add((keyword || positional)?.[2] || '', conditional);
|
|
205
|
+
} else if (lang === 'go') {
|
|
206
|
+
const match = GO_SKIP.exec(line);
|
|
207
|
+
if (match && !/^\s*\/\//.test(line))
|
|
208
|
+
add(/(['"`])((?:(?!\1).)*)\1/.exec(line.slice(match.index))?.[2] || '', false);
|
|
209
|
+
} else {
|
|
210
|
+
const match = RUST_IGNORE.exec(line);
|
|
211
|
+
if (match) add(match[2] || '', false);
|
|
212
|
+
else if (RUST_CFG_IGNORE.test(line)) add('', true);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return sites;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function commentOf(line, token) {
|
|
219
|
+
const at = line.indexOf(token);
|
|
220
|
+
return at < 0 ? '' : line.slice(at + token.length).trim();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function classify(reason, today, conditional) {
|
|
224
|
+
const until = UNTIL.exec(reason)?.[1] || '';
|
|
225
|
+
if (until && until < today) return 'expired';
|
|
226
|
+
if (TRACKED.test(reason)) return 'tracked';
|
|
227
|
+
if (!reason.trim()) return conditional ? 'capability' : 'untracked';
|
|
228
|
+
return CAPABILITY.test(reason) ? 'capability' : 'untracked';
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function scanText(text, today, lang = 'js') {
|
|
232
|
+
const spec = LANGS[lang];
|
|
233
|
+
const fakeClock = spec.fake.test(text);
|
|
234
|
+
const markers = Object.entries(spec.markers)
|
|
235
|
+
.filter(([name, pattern]) => pattern.test(text) && !(fakeClock && (name === 'timer' || name === 'clock')))
|
|
236
|
+
.map(([name]) => name);
|
|
237
|
+
const lines = text.split(/\r?\n/);
|
|
238
|
+
const skips = skipSites(lines, lang).map(({ index, reason, conditional }) => {
|
|
239
|
+
const before =
|
|
240
|
+
index > 0 && lines[index - 1].trim().startsWith(spec.comment) ? commentOf(lines[index - 1], spec.comment) : '';
|
|
241
|
+
const note = [commentOf(lines[index], spec.comment), before].filter(Boolean).join(' ');
|
|
242
|
+
const full = [reason, note].filter(Boolean).join(' ');
|
|
243
|
+
return { line: index + 1, reason: reason || note, kind: classify(full, today, conditional) };
|
|
244
|
+
});
|
|
245
|
+
return { markers, skips };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function inventory(root, { today = new Date().toISOString().slice(0, 10) } = {}) {
|
|
249
|
+
if (!statSync(root, { throwIfNoEntry: false })?.isDirectory()) throw new Error(`not a directory: ${root}`);
|
|
250
|
+
const files = [];
|
|
251
|
+
for (const { full, rel, lang } of walk(root)) {
|
|
252
|
+
const text = readHead(full);
|
|
253
|
+
if (lang === 'rust?' && !RUST_TEST.test(text)) continue;
|
|
254
|
+
const language = lang === 'rust?' ? 'rust' : lang;
|
|
255
|
+
files.push({ file: rel, lang: language, lane: laneOf(rel), area: areaOf(rel), ...scanText(text, today, language) });
|
|
256
|
+
}
|
|
257
|
+
const areas = new Map();
|
|
258
|
+
for (const entry of files) {
|
|
259
|
+
const row = areas.get(entry.area) || {
|
|
260
|
+
area: entry.area,
|
|
261
|
+
files: 0,
|
|
262
|
+
fast: 0,
|
|
263
|
+
slow: 0,
|
|
264
|
+
other: 0,
|
|
265
|
+
langs: {},
|
|
266
|
+
markers: {},
|
|
267
|
+
skips: {},
|
|
268
|
+
};
|
|
269
|
+
row.files += 1;
|
|
270
|
+
if (entry.lane === 'fast') row.fast += 1;
|
|
271
|
+
else if (entry.lane === 'slow') row.slow += 1;
|
|
272
|
+
else row.other += 1;
|
|
273
|
+
row.langs[entry.lang] = (row.langs[entry.lang] || 0) + 1;
|
|
274
|
+
for (const marker of entry.markers) row.markers[marker] = (row.markers[marker] || 0) + 1;
|
|
275
|
+
for (const skip of entry.skips) row.skips[skip.kind] = (row.skips[skip.kind] || 0) + 1;
|
|
276
|
+
areas.set(entry.area, row);
|
|
277
|
+
}
|
|
278
|
+
const attention = files.flatMap((entry) =>
|
|
279
|
+
entry.skips.filter((skip) => skip.kind !== 'capability').map((skip) => ({ file: entry.file, ...skip }))
|
|
280
|
+
);
|
|
281
|
+
const fastRisk = files.filter(
|
|
282
|
+
(entry) => entry.lane === 'fast' && entry.markers.includes('timer') && entry.markers.includes('spawn')
|
|
283
|
+
);
|
|
284
|
+
return {
|
|
285
|
+
root,
|
|
286
|
+
today,
|
|
287
|
+
files: files.length,
|
|
288
|
+
areas: [...areas.values()].sort((a, b) => b.files - a.files || a.area.localeCompare(b.area)),
|
|
289
|
+
attentionTotal: attention.length,
|
|
290
|
+
attention: attention.slice(0, LIST_LIMIT),
|
|
291
|
+
fastRiskTotal: fastRisk.length,
|
|
292
|
+
fastRisk: fastRisk.slice(0, LIST_LIMIT).map((entry) => entry.file),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function markdown(report) {
|
|
297
|
+
const cell = (counts) =>
|
|
298
|
+
Object.entries(counts)
|
|
299
|
+
.map(([key, count]) => `${key} ${count}`)
|
|
300
|
+
.join(', ') || '-';
|
|
301
|
+
const more = (total, shown) => (total > shown ? [`- … ${total - shown} more (use --json)`] : []);
|
|
302
|
+
const out = [`# Test inventory: ${report.root}`, '', `${report.files} test files, ${report.today}.`, ''];
|
|
303
|
+
out.push('| Area | Files | Fast | Slow | Other | Languages | Markers | Skips |', '|---|---|---|---|---|---|---|---|');
|
|
304
|
+
for (const row of report.areas) {
|
|
305
|
+
out.push(
|
|
306
|
+
`| ${row.area} | ${row.files} | ${row.fast} | ${row.slow} | ${row.other} | ${cell(row.langs)} | ${cell(row.markers)} | ${cell(row.skips)} |`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
out.push('', `## Skips needing action (${report.attentionTotal})`, '');
|
|
310
|
+
for (const item of report.attention)
|
|
311
|
+
out.push(`- ${item.kind}: \`${item.file}:${item.line}\` — ${item.reason || '(no reason)'}`);
|
|
312
|
+
out.push(...more(report.attentionTotal, report.attention.length));
|
|
313
|
+
out.push('', `## Fast-lane files with timers and real processes (${report.fastRiskTotal})`, '');
|
|
314
|
+
for (const file of report.fastRisk) out.push(`- \`${file}\``);
|
|
315
|
+
out.push(...more(report.fastRiskTotal, report.fastRisk.length));
|
|
316
|
+
return out.join('\n');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
|
|
320
|
+
const args = process.argv.slice(2);
|
|
321
|
+
const json = args.includes('--json');
|
|
322
|
+
const unknown = args.find((arg) => arg.startsWith('--') && arg !== '--json');
|
|
323
|
+
const root = args.find((arg) => !arg.startsWith('--'));
|
|
324
|
+
if (!root || unknown) {
|
|
325
|
+
console.error(`${unknown ? `unknown option ${unknown}; ` : ''}usage: inventory.mjs <project-root> [--json]`);
|
|
326
|
+
process.exit(2);
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
const report = inventory(root);
|
|
330
|
+
console.log(json ? JSON.stringify(report, null, 2) : markdown(report));
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error(`inventory: ${error.message}`);
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
@@ -115,6 +115,10 @@ or radius are one option.
|
|
|
115
115
|
- Open a result once, when it is ready to look at, not at every intermediate
|
|
116
116
|
write. Long multi-step work shows the first reviewable state, then lets
|
|
117
117
|
reloads carry the rest.
|
|
118
|
+
- `open` shows the user a deliverable. To check your own work (`check`,
|
|
119
|
+
`inspect`, `capture`, `export`, before/after screenshots), `open` with
|
|
120
|
+
`verify: true`: the tab stays off the user's panel and chat and closes when
|
|
121
|
+
the turn ends. Opening the same target without it shows it.
|
|
118
122
|
- Decks and documents: the panel shows the converted pages; still run the
|
|
119
123
|
owning skill's own render review — the panel is for the user, not your QC.
|
|
120
124
|
- Close tabs that no longer match the conversation (a resolved choice, a
|
|
@@ -129,8 +133,8 @@ or radius are one option.
|
|
|
129
133
|
|
|
130
134
|
### Inline content or a file
|
|
131
135
|
- **Inline** (`open` with `input.content` — `mermaid`, `svg`, `chart` (an
|
|
132
|
-
ECharts option as JSON), `html`, `markdown`): diagrams, charts
|
|
133
|
-
sketches
|
|
136
|
+
ECharts option as JSON), `html`, `markdown`): diagrams, charts and quick
|
|
137
|
+
sketches you will not edit again; never a report of your own work. No file is written. `mermaid`,
|
|
134
138
|
`svg` and `markdown` are static, sanitized output (no scripts). `chart` is
|
|
135
139
|
interactive (tooltips, zoom) and `html` runs its scripts, as in-memory pages
|
|
136
140
|
held to the same rules as an HTML file: outside network is blocked, so an
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// The one usability check for an editable instruction file (an orchestration
|
|
2
|
+
// mode, an output style): the editor's state, the prompt builders and the save
|
|
3
|
+
// path all decide with it, so the settings page never shows text the prompt
|
|
4
|
+
// does not use. Required by the CJS rules builder and imported by the ESM runtime.
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
/** Largest instruction file read or written (the agent editor's 256 KB text limit). */
|
|
8
|
+
const INSTRUCTION_FILE_MAX_BYTES = 256 * 1024;
|
|
9
|
+
|
|
10
|
+
const utf8 = new TextDecoder('utf-8', { fatal: true });
|
|
11
|
+
|
|
12
|
+
/** Nothing but NUL bytes and whitespace — what a crash leaves of a file. */
|
|
13
|
+
function holdsNoData(buffer) {
|
|
14
|
+
for (const byte of buffer) {
|
|
15
|
+
if (byte !== 0 && byte !== 0x20 && byte !== 0x09 && byte !== 0x0a && byte !== 0x0d) return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The file's bytes → `{ text }` (decoded, BOM dropped, otherwise as written)
|
|
22
|
+
* or `{ problem }`: 'too-large', 'empty' (no data), 'not-text' (NUL bytes or
|
|
23
|
+
* invalid UTF-8).
|
|
24
|
+
*/
|
|
25
|
+
function decodeInstructionFile(buffer) {
|
|
26
|
+
if (buffer.length > INSTRUCTION_FILE_MAX_BYTES) return { problem: 'too-large' };
|
|
27
|
+
if (holdsNoData(buffer)) return { problem: 'empty' };
|
|
28
|
+
if (buffer.includes(0)) return { problem: 'not-text' };
|
|
29
|
+
try {
|
|
30
|
+
return { text: utf8.decode(buffer).replace(/^\uFEFF/, '') };
|
|
31
|
+
} catch {
|
|
32
|
+
return { problem: 'not-text' };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { INSTRUCTION_FILE_MAX_BYTES, decodeInstructionFile };
|