@alecsibilia/luca 14.0.0-alpha.2 → 14.0.0-alpha.21
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 +76 -0
- package/README.md +7 -2
- package/board/client/board-look.ts +31 -1
- package/board/client/board-panel-parts.tsx +150 -0
- package/board/client/board-panel-stages.ts +99 -0
- package/board/client/board-panel-styles.ts +223 -0
- package/board/client/board-panel.tsx +77 -1275
- package/board/client/engine-life.ts +48 -0
- package/board/client/final-review-stack.tsx +144 -0
- package/board/client/heartbeat.tsx +61 -0
- package/board/client/helper-lines.tsx +69 -0
- package/board/client/live-feed.tsx +86 -0
- package/board/client/live-line.ts +73 -0
- package/board/client/model-line.tsx +178 -0
- package/board/client/needs-you-section.tsx +133 -0
- package/board/client/one-line.tsx +193 -0
- package/board/client/repo-wait-banner.tsx +69 -0
- package/board/client/run-footer.tsx +68 -0
- package/board/client/run-header.tsx +189 -0
- package/board/client/run-picker.tsx +98 -0
- package/board/client/status-bar.tsx +131 -0
- package/board/client/step-dots.tsx +127 -0
- package/board/client/stuck-actions.tsx +269 -0
- package/board/client/ticket-card-view.tsx +238 -0
- package/board/client/ticket-detail.tsx +87 -0
- package/board/client/ticket-stack.tsx +119 -0
- package/board/client/ticket-wait.ts +188 -0
- package/board/client/timeline-rows.tsx +41 -14
- package/board/client/usage-line.tsx +51 -0
- package/board/client/wait-line.tsx +39 -0
- package/board/index.client.tsx +1 -1
- package/board/index.server.ts +7 -1
- package/board/package.json +1 -1
- package/board/server/board-panel-state-helpers.ts +67 -0
- package/board/server/board-server-check.ts +294 -0
- package/board/server/board-server-engine.ts +129 -0
- package/board/server/board-server-events.ts +134 -0
- package/board/server/board-server-read.ts +190 -0
- package/board/server/board-server-resume.ts +164 -0
- package/board/server/board-server-start.ts +174 -0
- package/board/server/board-server-store.ts +281 -0
- package/board/server/board-server-types.ts +114 -0
- package/board/server/board-server-util.ts +4 -0
- package/board/server/board-server.ts +52 -943
- package/board/server/board-vocabulary-engine.ts +144 -0
- package/board/server/board-vocabulary-review.ts +115 -0
- package/board/server/board-vocabulary-run.ts +145 -0
- package/board/server/board-vocabulary-shapes.ts +153 -0
- package/board/server/board-vocabulary.ts +20 -375
- package/board/server/current-step-panel-helpers.ts +108 -0
- package/board/server/describe-record.ts +403 -0
- package/board/server/engine-launch.ts +20 -3
- package/board/server/engine-restart-helpers.ts +105 -0
- package/board/server/engine-watch.ts +45 -5
- package/board/server/journal-rebuild-helpers.ts +169 -0
- package/board/server/live-file.ts +130 -0
- package/board/server/luca-version.ts +1 -1
- package/board/server/make-rows.ts +14 -629
- package/board/server/record-texts.ts +350 -0
- package/board/server/reduce-board-agent-start.ts +224 -0
- package/board/server/reduce-board-agents.ts +160 -0
- package/board/server/reduce-board-counters.ts +138 -0
- package/board/server/reduce-board-create.ts +148 -0
- package/board/server/reduce-board-final-review.ts +174 -0
- package/board/server/reduce-board-needs-you.ts +283 -0
- package/board/server/reduce-board-reasons.ts +59 -0
- package/board/server/reduce-board-run.ts +255 -0
- package/board/server/reduce-board-settle.ts +88 -0
- package/board/server/reduce-board-steps.ts +226 -0
- package/board/server/reduce-board-text.ts +139 -0
- package/board/server/reduce-board-ticket-checks.ts +168 -0
- package/board/server/reduce-board-ticket-join.ts +144 -0
- package/board/server/reduce-board-ticket-start.ts +132 -0
- package/board/server/reduce-board-update.ts +117 -0
- package/board/server/reduce-board-usage.ts +247 -0
- package/board/server/reduce-board.ts +100 -1917
- package/board/server/reply-post.ts +407 -0
- package/board/server/run-registry.ts +8 -4
- package/board/server/ticket-stages-panel-helpers.ts +296 -0
- package/board/shared/board-rows.ts +9 -0
- package/board/shared/board-rpc.ts +42 -0
- package/board/shared/board-state-counts.ts +77 -0
- package/board/shared/board-state-live.ts +99 -0
- package/board/shared/board-state-review.ts +59 -0
- package/board/shared/board-state-run.ts +236 -0
- package/board/shared/board-state-ticket.ts +257 -0
- package/board/shared/board-state-usage.ts +107 -0
- package/board/shared/board-state.ts +97 -567
- package/board/shared/reply-actions.ts +207 -0
- package/engine/agents/agent-launcher.ts +27 -4
- package/engine/agents/claude-launcher-helpers.ts +233 -0
- package/engine/agents/claude-launcher.ts +28 -669
- package/engine/agents/claude-messages.ts +212 -0
- package/engine/agents/claude-options.ts +43 -8
- package/engine/agents/common-instructions.ts +138 -0
- package/engine/agents/input-channel.ts +36 -0
- package/engine/agents/launch-paths.ts +29 -0
- package/engine/agents/launch-session.ts +227 -0
- package/engine/agents/learner-instructions.ts +31 -0
- package/engine/agents/open-session.ts +210 -0
- package/engine/agents/prompt-sections.ts +95 -0
- package/engine/agents/rejoin-prompts.ts +135 -0
- package/engine/agents/reviewer-instructions.ts +99 -0
- package/engine/agents/role-instructions.ts +31 -244
- package/engine/agents/role-prompts.ts +39 -109
- package/engine/agents/role-results.ts +106 -7
- package/engine/agents/scripted-launcher.ts +21 -6
- package/engine/agents/session-pool.ts +124 -0
- package/engine/agents/turn-progress.ts +283 -0
- package/engine/agents/writer-instructions.ts +151 -0
- package/engine/cli/computer-adapters-real.ts +15 -3
- package/engine/cli/computer-adapters.ts +2 -0
- package/engine/cli/computer-checks.ts +87 -4
- package/engine/cli/config-reload-text.ts +39 -0
- package/engine/cli/decision-model-setup.ts +70 -0
- package/engine/cli/doctor-command.ts +1 -0
- package/engine/cli/doctor.ts +21 -3
- package/engine/cli/going-runs.ts +192 -36
- package/engine/cli/init-command.ts +1 -0
- package/engine/cli/init.ts +23 -1
- package/engine/cli/live-runs.ts +73 -0
- package/engine/cli/luca-run.ts +42 -7
- package/engine/cli/luca-skills.ts +183 -0
- package/engine/cli/luca.ts +8 -1
- package/engine/cli/models-command.ts +119 -0
- package/engine/cli/read-run.ts +81 -0
- package/engine/cli/run-args.ts +33 -6
- package/engine/cli/run-demo.ts +143 -0
- package/engine/cli/run-end.ts +184 -0
- package/engine/cli/run-modes-helpers.ts +81 -0
- package/engine/cli/run-modes.ts +62 -439
- package/engine/cli/setup.ts +5 -48
- package/engine/cli/unfinished-runs.ts +122 -0
- package/engine/cli/upgrade-command.ts +212 -30
- package/engine/cli/upgrade-finish.ts +149 -0
- package/engine/cli/upgrade.ts +112 -71
- package/engine/config/config-fields.ts +127 -0
- package/engine/config/config-reload.ts +250 -0
- package/engine/config/engine-config-schema.ts +235 -0
- package/engine/config/engine-config.ts +72 -142
- package/engine/config/test-commands.ts +102 -0
- package/engine/core/agent-guards-helpers.ts +84 -0
- package/engine/core/agent-turn.ts +395 -0
- package/engine/core/already-done.ts +44 -1
- package/engine/core/build-action.ts +214 -0
- package/engine/core/build-context.ts +135 -0
- package/engine/core/build-launch.ts +259 -0
- package/engine/core/commit-in.ts +282 -0
- package/engine/core/decide-build-early.ts +108 -0
- package/engine/core/decide-build-ending.ts +145 -0
- package/engine/core/decide-build-helpers.ts +87 -0
- package/engine/core/decide-build-tickets.ts +207 -0
- package/engine/core/decide-build-view.ts +103 -0
- package/engine/core/decide-build.ts +101 -1368
- package/engine/core/decide-final-fix.ts +203 -0
- package/engine/core/decide-final-review.ts +55 -310
- package/engine/core/decide-red-green.ts +398 -0
- package/engine/core/decide-rejoin.ts +259 -0
- package/engine/core/decide-repo-wait.ts +129 -0
- package/engine/core/decide-run-budget.ts +86 -12
- package/engine/core/decide-stuck-helpers.ts +127 -0
- package/engine/core/decide-stuck.ts +60 -8
- package/engine/core/decide-ticket-review.ts +95 -0
- package/engine/core/decide-ticket.ts +267 -0
- package/engine/core/decide-waits.ts +47 -0
- package/engine/core/decide.ts +74 -23
- package/engine/core/engine-chores.ts +163 -0
- package/engine/core/environment-rerun.ts +83 -0
- package/engine/core/evidence-text.ts +84 -0
- package/engine/core/execute-action.ts +303 -0
- package/engine/core/execute-already-done-check.ts +133 -0
- package/engine/core/execute-build.ts +68 -944
- package/engine/core/execute-changeset.ts +5 -7
- package/engine/core/execute-final-review.ts +125 -13
- package/engine/core/execute-gates.ts +182 -0
- package/engine/core/execute-intake.ts +130 -0
- package/engine/core/execute-join.ts +276 -0
- package/engine/core/execute-memory.ts +12 -0
- package/engine/core/execute-pull-request.ts +84 -0
- package/engine/core/execute-red-check.ts +219 -0
- package/engine/core/execute-repo-wait.ts +129 -0
- package/engine/core/execute-stuck.ts +25 -10
- package/engine/core/execute-waits.ts +158 -0
- package/engine/core/execute-with-jev.ts +118 -0
- package/engine/core/execute.ts +124 -831
- package/engine/core/final-failure-cap.ts +38 -0
- package/engine/core/final-review-action.ts +125 -0
- package/engine/core/final-review-text.ts +63 -17
- package/engine/core/final-stuck-text.ts +86 -0
- package/engine/core/fix-loop-text.ts +49 -2
- package/engine/core/left-out.ts +120 -0
- package/engine/core/live-file.ts +372 -0
- package/engine/core/loop-caps.ts +25 -2
- package/engine/core/not-in-run.ts +7 -3
- package/engine/core/pull-request-text.ts +255 -6
- package/engine/core/repo-wait-text.ts +81 -0
- package/engine/core/review-text.ts +55 -1
- package/engine/core/run-crash-recovery-helpers.ts +16 -0
- package/engine/core/run-session-close-helpers.ts +96 -0
- package/engine/core/run-start.ts +148 -0
- package/engine/core/run-stuck-text.ts +86 -0
- package/engine/core/schedule-rules.ts +193 -0
- package/engine/core/stuck-detail-text.ts +89 -0
- package/engine/core/stuck-format.ts +22 -0
- package/engine/core/stuck-text.ts +29 -332
- package/engine/core/ticket-stuck-text.ts +192 -0
- package/engine/core/worktree-changes.ts +106 -0
- package/engine/gates/already-done-check.ts +120 -0
- package/engine/gates/feature-map.ts +96 -0
- package/engine/gates/gate-runner.ts +108 -108
- package/engine/gates/gate-schemas.ts +61 -2
- package/engine/gates/leftover-scan.ts +154 -31
- package/engine/gates/new-tests.ts +45 -0
- package/engine/gates/own-files-check.ts +98 -0
- package/engine/gates/prepare-check.ts +60 -0
- package/engine/gates/prepare-slots.ts +99 -0
- package/engine/gates/red-check.ts +184 -16
- package/engine/gates/shell-check.ts +64 -0
- package/engine/gates/slot-waits.ts +55 -0
- package/engine/gates/slow-test-runner.ts +59 -0
- package/engine/gates/test-checks.ts +161 -0
- package/engine/gates/test-runner.ts +164 -5
- package/engine/gates/test-slots.ts +48 -0
- package/engine/git/git-adapter.ts +55 -396
- package/engine/git/git-commits.ts +132 -0
- package/engine/git/git-join.ts +139 -0
- package/engine/git/git-read.ts +123 -0
- package/engine/git/git-run.ts +32 -0
- package/engine/git/git-worktrees.ts +143 -0
- package/engine/git/outside-links.ts +55 -0
- package/engine/guards/after-turn-check.ts +31 -5
- package/engine/guards/guard-hook.ts +60 -12
- package/engine/guards/guard-roles.ts +68 -0
- package/engine/guards/helper-rules.ts +92 -0
- package/engine/guards/permission-rules.ts +161 -0
- package/engine/guards/role-rules-helpers.ts +48 -0
- package/engine/guards/role-rules.ts +34 -606
- package/engine/guards/shell-rules.ts +344 -0
- package/engine/guards/worktree-git.ts +208 -0
- package/engine/guards/worktree-snapshot.ts +412 -0
- package/engine/guards/worktree-state.ts +28 -825
- package/engine/guards/worktree-undo.ts +260 -0
- package/engine/guards/write-rules.ts +149 -0
- package/engine/index.ts +30 -9
- package/engine/intake/criteria-checks.ts +114 -0
- package/engine/intake/intake-checks.ts +164 -30
- package/engine/intake/intake-schemas.ts +37 -2
- package/engine/jev/clef-client.ts +259 -0
- package/engine/jev/decision-model-credentials.ts +212 -0
- package/engine/jev/jev-jobs.ts +144 -60
- package/engine/jev/jev-schemas.ts +86 -5
- package/engine/jev/jev-shadow-helpers.ts +218 -0
- package/engine/jev/jev-shadow.ts +109 -64
- package/engine/jev/model-pick.ts +275 -0
- package/engine/journal/agent-entries.ts +167 -0
- package/engine/journal/agent-message-entries.ts +72 -0
- package/engine/journal/agent-turn-replay.ts +203 -0
- package/engine/journal/already-done-entries.ts +55 -0
- package/engine/journal/commit-entries.ts +56 -0
- package/engine/journal/cross-ticket-replay.ts +222 -0
- package/engine/journal/decision-model-entries.ts +86 -0
- package/engine/journal/entry-fields.ts +10 -0
- package/engine/journal/final-review-entries.ts +128 -0
- package/engine/journal/final-review-replay.ts +324 -0
- package/engine/journal/final-review-round.ts +320 -0
- package/engine/journal/final-review-state.ts +180 -0
- package/engine/journal/gate-entries.ts +81 -0
- package/engine/journal/intake-entries.ts +87 -0
- package/engine/journal/join-entries.ts +126 -0
- package/engine/journal/journal-entry-schema.ts +218 -0
- package/engine/journal/journal-kinds.ts +97 -0
- package/engine/journal/journal-record-schema.ts +218 -0
- package/engine/journal/journal-record.ts +43 -1400
- package/engine/journal/journal.ts +6 -1
- package/engine/journal/limit-entries.ts +90 -0
- package/engine/journal/memory-entries.ts +124 -0
- package/engine/journal/memory-replay.ts +157 -0
- package/engine/journal/plan-replay.ts +139 -0
- package/engine/journal/pull-request-entries.ts +41 -0
- package/engine/journal/replay.ts +157 -2144
- package/engine/journal/reply-replay.ts +144 -0
- package/engine/journal/repo-wait-entries.ts +53 -0
- package/engine/journal/run-entries.ts +172 -0
- package/engine/journal/run-state.ts +264 -0
- package/engine/journal/shared-failure-replay.ts +133 -0
- package/engine/journal/stuck-entries.ts +193 -0
- package/engine/journal/ticket-progress.ts +392 -0
- package/engine/journal/ticket-replay.ts +411 -0
- package/engine/journal/ticket-result-replay.ts +364 -0
- package/engine/journal/ticket-retry-replay.ts +142 -0
- package/engine/journal/worktree-entries.ts +122 -0
- package/engine/models/model-score.ts +512 -0
- package/engine/shell/run-command.ts +187 -18
- package/engine/testing/agent-turn-fixtures.ts +287 -0
- package/engine/testing/already-done-fixtures.ts +97 -0
- package/engine/testing/build-fixtures.ts +68 -973
- package/engine/testing/checkouts-fixtures.ts +48 -0
- package/engine/testing/final-review-fixtures.ts +62 -1
- package/engine/testing/final-review-steps.ts +143 -0
- package/engine/testing/limit-fixtures.ts +85 -0
- package/engine/testing/live-file-fixtures.ts +57 -0
- package/engine/testing/practice-repo.ts +10 -4
- package/engine/testing/practice-run.ts +1 -1
- package/engine/testing/reply-fixtures.ts +88 -0
- package/engine/testing/run-budget-fixtures.ts +165 -0
- package/engine/testing/run-fixtures.ts +219 -0
- package/engine/testing/sdk-play.ts +177 -0
- package/engine/testing/setup-repo.ts +194 -0
- package/engine/testing/step-record-fixtures.ts +55 -0
- package/engine/testing/ticket-step-fixtures.ts +272 -0
- package/engine/testing/wait-scenarios.ts +186 -0
- package/engine/tracker/gh-retry.ts +217 -0
- package/engine/tracker/github-tracker.ts +310 -90
- package/engine/tracker/in-memory-tracker.ts +8 -4
- package/engine/tracker/tracker.ts +131 -6
- package/package.json +2 -1
- package/skills/luca-retro/SKILL.md +74 -0
- package/skills/luca-retro/scripts/retro-summary.ts +1356 -0
- package/skills/luca-unstick/SKILL.md +153 -0
- package/skills/luca-unstick/scripts/stuck-summary.ts +1063 -0
- package/engine/jev/jev-client.ts +0 -173
|
@@ -1,12 +1,43 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* The board's view of one run, as the plugin's server keeps it and the side
|
|
5
3
|
* panel reads it. Shared by both runtimes, so it holds only Zod schemas and
|
|
6
|
-
* plain values. Words follow
|
|
4
|
+
* plain values. Words follow GLOSSARY.md: ticket, blocked, gate, red check,
|
|
7
5
|
* fix loop, ticket review, final review, lens, finding, stuck, skipped ticket,
|
|
8
6
|
* limit wait, shadow mode.
|
|
7
|
+
*
|
|
8
|
+
* The pieces are in modules by responsibility, all re-exported from here:
|
|
9
|
+
* `board-state-ticket.ts` (a ticket's card and its steps),
|
|
10
|
+
* `board-state-run.ts` (the run, its status, its budget, what needs you),
|
|
11
|
+
* `board-state-review.ts` (the final review), `board-state-usage.ts` (plan
|
|
12
|
+
* usage) and `board-state-counts.ts` (what is only counted). This module
|
|
13
|
+
* holds the plugin's constants and the whole `BoardState`.
|
|
9
14
|
*/
|
|
15
|
+
import { z } from 'zod'
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
JevCountsSchema,
|
|
19
|
+
MemoryCountsSchema,
|
|
20
|
+
MessageCountsSchema,
|
|
21
|
+
NO_MEMORY,
|
|
22
|
+
} from './board-state-counts'
|
|
23
|
+
import { LiveAgentSchema, LiveFeedEntrySchema } from './board-state-live'
|
|
24
|
+
import { FinalReviewSchema } from './board-state-review'
|
|
25
|
+
import {
|
|
26
|
+
DEFAULT_CONFIDENCE_BAR,
|
|
27
|
+
DEFAULT_RUN_BUDGET_TOKENS,
|
|
28
|
+
NeedsYouSchema,
|
|
29
|
+
PersonTicketSchema,
|
|
30
|
+
RunInfoSchema,
|
|
31
|
+
} from './board-state-run'
|
|
32
|
+
import { CurrentStepSchema, TicketCardSchema } from './board-state-ticket'
|
|
33
|
+
import { PlanUsedSchema, USAGE_LABEL, UsageSchema } from './board-state-usage'
|
|
34
|
+
|
|
35
|
+
export * from './board-state-counts'
|
|
36
|
+
export * from './board-state-live'
|
|
37
|
+
export * from './board-state-review'
|
|
38
|
+
export * from './board-state-run'
|
|
39
|
+
export * from './board-state-ticket'
|
|
40
|
+
export * from './board-state-usage'
|
|
10
41
|
|
|
11
42
|
/** The plugin id, as in paseo-plugin.json. The engine calls RPCs on it. */
|
|
12
43
|
export const PLUGIN_ID = 'luca-board'
|
|
@@ -15,7 +46,7 @@ export const PLUGIN_ID = 'luca-board'
|
|
|
15
46
|
export const POLL_MS = 2000
|
|
16
47
|
|
|
17
48
|
/** How to call the slash command, as shown to people. */
|
|
18
|
-
export const RUN_USAGE = '/luca-run <spec number> | demo'
|
|
49
|
+
export const RUN_USAGE = '/luca-run <spec number> | demo | resume <run id>'
|
|
19
50
|
|
|
20
51
|
/** The side panel's text when this workspace has no run yet. */
|
|
21
52
|
export const EMPTY_BOARD_TEXT =
|
|
@@ -24,528 +55,13 @@ export const EMPTY_BOARD_TEXT =
|
|
|
24
55
|
/** Fix loops and review rounds are capped at 3. */
|
|
25
56
|
export const LOOP_CAP = 3
|
|
26
57
|
|
|
27
|
-
/** The steps of a ticket, shown as dots on its card. */
|
|
28
|
-
export const STEP_NAMES = [
|
|
29
|
-
'tests',
|
|
30
|
-
'red check',
|
|
31
|
-
'code',
|
|
32
|
-
'checks',
|
|
33
|
-
'review',
|
|
34
|
-
] as const
|
|
35
|
-
|
|
36
|
-
/** Refactor tickets skip the first two steps: no new test can fail first. */
|
|
37
|
-
export const REFACTOR_SKIPS_STEPS = 2
|
|
38
|
-
|
|
39
|
-
/** The step index a ticket has when every step is done. */
|
|
40
|
-
export const ALL_STEPS_DONE = STEP_NAMES.length
|
|
41
|
-
|
|
42
|
-
/** Plan usage is yellow from this percent. */
|
|
43
|
-
export const USAGE_WARN_FROM = 60
|
|
44
|
-
|
|
45
|
-
/** Plan usage is red above this percent. */
|
|
46
|
-
export const USAGE_HIGH_ABOVE = 85
|
|
47
|
-
|
|
48
|
-
export const UsageLevelSchema = z.enum(['ok', 'warn', 'high'])
|
|
49
|
-
|
|
50
|
-
export type UsageLevel = z.infer<typeof UsageLevelSchema>
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* The color level of a plan usage percent: `ok` (green) below 60, `warn`
|
|
54
|
-
* (yellow) from 60 to 85, `high` (red) above 85.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* usageLevel({ percent: 59 }) // 'ok'
|
|
58
|
-
* usageLevel({ percent: 85 }) // 'warn'
|
|
59
|
-
* usageLevel({ percent: 86 }) // 'high'
|
|
60
|
-
*/
|
|
61
|
-
export const usageLevel = ({ percent }: { percent: number }): UsageLevel => {
|
|
62
|
-
if (percent > USAGE_HIGH_ABOVE) return 'high'
|
|
63
|
-
if (percent >= USAGE_WARN_FROM) return 'warn'
|
|
64
|
-
return 'ok'
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Plan windows in words; any other window keeps its raw name. */
|
|
68
|
-
const WINDOW_WORDS: Record<string, string> = {
|
|
69
|
-
five_hour: 'five-hour',
|
|
70
|
-
seven_day: 'weekly',
|
|
71
|
-
seven_day_opus: 'weekly Opus',
|
|
72
|
-
seven_day_sonnet: 'weekly Sonnet',
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* A plan window's name in words.
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* windowWords({ window: 'seven_day_opus' }) // 'weekly Opus'
|
|
80
|
-
* windowWords({ window: 'overage' }) // 'overage'
|
|
81
|
-
*/
|
|
82
|
-
export const windowWords = ({ window }: { window: string }): string =>
|
|
83
|
-
WINDOW_WORDS[window] ?? window
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* The order windows are shown in: five-hour, weekly, the other weekly ones
|
|
87
|
-
* (Opus, Sonnet, ...), then the rest.
|
|
88
|
-
*/
|
|
89
|
-
export const windowRank = ({ window }: { window: string }): number => {
|
|
90
|
-
if (window === 'five_hour') return 0
|
|
91
|
-
if (window === 'seven_day') return 1
|
|
92
|
-
if (window.startsWith('seven_day')) return 2
|
|
93
|
-
return 3
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** How much of one plan window something used, as a whole percent. */
|
|
97
|
-
export const PlanUsedSchema = z.object({
|
|
98
|
-
/** The window in words, such as "five-hour" or "weekly". */
|
|
99
|
-
window: z.string(),
|
|
100
|
-
percent: z.number(),
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
export type PlanUsed = z.infer<typeof PlanUsedSchema>
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* The plan used, in words, windows in their shown order.
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* planUsedText({ used, sign: '+' }) // 'five-hour +1%, weekly +1%'
|
|
110
|
-
* planUsedText({ used, sign: '' }) // 'five-hour 3%, weekly 1%'
|
|
111
|
-
*/
|
|
112
|
-
export const planUsedText = ({
|
|
113
|
-
used,
|
|
114
|
-
sign,
|
|
115
|
-
}: {
|
|
116
|
-
used: PlanUsed[]
|
|
117
|
-
sign: '+' | ''
|
|
118
|
-
}): string =>
|
|
119
|
-
used.map(({ window, percent }) => `${window} ${sign}${percent}%`).join(', ')
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Why the run stopped and what to do, in words. A billing stop, or a stop
|
|
123
|
-
* after the same step crashed again and again, won't go on; any other stop
|
|
124
|
-
* picks up again when the run is started with its run id.
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* stoppedText({ reason: 'overage in use', billing: true })
|
|
128
|
-
* // 'Stopped for billing: overage in use. This run will not go on; ...'
|
|
129
|
-
*/
|
|
130
|
-
export const stoppedText = ({
|
|
131
|
-
reason,
|
|
132
|
-
billing,
|
|
133
|
-
crashed,
|
|
134
|
-
}: {
|
|
135
|
-
reason: string
|
|
136
|
-
billing: boolean
|
|
137
|
-
/** The same run-level step crashed again and again. */
|
|
138
|
-
crashed?: boolean
|
|
139
|
-
}): string => {
|
|
140
|
-
if (billing) {
|
|
141
|
-
return `Stopped for billing: ${reason}. This run will not go on; start a new run once per-token billing is off.`
|
|
142
|
-
}
|
|
143
|
-
if (crashed === true) {
|
|
144
|
-
return `Stopped after crashes: ${reason} This run will not go on; read the engine's log for why it crashed, then start a new run.`
|
|
145
|
-
}
|
|
146
|
-
return `The run stopped: ${reason}. Start it again with the same run id to pick up where it stopped.`
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** Where a run stands, as one word for the header row and the panel. */
|
|
150
|
-
export const RunStatusSchema = z.enum([
|
|
151
|
-
'starting',
|
|
152
|
-
'intake',
|
|
153
|
-
'building',
|
|
154
|
-
'final_review',
|
|
155
|
-
'limit_wait',
|
|
156
|
-
'usage_line_wait',
|
|
157
|
-
'done',
|
|
158
|
-
'refused',
|
|
159
|
-
'nothing_to_do',
|
|
160
|
-
'stuck',
|
|
161
|
-
'stopped',
|
|
162
|
-
'ended_with_error',
|
|
163
|
-
])
|
|
164
|
-
|
|
165
|
-
export type RunStatus = z.infer<typeof RunStatusSchema>
|
|
166
|
-
|
|
167
|
-
/** The part of a run's status the journal sets directly. */
|
|
168
|
-
export const RunPhaseSchema = z.enum([
|
|
169
|
-
'starting',
|
|
170
|
-
'intake',
|
|
171
|
-
'building',
|
|
172
|
-
'final_review',
|
|
173
|
-
'done',
|
|
174
|
-
'refused',
|
|
175
|
-
'nothing_to_do',
|
|
176
|
-
])
|
|
177
|
-
|
|
178
|
-
export type RunPhase = z.infer<typeof RunPhaseSchema>
|
|
179
|
-
|
|
180
|
-
export const TicketStageSchema = z.enum([
|
|
181
|
-
'blocked',
|
|
182
|
-
'building',
|
|
183
|
-
'reviewing',
|
|
184
|
-
'stuck',
|
|
185
|
-
'done',
|
|
186
|
-
'skipped',
|
|
187
|
-
])
|
|
188
|
-
|
|
189
|
-
export type TicketStage = z.infer<typeof TicketStageSchema>
|
|
190
|
-
|
|
191
|
-
export const FindingCountsSchema = z.object({
|
|
192
|
-
blocker: z.number().int().min(0),
|
|
193
|
-
should_fix: z.number().int().min(0),
|
|
194
|
-
nit: z.number().int().min(0),
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
export type FindingCounts = z.infer<typeof FindingCountsSchema>
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* A check whose failure went back to an agent: its fix loop is open. `review`
|
|
201
|
-
* is a ticket review that asked for changes: the next fixer starts a review
|
|
202
|
-
* fix round.
|
|
203
|
-
*/
|
|
204
|
-
export const OpenCheckSchema = z.enum(['red_check', 'gates', 'review'])
|
|
205
|
-
|
|
206
|
-
export type OpenCheck = z.infer<typeof OpenCheckSchema>
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* What the engine is doing right now for a ticket or the run, from its
|
|
210
|
-
* `step_started`, such as "running the baseline tests"; `since` is that
|
|
211
|
-
* record's time. Cleared by the step's `step_ended`.
|
|
212
|
-
*/
|
|
213
|
-
export const CurrentStepSchema = z.object({
|
|
214
|
-
text: z.string(),
|
|
215
|
-
since: z.string(),
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
export type CurrentStep = z.infer<typeof CurrentStepSchema>
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* A time span in words: seconds under a minute, then minutes and seconds,
|
|
222
|
-
* then hours and minutes.
|
|
223
|
-
*
|
|
224
|
-
* @example
|
|
225
|
-
* elapsedText({ ms: 125_000 }) // '2m 5s'
|
|
226
|
-
* elapsedText({ ms: 3_790_000 }) // '1h 3m'
|
|
227
|
-
*/
|
|
228
|
-
export const elapsedText = ({ ms }: { ms: number }): string => {
|
|
229
|
-
const seconds = Math.max(0, Math.floor(ms / 1000))
|
|
230
|
-
const hours = Math.floor(seconds / 3600)
|
|
231
|
-
const minutes = Math.floor((seconds % 3600) / 60)
|
|
232
|
-
if (hours > 0) return `${hours}h ${minutes}m`
|
|
233
|
-
if (minutes > 0) return `${minutes}m ${seconds % 60}s`
|
|
234
|
-
return `${seconds}s`
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* The current step in words, with how long it has been running.
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* currentStepText({
|
|
242
|
-
* step: { text: 'running the checks', since: '2026-09-23T12:00:00.000Z' },
|
|
243
|
-
* now: Date.parse('2026-09-23T12:02:05.000Z'),
|
|
244
|
-
* }) // 'running the checks (2m 5s)'
|
|
245
|
-
*/
|
|
246
|
-
export const currentStepText = ({
|
|
247
|
-
step,
|
|
248
|
-
now,
|
|
249
|
-
}: {
|
|
250
|
-
step: CurrentStep
|
|
251
|
-
now: number
|
|
252
|
-
}): string =>
|
|
253
|
-
`${step.text} (${elapsedText({ ms: now - Date.parse(step.since) })})`
|
|
254
|
-
|
|
255
|
-
export const TicketCardSchema = z.object({
|
|
256
|
-
number: z.number().int(),
|
|
257
|
-
title: z.string(),
|
|
258
|
-
refactor: z.boolean(),
|
|
259
|
-
/** Tickets of this run this one waits on. */
|
|
260
|
-
blockers: z.array(z.number().int()),
|
|
261
|
-
/** The engine has begun work on it (its worktree exists). */
|
|
262
|
-
started: z.boolean(),
|
|
263
|
-
stage: TicketStageSchema,
|
|
264
|
-
/**
|
|
265
|
-
* Index into STEP_NAMES of the current step: -1 not started, 5 when every
|
|
266
|
-
* step is done. A stuck or skipped ticket keeps the step it stopped at.
|
|
267
|
-
*/
|
|
268
|
-
step: z.number().int().min(-1).max(ALL_STEPS_DONE),
|
|
269
|
-
/** One-word (or two) activity, such as "coding" or "reviewing". */
|
|
270
|
-
activity: z.string(),
|
|
271
|
-
/** The role working on it now, `null` when no agent is. */
|
|
272
|
-
role: z.string().nullable(),
|
|
273
|
-
/**
|
|
274
|
-
* The engine's step on it now, `null` between steps. Defaulted, so a
|
|
275
|
-
* board state from before it still parses.
|
|
276
|
-
*/
|
|
277
|
-
current_step: CurrentStepSchema.nullable().default(null),
|
|
278
|
-
/** Fix rounds in the current fix loop; back to 0 once its check passes. */
|
|
279
|
-
fix_round: z.number().int().min(0),
|
|
280
|
-
review_round: z.number().int().min(0),
|
|
281
|
-
/** Review fix rounds so far (up to LOOP_CAP): fixes after a review. */
|
|
282
|
-
review_fix_round: z.number().int().min(0),
|
|
283
|
-
/** The check whose failure the next follow-up answers, if any. */
|
|
284
|
-
open_check: OpenCheckSchema.nullable(),
|
|
285
|
-
/** The role whose latest turn failed, until an agent finishes again. */
|
|
286
|
-
failed_turn: z.string().nullable(),
|
|
287
|
-
tests: z
|
|
288
|
-
.object({
|
|
289
|
-
failing: z.number().int().min(0),
|
|
290
|
-
total: z.number().int().min(0),
|
|
291
|
-
})
|
|
292
|
-
.nullable(),
|
|
293
|
-
/**
|
|
294
|
-
* Its own baseline's test counts, kept so a ticket that reuses this one's
|
|
295
|
-
* baseline (`baseline_reused`) gets them after `tests` has moved on.
|
|
296
|
-
* Defaulted, so a board state from before it still parses.
|
|
297
|
-
*/
|
|
298
|
-
baseline_tests: z
|
|
299
|
-
.object({
|
|
300
|
-
failing: z.number().int().min(0),
|
|
301
|
-
total: z.number().int().min(0),
|
|
302
|
-
})
|
|
303
|
-
.nullable()
|
|
304
|
-
.default(null),
|
|
305
|
-
findings: FindingCountsSchema.nullable(),
|
|
306
|
-
/** Every token the ticket's agents read or wrote, cache reads included. */
|
|
307
|
-
tokens: z.number().min(0),
|
|
308
|
-
/** The same tokens by role. */
|
|
309
|
-
agent_tokens: z.record(z.string(), z.number().min(0)),
|
|
310
|
-
/** What was tried on it so far (failed checks, fix rounds), oldest first. */
|
|
311
|
-
tried: z.array(z.string()),
|
|
312
|
-
/** How much of the plan the ticket used, per window; empty until known. */
|
|
313
|
-
plan_used: z.array(PlanUsedSchema),
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
export type TicketCard = z.infer<typeof TicketCardSchema>
|
|
317
|
-
|
|
318
|
-
/** Stuck work waiting for a one-word reply on the spec issue. */
|
|
319
|
-
export const NeedsYouSchema = z.object({
|
|
320
|
-
/** `ticket-<n>`, `final`, or `run` (the run stuck on its budget). */
|
|
321
|
-
key: z.string(),
|
|
322
|
-
ticket: z.number().int().nullable(),
|
|
323
|
-
subject: z.string(),
|
|
324
|
-
reason: z.string(),
|
|
325
|
-
detail: z.string(),
|
|
326
|
-
/** What was tried before it got stuck, oldest first. */
|
|
327
|
-
tried: z.array(z.string()),
|
|
328
|
-
/** The exact replies to post as a comment on the spec issue. */
|
|
329
|
-
replies: z.array(z.string()),
|
|
330
|
-
since: z.string(),
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
export type NeedsYou = z.infer<typeof NeedsYouSchema>
|
|
334
|
-
|
|
335
|
-
export const LENS_NAMES = [
|
|
336
|
-
'architecture',
|
|
337
|
-
'simplification',
|
|
338
|
-
'security',
|
|
339
|
-
'integration',
|
|
340
|
-
'rules',
|
|
341
|
-
] as const
|
|
342
|
-
|
|
343
|
-
export const LensNameSchema = z.enum(LENS_NAMES)
|
|
344
|
-
|
|
345
|
-
export type LensName = z.infer<typeof LensNameSchema>
|
|
346
|
-
|
|
347
|
-
export const LensStateSchema = z.enum([
|
|
348
|
-
'waiting',
|
|
349
|
-
'reviewing',
|
|
350
|
-
'fixing',
|
|
351
|
-
'clean',
|
|
352
|
-
])
|
|
353
|
-
|
|
354
|
-
export type LensState = z.infer<typeof LensStateSchema>
|
|
355
|
-
|
|
356
|
-
export const LensCardSchema = z.object({
|
|
357
|
-
name: LensNameSchema,
|
|
358
|
-
state: LensStateSchema,
|
|
359
|
-
findings: FindingCountsSchema,
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
export type LensCard = z.infer<typeof LensCardSchema>
|
|
363
|
-
|
|
364
|
-
export const FinalReviewStateSchema = z.enum([
|
|
365
|
-
'waiting',
|
|
366
|
-
'reviewing',
|
|
367
|
-
'fixing',
|
|
368
|
-
'stuck',
|
|
369
|
-
'passed',
|
|
370
|
-
])
|
|
371
|
-
|
|
372
|
-
export type FinalReviewState = z.infer<typeof FinalReviewStateSchema>
|
|
373
|
-
|
|
374
|
-
export const FinalReviewSchema = z.object({
|
|
375
|
-
state: FinalReviewStateSchema,
|
|
376
|
-
/** False (drawn dimmed) until every ticket is done or skipped. */
|
|
377
|
-
active: z.boolean(),
|
|
378
|
-
round: z.number().int().min(0),
|
|
379
|
-
fix_round: z.number().int().min(0),
|
|
380
|
-
lenses: z.array(LensCardSchema),
|
|
381
|
-
/** What was tried on it so far, oldest first. */
|
|
382
|
-
tried: z.array(z.string()),
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
export type FinalReview = z.infer<typeof FinalReviewSchema>
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* The plan's usage, from the rate-limit readings in agents' sessions. Each
|
|
389
|
-
* window keeps its latest reading; `null` until one arrives.
|
|
390
|
-
*/
|
|
391
|
-
export const UsageSchema = z.object({
|
|
392
|
-
five_hour_percent: z.number().nullable(),
|
|
393
|
-
weekly_percent: z.number().nullable(),
|
|
394
|
-
five_hour_level: UsageLevelSchema.nullable(),
|
|
395
|
-
weekly_level: UsageLevelSchema.nullable(),
|
|
396
|
-
/** When the five-hour window resets. */
|
|
397
|
-
resets_at: z.string().nullable(),
|
|
398
|
-
read_at: z.string(),
|
|
399
|
-
})
|
|
400
|
-
|
|
401
|
-
export type Usage = z.infer<typeof UsageSchema>
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* The words on the plan usage: its windows are the whole account's, every
|
|
405
|
-
* run's and chat's, never one run's.
|
|
406
|
-
*/
|
|
407
|
-
export const USAGE_LABEL = 'plan usage (account-wide)'
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* The engine's default run budget in tokens (its
|
|
411
|
-
* `DEFAULT_RUN_BUDGET_TOKENS`, in `engine/src/limits/run-budget.ts`), for a
|
|
412
|
-
* run whose engine config sets no `run_budget_tokens`. The plugin never
|
|
413
|
-
* loads the engine's code, so the number is kept here too.
|
|
414
|
-
*/
|
|
415
|
-
export const DEFAULT_RUN_BUDGET_TOKENS = 9_000_000
|
|
416
|
-
|
|
417
|
-
export const EngineEndedSchema = z.object({
|
|
418
|
-
ok: z.boolean(),
|
|
419
|
-
message: z.string(),
|
|
420
|
-
})
|
|
421
|
-
|
|
422
|
-
export type EngineEnded = z.infer<typeof EngineEndedSchema>
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* The run stopped because going on was unsafe (wrong credentials or plan,
|
|
426
|
-
* a rejected rate limit, overage, ...). Starting it again with the same run
|
|
427
|
-
* id picks the step up again, except after a billing stop, which won't go on.
|
|
428
|
-
*/
|
|
429
|
-
export const RunStoppedSchema = z.object({
|
|
430
|
-
reason: z.string(),
|
|
431
|
-
role: z.string().nullable(),
|
|
432
|
-
ticket: z.number().int().nullable(),
|
|
433
|
-
/** The session would bill per token; this run won't go on. */
|
|
434
|
-
billing: z.boolean(),
|
|
435
|
-
/** The same step crashed again and again; this run won't go on. */
|
|
436
|
-
crashed: z.boolean().default(false),
|
|
437
|
-
since: z.string(),
|
|
438
|
-
})
|
|
439
|
-
|
|
440
|
-
export type RunStopped = z.infer<typeof RunStoppedSchema>
|
|
441
|
-
|
|
442
|
-
export const RunInfoSchema = z.object({
|
|
443
|
-
run_id: z.string(),
|
|
444
|
-
/** `null` for a demo run until the engine names its spec. */
|
|
445
|
-
spec_number: z.number().int().nullable(),
|
|
446
|
-
spec_title: z.string().nullable(),
|
|
447
|
-
demo: z.boolean(),
|
|
448
|
-
branch: z.string().nullable(),
|
|
449
|
-
phase: RunPhaseSchema,
|
|
450
|
-
status: RunStatusSchema,
|
|
451
|
-
pr_url: z.string().nullable(),
|
|
452
|
-
pr_number: z.number().int().nullable(),
|
|
453
|
-
/** Why intake refused the run, one line per problem. */
|
|
454
|
-
refusal: z.array(z.string()),
|
|
455
|
-
started_at: z.string(),
|
|
456
|
-
last_time: z.string().nullable(),
|
|
457
|
-
engine_ended: EngineEndedSchema.nullable(),
|
|
458
|
-
/** Set by `run_stopped`, cleared once the engine moves on. */
|
|
459
|
-
stopped: RunStoppedSchema.nullable(),
|
|
460
|
-
log_path: z.string().nullable(),
|
|
461
|
-
/**
|
|
462
|
-
* Luca's version the run started on (#460); `null` when its journal
|
|
463
|
-
* doesn't say. Defaulted, so an older board state still parses.
|
|
464
|
-
*/
|
|
465
|
-
started_on: z.string().nullable().default(null),
|
|
466
|
-
/**
|
|
467
|
-
* Set once the run resumed on a different Luca version than it started
|
|
468
|
-
* on, naming both. The run keeps going. Defaulted, so an older board
|
|
469
|
-
* state still parses.
|
|
470
|
-
*/
|
|
471
|
-
version_note: z.string().nullable().default(null),
|
|
472
|
-
})
|
|
473
|
-
|
|
474
|
-
export type RunInfo = z.infer<typeof RunInfoSchema>
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Jev in shadow mode: how often the engine asked it and what came back. The
|
|
478
|
-
* engine never acts on the answers, so the board only counts them.
|
|
479
|
-
*/
|
|
480
|
-
export const JevCountsSchema = z.object({
|
|
481
|
-
asked: z.number().int().min(0),
|
|
482
|
-
answered: z.number().int().min(0),
|
|
483
|
-
failed: z.number().int().min(0),
|
|
484
|
-
})
|
|
485
|
-
|
|
486
|
-
export type JevCounts = z.infer<typeof JevCountsSchema>
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Agent messages: `sent` counts the queued and the not delivered ones,
|
|
490
|
-
* `refused` the ones the engine turned down, and `delivered` the messages
|
|
491
|
-
* handed over, once per receiver (a message to `all` can count more than
|
|
492
|
-
* once). Messages happen inside a turn, so the board only counts them.
|
|
493
|
-
*/
|
|
494
|
-
export const MessageCountsSchema = z.object({
|
|
495
|
-
sent: z.number().int().min(0),
|
|
496
|
-
refused: z.number().int().min(0),
|
|
497
|
-
delivered: z.number().int().min(0),
|
|
498
|
-
})
|
|
499
|
-
|
|
500
|
-
export type MessageCounts = z.infer<typeof MessageCountsSchema>
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Where the learner stands at the end of a run (#370): `waiting` until it
|
|
504
|
-
* starts (a run without memory never starts it), `learning`, `learned`
|
|
505
|
-
* once it answered, or `skipped` when the engine gave up on it.
|
|
506
|
-
*/
|
|
507
|
-
export const LearnerStateSchema = z.enum([
|
|
508
|
-
'waiting',
|
|
509
|
-
'learning',
|
|
510
|
-
'learned',
|
|
511
|
-
'skipped',
|
|
512
|
-
])
|
|
513
|
-
|
|
514
|
-
export type LearnerState = z.infer<typeof LearnerStateSchema>
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* Memory (#370), counted: the searches at recall points (and the vault
|
|
518
|
-
* searches among them that failed), the memories they showed agents, the
|
|
519
|
-
* learner, and what became of its memories. Memory changes no ticket, so
|
|
520
|
-
* the board only counts it.
|
|
521
|
-
*/
|
|
522
|
-
export const MemoryCountsSchema = z.object({
|
|
523
|
-
searches: z.number().int().min(0),
|
|
524
|
-
search_errors: z.number().int().min(0),
|
|
525
|
-
shown: z.number().int().min(0),
|
|
526
|
-
learner: LearnerStateSchema,
|
|
527
|
-
added: z.number().int().min(0),
|
|
528
|
-
updated: z.number().int().min(0),
|
|
529
|
-
refused: z.number().int().min(0),
|
|
530
|
-
failed: z.number().int().min(0),
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
export type MemoryCounts = z.infer<typeof MemoryCountsSchema>
|
|
534
|
-
|
|
535
|
-
/** Memory before any of its records. */
|
|
536
|
-
export const NO_MEMORY: MemoryCounts = {
|
|
537
|
-
searches: 0,
|
|
538
|
-
search_errors: 0,
|
|
539
|
-
shown: 0,
|
|
540
|
-
learner: 'waiting',
|
|
541
|
-
added: 0,
|
|
542
|
-
updated: 0,
|
|
543
|
-
refused: 0,
|
|
544
|
-
failed: 0,
|
|
545
|
-
}
|
|
546
|
-
|
|
547
58
|
export const BoardStateSchema = z.object({
|
|
548
59
|
run: RunInfoSchema,
|
|
60
|
+
/**
|
|
61
|
+
* The open tickets left out for a person (#499), by number. Defaulted,
|
|
62
|
+
* so an older board state still parses.
|
|
63
|
+
*/
|
|
64
|
+
for_a_person: z.array(PersonTicketSchema).default([]),
|
|
549
65
|
usage: UsageSchema.nullable(),
|
|
550
66
|
/** What `usage` is, in words. Defaulted, so an older board state still parses. */
|
|
551
67
|
usage_label: z.string().default(USAGE_LABEL),
|
|
@@ -558,12 +74,25 @@ export const BoardStateSchema = z.object({
|
|
|
558
74
|
run_tokens: z.number().min(0).default(0),
|
|
559
75
|
/**
|
|
560
76
|
* The tokens the run may use before it is stuck (#435): one full run
|
|
561
|
-
* budget, plus
|
|
562
|
-
*
|
|
77
|
+
* budget, plus the top-up of each `retry` the owner gave the run stuck
|
|
78
|
+
* on its budget (#543; one whole budget for a retry journaled with no
|
|
79
|
+
* top-up). Defaulted, so an older board state still parses.
|
|
563
80
|
*/
|
|
564
81
|
run_budget_tokens: z.number().min(0).default(DEFAULT_RUN_BUDGET_TOKENS),
|
|
565
82
|
/** One full run budget: the engine config's, else the default. */
|
|
566
83
|
run_budget_each: z.number().min(0).default(DEFAULT_RUN_BUDGET_TOKENS),
|
|
84
|
+
/**
|
|
85
|
+
* Why the whole run is stuck (`run_stuck`'s reason), until the owner's
|
|
86
|
+
* reply; `null` while it isn't. Defaulted, so an older board state
|
|
87
|
+
* still parses.
|
|
88
|
+
*/
|
|
89
|
+
run_stuck_reason: z.string().nullable().default(null),
|
|
90
|
+
/**
|
|
91
|
+
* The engine config's `models.confidence_bar` (#630): the decision
|
|
92
|
+
* model is sharp at or over it. Defaulted, so an older board state
|
|
93
|
+
* still parses.
|
|
94
|
+
*/
|
|
95
|
+
confidence_bar: z.number().min(0).max(1).default(DEFAULT_CONFIDENCE_BAR),
|
|
567
96
|
/** The plan limit was hit; the engine waits and then carries on. */
|
|
568
97
|
limit_wait: z
|
|
569
98
|
.object({
|
|
@@ -593,6 +122,19 @@ export const BoardStateSchema = z.object({
|
|
|
593
122
|
})
|
|
594
123
|
.nullable()
|
|
595
124
|
.default(null),
|
|
125
|
+
/**
|
|
126
|
+
* The run waits for the earlier runs on its repo that are going (#615),
|
|
127
|
+
* from `repo_wait_started` until `repo_wait_ended`. Defaulted, so a
|
|
128
|
+
* board state from before it still parses.
|
|
129
|
+
*/
|
|
130
|
+
repo_wait: z
|
|
131
|
+
.object({
|
|
132
|
+
/** The run ids of the earlier runs it waits for. */
|
|
133
|
+
runs: z.array(z.string()),
|
|
134
|
+
since: z.string(),
|
|
135
|
+
})
|
|
136
|
+
.nullable()
|
|
137
|
+
.default(null),
|
|
596
138
|
/** How much of the plan the whole run used, per window. */
|
|
597
139
|
run_plan_used: z.array(PlanUsedSchema),
|
|
598
140
|
needs_you: z.array(NeedsYouSchema),
|
|
@@ -621,12 +163,41 @@ export const BoardStateSchema = z.object({
|
|
|
621
163
|
run_steps: z
|
|
622
164
|
.array(CurrentStepSchema.extend({ key: z.string() }))
|
|
623
165
|
.default([]),
|
|
166
|
+
/**
|
|
167
|
+
* Every agent in a turn, from the run's live file (#628), those on no
|
|
168
|
+
* ticket too. Laid over the state on each read, never journaled.
|
|
169
|
+
* Defaulted, so a board state from before it still parses.
|
|
170
|
+
*/
|
|
171
|
+
live_agents: z.array(LiveAgentSchema).default([]),
|
|
624
172
|
/** The newest of `run_steps`, `null` when none runs. */
|
|
625
173
|
current_step: CurrentStepSchema.nullable().default(null),
|
|
174
|
+
/**
|
|
175
|
+
* The run's last actions across tickets, oldest first, from its live
|
|
176
|
+
* file (#634), never from the journal. Defaulted, so a board state
|
|
177
|
+
* from before it still parses.
|
|
178
|
+
*/
|
|
179
|
+
feed: z.array(LiveFeedEntrySchema).default([]),
|
|
180
|
+
/**
|
|
181
|
+
* When the engine last wrote the run's live file, `null` with none: its
|
|
182
|
+
* last sign of life (#635). Defaulted, so a board state from before it
|
|
183
|
+
* still parses.
|
|
184
|
+
*/
|
|
185
|
+
live_written_at: z.string().nullable().default(null),
|
|
186
|
+
/**
|
|
187
|
+
* The plugin's process check found no engine for this run, which it
|
|
188
|
+
* didn't start and so never restarts (#635). Defaulted, so a board
|
|
189
|
+
* state from before it still parses.
|
|
190
|
+
*/
|
|
191
|
+
engine_gone: z.boolean().default(false),
|
|
626
192
|
/** Journal records applied so far. */
|
|
627
193
|
event_count: z.number().int().min(0),
|
|
628
194
|
/** The latest thing that happened, in words (for the footer). */
|
|
629
195
|
latest: z.string().nullable(),
|
|
196
|
+
/**
|
|
197
|
+
* When `latest` happened (its record's time), so the footer can say how
|
|
198
|
+
* long ago. Defaulted, so a board state from before it still parses.
|
|
199
|
+
*/
|
|
200
|
+
latest_at: z.string().nullable().default(null),
|
|
630
201
|
})
|
|
631
202
|
|
|
632
203
|
export type BoardState = z.infer<typeof BoardStateSchema>
|
|
@@ -640,44 +211,3 @@ export type BoardState = z.infer<typeof BoardStateSchema>
|
|
|
640
211
|
*/
|
|
641
212
|
export const showsFinalReview = ({ state }: { state: BoardState }): boolean =>
|
|
642
213
|
state.run.phase !== 'nothing_to_do' && state.run.phase !== 'refused'
|
|
643
|
-
|
|
644
|
-
/** One run in the panel's run list. */
|
|
645
|
-
export const RunSummarySchema = z.object({
|
|
646
|
-
run_id: z.string(),
|
|
647
|
-
spec_number: z.number().int().nullable(),
|
|
648
|
-
spec_title: z.string().nullable(),
|
|
649
|
-
demo: z.boolean(),
|
|
650
|
-
status: RunStatusSchema,
|
|
651
|
-
started_at: z.string(),
|
|
652
|
-
needs_you: z.number().int().min(0),
|
|
653
|
-
})
|
|
654
|
-
|
|
655
|
-
export type RunSummary = z.infer<typeof RunSummarySchema>
|
|
656
|
-
|
|
657
|
-
/** How many of the newest runs get a tab; the older ones are folded. */
|
|
658
|
-
export const RECENT_RUN_TABS = 6
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Splits runs (newest first) into the ones with a tab and the folded older
|
|
662
|
-
* ones. A picked older run keeps a tab too, after the newest ones.
|
|
663
|
-
*
|
|
664
|
-
* @example
|
|
665
|
-
* const { shown, folded } = foldRuns({ runs, selected: picked })
|
|
666
|
-
*/
|
|
667
|
-
export const foldRuns = ({
|
|
668
|
-
runs,
|
|
669
|
-
selected,
|
|
670
|
-
}: {
|
|
671
|
-
runs: RunSummary[]
|
|
672
|
-
selected: string | null
|
|
673
|
-
}): { shown: RunSummary[]; folded: RunSummary[] } => {
|
|
674
|
-
const shown = runs.slice(0, RECENT_RUN_TABS)
|
|
675
|
-
const older = runs.slice(RECENT_RUN_TABS)
|
|
676
|
-
const picked = older.find((run) => run.run_id === selected)
|
|
677
|
-
return picked
|
|
678
|
-
? {
|
|
679
|
-
shown: [...shown, picked],
|
|
680
|
-
folded: older.filter((run) => run !== picked),
|
|
681
|
-
}
|
|
682
|
-
: { shown, folded: older }
|
|
683
|
-
}
|