@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
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
|
|
5
|
+
import { createHarness } from './testing/board-harness'
|
|
6
|
+
import {
|
|
7
|
+
intakeOfThree,
|
|
8
|
+
nothingToDo,
|
|
9
|
+
pullRequestOpened,
|
|
10
|
+
runStarted,
|
|
11
|
+
stamp,
|
|
12
|
+
ticketStuck,
|
|
13
|
+
ticketWorktreeCreated,
|
|
14
|
+
wholeTicket,
|
|
15
|
+
type Entry,
|
|
16
|
+
} from './testing/journal-fixtures'
|
|
17
|
+
|
|
18
|
+
import type { BoardState } from '../shared/board-state'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Helpers shared by the journal rebuild tests (`journal-rebuild.test.ts` and
|
|
22
|
+
* the `journal-rebuild-*.test.ts` files beside it).
|
|
23
|
+
*
|
|
24
|
+
* Each test writes journals to a runs folder
|
|
25
|
+
* (`<runs_dir>/<run_id>/journal.jsonl`, as the engine does) and reads the
|
|
26
|
+
* board a plugin built from them. The folders a test makes are in `dirs`;
|
|
27
|
+
* each test file removes them after every test.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export const dirs: string[] = []
|
|
31
|
+
|
|
32
|
+
export const tempDir = async () => {
|
|
33
|
+
const dir = await mkdtemp(join(tmpdir(), 'luca-board-journal-'))
|
|
34
|
+
dirs.push(dir)
|
|
35
|
+
return dir
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** A registry folder and a runs folder that outlive one plugin. */
|
|
39
|
+
export const disk = async () => ({
|
|
40
|
+
registry_dir: await tempDir(),
|
|
41
|
+
runs_dir: await tempDir(),
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
/** The repo of the harness's chats, and so the folder of workspace `ws-1`. */
|
|
45
|
+
export const REPO = '/repo'
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The entries with their `run_started` naming the repo the run is on, as
|
|
49
|
+
* the engine journals it.
|
|
50
|
+
*/
|
|
51
|
+
export const inRepo = ({ entries }: { entries: Entry[] }): Entry[] =>
|
|
52
|
+
entries.map((entry) =>
|
|
53
|
+
entry.kind === 'run_started'
|
|
54
|
+
? {
|
|
55
|
+
...entry,
|
|
56
|
+
content: { ...(entry.content as object), repo: REPO },
|
|
57
|
+
}
|
|
58
|
+
: entry
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Writes a run on `REPO`'s journal the way the engine does: one JSON line
|
|
63
|
+
* per record.
|
|
64
|
+
*/
|
|
65
|
+
export const writeJournal = async ({
|
|
66
|
+
runs_dir,
|
|
67
|
+
run_id,
|
|
68
|
+
entries,
|
|
69
|
+
}: {
|
|
70
|
+
runs_dir: string
|
|
71
|
+
run_id: string
|
|
72
|
+
entries: Entry[]
|
|
73
|
+
}) => {
|
|
74
|
+
await mkdir(join(runs_dir, run_id), { recursive: true })
|
|
75
|
+
const lines = stamp({ entries: inRepo({ entries }) }).map((record) =>
|
|
76
|
+
JSON.stringify(record)
|
|
77
|
+
)
|
|
78
|
+
await writeFile(
|
|
79
|
+
join(runs_dir, run_id, 'journal.jsonl'),
|
|
80
|
+
`${lines.join('\n')}\n`
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A board plugin on `registry_dir` and `runs_dir`, built with the shared
|
|
86
|
+
* harness. Making a second one on the same folders is a reload.
|
|
87
|
+
*/
|
|
88
|
+
export const plugin = async ({
|
|
89
|
+
registry_dir,
|
|
90
|
+
runs_dir,
|
|
91
|
+
}: {
|
|
92
|
+
registry_dir: string
|
|
93
|
+
runs_dir: string
|
|
94
|
+
}) => {
|
|
95
|
+
const harness = await createHarness({ registry_dir, runs_dir })
|
|
96
|
+
|
|
97
|
+
/** Starts a run from a chat, as `/luca-run 10` does. */
|
|
98
|
+
const start = async () => {
|
|
99
|
+
const { output, run_id, token } = await harness.start()
|
|
100
|
+
if (!output.ok) throw new Error(output.message)
|
|
101
|
+
return { run_id, token }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** One run's full state, as the side panel of `ws-1` (in `REPO`) reads it. */
|
|
105
|
+
const stateOf = async ({
|
|
106
|
+
run_id,
|
|
107
|
+
}: {
|
|
108
|
+
run_id: string
|
|
109
|
+
}): Promise<BoardState> => {
|
|
110
|
+
const { selected } = await harness.board.readBoard({
|
|
111
|
+
workspace_id: 'ws-1',
|
|
112
|
+
directory: REPO,
|
|
113
|
+
run_id,
|
|
114
|
+
})
|
|
115
|
+
if (selected?.run.run_id !== run_id) {
|
|
116
|
+
throw new Error(`the board doesn't show run ${run_id}`)
|
|
117
|
+
}
|
|
118
|
+
return selected
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return { ...harness, start, stateOf }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** A whole run of spec 10: three tickets built, the review passed, a PR. */
|
|
125
|
+
export const finishedRun = (): Entry[] => [
|
|
126
|
+
...intakeOfThree(),
|
|
127
|
+
...wholeTicket({ ticket: 11 }),
|
|
128
|
+
...wholeTicket({ ticket: 12 }),
|
|
129
|
+
...wholeTicket({ ticket: 13 }),
|
|
130
|
+
pullRequestOpened({
|
|
131
|
+
number: 408,
|
|
132
|
+
url: 'https://github.com/acme/app/pull/408',
|
|
133
|
+
}),
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
/** Spec 10 with ticket 13 stuck and nothing else running. */
|
|
137
|
+
export const stuckRun = (): Entry[] => [
|
|
138
|
+
...intakeOfThree(),
|
|
139
|
+
ticketWorktreeCreated({ ticket: 13 }),
|
|
140
|
+
ticketStuck({ ticket: 13, reason: 'red_check_failed', detail: 'x' }),
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
export const nothingToDoRun = (): Entry[] => [
|
|
144
|
+
runStarted({ spec: 10 }),
|
|
145
|
+
nothingToDo(),
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
/** A run the board launched, whose journal then went on without it. */
|
|
149
|
+
export const launchedRun = async ({
|
|
150
|
+
registry_dir,
|
|
151
|
+
runs_dir,
|
|
152
|
+
entries,
|
|
153
|
+
}: {
|
|
154
|
+
registry_dir: string
|
|
155
|
+
runs_dir: string
|
|
156
|
+
entries: Entry[]
|
|
157
|
+
}) => {
|
|
158
|
+
const first = await plugin({ registry_dir, runs_dir })
|
|
159
|
+
const { run_id, token } = await first.start()
|
|
160
|
+
await first.board.handleEngineEvent({
|
|
161
|
+
run_id,
|
|
162
|
+
token,
|
|
163
|
+
records: stamp({ entries: [runStarted({ spec: 10 })] }),
|
|
164
|
+
ended: null,
|
|
165
|
+
})
|
|
166
|
+
await first.board.idle()
|
|
167
|
+
await writeJournal({ runs_dir, run_id, entries })
|
|
168
|
+
return { run_id, token }
|
|
169
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run's live file (#628): `<runs_dir>/<run_id>/live.json`, what each
|
|
3
|
+
* agent in a turn is doing now, as the engine keeps it beside the journal.
|
|
4
|
+
* The board reads it on each read, for the runs it started and the ones it
|
|
5
|
+
* didn't, and lays it over the state the journal made. Only the latest
|
|
6
|
+
* file counts; nothing of it is stored or replayed.
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from 'node:fs/promises'
|
|
9
|
+
import { join } from 'node:path'
|
|
10
|
+
|
|
11
|
+
import { z } from 'zod'
|
|
12
|
+
|
|
13
|
+
import { RateLimitReadingSchema } from './board-vocabulary-shapes'
|
|
14
|
+
import { usageAfter } from './reduce-board-usage'
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
LiveAgentSchema,
|
|
18
|
+
LiveFeedEntrySchema,
|
|
19
|
+
LiveWaitSchema,
|
|
20
|
+
type BoardState,
|
|
21
|
+
} from '../shared/board-state'
|
|
22
|
+
|
|
23
|
+
/** The live file's name inside a run folder. */
|
|
24
|
+
export const LIVE_FILE = 'live.json'
|
|
25
|
+
|
|
26
|
+
const LiveFileSchema = z.object({
|
|
27
|
+
written_at: z.string(),
|
|
28
|
+
/** The run's first plan-usage reading, with its `arrived_at`. */
|
|
29
|
+
plan_usage: RateLimitReadingSchema.extend({
|
|
30
|
+
arrived_at: z.string().optional().catch(undefined),
|
|
31
|
+
})
|
|
32
|
+
.nullable()
|
|
33
|
+
.catch(null)
|
|
34
|
+
.default(null),
|
|
35
|
+
/** Each agent's entry; one that doesn't read is left out. */
|
|
36
|
+
agents: z
|
|
37
|
+
.array(z.unknown())
|
|
38
|
+
.catch([])
|
|
39
|
+
.transform((agents) =>
|
|
40
|
+
agents.flatMap((agent) => {
|
|
41
|
+
const parsed = LiveAgentSchema.safeParse(agent)
|
|
42
|
+
return parsed.success ? [parsed.data] : []
|
|
43
|
+
})
|
|
44
|
+
),
|
|
45
|
+
/**
|
|
46
|
+
* The waits inside a step going now (#632); one that doesn't read is
|
|
47
|
+
* left out, and a file from before them has none.
|
|
48
|
+
*/
|
|
49
|
+
waits: z
|
|
50
|
+
.array(z.unknown())
|
|
51
|
+
.catch([])
|
|
52
|
+
.transform((waits) =>
|
|
53
|
+
waits.flatMap((wait) => {
|
|
54
|
+
const parsed = LiveWaitSchema.safeParse(wait)
|
|
55
|
+
return parsed.success ? [parsed.data] : []
|
|
56
|
+
})
|
|
57
|
+
),
|
|
58
|
+
/**
|
|
59
|
+
* The run's last actions, oldest first (#634); one that doesn't read is
|
|
60
|
+
* left out, and a file from before it has none.
|
|
61
|
+
*/
|
|
62
|
+
feed: z
|
|
63
|
+
.array(z.unknown())
|
|
64
|
+
.catch([])
|
|
65
|
+
.default([])
|
|
66
|
+
.transform((feed) =>
|
|
67
|
+
feed.flatMap((entry) => {
|
|
68
|
+
const parsed = LiveFeedEntrySchema.safeParse(entry)
|
|
69
|
+
return parsed.success ? [parsed.data] : []
|
|
70
|
+
})
|
|
71
|
+
),
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
export type LiveFile = z.infer<typeof LiveFileSchema>
|
|
75
|
+
|
|
76
|
+
/** A run's live file, or `null` when it has none or it doesn't read. */
|
|
77
|
+
export const readLiveFile = async ({
|
|
78
|
+
runs_dir,
|
|
79
|
+
run_id,
|
|
80
|
+
}: {
|
|
81
|
+
runs_dir: string
|
|
82
|
+
run_id: string
|
|
83
|
+
}): Promise<LiveFile | null> => {
|
|
84
|
+
try {
|
|
85
|
+
const text = await readFile(join(runs_dir, run_id, LIVE_FILE), 'utf8')
|
|
86
|
+
const parsed = LiveFileSchema.safeParse(JSON.parse(text))
|
|
87
|
+
return parsed.success ? parsed.data : null
|
|
88
|
+
} catch {
|
|
89
|
+
return null
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The state with its live file laid over it: each card gets its agent's
|
|
95
|
+
* entry (or none) and its check's slot wait (or none), the feed and
|
|
96
|
+
* `written_at` are the file's, and the plan usage, with no reading yet,
|
|
97
|
+
* fills in from the file's first one.
|
|
98
|
+
*/
|
|
99
|
+
export const withLive = ({
|
|
100
|
+
state,
|
|
101
|
+
live,
|
|
102
|
+
}: {
|
|
103
|
+
state: BoardState
|
|
104
|
+
live: LiveFile | null
|
|
105
|
+
}): BoardState => {
|
|
106
|
+
const agents = live?.agents ?? []
|
|
107
|
+
const waits = live?.waits ?? []
|
|
108
|
+
const reading = live?.plan_usage ?? null
|
|
109
|
+
return {
|
|
110
|
+
...state,
|
|
111
|
+
live_agents: agents,
|
|
112
|
+
tickets: state.tickets.map((card) => ({
|
|
113
|
+
...card,
|
|
114
|
+
live: agents.find((agent) => agent.ticket === card.number) ?? null,
|
|
115
|
+
slot_wait:
|
|
116
|
+
waits.find((wait) => wait.ticket === card.number) ?? null,
|
|
117
|
+
})),
|
|
118
|
+
feed: live?.feed ?? [],
|
|
119
|
+
live_written_at: live?.written_at ?? null,
|
|
120
|
+
usage:
|
|
121
|
+
state.usage ??
|
|
122
|
+
(reading === null || live === null
|
|
123
|
+
? null
|
|
124
|
+
: usageAfter({
|
|
125
|
+
usage: null,
|
|
126
|
+
readings: [reading],
|
|
127
|
+
time: reading.arrived_at ?? live.written_at,
|
|
128
|
+
})),
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** The Luca version of this board, stamped when the package was packed. */
|
|
2
|
-
export const LUCA_VERSION: string = "14.0.0-alpha.
|
|
2
|
+
export const LUCA_VERSION: string = "14.0.0-alpha.21"
|