catherd-cli 1.4.0 → 2.0.0-beta.20261022113309
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -169
- package/THIRD_PARTY_NOTICES.md +217 -35
- package/catalog/jev.json +27 -1
- package/catalog/models.json +56 -239
- package/package.json +6 -8
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/bin/catherd-mcp +1 -1
- package/plugin/commands/catherd.md +2 -2
- package/plugin/skills/catherd/SKILL.md +97 -356
- package/plugin/skills/catherd-setup/SKILL.md +21 -20
- package/src/adapters/all.ts +0 -4
- package/src/adapters/backend.ts +19 -4
- package/src/adapters/claude-code/index.ts +126 -14
- package/src/adapters/codex/events.ts +10 -0
- package/src/adapters/codex/index.ts +17 -5
- package/src/adapters/cursor/home.ts +1 -1
- package/src/adapters/cursor/index.ts +10 -4
- package/src/adapters/opencode/index.ts +38 -1
- package/src/cli.ts +27 -27
- package/src/domain/agents.ts +3 -1
- package/src/domain/bars.ts +33 -107
- package/src/domain/blocked.ts +72 -0
- package/src/domain/branch.ts +51 -0
- package/src/domain/brief.ts +106 -0
- package/src/domain/catalog.ts +69 -313
- package/src/domain/changes.ts +23 -1
- package/src/domain/cost.ts +19 -29
- package/src/domain/errors.ts +6 -2
- package/src/domain/fail-lines.ts +26 -0
- package/src/domain/failover.ts +37 -75
- package/src/domain/findings.ts +47 -0
- package/src/domain/gate-brief.ts +53 -0
- package/src/domain/hints.ts +13 -2
- package/src/domain/ids.ts +13 -2
- package/src/domain/jev.ts +47 -2
- package/src/domain/judge.ts +124 -0
- package/src/domain/lane.ts +118 -3
- package/src/domain/milestone-memory.ts +53 -0
- package/src/domain/notice.ts +32 -8
- package/src/domain/notify.ts +32 -0
- package/src/domain/plan-doc.ts +198 -0
- package/src/domain/plan-lint.ts +141 -0
- package/src/domain/profile-rules.ts +175 -138
- package/src/domain/profile.ts +140 -63
- package/src/domain/record.ts +68 -3
- package/src/domain/reply.ts +29 -0
- package/src/domain/role-prompts.ts +182 -56
- package/src/domain/role-scope.ts +76 -0
- package/src/domain/role-tools.ts +34 -0
- package/src/domain/roles.ts +2 -0
- package/src/domain/route.ts +90 -0
- package/src/domain/rules.ts +33 -0
- package/src/domain/run-events.ts +298 -0
- package/src/domain/run-machine.ts +668 -0
- package/src/domain/run-state.ts +1310 -0
- package/src/domain/scorecard.ts +197 -0
- package/src/domain/select.ts +229 -72
- package/src/domain/slopalytics.ts +72 -0
- package/src/domain/state.ts +5 -0
- package/src/domain/util.ts +22 -0
- package/src/domain/workspace.ts +130 -0
- package/src/entry/answer-command.ts +39 -0
- package/src/entry/catalog-command.ts +24 -165
- package/src/entry/check-bin.ts +17 -0
- package/src/entry/cli-kit.ts +18 -2
- package/src/entry/daemon-bin.ts +22 -0
- package/src/entry/deps.ts +2 -0
- package/src/entry/doctor-command.ts +20 -2
- package/src/entry/glyphs.ts +15 -2
- package/src/entry/host-arg.ts +28 -0
- package/src/entry/init-command.ts +20 -69
- package/src/entry/knowledge-command.ts +121 -5
- package/src/entry/lock-command.ts +103 -8
- package/src/entry/mcp/handshake.ts +6 -2
- package/src/entry/mcp/role-bin.ts +20 -0
- package/src/entry/mcp/role-server.ts +134 -0
- package/src/entry/mcp/server.ts +85 -21
- package/src/entry/mcp/session-tools.ts +149 -0
- package/src/entry/panel/openapi.ts +189 -0
- package/src/entry/panel/server.ts +410 -0
- package/src/entry/panel-command.ts +68 -0
- package/src/entry/pause-command.ts +67 -0
- package/src/entry/profile-command.ts +33 -18
- package/src/entry/role-cli-command.ts +159 -0
- package/src/entry/runs-command.ts +81 -27
- package/src/entry/scorecard-command.ts +187 -0
- package/src/entry/supervise-bin.ts +1 -1
- package/src/entry/supervise-command.ts +30 -3
- package/src/entry/workspace-command.ts +44 -0
- package/src/infra/boot-lock.ts +25 -0
- package/src/infra/delivery.ts +3 -0
- package/src/infra/dispatch-dir.ts +2 -0
- package/src/infra/env.ts +11 -3
- package/src/infra/git.ts +70 -0
- package/src/infra/heavy-lock.ts +133 -6
- package/src/infra/host-probe.ts +16 -0
- package/src/infra/launch.ts +63 -7
- package/src/infra/lock-activity.ts +88 -0
- package/src/infra/login-env.ts +48 -0
- package/src/infra/memory.ts +45 -0
- package/src/infra/ntfy.ts +40 -0
- package/src/infra/open-url.ts +42 -0
- package/src/infra/paths.ts +37 -2
- package/src/infra/role-mcp.ts +69 -0
- package/src/infra/slopalytics.ts +30 -0
- package/src/infra/store.ts +6 -1
- package/src/infra/supervisor.ts +107 -16
- package/src/services/admission.ts +133 -31
- package/src/services/backends.ts +4 -6
- package/src/services/budget.ts +26 -6
- package/src/services/capture.ts +1 -22
- package/src/services/catalog-service.ts +155 -254
- package/src/services/credentials.ts +15 -26
- package/src/services/daemon.ts +181 -0
- package/src/services/dispatch-service.ts +209 -17
- package/src/services/dispatches.ts +30 -2
- package/src/services/doctor-access.ts +8 -3
- package/src/services/doctor-backends.ts +1 -1
- package/src/services/doctor-checks.ts +47 -0
- package/src/services/doctor-docker.ts +221 -0
- package/src/services/doctor-role-mcp.ts +65 -0
- package/src/services/doctor.ts +72 -15
- package/src/services/end-push.ts +157 -0
- package/src/services/failover-rungs.ts +109 -0
- package/src/services/finalize.ts +24 -2
- package/src/services/gate-env.ts +217 -0
- package/src/services/gate-service.ts +231 -45
- package/src/services/global-install.ts +46 -13
- package/src/services/jev-service.ts +2 -4
- package/src/services/lane-edit.ts +154 -0
- package/src/services/lane-service.ts +291 -55
- package/src/services/milestone-check.ts +433 -0
- package/src/services/milestone-tree.ts +170 -0
- package/src/services/milestones.ts +167 -29
- package/src/services/notifier.ts +124 -4
- package/src/services/notify-service.ts +26 -0
- package/src/services/orchestrator-wait.ts +82 -0
- package/src/services/panel-setup.ts +116 -0
- package/src/services/pause.ts +161 -0
- package/src/services/peek.ts +79 -17
- package/src/services/plan-input.ts +151 -0
- package/src/services/ports.ts +60 -5
- package/src/services/preflight.ts +232 -24
- package/src/services/profile-service.ts +31 -3
- package/src/services/profile-store.ts +18 -6
- package/src/services/protocol.ts +123 -25
- package/src/services/provenance.ts +34 -89
- package/src/services/questions.ts +24 -0
- package/src/services/reconcile.ts +33 -1
- package/src/services/reentry.ts +7 -6
- package/src/services/role-access.ts +27 -0
- package/src/services/routing-service.ts +161 -42
- package/src/services/run-briefs.ts +477 -0
- package/src/services/run-client.ts +217 -0
- package/src/services/run-effects.ts +837 -0
- package/src/services/run-events-store.ts +174 -0
- package/src/services/run-evidence.ts +1 -1
- package/src/services/run-pin.ts +125 -0
- package/src/services/run-read.ts +221 -0
- package/src/services/run-report.ts +176 -0
- package/src/services/run-service.ts +204 -23
- package/src/services/run-store.ts +159 -18
- package/src/services/scorecard-metrics.ts +86 -0
- package/src/services/scorecard.ts +382 -0
- package/src/services/scratch.ts +60 -0
- package/src/services/sessions.ts +3 -1
- package/src/services/state.ts +21 -0
- package/src/services/summary.ts +76 -12
- package/src/services/tree-path.ts +27 -0
- package/src/services/verifier-brief.ts +23 -0
- package/src/services/verifier-step.ts +48 -0
- package/src/services/workspace-admission.ts +259 -0
- package/src/services/workspace-service.ts +259 -0
- package/src/services/workspace-store.ts +95 -0
- package/web/dist/assets/Brand-PKlUX5TE.js +1 -0
- package/web/dist/assets/Brand-PKlUX5TE.js.br +0 -0
- package/web/dist/assets/Brand-PKlUX5TE.js.gz +0 -0
- package/web/dist/assets/Modal-Dxc5so53.js +1 -0
- package/web/dist/assets/Modal-Dxc5so53.js.br +0 -0
- package/web/dist/assets/Modal-Dxc5so53.js.gz +0 -0
- package/web/dist/assets/Pressable-C8-T6Ed_.js +1 -0
- package/web/dist/assets/StatusChip-B5xfI_Mn.js +153 -0
- package/web/dist/assets/StatusChip-B5xfI_Mn.js.br +0 -0
- package/web/dist/assets/StatusChip-B5xfI_Mn.js.gz +0 -0
- package/web/dist/assets/_app-Ea5cpyKe.js +1 -0
- package/web/dist/assets/_app-Ea5cpyKe.js.br +0 -0
- package/web/dist/assets/_app-Ea5cpyKe.js.gz +0 -0
- package/web/dist/assets/_runId-pTG0fXVo.js +1 -0
- package/web/dist/assets/_runId-pTG0fXVo.js.br +0 -0
- package/web/dist/assets/_runId-pTG0fXVo.js.gz +0 -0
- package/web/dist/assets/drawer-Du3cdlok.js +1 -0
- package/web/dist/assets/drawer-Du3cdlok.js.br +0 -0
- package/web/dist/assets/drawer-Du3cdlok.js.gz +0 -0
- package/web/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/web/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/web/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/web/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/web/dist/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/web/dist/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/web/dist/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/web/dist/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/web/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/web/dist/assets/index-B6GiwDkh.js +11 -0
- package/web/dist/assets/index-B6GiwDkh.js.br +0 -0
- package/web/dist/assets/index-B6GiwDkh.js.gz +0 -0
- package/web/dist/assets/index-C5IbylvM.css +2 -0
- package/web/dist/assets/index-C5IbylvM.css.br +0 -0
- package/web/dist/assets/index-C5IbylvM.css.gz +0 -0
- package/web/dist/assets/label-DFSYBc62.js +1 -0
- package/web/dist/assets/label-DFSYBc62.js.br +0 -0
- package/web/dist/assets/label-DFSYBc62.js.gz +0 -0
- package/web/dist/assets/link-D8EcKZUt.js +1 -0
- package/web/dist/assets/link-D8EcKZUt.js.br +0 -0
- package/web/dist/assets/link-D8EcKZUt.js.gz +0 -0
- package/web/dist/assets/login-DaN5HPPW.js +1 -0
- package/web/dist/assets/login-DaN5HPPW.js.br +0 -0
- package/web/dist/assets/login-DaN5HPPW.js.gz +0 -0
- package/web/dist/assets/query-Cu--ccT3.js +1 -0
- package/web/dist/assets/questions-shoO9OVj.js +1 -0
- package/web/dist/assets/questions-shoO9OVj.js.br +0 -0
- package/web/dist/assets/questions-shoO9OVj.js.gz +0 -0
- package/web/dist/assets/react-query.gen-Bu2yV-qJ.js +12 -0
- package/web/dist/assets/react-query.gen-Bu2yV-qJ.js.br +0 -0
- package/web/dist/assets/react-query.gen-Bu2yV-qJ.js.gz +0 -0
- package/web/dist/assets/rolldown-runtime-XKyaHtl9.js +1 -0
- package/web/dist/assets/run-status-C0DRuV7U.js +1 -0
- package/web/dist/assets/runs-C3rg2zZc.js +1 -0
- package/web/dist/assets/runs-C3rg2zZc.js.br +0 -0
- package/web/dist/assets/runs-C3rg2zZc.js.gz +0 -0
- package/web/dist/assets/setup-5I4Vl9fR.js +1 -0
- package/web/dist/assets/setup-5I4Vl9fR.js.br +0 -0
- package/web/dist/assets/setup-5I4Vl9fR.js.gz +0 -0
- package/web/dist/assets/table-BOxXhqS4.js +1 -0
- package/web/dist/assets/table-BOxXhqS4.js.br +0 -0
- package/web/dist/assets/table-BOxXhqS4.js.gz +0 -0
- package/web/dist/assets/textfield-BzRFkxBF.js +1 -0
- package/web/dist/assets/textfield-BzRFkxBF.js.br +0 -0
- package/web/dist/assets/textfield-BzRFkxBF.js.gz +0 -0
- package/web/dist/assets/time--9kSQbbp.js +1 -0
- package/web/dist/assets/use-css-variable-CpnN9WtA.js +5 -0
- package/web/dist/assets/use-css-variable-CpnN9WtA.js.br +0 -0
- package/web/dist/assets/use-css-variable-CpnN9WtA.js.gz +0 -0
- package/web/dist/assets/useMutation-CVPKlR34.js +1 -0
- package/web/dist/assets/useMutation-CVPKlR34.js.br +0 -0
- package/web/dist/assets/useMutation-CVPKlR34.js.gz +0 -0
- package/web/dist/index.html +15 -0
- package/catalog/ATTRIBUTION.md +0 -36
- package/catalog/scores.json +0 -3202
- package/catalog/sources.json +0 -97
- package/src/adapters/antigravity/events.ts +0 -131
- package/src/adapters/antigravity/home.ts +0 -46
- package/src/adapters/antigravity/index.ts +0 -320
- package/src/adapters/antigravity/models.ts +0 -37
- package/src/adapters/grok/events.ts +0 -112
- package/src/adapters/grok/home.ts +0 -132
- package/src/adapters/grok/index.ts +0 -339
- package/src/adapters/grok/models.ts +0 -48
- package/src/domain/calibration.ts +0 -125
- package/src/domain/sources.ts +0 -144
- package/src/entry/mcp/dispatch-tools.ts +0 -52
- package/src/entry/mcp/lane-tools.ts +0 -84
- package/src/entry/mcp/protocol-tools.ts +0 -57
- package/src/entry/mcp/run-tools.ts +0 -148
- package/src/entry/mcp/setup-tools.ts +0 -108
- package/src/entry/tui/commands.ts +0 -563
- package/src/entry/tui/effects.ts +0 -381
- package/src/entry/tui/fixtures.ts +0 -637
- package/src/entry/tui/profile-edits.ts +0 -146
- package/src/entry/tui/profile-tree.ts +0 -429
- package/src/entry/tui/providers/app.tsx +0 -162
- package/src/entry/tui/providers/boundary.tsx +0 -57
- package/src/entry/tui/providers/data.tsx +0 -160
- package/src/entry/tui/providers/keymap.tsx +0 -166
- package/src/entry/tui/providers/root.tsx +0 -45
- package/src/entry/tui/providers/theme.tsx +0 -17
- package/src/entry/tui/providers/toast.tsx +0 -77
- package/src/entry/tui/run.tsx +0 -114
- package/src/entry/tui/state.ts +0 -373
- package/src/entry/tui/stories.ts +0 -114
- package/src/entry/tui/text.ts +0 -130
- package/src/entry/tui/theme.ts +0 -140
- package/src/entry/tui/views/app.tsx +0 -208
- package/src/entry/tui/views/dialogs.tsx +0 -41
- package/src/entry/tui/views/profile-actions.ts +0 -331
- package/src/entry/tui/views/profiles.tsx +0 -520
- package/src/entry/tui/views/runs.tsx +0 -573
- package/src/entry/tui/views/save-dialog.tsx +0 -340
- package/src/entry/tui/views/status.tsx +0 -209
- package/src/entry/tui/widgets/chrome.tsx +0 -114
- package/src/entry/tui/widgets/dialog-confirm.tsx +0 -58
- package/src/entry/tui/widgets/dialog-prompt.tsx +0 -52
- package/src/entry/tui/widgets/dialog-select.tsx +0 -212
- package/src/entry/tui/widgets/dialog.tsx +0 -68
- package/src/entry/tui/widgets/line.tsx +0 -92
- package/src/entry/tui/widgets/list.tsx +0 -197
- package/src/entry/tui/widgets/spinner.tsx +0 -49
- package/src/entry/tui/widgets/toast.tsx +0 -62
- package/src/infra/sources/arena.ts +0 -87
- package/src/infra/sources/artificial-analysis.ts +0 -112
- package/src/infra/sources/cache.ts +0 -124
- package/src/infra/sources/csv.ts +0 -38
- package/src/infra/sources/epoch.ts +0 -82
- package/src/infra/sources/http.ts +0 -75
- package/src/infra/sources/litellm.ts +0 -58
- package/src/infra/sources/models-dev.ts +0 -59
- package/src/infra/sources/openrouter-endpoints.ts +0 -52
- package/src/infra/sources/openrouter-models.ts +0 -60
- package/src/infra/sources/rows.ts +0 -38
- package/src/infra/sources/vectara.ts +0 -69
- package/src/infra/sources/zip.ts +0 -48
- package/src/services/catalog-refresh.ts +0 -201
- package/src/services/doctor-sources.ts +0 -76
- package/src/services/runs-page.ts +0 -255
- package/src/services/source-derive.ts +0 -374
- package/src/services/source-sync.ts +0 -305
- package/src/services/standins.ts +0 -204
- package/src/services/treat-likes.ts +0 -97
package/src/entry/tui/effects.ts
DELETED
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
import type { HostContext } from "../../domain/host.ts";
|
|
2
|
-
import { sessionKey } from "../../domain/host.ts";
|
|
3
|
-
import { realpathSync, statSync, watch } from "node:fs";
|
|
4
|
-
import { adapterFor } from "../../adapters/registry.ts";
|
|
5
|
-
import "../../adapters/all.ts";
|
|
6
|
-
import { agentFiles } from "../../domain/agents.ts";
|
|
7
|
-
import { type Catalog, rungInfo } from "../../domain/catalog.ts";
|
|
8
|
-
import { HARNESS_KEYS, type Profile, type ProfileDoc, type ProfilePatch } from "../../domain/profile.ts";
|
|
9
|
-
import type { Validation } from "../../domain/profile-rules.ts";
|
|
10
|
-
import type { Access } from "../../domain/record.ts";
|
|
11
|
-
import { VERSION } from "../../infra/version.ts";
|
|
12
|
-
import {
|
|
13
|
-
type CatalogModel,
|
|
14
|
-
catalogQuery,
|
|
15
|
-
loadCatalog,
|
|
16
|
-
type Refreshed,
|
|
17
|
-
refreshDiscovery,
|
|
18
|
-
saveTreatLike,
|
|
19
|
-
} from "../../services/catalog-service.ts";
|
|
20
|
-
import { cancel } from "../../services/dispatch-service.ts";
|
|
21
|
-
import { type DoctorReport, doctor } from "../../services/doctor.ts";
|
|
22
|
-
import { ageText } from "../../services/doctor-sources.ts";
|
|
23
|
-
import { valuesUsed, type ValueUsed } from "../../services/provenance.ts";
|
|
24
|
-
import { evidenceLine, evidenceOf, runEvidence } from "../../services/run-evidence.ts";
|
|
25
|
-
import { type SyncReport, sourcesStatus, syncSources } from "../../services/source-sync.ts";
|
|
26
|
-
import { type Suggestion, suggestStandIns } from "../../services/standins.ts";
|
|
27
|
-
import type { Synced } from "../../services/agent-links.ts";
|
|
28
|
-
import {
|
|
29
|
-
activate,
|
|
30
|
-
createProfile,
|
|
31
|
-
deleteProfile,
|
|
32
|
-
patchProfile,
|
|
33
|
-
type Saved,
|
|
34
|
-
} from "../../services/profile-service.ts";
|
|
35
|
-
import {
|
|
36
|
-
activeName,
|
|
37
|
-
configFile,
|
|
38
|
-
enforcementOf,
|
|
39
|
-
listProfiles,
|
|
40
|
-
profilesDir,
|
|
41
|
-
projectsFile,
|
|
42
|
-
readProfileDoc,
|
|
43
|
-
readProjects,
|
|
44
|
-
validateHere,
|
|
45
|
-
} from "../../services/profile-store.ts";
|
|
46
|
-
import { listRuns, type Run, runPaths } from "../../services/run-store.ts";
|
|
47
|
-
import {
|
|
48
|
-
type MilestoneDetail,
|
|
49
|
-
milestoneDetail,
|
|
50
|
-
type RoleDetail,
|
|
51
|
-
roleDetail,
|
|
52
|
-
type SessionDetail,
|
|
53
|
-
sessionDetail,
|
|
54
|
-
type SessionRow,
|
|
55
|
-
sessionRows,
|
|
56
|
-
} from "../../services/runs-page.ts";
|
|
57
|
-
import { type RunSummary, summarizeRun } from "../../services/summary.ts";
|
|
58
|
-
import { defaultDeps } from "../deps.ts";
|
|
59
|
-
import { mcpHandshake } from "../mcp/handshake.ts";
|
|
60
|
-
|
|
61
|
-
/** A save refused because the profile changed on disk since its preview read it carries this path. */
|
|
62
|
-
export { CHANGED_ON_DISK } from "../../services/profile-service.ts";
|
|
63
|
-
export type {
|
|
64
|
-
Milestone,
|
|
65
|
-
MilestoneDetail,
|
|
66
|
-
RoleDetail,
|
|
67
|
-
RoleRow,
|
|
68
|
-
SessionDetail,
|
|
69
|
-
SessionRow,
|
|
70
|
-
SessionRun,
|
|
71
|
-
} from "../../services/runs-page.ts";
|
|
72
|
-
|
|
73
|
-
/** One line of the run list. */
|
|
74
|
-
export interface RunRow {
|
|
75
|
-
id: string;
|
|
76
|
-
title: string;
|
|
77
|
-
repo: string;
|
|
78
|
-
createdAt: string;
|
|
79
|
-
live: number;
|
|
80
|
-
roleRuns: number;
|
|
81
|
-
landed: number;
|
|
82
|
-
/** the budget's spent fraction, null without a cap */
|
|
83
|
-
budget: number | null;
|
|
84
|
-
/** the session that started it (the Runs tab opens it); null for a run from before 1.1 */
|
|
85
|
-
session: string | null;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Everything the TUI reads or changes, behind one seam (spec §9.4 `effects.ts`: services injected).
|
|
90
|
-
* The live set calls the services; tests and the storybook pass fakes.
|
|
91
|
-
*/
|
|
92
|
-
export interface Effects {
|
|
93
|
-
host: HostContext;
|
|
94
|
-
version: string;
|
|
95
|
-
doctor(): Promise<DoctorReport>;
|
|
96
|
-
runs(): { rows: RunRow[]; warnings: string[] };
|
|
97
|
-
/** spec §4: the Runs tab's top level, the sessions */
|
|
98
|
-
sessions(): { rows: SessionRow[]; warnings: string[] };
|
|
99
|
-
/** a session's screen; `key` null is "earlier runs" */
|
|
100
|
-
session(key: string | null): SessionDetail;
|
|
101
|
-
/** a role's screen */
|
|
102
|
-
role(run: string, dispatchId: string): RoleDetail;
|
|
103
|
-
/** spec 1.1 §10: a milestone's screen, its digest */
|
|
104
|
-
milestone(run: string, name: string): MilestoneDetail;
|
|
105
|
-
/**
|
|
106
|
-
* calls `onChange` when a file under one of `dirs` changes (spec §4: the open screen redraws when a run file
|
|
107
|
-
* changes); null when they cannot be watched here, and the screen polls every second instead
|
|
108
|
-
*/
|
|
109
|
-
watch(dirs: string[], onChange: () => void): (() => void) | null;
|
|
110
|
-
/** stops a live role; resolves to the line the toast shows */
|
|
111
|
-
cancel(run: string, name: string): Promise<string>;
|
|
112
|
-
profiles(): {
|
|
113
|
-
names: string[];
|
|
114
|
-
/** global */
|
|
115
|
-
active: string;
|
|
116
|
-
/** what this directory runs on */
|
|
117
|
-
here: string;
|
|
118
|
-
/** the bound repo, null outside one or unbound */
|
|
119
|
-
repo: string | null;
|
|
120
|
-
};
|
|
121
|
-
readProfile(name: string): ProfileDoc;
|
|
122
|
-
catalog(billing: Profile["billing"]): { catalog: Catalog; models: CatalogModel[] };
|
|
123
|
-
validate(p: Profile, c: Catalog): Validation;
|
|
124
|
-
enforcement(rung: string, access: Access): "enforced" | "advisory";
|
|
125
|
-
/** the harnesses a profile can isolate */
|
|
126
|
-
harnesses: readonly string[];
|
|
127
|
-
/** spec 1.3 §8: what a harness's native mode loads, and the API key its isolation needs, when it says */
|
|
128
|
-
isolation(harness: string): { note?: string; key?: string };
|
|
129
|
-
/** the native agents a profile links, by name */
|
|
130
|
-
agents(p: Profile): string[];
|
|
131
|
-
/**
|
|
132
|
-
* writes the staged treat-likes, then the profile patch, through the ProfileService (validation reads
|
|
133
|
-
* the treat-likes, so they go first); a refused patch leaves the treat-likes written. With `shown` (the
|
|
134
|
-
* profile as the save dialog's last preview read it), the patch is written only over that profile: when
|
|
135
|
-
* another process changed it meanwhile (while a treat-like waited for the catalog lock, say), nothing
|
|
136
|
-
* is written and the result's one error has the path CHANGED_ON_DISK
|
|
137
|
-
*/
|
|
138
|
-
save(
|
|
139
|
-
name: string,
|
|
140
|
-
patch: ProfilePatch,
|
|
141
|
-
treatLikes: Record<string, string>,
|
|
142
|
-
shown?: ProfileDoc,
|
|
143
|
-
): Promise<Saved>;
|
|
144
|
-
/**
|
|
145
|
-
* applies the scope the user confirmed: binds `repo` (this TUI's repo) to it, or with null makes it the
|
|
146
|
-
* global active profile; never a scope recomputed as it writes
|
|
147
|
-
*/
|
|
148
|
-
activate(name: string, repo: string | null): Synced;
|
|
149
|
-
create(name: string, from?: string): Saved;
|
|
150
|
-
remove(name: string): Synced;
|
|
151
|
-
refreshCatalog(): Promise<Refreshed[]>;
|
|
152
|
-
/** spec 1.2 §9 (`r`): syncs the public sources (each at most every 12 hours) */
|
|
153
|
-
syncSources(): Promise<SyncReport>;
|
|
154
|
-
/** spec 1.2 §9: each source's name, age and last error, as the `r` dialog shows them */
|
|
155
|
-
sources(): { source: string; name: string; age: string; error: string | null }[];
|
|
156
|
-
/** spec 1.2 §6.3: the three nearest stand-ins for a rung, for the treat-like picker */
|
|
157
|
-
suggest(c: Catalog, rung: string): Suggestion[];
|
|
158
|
-
/** spec 1.2 §5.3, §8: a rung's values with confidence and source, and catherd's own runs on it */
|
|
159
|
-
rungDetail(c: Catalog, rung: string): { values: ValueUsed[]; evidence: string | null };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/** Spec 1.2 §9: each source's age and last error, from the sync's state. */
|
|
163
|
-
export function sourceRows(now = Date.now()): ReturnType<Effects["sources"]> {
|
|
164
|
-
return sourcesStatus().sources.map((s) => ({
|
|
165
|
-
source: s.source,
|
|
166
|
-
name: s.name,
|
|
167
|
-
age: s.fetchedAt ? `${ageText(now - Date.parse(s.fetchedAt))} ago` : "never fetched",
|
|
168
|
-
error: s.error,
|
|
169
|
-
}));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/** Spec 1.2 §5.3, §8: what the rung detail shows; an unparseable rung has nothing to show. */
|
|
173
|
-
export function rungDetailOf(c: Catalog, rung: string): ReturnType<Effects["rungDetail"]> {
|
|
174
|
-
try {
|
|
175
|
-
const canonical = rungInfo(c, rung).canonical;
|
|
176
|
-
return {
|
|
177
|
-
values: valuesUsed(c, canonical),
|
|
178
|
-
evidence: evidenceLine(evidenceOf(runEvidence(c), canonical)),
|
|
179
|
-
};
|
|
180
|
-
} catch {
|
|
181
|
-
return { values: [], evidence: null };
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/** Spec 1.2 §6.3: a rung's nearest stand-ins; none for a rung that does not parse. */
|
|
186
|
-
export function suggestFor(c: Catalog, rung: string): Suggestion[] {
|
|
187
|
-
try {
|
|
188
|
-
return suggestStandIns(c, rungInfo(c, rung).canonical);
|
|
189
|
-
} catch {
|
|
190
|
-
return [];
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/** The word for `here`: the bound repo's profile, or the global active one. */
|
|
195
|
-
export const hereWord = (p: { repo: string | null }): string => (p.repo ? "this repo" : "active");
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* What changes when a run changes: the mtimes of its record files and of its roles folder, plus the
|
|
199
|
-
* profiles folder, config.json and projects.json (a saved budget cap or another active profile moves the
|
|
200
|
-
* run's budget fraction).
|
|
201
|
-
*/
|
|
202
|
-
export function stampOf(dir: string): string {
|
|
203
|
-
const p = runPaths(dir);
|
|
204
|
-
return [
|
|
205
|
-
p.runs,
|
|
206
|
-
p.routes,
|
|
207
|
-
p.jev,
|
|
208
|
-
p.agents,
|
|
209
|
-
p.state,
|
|
210
|
-
p.ledger,
|
|
211
|
-
p.roles,
|
|
212
|
-
profilesDir(),
|
|
213
|
-
configFile(),
|
|
214
|
-
projectsFile(),
|
|
215
|
-
]
|
|
216
|
-
.map((f) => {
|
|
217
|
-
try {
|
|
218
|
-
return String(statSync(f).mtimeMs);
|
|
219
|
-
} catch {
|
|
220
|
-
return "-";
|
|
221
|
-
}
|
|
222
|
-
})
|
|
223
|
-
.join(" ");
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* The run list, each row computed again only when its run's files changed or a role is live (spec §9.4:
|
|
228
|
-
* runs data memoised by mtime). A live run's elapsed times move without any file changing.
|
|
229
|
-
*/
|
|
230
|
-
export function memoRuns(compute: (run: Run) => RunRow, stamp: (dir: string) => string = stampOf) {
|
|
231
|
-
const cache = new Map<string, { stamp: string; row: RunRow }>();
|
|
232
|
-
return (runs: Run[]): RunRow[] =>
|
|
233
|
-
runs.map((r) => {
|
|
234
|
-
const s = stamp(r.dir);
|
|
235
|
-
const hit = cache.get(r.dir);
|
|
236
|
-
if (hit && hit.stamp === s && hit.row.live === 0) return hit.row;
|
|
237
|
-
const row = compute(r);
|
|
238
|
-
cache.set(r.dir, { stamp: s, row });
|
|
239
|
-
return row;
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export function rowOf(s: RunSummary): RunRow {
|
|
244
|
-
return {
|
|
245
|
-
id: s.id,
|
|
246
|
-
title: s.title,
|
|
247
|
-
repo: s.repo,
|
|
248
|
-
createdAt: s.createdAt,
|
|
249
|
-
live: s.live.length,
|
|
250
|
-
roleRuns: s.totals.runs,
|
|
251
|
-
landed: s.milestones.length,
|
|
252
|
-
budget: s.budget?.fraction ?? null,
|
|
253
|
-
session: s.session ? sessionKey(s.session) : null,
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/** How long a burst of file events is gathered into one redraw. */
|
|
258
|
-
const WATCH_SETTLE_MS = 100;
|
|
259
|
-
|
|
260
|
-
/** What `watchDirs` watches and times with; tests pass fakes. */
|
|
261
|
-
export interface WatchPorts {
|
|
262
|
-
watch(dir: string, fire: () => void): { on(event: "error", f: () => void): unknown; close(): void };
|
|
263
|
-
setTimeout(f: () => void, ms: number): unknown;
|
|
264
|
-
clearTimeout(h: unknown): void;
|
|
265
|
-
/** the folder's real path: macOS reports FSEvents under it (/var is /private/var) */
|
|
266
|
-
realpath(dir: string): string;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const LIVE_WATCH: WatchPorts = {
|
|
270
|
-
watch: (dir, fire) => watch(dir, { recursive: true }, fire),
|
|
271
|
-
setTimeout: (f, ms) => setTimeout(f, ms),
|
|
272
|
-
clearTimeout: (h) => clearTimeout(h as ReturnType<typeof setTimeout>),
|
|
273
|
-
realpath: (dir) => realpathSync(dir),
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* `fs.watch` on each run folder's real path, recursive; null when any of them cannot be watched. After the
|
|
278
|
-
* returned stop, `onChange` is never called, even for an event already queued.
|
|
279
|
-
*/
|
|
280
|
-
export function watchDirs(
|
|
281
|
-
dirs: string[],
|
|
282
|
-
onChange: () => void,
|
|
283
|
-
ports: Partial<WatchPorts> = {},
|
|
284
|
-
): (() => void) | null {
|
|
285
|
-
const io = { ...LIVE_WATCH, ...ports };
|
|
286
|
-
const watchers: { close(): void }[] = [];
|
|
287
|
-
let timer: unknown = null;
|
|
288
|
-
let stopped = false;
|
|
289
|
-
const fire = () => {
|
|
290
|
-
if (stopped || timer !== null) return;
|
|
291
|
-
timer = io.setTimeout(() => {
|
|
292
|
-
timer = null;
|
|
293
|
-
if (!stopped) onChange();
|
|
294
|
-
}, WATCH_SETTLE_MS);
|
|
295
|
-
};
|
|
296
|
-
const stop = () => {
|
|
297
|
-
stopped = true;
|
|
298
|
-
if (timer !== null) io.clearTimeout(timer);
|
|
299
|
-
timer = null;
|
|
300
|
-
for (const w of watchers) w.close();
|
|
301
|
-
};
|
|
302
|
-
try {
|
|
303
|
-
for (const d of dirs) {
|
|
304
|
-
const w = io.watch(io.realpath(d), fire);
|
|
305
|
-
// a watcher that breaks later (the folder removed) just stops; the screen's slow poll still reads
|
|
306
|
-
w.on("error", () => w.close());
|
|
307
|
-
watchers.push(w);
|
|
308
|
-
}
|
|
309
|
-
} catch {
|
|
310
|
-
stop();
|
|
311
|
-
return null;
|
|
312
|
-
}
|
|
313
|
-
return stop;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* The live effects. `repo` is the git toplevel the TUI was opened in (null outside one): inside a repo
|
|
318
|
-
* bound to a profile, `here` is that profile and activating binds the repo instead of the global profile.
|
|
319
|
-
*/
|
|
320
|
-
export function liveEffects(
|
|
321
|
-
repo: string | null = null,
|
|
322
|
-
host: HostContext = { host: "unknown", session: null, conflict: null },
|
|
323
|
-
): Effects {
|
|
324
|
-
const deps = defaultDeps(host);
|
|
325
|
-
const rows = memoRuns((r) => rowOf(summarizeRun(deps, r)));
|
|
326
|
-
const harnesses = HARNESS_KEYS.filter((h) => adapterFor(h));
|
|
327
|
-
const bound = () => (repo !== null && readProjects().bindings[repo] !== undefined ? repo : null);
|
|
328
|
-
return {
|
|
329
|
-
host,
|
|
330
|
-
version: VERSION,
|
|
331
|
-
doctor: () =>
|
|
332
|
-
doctor({ host, repo, bunVersion: Bun.version, version: VERSION, handshake: () => mcpHandshake() }),
|
|
333
|
-
runs() {
|
|
334
|
-
const { runs, corrupt } = listRuns();
|
|
335
|
-
return { rows: rows(runs), warnings: corrupt.map((c) => `skipped run ${c.id}: ${c.reason}`) };
|
|
336
|
-
},
|
|
337
|
-
sessions: () => sessionRows(deps),
|
|
338
|
-
session: (key) => sessionDetail(deps, key),
|
|
339
|
-
role: (run, dispatchId) => roleDetail(deps, run, dispatchId),
|
|
340
|
-
milestone: (run, name) => milestoneDetail(run, name),
|
|
341
|
-
watch: watchDirs,
|
|
342
|
-
async cancel(run, name) {
|
|
343
|
-
const r = await cancel(deps, run, name);
|
|
344
|
-
return `${r.record.name} ${r.record.status}`;
|
|
345
|
-
},
|
|
346
|
-
profiles: () => ({ names: listProfiles(), active: activeName(), here: activeName(repo), repo: bound() }),
|
|
347
|
-
readProfile: readProfileDoc,
|
|
348
|
-
catalog(billing) {
|
|
349
|
-
return {
|
|
350
|
-
catalog: loadCatalog({ timings: false }),
|
|
351
|
-
models: catalogQuery({ scoredOnly: false, limit: Number.MAX_SAFE_INTEGER }, billing).models,
|
|
352
|
-
};
|
|
353
|
-
},
|
|
354
|
-
validate: (p, c) => validateHere(p, c, undefined, host.host),
|
|
355
|
-
enforcement: enforcementOf,
|
|
356
|
-
harnesses,
|
|
357
|
-
isolation(h) {
|
|
358
|
-
const a = adapterFor(h);
|
|
359
|
-
return {
|
|
360
|
-
...(a?.isolationNote ? { note: a.isolationNote } : {}),
|
|
361
|
-
...(a?.isolationKey ? { key: a.isolationKey } : {}),
|
|
362
|
-
};
|
|
363
|
-
},
|
|
364
|
-
agents: (p) => agentFiles(p, VERSION).map((f) => f.name),
|
|
365
|
-
async save(name, patch, treatLikes, shown) {
|
|
366
|
-
for (const [rung, like] of Object.entries(treatLikes)) await saveTreatLike(rung, like);
|
|
367
|
-
return patchProfile(name, patch, {
|
|
368
|
-
host: host.host,
|
|
369
|
-
...(shown === undefined ? {} : { expect: shown }),
|
|
370
|
-
});
|
|
371
|
-
},
|
|
372
|
-
activate: (name, scope) => activate(name, scope, host.host),
|
|
373
|
-
create: (name, from) => createProfile(name, from, host.host),
|
|
374
|
-
remove: deleteProfile,
|
|
375
|
-
refreshCatalog: () => refreshDiscovery(),
|
|
376
|
-
syncSources: () => syncSources(),
|
|
377
|
-
sources: () => sourceRows(),
|
|
378
|
-
suggest: suggestFor,
|
|
379
|
-
rungDetail: rungDetailOf,
|
|
380
|
-
};
|
|
381
|
-
}
|