@gajae-code/coding-agent 0.14.2 → 0.15.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/CHANGELOG.md +120 -1
- package/dist/types/async/job-manager.d.ts +4 -1
- package/dist/types/autoresearch/dashboard.d.ts +29 -4
- package/dist/types/autoresearch/data-context.d.ts +25 -0
- package/dist/types/autoresearch/git.d.ts +65 -7
- package/dist/types/autoresearch/harness.d.ts +58 -0
- package/dist/types/autoresearch/prompts.d.ts +51 -0
- package/dist/types/autoresearch/runs.d.ts +173 -0
- package/dist/types/autoresearch/types.d.ts +9 -139
- package/dist/types/capability/types.d.ts +20 -0
- package/dist/types/cli/accounts-cli.d.ts +1 -0
- package/dist/types/commands/{rlm.d.ts → autoresearch.d.ts} +2 -4
- package/dist/types/config/autorouting-contract.d.ts +146 -0
- package/dist/types/config/autorouting-generator.d.ts +40 -0
- package/dist/types/config/autorouting-tier-map.d.ts +16844 -0
- package/dist/types/config/autorouting.d.ts +35 -0
- package/dist/types/config/model-discovery-manager.d.ts +8 -1
- package/dist/types/config/model-registry.d.ts +30 -1
- package/dist/types/config/provider-selection-policy.d.ts +23 -0
- package/dist/types/config/settings-schema.d.ts +61 -3
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/coordinator-mcp/durability.d.ts +29 -0
- package/dist/types/coordinator-mcp/event-webhook.d.ts +50 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +1 -1
- package/dist/types/coordinator-mcp/server.d.ts +14 -0
- package/dist/types/crash/index-store.d.ts +3 -0
- package/dist/types/crash/record-loader.d.ts +2 -0
- package/dist/types/crash/upstream/relay.d.ts +5 -3
- package/dist/types/cursor.d.ts +12 -0
- package/dist/types/defaults/gjc-defaults.d.ts +35 -1
- package/dist/types/defaults/gjc-skills.generated.d.ts +1 -1
- package/dist/types/discovery/helpers.d.ts +1 -1
- package/dist/types/edit/index.d.ts +2 -1
- package/dist/types/eval/py/executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/loader.d.ts +32 -0
- package/dist/types/extensibility/gjc-plugins/types.d.ts +1 -1
- package/dist/types/extensibility/skills.d.ts +2 -0
- package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +194 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/psmux-detect.d.ts +1 -1
- package/dist/types/gjc-runtime/python-transcript.d.ts +19 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +2 -8
- package/dist/types/gjc-runtime/session-layout.d.ts +6 -3
- package/dist/types/gjc-runtime/state-renderer.d.ts +0 -22
- package/dist/types/gjc-runtime/state-schema.d.ts +7 -7
- package/dist/types/gjc-runtime/tmux-common.d.ts +2 -2
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +38 -1
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -24
- package/dist/types/gjc-runtime/ultragoal-validation-policy.d.ts +73 -0
- package/dist/types/gjc-runtime/workflow-recovery-projection.d.ts +100 -0
- package/dist/types/hooks/skill-keywords.d.ts +1 -1
- package/dist/types/main.d.ts +0 -10
- package/dist/types/modes/acp/acp-agent.d.ts +13 -6
- package/dist/types/modes/components/model-selector.d.ts +14 -0
- package/dist/types/modes/components/skill-hud/render.d.ts +6 -1
- package/dist/types/modes/components/smart-routing-panel.d.ts +82 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +14 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/types.d.ts +9 -0
- package/dist/types/rlm/artifacts.d.ts +4 -4
- package/dist/types/runtime/optional-runtime-services.d.ts +2 -1
- package/dist/types/runtime/workspace-tree-service.d.ts +5 -1
- package/dist/types/runtime-mcp/config.d.ts +6 -0
- package/dist/types/runtime-mcp/manager.d.ts +10 -0
- package/dist/types/sdk/acp/adapter.d.ts +0 -4
- package/dist/types/sdk/broker/broker.d.ts +1 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +57 -2
- package/dist/types/sdk/broker/session-index.d.ts +15 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/index.d.ts +8 -0
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -2
- package/dist/types/sdk/client/client.d.ts +39 -4
- package/dist/types/sdk/host/host.d.ts +1 -0
- package/dist/types/sdk/host/internal-autorouting-state.d.ts +3 -0
- package/dist/types/sdk/host/model-pin.d.ts +29 -0
- package/dist/types/sdk/host/session-runtime.d.ts +2 -1
- package/dist/types/sdk/lifecycle-session.d.ts +13 -0
- package/dist/types/sdk/router/session-router.d.ts +27 -1
- package/dist/types/sdk/session.d.ts +11 -1
- package/dist/types/session/agent-session.d.ts +36 -6
- package/dist/types/session/artifacts.d.ts +16 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
- package/dist/types/session/session-manager.d.ts +84 -2
- package/dist/types/session/session-staging-paths.d.ts +3 -0
- package/dist/types/skill-state/canonical-skills.d.ts +1 -1
- package/dist/types/skill-state/workflow-hud.d.ts +12 -21
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +1 -0
- package/dist/types/slash-commands/helpers/autorouting-status.d.ts +8 -0
- package/dist/types/system-prompt.d.ts +23 -0
- package/dist/types/task/executor.d.ts +35 -4
- package/dist/types/task/index.d.ts +17 -3
- package/dist/types/task/receipt.d.ts +3 -1
- package/dist/types/task/types.d.ts +144 -0
- package/dist/types/tools/atomic-file-write.d.ts +72 -0
- package/dist/types/tools/descriptors.d.ts +1 -0
- package/dist/types/tools/index.d.ts +36 -1
- package/dist/types/tools/move-session.d.ts +40 -0
- package/dist/types/tools/python.d.ts +12 -0
- package/dist/types/tools/resource-gc.d.ts +0 -3
- package/dist/types/tools/search.d.ts +8 -1
- package/dist/types/tools/skill.d.ts +9 -4
- package/dist/types/tools/subagent.d.ts +33 -3
- package/dist/types/utils/xml-escape.d.ts +2 -0
- package/dist/types/workflow/workflow-intent-diff.d.ts +2 -2
- package/dist/types/workflow/workflow-intent-report-consumer.d.ts +1 -1
- package/package.json +11 -12
- package/scripts/build-sdk-package-smoke.ts +7 -5
- package/scripts/check-autorouting-tier-map.ts +183 -0
- package/scripts/generate-sdk-operation-inventory.ts +12 -0
- package/scripts/generate-tool-catalog.ts +40 -5
- package/src/async/job-manager.ts +5 -2
- package/src/autoresearch/dashboard.ts +134 -314
- package/src/autoresearch/data-context.ts +35 -0
- package/src/autoresearch/git.ts +186 -26
- package/src/autoresearch/{helpers.ts → harness.ts} +65 -40
- package/src/autoresearch/{prompt-setup.md → prompts/prompt-setup.md} +7 -7
- package/src/autoresearch/prompts/prompt.md +103 -0
- package/src/autoresearch/prompts.ts +126 -0
- package/src/autoresearch/runs.ts +708 -0
- package/src/autoresearch/types.ts +9 -150
- package/src/capability/index.ts +4 -4
- package/src/capability/types.ts +20 -0
- package/src/cli/accounts-cli.ts +21 -5
- package/src/cli/config-cli.ts +25 -1
- package/src/cli/fast-help.ts +1 -2
- package/src/cli/list-models.ts +5 -8
- package/src/cli/setup-cli.ts +8 -0
- package/src/cli.ts +2 -21
- package/src/commands/autoresearch.ts +33 -0
- package/src/commands/coordinator.ts +15 -0
- package/src/commands/launch.ts +2 -4
- package/src/commands/quick-lane.ts +1 -1
- package/src/commands/sdk.ts +24 -0
- package/src/commands/state.ts +1 -1
- package/src/config/autorouting-contract.ts +474 -0
- package/src/config/autorouting-generator.ts +238 -0
- package/src/config/autorouting-tier-map.ts +6108 -0
- package/src/config/autorouting.ts +120 -0
- package/src/config/model-discovery-manager.ts +42 -11
- package/src/config/model-registry.ts +348 -68
- package/src/config/provider-selection-policy.ts +60 -9
- package/src/config/settings-schema.ts +195 -6
- package/src/config/settings.ts +62 -1
- package/src/config.ts +2 -3
- package/src/coordinator/contract.ts +0 -1
- package/src/coordinator-mcp/codex-handoff.ts +68 -42
- package/src/coordinator-mcp/durability.ts +200 -0
- package/src/coordinator-mcp/event-webhook.ts +278 -0
- package/src/coordinator-mcp/question-state.ts +109 -46
- package/src/coordinator-mcp/server.ts +932 -504
- package/src/crash/index-store.ts +126 -22
- package/src/crash/record-loader.ts +7 -0
- package/src/crash/upstream/relay.ts +82 -34
- package/src/cursor.ts +84 -1
- package/src/debug/index.ts +26 -0
- package/src/defaults/gjc/skills/autoresearch/SKILL.md +116 -0
- package/src/defaults/gjc/skills/autoresearch/auto-critic.md +46 -0
- package/src/defaults/gjc/skills/autoresearch/auto-iterate.md +42 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +17 -37
- package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -18
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +6 -17
- package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +2 -2
- package/src/defaults/gjc-defaults.ts +89 -2
- package/src/defaults/gjc-skills.generated.ts +24 -17
- package/src/discovery/builtin.ts +18 -5
- package/src/discovery/helpers.ts +6 -6
- package/src/edit/index.ts +5 -2
- package/src/eval/py/executor.ts +8 -0
- package/src/extensibility/extensions/loader.ts +135 -13
- package/src/extensibility/extensions/wrapper.ts +1 -2
- package/src/extensibility/gjc-plugins/schema.ts +1 -1
- package/src/extensibility/runtime-skill-discovery.ts +2 -2
- package/src/extensibility/skill-management.ts +2 -3
- package/src/extensibility/skills.ts +16 -8
- package/src/gjc-runtime/autoresearch-runtime.ts +1509 -0
- package/src/gjc-runtime/gc-render.ts +0 -1
- package/src/gjc-runtime/gc-runtime.ts +1 -11
- package/src/gjc-runtime/launch-tmux.ts +3 -3
- package/src/gjc-runtime/psmux-detect.ts +2 -2
- package/src/gjc-runtime/python-transcript.ts +58 -0
- package/src/gjc-runtime/ralplan-runtime.ts +6 -18
- package/src/gjc-runtime/session-layout.ts +18 -7
- package/src/gjc-runtime/session-state-sidecar.ts +58 -9
- package/src/gjc-runtime/state-renderer.ts +0 -38
- package/src/gjc-runtime/state-runtime.ts +43 -22
- package/src/gjc-runtime/state-schema.ts +1 -1
- package/src/gjc-runtime/tmux-common.ts +7 -7
- package/src/gjc-runtime/ultragoal-change-set.ts +232 -11
- package/src/gjc-runtime/ultragoal-runtime.ts +309 -114
- package/src/gjc-runtime/ultragoal-validation-policy.ts +247 -0
- package/src/gjc-runtime/workflow-command-ref.ts +15 -11
- package/src/gjc-runtime/workflow-manifest.generated.json +413 -532
- package/src/gjc-runtime/workflow-manifest.ts +43 -83
- package/src/gjc-runtime/workflow-recovery-projection.ts +616 -0
- package/src/hooks/skill-keywords.ts +3 -3
- package/src/hooks/skill-state.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +26 -24
- package/src/lsp/index.ts +25 -5
- package/src/main.ts +2 -27
- package/src/modes/acp/acp-agent.ts +200 -75
- package/src/modes/components/model-selector.ts +216 -13
- package/src/modes/components/oauth-selector.ts +5 -5
- package/src/modes/components/skill-hud/render.ts +173 -35
- package/src/modes/components/smart-routing-panel.ts +531 -0
- package/src/modes/components/tool-status-header.ts +6 -3
- package/src/modes/controllers/command-controller.ts +17 -7
- package/src/modes/controllers/input-controller.ts +44 -9
- package/src/modes/controllers/runtime-mcp-command-controller.ts +4 -0
- package/src/modes/controllers/selector-controller.ts +298 -65
- package/src/modes/interactive-mode.ts +8 -1
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +1 -1
- package/src/modes/types.ts +9 -1
- package/src/prompts/agents/planner.md +1 -1
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/volatile-project-context.md +2 -1
- package/src/prompts/tools/move-session.md +15 -0
- package/src/prompts/tools/python.md +12 -0
- package/src/prompts/tools/skill-discovery.md +1 -1
- package/src/prompts/tools/skill.md +2 -2
- package/src/prompts/tools/task-summary.md +1 -0
- package/src/prompts/tools/task.md +6 -0
- package/src/rlm/artifacts.ts +12 -10
- package/src/runtime/optional-runtime-services.ts +3 -2
- package/src/runtime/workspace-tree-service.ts +11 -3
- package/src/runtime-mcp/config.ts +8 -1
- package/src/runtime-mcp/manager.ts +33 -0
- package/src/sdk/acp/adapter.ts +48 -1
- package/src/sdk/broker/broker.ts +30 -2
- package/src/sdk/broker/discovery.ts +217 -2
- package/src/sdk/broker/lifecycle.ts +385 -59
- package/src/sdk/broker/session-index.ts +243 -48
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +8 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +5 -0
- package/src/sdk/bus/index.ts +208 -11
- package/src/sdk/bus/kind-aware-reconciliation.ts +16 -0
- package/src/sdk/bus/reconciliation-store.ts +27 -5
- package/src/sdk/bus/telegram-daemon-contract.ts +12 -2
- package/src/sdk/client/client.ts +204 -22
- package/src/sdk/host/host.ts +16 -0
- package/src/sdk/host/internal-autorouting-state.ts +13 -0
- package/src/sdk/host/model-pin.ts +101 -0
- package/src/sdk/host/reverse-leases.ts +2 -1
- package/src/sdk/host/session-runtime.test.ts +224 -1
- package/src/sdk/host/session-runtime.ts +125 -37
- package/src/sdk/lifecycle/service.ts +3 -1
- package/src/sdk/lifecycle-session.ts +42 -1
- package/src/sdk/protocol/operation-inventory.generated.json +66 -0
- package/src/sdk/router/session-router.ts +375 -36
- package/src/sdk/session.ts +547 -47
- package/src/session/account-inventory.ts +1 -1
- package/src/session/agent-session.ts +765 -189
- package/src/session/artifacts.ts +234 -4
- package/src/session/internal/managed-session-storage.ts +91 -4
- package/src/session/provider-safety-stop-hint.ts +3 -2
- package/src/session/session-manager.ts +775 -16
- package/src/session/session-staging-paths.ts +8 -0
- package/src/setup/hermes/templates/operator-instructions.v1.md +0 -1
- package/src/setup/host-plugin-setup.ts +2 -2
- package/src/skill-state/active-state.ts +2 -2
- package/src/skill-state/canonical-skills.ts +1 -1
- package/src/skill-state/initial-phase.ts +1 -1
- package/src/skill-state/workflow-hud.ts +41 -41
- package/src/skill-state/workflow-mutation-guard.ts +26 -7
- package/src/slash-commands/builtin-registry.ts +77 -0
- package/src/slash-commands/helpers/autorouting-status.ts +55 -0
- package/src/system-prompt.ts +102 -5
- package/src/task/discovery.ts +2 -3
- package/src/task/executor.ts +617 -43
- package/src/task/index.ts +262 -15
- package/src/task/receipt.ts +30 -0
- package/src/task/render.ts +11 -1
- package/src/task/types.ts +316 -0
- package/src/tools/atomic-file-write.ts +594 -0
- package/src/tools/bisect.ts +3 -2
- package/src/tools/descriptors.test.ts +3 -0
- package/src/tools/descriptors.ts +24 -0
- package/src/tools/image-gen.ts +5 -1
- package/src/tools/index.ts +62 -5
- package/src/tools/move-session.ts +107 -0
- package/src/tools/python.ts +205 -0
- package/src/tools/read.ts +88 -15
- package/src/tools/renderers.ts +2 -0
- package/src/tools/resource-gc.ts +8 -177
- package/src/tools/search.ts +30 -6
- package/src/tools/skill-discovery.ts +1 -0
- package/src/tools/skill.ts +37 -7
- package/src/tools/subagent-render.ts +119 -13
- package/src/tools/subagent.ts +91 -74
- package/src/tools/tool-catalog.generated.ts +64 -2
- package/src/tools/write.ts +16 -12
- package/src/utils/xml-escape.ts +14 -0
- package/src/web/search/providers/codex.ts +2 -2
- package/src/workflow/workflow-intent-diff.ts +13 -12
- package/src/workflow/workflow-intent-report-consumer.ts +6 -6
- package/dist/types/autoresearch/helpers.d.ts +0 -24
- package/dist/types/autoresearch/index.d.ts +0 -2
- package/dist/types/autoresearch/state.d.ts +0 -17
- package/dist/types/autoresearch/storage.d.ts +0 -142
- package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
- package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
- package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
- package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
- package/dist/types/commands/team.d.ts +0 -24
- package/dist/types/gjc-runtime/team-gc.d.ts +0 -7
- package/dist/types/gjc-runtime/team-launch.d.ts +0 -61
- package/dist/types/gjc-runtime/team-notify.d.ts +0 -45
- package/dist/types/gjc-runtime/team-runtime.d.ts +0 -336
- package/dist/types/gjc-runtime/team-store.d.ts +0 -168
- package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +0 -43
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +0 -92
- package/dist/types/gjc-runtime/team-workers.d.ts +0 -83
- package/dist/types/rlm/index.d.ts +0 -47
- package/dist/types/rlm/preset.d.ts +0 -23
- package/dist/types/rlm/python-tool.d.ts +0 -16
- package/src/autoresearch/command-resume.md +0 -14
- package/src/autoresearch/index.ts +0 -536
- package/src/autoresearch/prompt.md +0 -103
- package/src/autoresearch/resume-message.md +0 -10
- package/src/autoresearch/state.ts +0 -273
- package/src/autoresearch/storage.ts +0 -699
- package/src/autoresearch/tools/init-experiment.ts +0 -272
- package/src/autoresearch/tools/log-experiment.ts +0 -524
- package/src/autoresearch/tools/run-experiment.ts +0 -475
- package/src/autoresearch/tools/update-notes.ts +0 -109
- package/src/commands/rlm.ts +0 -19
- package/src/commands/team.ts +0 -238
- package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +0 -42
- package/src/defaults/gjc/skills/team/SKILL.md +0 -467
- package/src/gjc-runtime/team-gc.ts +0 -49
- package/src/gjc-runtime/team-launch.ts +0 -404
- package/src/gjc-runtime/team-notify.ts +0 -326
- package/src/gjc-runtime/team-runtime.ts +0 -5923
- package/src/gjc-runtime/team-store.ts +0 -878
- package/src/gjc-runtime/team-worker-heartbeat.ts +0 -149
- package/src/gjc-runtime/team-worker-memory-guard.ts +0 -363
- package/src/gjc-runtime/team-workers.ts +0 -1123
- package/src/prompts/system/rlm-report-command.md +0 -1
- package/src/prompts/system/rlm-research.md +0 -23
- package/src/rlm/index.ts +0 -365
- package/src/rlm/preset.ts +0 -76
- package/src/rlm/python-tool.ts +0 -68
|
@@ -1,273 +1,138 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Autoresearch TUI dashboard (ported from the deleted extension's
|
|
3
|
+
* `dashboard.ts`): run table plus collapsed/expanded rendering.
|
|
4
|
+
*
|
|
5
|
+
* The extension version rendered through TUI widget/overlay machinery with
|
|
6
|
+
* theme colors; this rebuild renders the same content as sanitized plain text
|
|
7
|
+
* lines (every string passes through `replaceTabs` and `truncateToWidth` like
|
|
8
|
+
* the other renderers) so it can be shown in any text surface.
|
|
9
|
+
*/
|
|
10
|
+
import { replaceTabs, truncateToWidth } from "@gajae-code/tui";
|
|
11
|
+
import { formatElapsed, formatNum, isBetter } from "./harness";
|
|
12
|
+
import {
|
|
13
|
+
type AutoresearchExperimentResult,
|
|
14
|
+
type AutoresearchExperimentState,
|
|
15
|
+
findBaselineMetric,
|
|
16
|
+
findBaselineRunNumber,
|
|
17
|
+
findBaselineSecondary,
|
|
18
|
+
} from "./runs";
|
|
6
19
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const stopSpinner = (): void => {
|
|
17
|
-
if (!spinnerTimer) return;
|
|
18
|
-
clearInterval(spinnerTimer);
|
|
19
|
-
spinnerTimer = undefined;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const syncSpinner = (runtime: AutoresearchRuntime): void => {
|
|
23
|
-
if (!overlayTui || !runtime.runningExperiment) {
|
|
24
|
-
stopSpinner();
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (spinnerTimer) return;
|
|
28
|
-
spinnerTimer = setInterval(() => {
|
|
29
|
-
if (!runtime.runningExperiment) {
|
|
30
|
-
stopSpinner();
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
spinnerFrame += 1;
|
|
34
|
-
requestRender();
|
|
35
|
-
}, 80);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const clear = (): void => {
|
|
39
|
-
overlayTui = null;
|
|
40
|
-
stopSpinner();
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
clear(ctx): void {
|
|
45
|
-
clear();
|
|
46
|
-
if (ctx.hasUI) {
|
|
47
|
-
ctx.ui.setWidget("autoresearch", undefined);
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
requestRender,
|
|
51
|
-
updateWidget(ctx, runtime): void {
|
|
52
|
-
if (!ctx.hasUI) return;
|
|
53
|
-
syncSpinner(runtime);
|
|
54
|
-
const state = runtime.state;
|
|
55
|
-
if (!shouldShowDashboard(runtime, state)) {
|
|
56
|
-
ctx.ui.setWidget("autoresearch", undefined);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
ctx.ui.setWidget("autoresearch", (_tui, theme) => {
|
|
61
|
-
if (state.results.length === 0 && runtime.runningExperiment) {
|
|
62
|
-
return new Text(renderRunningOnly(runtime, state, theme), 0, 0);
|
|
63
|
-
}
|
|
64
|
-
if (runtime.dashboardExpanded) {
|
|
65
|
-
const width = process.stdout.columns ?? 120;
|
|
66
|
-
const lines = [
|
|
67
|
-
renderExpandedHeader(runtime, width, theme),
|
|
68
|
-
...renderDashboardLines(runtime, width, theme, 8),
|
|
69
|
-
];
|
|
70
|
-
return new Text(lines.join("\n"), 0, 0);
|
|
71
|
-
}
|
|
72
|
-
return new Text(renderCollapsedLine(runtime, state, theme), 0, 0);
|
|
73
|
-
});
|
|
74
|
-
},
|
|
75
|
-
async showOverlay(ctx, runtime): Promise<void> {
|
|
76
|
-
if (!ctx.hasUI || !shouldShowDashboard(runtime, runtime.state)) return;
|
|
77
|
-
await ctx.ui.custom<void>(
|
|
78
|
-
(tui, theme, _keybindings, done) => {
|
|
79
|
-
overlayTui = tui;
|
|
80
|
-
syncSpinner(runtime);
|
|
81
|
-
|
|
82
|
-
let scrollOffset = 0;
|
|
83
|
-
return {
|
|
84
|
-
render(width: number): string[] {
|
|
85
|
-
const terminalRows = process.stdout.rows ?? 40;
|
|
86
|
-
const header = renderExpandedHeader(runtime, width, theme);
|
|
87
|
-
const body = renderDashboardLines(runtime, width, theme, 0);
|
|
88
|
-
if (runtime.runningExperiment) {
|
|
89
|
-
body.push(renderOverlayRunningLine(runtime, theme, width, spinnerFrame));
|
|
90
|
-
}
|
|
91
|
-
const viewportRows = Math.max(4, terminalRows - 4);
|
|
92
|
-
const maxScroll = Math.max(0, body.length - viewportRows);
|
|
93
|
-
if (scrollOffset > maxScroll) scrollOffset = maxScroll;
|
|
94
|
-
const visible = body.slice(scrollOffset, scrollOffset + viewportRows);
|
|
95
|
-
const footer = renderOverlayFooter(width, scrollOffset, viewportRows, body.length, theme);
|
|
96
|
-
return [
|
|
97
|
-
header,
|
|
98
|
-
...visible,
|
|
99
|
-
...Array.from({ length: Math.max(0, viewportRows - visible.length) }, () => ""),
|
|
100
|
-
footer,
|
|
101
|
-
];
|
|
102
|
-
},
|
|
103
|
-
handleInput(data: string): void {
|
|
104
|
-
const totalRows =
|
|
105
|
-
renderDashboardLines(runtime, process.stdout.columns ?? 120, theme, 0).length +
|
|
106
|
-
(runtime.runningExperiment ? 1 : 0);
|
|
107
|
-
const viewportRows = Math.max(4, (process.stdout.rows ?? 40) - 4);
|
|
108
|
-
const maxScroll = Math.max(0, totalRows - viewportRows);
|
|
109
|
-
if (matchesKey(data, "escape") || matchesKey(data, "esc") || data === "q") {
|
|
110
|
-
done(undefined);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (matchesKey(data, "up") || data === "k") {
|
|
114
|
-
scrollOffset = Math.max(0, scrollOffset - 1);
|
|
115
|
-
} else if (matchesKey(data, "down") || data === "j") {
|
|
116
|
-
scrollOffset = Math.min(maxScroll, scrollOffset + 1);
|
|
117
|
-
} else if (matchesKey(data, "pageUp")) {
|
|
118
|
-
scrollOffset = Math.max(0, scrollOffset - viewportRows);
|
|
119
|
-
} else if (matchesKey(data, "pageDown")) {
|
|
120
|
-
scrollOffset = Math.min(maxScroll, scrollOffset + viewportRows);
|
|
121
|
-
} else if (data === "g") {
|
|
122
|
-
scrollOffset = 0;
|
|
123
|
-
} else if (data === "G") {
|
|
124
|
-
scrollOffset = maxScroll;
|
|
125
|
-
}
|
|
126
|
-
tui.requestLayoutRender("autoresearch-overlay-input");
|
|
127
|
-
},
|
|
128
|
-
invalidate(): void {},
|
|
129
|
-
dispose(): void {
|
|
130
|
-
clear();
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
},
|
|
134
|
-
{ overlay: true },
|
|
135
|
-
);
|
|
136
|
-
},
|
|
137
|
-
};
|
|
20
|
+
export interface AutoresearchDashboardRuntime {
|
|
21
|
+
modeOn: boolean;
|
|
22
|
+
running?: { command: string; startedAt: number } | null;
|
|
23
|
+
pendingRun?: {
|
|
24
|
+
runNumber: number;
|
|
25
|
+
passed: boolean;
|
|
26
|
+
parsedPrimary: number | null;
|
|
27
|
+
} | null;
|
|
138
28
|
}
|
|
139
29
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
parts.push(theme.fg("dim", ` | ${replaceTabs(state.name)}`));
|
|
144
|
-
}
|
|
145
|
-
if (runtime.runningExperiment) {
|
|
146
|
-
parts.push(theme.fg("dim", ` | ${replaceTabs(runtime.runningExperiment.command)}`));
|
|
147
|
-
}
|
|
148
|
-
return parts.join("");
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function shouldShowDashboard(runtime: AutoresearchRuntime, state: ExperimentState): boolean {
|
|
152
|
-
return (
|
|
153
|
-
runtime.autoresearchMode ||
|
|
154
|
-
state.results.length > 0 ||
|
|
155
|
-
runtime.runningExperiment !== null ||
|
|
156
|
-
runtime.lastRunSummary !== null
|
|
157
|
-
);
|
|
30
|
+
export interface AutoresearchDashboardInput {
|
|
31
|
+
state: AutoresearchExperimentState;
|
|
32
|
+
runtime?: AutoresearchDashboardRuntime;
|
|
158
33
|
}
|
|
159
34
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
const fillWidth = Math.max(0, width - visibleWidth(label) - visibleWidth(hint));
|
|
166
|
-
return truncateToWidth(theme.fg("accent", label) + theme.fg("borderMuted", "-".repeat(fillWidth)) + hint, width);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function renderCollapsedLine(runtime: AutoresearchRuntime, state: ExperimentState, theme: Theme): string {
|
|
170
|
-
if (runtime.lastRunSummary) {
|
|
35
|
+
/** Collapsed one-line summary. */
|
|
36
|
+
export function renderCollapsedLine(input: AutoresearchDashboardInput, width = 120): string {
|
|
37
|
+
const state = input.state;
|
|
38
|
+
const runtime = input.runtime ?? { modeOn: true };
|
|
39
|
+
if (runtime.pendingRun) {
|
|
171
40
|
const parts = [
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
41
|
+
"autoresearch",
|
|
42
|
+
` pending run #${runtime.pendingRun.runNumber}`,
|
|
43
|
+
runtime.pendingRun.passed ? " pass" : " fail",
|
|
175
44
|
];
|
|
176
|
-
if (runtime.
|
|
177
|
-
parts.push(
|
|
178
|
-
theme.fg(
|
|
179
|
-
"muted",
|
|
180
|
-
` | ${state.metricName}=${formatNum(runtime.lastRunSummary.parsedPrimary, state.metricUnit)}`,
|
|
181
|
-
),
|
|
182
|
-
);
|
|
45
|
+
if (runtime.pendingRun.parsedPrimary !== null) {
|
|
46
|
+
parts.push(` | ${state.metricName}=${formatNum(runtime.pendingRun.parsedPrimary, state.metricUnit)}`);
|
|
183
47
|
}
|
|
184
|
-
parts.push(
|
|
185
|
-
if (!runtime.
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
return parts.join("");
|
|
48
|
+
parts.push(" | log required");
|
|
49
|
+
if (!runtime.modeOn) parts.push(" | mode off");
|
|
50
|
+
return truncateToWidth(replaceTabs(parts.join("")), width);
|
|
189
51
|
}
|
|
190
52
|
if (state.results.length === 0) {
|
|
191
|
-
const modeStatus = runtime.
|
|
192
|
-
const parts = [
|
|
193
|
-
if (state.name) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (runtime.autoresearchMode) {
|
|
197
|
-
parts.push(theme.fg("dim", " | run the baseline"));
|
|
198
|
-
}
|
|
199
|
-
return parts.join("");
|
|
53
|
+
const modeStatus = runtime.modeOn ? "baseline pending" : "mode off";
|
|
54
|
+
const parts = ["autoresearch", ` ${modeStatus}`];
|
|
55
|
+
if (state.name) parts.push(` | ${replaceTabs(state.name)}`);
|
|
56
|
+
if (runtime.modeOn) parts.push(" | run the baseline");
|
|
57
|
+
return truncateToWidth(replaceTabs(parts.join("")), width);
|
|
200
58
|
}
|
|
201
|
-
const current =
|
|
59
|
+
const current = state.results.filter(result => result.segment === state.currentSegment);
|
|
202
60
|
const kept = current.filter(result => result.status === "keep").length;
|
|
203
61
|
const crashed = current.filter(result => result.status === "crash").length;
|
|
204
62
|
const checksFailed = current.filter(result => result.status === "checks_failed").length;
|
|
205
63
|
const best = findBestResult(state);
|
|
206
64
|
const archivedRuns = Math.max(0, state.results.length - current.length);
|
|
207
|
-
const parts = [
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
parts.push(theme.fg("dim", " | "));
|
|
216
|
-
if (best && state.bestMetric !== null && best.result.metric !== state.bestMetric) {
|
|
217
|
-
parts.push(theme.fg("warning", `best ${formatNum(best.result.metric, state.metricUnit)}`));
|
|
218
|
-
parts.push(theme.fg("dim", ` baseline ${formatNum(state.bestMetric, state.metricUnit)}`));
|
|
65
|
+
const parts = ["autoresearch", ` ${current.length} runs`, ` ${kept} kept`];
|
|
66
|
+
if (archivedRuns > 0) parts.push(` +${archivedRuns} archived`);
|
|
67
|
+
if (crashed > 0) parts.push(` ${crashed} crash`);
|
|
68
|
+
if (checksFailed > 0) parts.push(` ${checksFailed} checks_failed`);
|
|
69
|
+
parts.push(" | ");
|
|
70
|
+
if (best && state.bestMetric !== null && best.metric !== state.bestMetric) {
|
|
71
|
+
parts.push(`best ${formatNum(best.metric, state.metricUnit)}`);
|
|
72
|
+
parts.push(` baseline ${formatNum(state.bestMetric, state.metricUnit)}`);
|
|
219
73
|
} else if (state.bestMetric !== null) {
|
|
220
|
-
parts.push(
|
|
74
|
+
parts.push(`baseline ${formatNum(state.bestMetric, state.metricUnit)}`);
|
|
221
75
|
} else {
|
|
222
|
-
parts.push(
|
|
76
|
+
parts.push("no kept runs yet");
|
|
223
77
|
}
|
|
224
78
|
if (state.confidence !== null) {
|
|
225
|
-
|
|
226
|
-
parts.push(
|
|
227
|
-
parts.push(theme.fg(confidenceColor, `conf ${state.confidence.toFixed(1)}x`));
|
|
79
|
+
parts.push(" | ");
|
|
80
|
+
parts.push(`conf ${state.confidence.toFixed(1)}x`);
|
|
228
81
|
}
|
|
229
|
-
if (runtime.
|
|
230
|
-
parts.push(
|
|
231
|
-
} else if (!runtime.
|
|
232
|
-
parts.push(
|
|
82
|
+
if (runtime.running) {
|
|
83
|
+
parts.push(` | running ${formatElapsed(Date.now() - runtime.running.startedAt)}`);
|
|
84
|
+
} else if (!runtime.modeOn) {
|
|
85
|
+
parts.push(" | mode off");
|
|
233
86
|
}
|
|
234
|
-
parts.push(
|
|
235
|
-
return parts.join("");
|
|
87
|
+
parts.push(" | ctrl+x expand");
|
|
88
|
+
return truncateToWidth(replaceTabs(parts.join("")), width);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Expanded header line. */
|
|
92
|
+
export function renderExpandedHeader(input: AutoresearchDashboardInput, width = 120): string {
|
|
93
|
+
const state = input.state;
|
|
94
|
+
const label = state.name ? ` autoresearch: ${replaceTabs(state.name)} ` : " autoresearch ";
|
|
95
|
+
const hint = " ctrl+x collapse ctrl+shift+x overlay ";
|
|
96
|
+
const fillWidth = Math.max(0, width - label.length - hint.length);
|
|
97
|
+
return truncateToWidth(`${label}${"-".repeat(fillWidth)}${hint}`, width);
|
|
236
98
|
}
|
|
237
99
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
): string[] {
|
|
244
|
-
const state =
|
|
100
|
+
/**
|
|
101
|
+
* Expanded dashboard body: segment summary, baseline/best lines, then the run
|
|
102
|
+
* table. `maxRows > 0` keeps only the last `maxRows` rows of the current
|
|
103
|
+
* segment (with an ellipsis for hidden earlier runs); `0` shows all.
|
|
104
|
+
*/
|
|
105
|
+
export function renderDashboardLines(input: AutoresearchDashboardInput, width = 120, maxRows = 0): string[] {
|
|
106
|
+
const state = input.state;
|
|
107
|
+
const runtime = input.runtime ?? { modeOn: true };
|
|
245
108
|
if (state.results.length === 0) {
|
|
246
|
-
if (runtime.
|
|
109
|
+
if (runtime.pendingRun) {
|
|
247
110
|
const lines = [
|
|
248
|
-
truncateToWidth(`Pending run: #${runtime.
|
|
111
|
+
truncateToWidth(`Pending run: #${runtime.pendingRun.runNumber}`, width),
|
|
249
112
|
truncateToWidth(
|
|
250
|
-
`Result: ${runtime.
|
|
113
|
+
`Result: ${runtime.pendingRun.passed ? "passed" : "failed"}${
|
|
114
|
+
runtime.pendingRun.parsedPrimary !== null
|
|
115
|
+
? ` ${state.metricName} ${formatNum(runtime.pendingRun.parsedPrimary, state.metricUnit)}`
|
|
116
|
+
: ""
|
|
117
|
+
}`,
|
|
251
118
|
width,
|
|
252
119
|
),
|
|
253
|
-
truncateToWidth("Next action:
|
|
120
|
+
truncateToWidth("Next action: log the run before starting another benchmark.", width),
|
|
254
121
|
];
|
|
255
|
-
if (!runtime.
|
|
256
|
-
lines.push(truncateToWidth("Mode: off", width));
|
|
257
|
-
}
|
|
122
|
+
if (!runtime.modeOn) lines.push(truncateToWidth("Mode: off", width));
|
|
258
123
|
return lines;
|
|
259
124
|
}
|
|
260
|
-
if (runtime.
|
|
125
|
+
if (runtime.modeOn) {
|
|
261
126
|
return [
|
|
262
127
|
truncateToWidth("Current segment: 0 runs", width),
|
|
263
128
|
truncateToWidth("Baseline: pending", width),
|
|
264
129
|
truncateToWidth("Next action: run and log the baseline experiment.", width),
|
|
265
130
|
];
|
|
266
131
|
}
|
|
267
|
-
return [
|
|
132
|
+
return ["No experiments logged yet."];
|
|
268
133
|
}
|
|
269
134
|
|
|
270
|
-
const current =
|
|
135
|
+
const current = state.results.filter(result => result.segment === state.currentSegment);
|
|
271
136
|
const kept = current.filter(result => result.status === "keep").length;
|
|
272
137
|
const discarded = current.filter(result => result.status === "discard").length;
|
|
273
138
|
const crashed = current.filter(result => result.status === "crash").length;
|
|
@@ -291,22 +156,21 @@ export function renderDashboardLines(
|
|
|
291
156
|
truncateToWidth(`Archived from earlier segments: ${state.results.length - current.length} runs`, width),
|
|
292
157
|
);
|
|
293
158
|
}
|
|
294
|
-
if (runtime.
|
|
159
|
+
if (runtime.pendingRun) {
|
|
295
160
|
lines.push(
|
|
296
161
|
truncateToWidth(
|
|
297
|
-
`Pending run: #${runtime.
|
|
162
|
+
`Pending run: #${runtime.pendingRun.runNumber} (${runtime.pendingRun.passed ? "passed" : "failed"}) — log required`,
|
|
298
163
|
width,
|
|
299
164
|
),
|
|
300
165
|
);
|
|
301
166
|
}
|
|
302
|
-
if (!runtime.
|
|
303
|
-
lines.push(truncateToWidth(
|
|
167
|
+
if (!runtime.modeOn) {
|
|
168
|
+
lines.push(truncateToWidth("Mode: off", width));
|
|
304
169
|
}
|
|
305
170
|
if (best) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const delta = ((best.result.metric - baseline) / baseline) * 100;
|
|
171
|
+
let progress = `Best: ${formatNum(best.metric, state.metricUnit)} (#${best.runNumber})`;
|
|
172
|
+
if (baseline !== null && baseline !== 0 && best.metric !== null && best.metric !== baseline) {
|
|
173
|
+
const delta = ((best.metric - baseline) / baseline) * 100;
|
|
310
174
|
const sign = delta > 0 ? "+" : "";
|
|
311
175
|
progress += ` ${sign}${delta.toFixed(1)}%`;
|
|
312
176
|
}
|
|
@@ -319,7 +183,7 @@ export function renderDashboardLines(
|
|
|
319
183
|
.map(metric =>
|
|
320
184
|
renderSecondarySummary(
|
|
321
185
|
metric.name,
|
|
322
|
-
best.
|
|
186
|
+
best.metrics[metric.name],
|
|
323
187
|
baselineSecondary[metric.name],
|
|
324
188
|
metric.unit,
|
|
325
189
|
),
|
|
@@ -331,35 +195,36 @@ export function renderDashboardLines(
|
|
|
331
195
|
}
|
|
332
196
|
}
|
|
333
197
|
lines.push("");
|
|
334
|
-
lines.push(renderTableHeader(state, width
|
|
335
|
-
lines.push(
|
|
198
|
+
lines.push(truncateToWidth(renderTableHeader(state), width));
|
|
199
|
+
lines.push(truncateToWidth("-".repeat(Math.max(0, width - 1)), width));
|
|
336
200
|
|
|
337
201
|
const visible = maxRows > 0 ? current.slice(-maxRows) : current;
|
|
338
202
|
if (visible.length < current.length) {
|
|
339
|
-
lines.push(
|
|
203
|
+
lines.push(`... ${current.length - visible.length} earlier runs hidden ...`);
|
|
340
204
|
}
|
|
341
205
|
for (const result of visible) {
|
|
342
|
-
lines.push(renderResultRow(result, state, baselineSecondary, width
|
|
206
|
+
lines.push(truncateToWidth(renderResultRow(result, state, baselineSecondary), width));
|
|
343
207
|
}
|
|
344
|
-
return lines;
|
|
208
|
+
return lines.map(line => replaceTabs(line));
|
|
345
209
|
}
|
|
346
210
|
|
|
347
|
-
|
|
211
|
+
/** The full expanded dashboard (header + body). */
|
|
212
|
+
export function renderExpandedDashboard(input: AutoresearchDashboardInput, width = 120, maxRows = 0): string {
|
|
213
|
+
return [renderExpandedHeader(input, width), ...renderDashboardLines(input, width, maxRows)].join("\n");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function renderTableHeader(state: AutoresearchExperimentState): string {
|
|
348
217
|
const secondaryHeader = state.secondaryMetrics.map(metric => truncateToWidth(metric.name, 10)).join(" ");
|
|
349
|
-
return
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
);
|
|
218
|
+
return `${"#".padEnd(4)}${"commit".padEnd(10)}${state.metricName.padEnd(12)}${
|
|
219
|
+
secondaryHeader ? `${secondaryHeader} ` : ""
|
|
220
|
+
}${"status".padEnd(14)}description`;
|
|
353
221
|
}
|
|
354
222
|
|
|
355
223
|
function renderResultRow(
|
|
356
|
-
result:
|
|
357
|
-
state:
|
|
224
|
+
result: AutoresearchExperimentResult,
|
|
225
|
+
state: AutoresearchExperimentState,
|
|
358
226
|
baselineSecondary: { [key: string]: number },
|
|
359
|
-
width: number,
|
|
360
|
-
theme: Theme,
|
|
361
227
|
): string {
|
|
362
|
-
const runNumber = result.runNumber ?? state.results.indexOf(result) + 1;
|
|
363
228
|
const secondary = state.secondaryMetrics
|
|
364
229
|
.map(metric =>
|
|
365
230
|
truncateToWidth(
|
|
@@ -368,15 +233,14 @@ function renderResultRow(
|
|
|
368
233
|
).padEnd(11),
|
|
369
234
|
)
|
|
370
235
|
.join("");
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
`${
|
|
374
|
-
`${
|
|
375
|
-
`${theme.fg(statusColor, formatNum(result.metric, state.metricUnit).padEnd(12))}` +
|
|
236
|
+
return (
|
|
237
|
+
`${String(result.runNumber).padEnd(4)}` +
|
|
238
|
+
`${(result.commit || "-").padEnd(10)}` +
|
|
239
|
+
`${formatNum(result.metric, state.metricUnit).padEnd(12)}` +
|
|
376
240
|
`${secondary}` +
|
|
377
|
-
`${
|
|
378
|
-
`${
|
|
379
|
-
|
|
241
|
+
`${result.status.padEnd(14)}` +
|
|
242
|
+
`${replaceTabs(result.description)}`
|
|
243
|
+
);
|
|
380
244
|
}
|
|
381
245
|
|
|
382
246
|
function renderSecondaryCell(value: number | undefined, unit: string, baseline: number | undefined): string {
|
|
@@ -403,58 +267,14 @@ function renderSecondarySummary(
|
|
|
403
267
|
return `${name} ${formatNum(value, unit)} ${sign}${delta.toFixed(1)}%`;
|
|
404
268
|
}
|
|
405
269
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
theme.fg(
|
|
415
|
-
"warning",
|
|
416
|
-
`${spinner} running ${formatElapsed(Date.now() - (runtime.runningExperiment?.startedAt ?? Date.now()))} ${replaceTabs(
|
|
417
|
-
runtime.runningExperiment?.command ?? "",
|
|
418
|
-
)}`,
|
|
419
|
-
),
|
|
420
|
-
width,
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
function renderOverlayFooter(
|
|
425
|
-
width: number,
|
|
426
|
-
scrollOffset: number,
|
|
427
|
-
viewportRows: number,
|
|
428
|
-
totalRows: number,
|
|
429
|
-
theme: Theme,
|
|
430
|
-
): string {
|
|
431
|
-
const position =
|
|
432
|
-
totalRows > viewportRows
|
|
433
|
-
? ` ${scrollOffset + 1}-${Math.min(totalRows, scrollOffset + viewportRows)}/${totalRows}`
|
|
434
|
-
: "";
|
|
435
|
-
const hint = theme.fg("dim", ` up/down j/k pageup pagedown g G esc${position} `);
|
|
436
|
-
const fill = Math.max(0, width - visibleWidth(hint));
|
|
437
|
-
return theme.fg("borderMuted", "-".repeat(fill)) + hint;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function renderModeStatus(runtime: AutoresearchRuntime, state: ExperimentState): string {
|
|
441
|
-
if (runtime.autoresearchMode) {
|
|
442
|
-
return state.results.length === 0 ? "baseline pending" : "mode on";
|
|
443
|
-
}
|
|
444
|
-
const current = currentResults(state.results, state.currentSegment);
|
|
445
|
-
if (state.maxExperiments !== null && current.length >= state.maxExperiments) {
|
|
446
|
-
return "segment complete";
|
|
447
|
-
}
|
|
448
|
-
return "mode off";
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
function findBestResult(state: ExperimentState): { index: number; result: ExperimentResult } | null {
|
|
452
|
-
let best: { index: number; result: ExperimentResult } | null = null;
|
|
453
|
-
for (let index = 0; index < state.results.length; index += 1) {
|
|
454
|
-
const result = state.results[index];
|
|
455
|
-
if (result.segment !== state.currentSegment || result.status !== "keep" || result.metric <= 0) continue;
|
|
456
|
-
if (!best || isBetter(result.metric, best.result.metric, state.bestDirection)) {
|
|
457
|
-
best = { index, result };
|
|
270
|
+
/** Best kept, unflagged result in the current segment (direction-aware). */
|
|
271
|
+
function findBestResult(state: AutoresearchExperimentState): AutoresearchExperimentResult | null {
|
|
272
|
+
let best: AutoresearchExperimentResult | null = null;
|
|
273
|
+
for (const result of state.results) {
|
|
274
|
+
if (result.segment !== state.currentSegment || result.status !== "keep" || result.flagged) continue;
|
|
275
|
+
if (result.metric === null || result.metric <= 0) continue;
|
|
276
|
+
if (!best || best.metric === null || isBetter(result.metric, best.metric, state.bestDirection)) {
|
|
277
|
+
best = result;
|
|
458
278
|
}
|
|
459
279
|
}
|
|
460
280
|
return best;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autoresearch data context: RLM data-description loading, GATED to explicit
|
|
3
|
+
* `data` or `mixed` mission mode only.
|
|
4
|
+
*
|
|
5
|
+
* This is the AC-16 no-inference rule at the consumption end: a mission mode is
|
|
6
|
+
* never inferred from the presence of a data file, so in `web` mode a data
|
|
7
|
+
* description must NOT be loaded — not an explicit `--data` flag, and not a
|
|
8
|
+
* project-root `DATA.md` auto-load. `data` and `mixed` modes may load one.
|
|
9
|
+
*/
|
|
10
|
+
import { loadRlmDataContext, type RlmDataContext } from "../rlm/data-context";
|
|
11
|
+
|
|
12
|
+
export type { RlmDataContext };
|
|
13
|
+
|
|
14
|
+
export type AutoresearchDataContextMode = "web" | "mixed" | "data";
|
|
15
|
+
|
|
16
|
+
export interface AutoresearchDataContextInput {
|
|
17
|
+
cwd: string;
|
|
18
|
+
mode: AutoresearchDataContextMode;
|
|
19
|
+
/** Explicit data path (resolved against `cwd`). Optional. */
|
|
20
|
+
dataFlag?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Load the data description for a mission, or return null when the mode does
|
|
25
|
+
* not permit one. `web` mode always returns null without touching the
|
|
26
|
+
* filesystem; `data`/`mixed` delegate to the RLM loader (explicit `--data`
|
|
27
|
+
* path wins over project-root `DATA.md`, which auto-loads when present).
|
|
28
|
+
*/
|
|
29
|
+
export async function loadAutoresearchDataContext(input: AutoresearchDataContextInput): Promise<RlmDataContext | null> {
|
|
30
|
+
if (input.mode === "web") {
|
|
31
|
+
// AC-16 consumption gate: never infer or attach data context in web mode.
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return loadRlmDataContext(input.cwd, input.dataFlag);
|
|
35
|
+
}
|