@joshuafolkken/kit 1.3041.0 → 1.3044.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/workflow-commands/progress-watcher.md +10 -8
- package/dist/.inputs-verified.json +1 -1
- package/dist/commands/backlogrun-cli.js +1 -1
- package/dist/commands/{chunk-IF3EIFK4.js → chunk-24OATKOF.js} +34 -15
- package/dist/commands/{chunk-Z3WGHIVB.js → chunk-LZPPSOTP.js} +1 -1
- package/dist/commands/inputs.json +1555 -1555
- package/dist/commands/metrics-command.js +1 -1
- package/dist/commands/run-board-main.js +1 -1
- package/dist/commands/session-language-main.js +1 -1
- package/dist/hooks/inputs.json +447 -447
- package/dist/hooks/session-lang.js +1 -1
- package/dist/inputs.json +60 -60
- package/package.json +1 -1
- package/scripts/josh/session-language-cli.ts +1 -1
- package/scripts/run/board/run-board-header.ts +4 -5
- package/scripts/run/board/run-board-read.ts +7 -1
- package/scripts/run/board/run-board-roots.ts +25 -2
- package/scripts/run/board/run-board-setup.ts +13 -7
- package/scripts/run/board/run-board-status.ts +2 -0
- package/scripts/run/board/run-board-tick.ts +7 -1
|
@@ -1054,7 +1054,7 @@ var session_handoff_line = {
|
|
|
1054
1054
|
|
|
1055
1055
|
// scripts/josh/session-language-cli.ts
|
|
1056
1056
|
var { DEFAULT_SESSION_LANG, ENV_KEY, resolve_session_lang } = session_language;
|
|
1057
|
-
var BOARD_LINE = "
|
|
1057
|
+
var BOARD_LINE = "Live backlogrun: for progress-only questions, run `pnpm josh run:board --chat`; relay output verbatim in one code block. For cause or improvement questions, investigate state, logs and code; cite evidence and uncertainty, even with quoted board lines. For mixed questions, do both.";
|
|
1058
1058
|
var LIVE_PORTS = {
|
|
1059
1059
|
repository_directory: run_carry.repository_directory,
|
|
1060
1060
|
is_running: backlogrun_launch.is_running
|
package/dist/inputs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"digest": "
|
|
2
|
+
"digest": "eda527eb5ac4613c8f26ec5b3ee11d167fbb152a7cc10d250d57365c9ce5e46e",
|
|
3
3
|
"inputs": [
|
|
4
4
|
"scripts/build/build-hooks.ts",
|
|
5
5
|
"scripts/build/build-bin.ts",
|
|
@@ -38,20 +38,20 @@
|
|
|
38
38
|
"scripts/josh/command-usage.ts",
|
|
39
39
|
"scripts/josh/josh-gh-usage.ts",
|
|
40
40
|
"scripts/josh/josh-logic.ts",
|
|
41
|
-
"scripts/issue/issue-number-shape.ts",
|
|
42
|
-
"scripts/gh/gh-core-rate-limit.ts",
|
|
43
|
-
"scripts/gh/gh-request-tally.ts",
|
|
44
|
-
"scripts/gh/gh-usage-event.ts",
|
|
45
|
-
"scripts/gh/git-gh-exec.ts",
|
|
46
41
|
"scripts/josh/josh-command-map.ts",
|
|
47
42
|
"scripts/josh/josh-aliases.ts",
|
|
48
43
|
"scripts/version/kit-descriptor.ts",
|
|
49
|
-
"scripts/
|
|
44
|
+
"scripts/issue/issue-number-shape.ts",
|
|
45
|
+
"scripts/lib/package-manifest.ts",
|
|
50
46
|
"scripts/git/git-spawn-sync.ts",
|
|
51
47
|
"scripts/lib/json-value.ts",
|
|
52
|
-
"scripts/lib/package-manifest.ts",
|
|
53
48
|
"scripts/lib/read-file.ts",
|
|
54
49
|
"scripts/lib/timeouts.ts",
|
|
50
|
+
"scripts/gh/gh-core-rate-limit.ts",
|
|
51
|
+
"scripts/gh/gh-request-tally.ts",
|
|
52
|
+
"scripts/gh/gh-usage-event.ts",
|
|
53
|
+
"scripts/gh/git-gh-exec.ts",
|
|
54
|
+
"scripts/josh/run-github-prerequisite.ts",
|
|
55
55
|
"scripts/build/local-bin.ts",
|
|
56
56
|
"scripts/gate/core-budget.ts",
|
|
57
57
|
"scripts/hooks/hook-lap.ts",
|
|
@@ -63,19 +63,13 @@
|
|
|
63
63
|
"scripts/josh/josh-in-process.ts",
|
|
64
64
|
"scripts/josh/kit-only.ts",
|
|
65
65
|
"scripts/josh/package-directory.ts",
|
|
66
|
+
"scripts/josh/josh-commands-workflow.ts",
|
|
67
|
+
"scripts/lib/ancestor-directories.ts",
|
|
68
|
+
"scripts/git/git-location-environment.ts",
|
|
66
69
|
"scripts/gh/gh-usage-log.ts",
|
|
67
|
-
"scripts/lib/error-message.ts",
|
|
68
|
-
"scripts/run/carry/run-carry.ts",
|
|
69
70
|
"scripts/gh/git-gh-spawn-width.ts",
|
|
70
|
-
"scripts/
|
|
71
|
-
"scripts/
|
|
72
|
-
"scripts/lib/bounded-pool.ts",
|
|
73
|
-
"scripts/josh/agent-session-environment.ts",
|
|
74
|
-
"scripts/gh/git-gh-check.ts",
|
|
75
|
-
"scripts/git/git-execa-error.ts",
|
|
76
|
-
"scripts/gh/git-gh-retry.ts",
|
|
77
|
-
"scripts/gh/git-gh-failure.ts",
|
|
78
|
-
"scripts/josh/josh-commands-workflow.ts",
|
|
71
|
+
"scripts/discovery/repo-origin.ts",
|
|
72
|
+
"scripts/lib/pnpm-reach.ts",
|
|
79
73
|
"scripts/josh/josh-commands-ai.ts",
|
|
80
74
|
"scripts/josh/josh-commands-clone.ts",
|
|
81
75
|
"scripts/josh/josh-commands-development.ts",
|
|
@@ -84,12 +78,20 @@
|
|
|
84
78
|
"scripts/josh/josh-commands-maintenance.ts",
|
|
85
79
|
"scripts/josh/josh-commands-project.ts",
|
|
86
80
|
"scripts/josh/josh-commands-versioning.ts",
|
|
87
|
-
"scripts/run/ship/run-ship-lap.ts",
|
|
88
|
-
"scripts/lib/ancestor-directories.ts",
|
|
89
|
-
"scripts/lib/pnpm-reach.ts",
|
|
90
|
-
"scripts/git/git-location-environment.ts",
|
|
91
81
|
"scripts/git/constants.ts",
|
|
92
|
-
"scripts/
|
|
82
|
+
"scripts/lib/error-message.ts",
|
|
83
|
+
"scripts/run/carry/run-carry.ts",
|
|
84
|
+
"scripts/git/git-execa-error.ts",
|
|
85
|
+
"scripts/josh/agent-session-environment.ts",
|
|
86
|
+
"scripts/lib/bounded-pool.ts",
|
|
87
|
+
"scripts/lib/token-shape.ts",
|
|
88
|
+
"scripts/gh/gh-call-kind.ts",
|
|
89
|
+
"scripts/gh/git-gh-check.ts",
|
|
90
|
+
"scripts/gh/git-gh-failure.ts",
|
|
91
|
+
"scripts/gh/git-gh-retry.ts",
|
|
92
|
+
"scripts/run/ship/run-ship-lap.ts",
|
|
93
|
+
"scripts/josh/josh-command-types.ts",
|
|
94
|
+
"ports/index.js",
|
|
93
95
|
"scripts/gate/machine-capacity.ts",
|
|
94
96
|
"scripts/josh/platform-temporary.ts",
|
|
95
97
|
"scripts/josh/process-identity.ts",
|
|
@@ -102,66 +104,64 @@
|
|
|
102
104
|
"scripts/gate/core-reservation.ts",
|
|
103
105
|
"scripts/gate/core-wait.ts",
|
|
104
106
|
"scripts/gate/core-wait-record.ts",
|
|
105
|
-
"scripts/josh/josh-command-types.ts",
|
|
106
107
|
"scripts/gate/core-weights.ts",
|
|
107
108
|
"scripts/gate/held-mark.ts",
|
|
108
|
-
"
|
|
109
|
-
"scripts/
|
|
109
|
+
"scripts/lib/atomic-write.ts",
|
|
110
|
+
"scripts/test/unit-run-marker.ts",
|
|
111
|
+
"scripts/gate/core-priority.ts",
|
|
112
|
+
"scripts/lane/lane-paths.ts",
|
|
113
|
+
"scripts/lane/lane-ledger-write.ts",
|
|
110
114
|
"scripts/run/carry/run-carry-conversation.ts",
|
|
111
115
|
"scripts/rules/gh-api.ts",
|
|
112
116
|
"scripts/git/parse-json-array.ts",
|
|
113
117
|
"scripts/git/repository-lock.ts",
|
|
114
118
|
"scripts/agent/agent-provider.ts",
|
|
115
119
|
"scripts/git/git-command.ts",
|
|
120
|
+
"scripts/josh/durable-state.ts",
|
|
116
121
|
"scripts/run/run-invocation.ts",
|
|
117
122
|
"scripts/run/carry/run-carry-added.ts",
|
|
118
123
|
"scripts/run/carry/run-carry-change.ts",
|
|
119
124
|
"scripts/josh/josh-commands-ship.ts",
|
|
120
|
-
"scripts/josh/josh-commands-
|
|
121
|
-
"scripts/
|
|
122
|
-
"scripts/
|
|
123
|
-
"scripts/
|
|
124
|
-
"scripts/gate/core-priority.ts",
|
|
125
|
-
"scripts/lane/lane-paths.ts",
|
|
125
|
+
"scripts/josh/josh-commands-backlog.ts",
|
|
126
|
+
"scripts/josh/josh-commands-document.ts",
|
|
127
|
+
"scripts/josh/josh-commands-epic.ts",
|
|
128
|
+
"scripts/josh/josh-commands-issue.ts",
|
|
126
129
|
"scripts/josh/josh-commands-review.ts",
|
|
130
|
+
"scripts/josh/josh-commands-run.ts",
|
|
131
|
+
"scripts/josh/josh-commands-test-check.ts",
|
|
132
|
+
"scripts/gate/gate-plan.ts",
|
|
133
|
+
"scripts/josh/josh-commands-agent-hooks.ts",
|
|
127
134
|
"scripts/init/init-paths.ts",
|
|
135
|
+
"scripts/test/unit-lane-count.ts",
|
|
136
|
+
"scripts/josh/process-owner.ts",
|
|
137
|
+
"scripts/josh/josh-commands-issue-write.ts",
|
|
138
|
+
"scripts/josh/josh-commands-progress.ts",
|
|
139
|
+
"scripts/gate/gate-labels.ts",
|
|
140
|
+
"scripts/lane/lane-state-record.ts",
|
|
141
|
+
"scripts/cost-runtime/own-session.ts",
|
|
142
|
+
"scripts/josh/josh-commands-pause.ts",
|
|
143
|
+
"scripts/josh/josh-commands-prime.ts",
|
|
144
|
+
"scripts/josh/josh-verdict.ts",
|
|
145
|
+
"scripts/gate/gate-checks.ts",
|
|
146
|
+
"scripts/discovery/git-directory.ts",
|
|
147
|
+
"scripts/josh/durable-state-root.ts",
|
|
148
|
+
"scripts/lane/lane-ledger-kind.ts",
|
|
128
149
|
"scripts/rules/git-argv.ts",
|
|
129
150
|
"scripts/git/git-common-directory.ts",
|
|
130
151
|
"scripts/git/git-spawn.ts",
|
|
131
|
-
"scripts/lib/cli-flags.ts",
|
|
132
152
|
"scripts/run/carry/run-carry-streak.ts",
|
|
133
|
-
"scripts/lane/lane-ledger-kind.ts",
|
|
134
|
-
"scripts/cost-runtime/own-session.ts",
|
|
135
153
|
"scripts/cost-runtime/cost-transcript.ts",
|
|
136
|
-
"scripts/
|
|
137
|
-
"scripts/
|
|
138
|
-
"scripts/josh/
|
|
139
|
-
"scripts/josh/josh-commands-backlog.ts",
|
|
140
|
-
"scripts/test/unit-lane-count.ts",
|
|
141
|
-
"scripts/gate/gate-plan.ts",
|
|
142
|
-
"scripts/josh/process-owner.ts",
|
|
154
|
+
"scripts/issue/issue-body-keys.ts",
|
|
155
|
+
"scripts/lib/status-icons.ts",
|
|
156
|
+
"scripts/josh/durable-state-migrate.ts",
|
|
143
157
|
"scripts/git/git-diff-reads.ts",
|
|
144
158
|
"scripts/git/git-pre-push-hook.ts",
|
|
145
159
|
"scripts/git/git-push-transport.ts",
|
|
146
|
-
"scripts/
|
|
147
|
-
"scripts/josh/
|
|
148
|
-
"scripts/josh/durable-state-root.ts",
|
|
149
|
-
"scripts/josh/durable-state-migrate.ts",
|
|
160
|
+
"scripts/lib/cli-flags.ts",
|
|
161
|
+
"scripts/josh/session-language.ts",
|
|
150
162
|
"scripts/git/git-ssh-keepalive.ts",
|
|
151
|
-
"scripts/josh/josh-commands-progress.ts",
|
|
152
|
-
"scripts/lane/lane-state-record.ts",
|
|
153
|
-
"scripts/gate/gate-labels.ts",
|
|
154
|
-
"scripts/josh/josh-commands-pause.ts",
|
|
155
|
-
"scripts/josh/josh-commands-prime.ts",
|
|
156
|
-
"scripts/discovery/git-directory.ts",
|
|
157
|
-
"scripts/josh/josh-verdict.ts",
|
|
158
|
-
"scripts/gate/gate-checks.ts",
|
|
159
|
-
"scripts/josh/josh-commands-issue-write.ts",
|
|
160
163
|
"scripts/cost-runtime/cost-usage.ts",
|
|
161
|
-
"scripts/time-runtime/time-instant.ts"
|
|
162
|
-
"scripts/lib/status-icons.ts",
|
|
163
|
-
"scripts/issue/issue-body-keys.ts",
|
|
164
|
-
"scripts/josh/session-language.ts"
|
|
164
|
+
"scripts/time-runtime/time-instant.ts"
|
|
165
165
|
],
|
|
166
166
|
"outputs": [
|
|
167
167
|
"josh.js"
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.3044.0",
|
|
3
3
|
"name": "@joshuafolkken/kit",
|
|
4
4
|
"description": "Hand-off kit for Claude Code and Codex: backlogrun takes your GitHub Issues to tested, reviewed, merged PRs — in parallel and unattended — with the rules, hooks and checks that keep the agent on track",
|
|
5
5
|
"keywords": [
|
|
@@ -32,7 +32,7 @@ import { session_language, type Resolution } from './session-language'
|
|
|
32
32
|
const { DEFAULT_SESSION_LANG, ENV_KEY, resolve_session_lang } = session_language
|
|
33
33
|
|
|
34
34
|
const BOARD_LINE =
|
|
35
|
-
'
|
|
35
|
+
'Live backlogrun: for progress-only questions, run `pnpm josh run:board --chat`; relay output verbatim in one code block. For cause or improvement questions, investigate state, logs and code; cite evidence and uncertainty, even with quoted board lines. For mixed questions, do both.'
|
|
36
36
|
|
|
37
37
|
interface LivePorts {
|
|
38
38
|
// The common git directory the run's records are keyed on; `undefined` outside a repository.
|
|
@@ -19,6 +19,7 @@ import type { QuotaHold, QuotaView } from './run-board-render-quota'
|
|
|
19
19
|
import { run_board_render_slot } from './run-board-render-slot'
|
|
20
20
|
import { run_board_render_title } from './run-board-render-title'
|
|
21
21
|
import type { SeatRead } from './run-board-seat'
|
|
22
|
+
import { run_board_setup } from './run-board-setup'
|
|
22
23
|
import type { RunActivity } from './run-board-status'
|
|
23
24
|
import type { LaneUsages, UsageScale } from './run-board-usage'
|
|
24
25
|
import type { UsualTimes } from './run-board-usual'
|
|
@@ -46,7 +47,6 @@ const { padded } = run_board_fresh
|
|
|
46
47
|
const aged_fresh = run_board_fresh.aged
|
|
47
48
|
const UNKNOWN = '-'
|
|
48
49
|
const BLANK = ' '
|
|
49
|
-
const REPO_SEPARATOR = '/'
|
|
50
50
|
const { GAP, PERCENT_WIDTH } = run_board_machine
|
|
51
51
|
// A running run whose newest event is older than this is drawn as stale, so a hang stands out; past
|
|
52
52
|
// twice that it is drawn as alarming.
|
|
@@ -165,9 +165,8 @@ const WORKING_MARKS: ReadonlySet<RunMark> = new Set<RunMark>(['running', 'setup'
|
|
|
165
165
|
// Nothing running: the run is at work on a stage of its own; else it is waiting on a person when all
|
|
166
166
|
// the plan has left is what `needs-decision` holds, or idle.
|
|
167
167
|
function quiet_mark(header: BoardHeader): RunMark {
|
|
168
|
-
const { layout } = header
|
|
169
|
-
|
|
170
|
-
if (header.activity.setup !== undefined) return 'setup'
|
|
168
|
+
const { activity, layout } = header
|
|
169
|
+
if (run_board_setup.is_working(activity.setup, activity.is_setup_working)) return 'setup'
|
|
171
170
|
|
|
172
171
|
return layout?.queued.length === 0 && run_board_layout.people_of(layout).length > 0
|
|
173
172
|
? 'human'
|
|
@@ -191,7 +190,7 @@ function run_part(mark: RunMark, name = RUN_NAME): string {
|
|
|
191
190
|
// The repository's own name — `kit` of `owner/kit` — under the run's, past the mark's columns, so a
|
|
192
191
|
// board open beside another repository's is told apart. Blank before a plan names one.
|
|
193
192
|
function repo_part(header: BoardHeader, mark: RunMark): string {
|
|
194
|
-
const name = header.repo?.split(
|
|
193
|
+
const name = header.repo?.split('/').at(-1) ?? ''
|
|
195
194
|
const indent = run_board_fit.width_of(RUN_MARKS[mark].glyph) + BLANK.length
|
|
196
195
|
|
|
197
196
|
return `${BLANK.repeat(indent)}${header.repo_link(name, 'home')}`
|
|
@@ -59,6 +59,8 @@ interface LocalRead {
|
|
|
59
59
|
is_stranded: boolean
|
|
60
60
|
// The newest operation of each session of the run, read off the end of its log.
|
|
61
61
|
operations?: SessionOperations | undefined
|
|
62
|
+
// The carry's session owner is still running, apart from the supervisor's own driver.
|
|
63
|
+
is_session_active?: boolean | undefined
|
|
62
64
|
// The open lanes no child is working in at this read (`lane-spent.ts`); one is drawn stopped once it
|
|
63
65
|
// has stayed so (`run-board-idle.ts`).
|
|
64
66
|
idle_lanes?: ReadonlyArray<string> | undefined
|
|
@@ -108,6 +110,7 @@ const NO_SPAN: SpanHere = {
|
|
|
108
110
|
roots: {},
|
|
109
111
|
carry: undefined,
|
|
110
112
|
is_stranded: false,
|
|
113
|
+
is_session_active: false,
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
interface SpanHere {
|
|
@@ -118,6 +121,7 @@ interface SpanHere {
|
|
|
118
121
|
roots: ProcessRoots
|
|
119
122
|
carry: RunCarry | undefined
|
|
120
123
|
is_stranded: boolean
|
|
124
|
+
is_session_active: boolean
|
|
121
125
|
}
|
|
122
126
|
|
|
123
127
|
// The main work tree, resolved once: it does not move while the board is open, and resolving it runs a
|
|
@@ -159,6 +163,7 @@ async function recorded_span_here(
|
|
|
159
163
|
resume: run_board_span.resume_of(read, ended, launch),
|
|
160
164
|
transcript: read.kind === 'carried' ? read.carry.owner_transcript : undefined,
|
|
161
165
|
roots: run_board_roots.roots_of(repository, read, same_process),
|
|
166
|
+
is_session_active: run_board_roots.session_is_active(repository, read, same_process),
|
|
162
167
|
carry: read.kind === 'carried' ? read.carry : undefined,
|
|
163
168
|
is_stranded: run_stranded_detect.is_stranded_at(repository, stranded_ports),
|
|
164
169
|
}
|
|
@@ -341,7 +346,7 @@ function span_fields(
|
|
|
341
346
|
// snapshot, so it agrees with the usage columns.
|
|
342
347
|
async function read_local(table?: TableRead): Promise<LocalRead | undefined> {
|
|
343
348
|
const repository = await run_carry.repository_directory()
|
|
344
|
-
const { span, resume, transcript, roots, carry, is_stranded } =
|
|
349
|
+
const { span, resume, transcript, roots, carry, is_stranded, is_session_active } =
|
|
345
350
|
repository === undefined ? NO_SPAN : await span_here(repository, table)
|
|
346
351
|
|
|
347
352
|
if (repository === undefined || span === undefined) return undefined
|
|
@@ -361,6 +366,7 @@ async function read_local(table?: TableRead): Promise<LocalRead | undefined> {
|
|
|
361
366
|
roots,
|
|
362
367
|
carry,
|
|
363
368
|
is_stranded,
|
|
369
|
+
is_session_active,
|
|
364
370
|
operations: run_board_operation_read.read(sources_of(repository, lanes, transcript)),
|
|
365
371
|
...(await lane_room_of(lanes, lane_read.lane_states, table)),
|
|
366
372
|
...ledger_here(repository),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { process_identity } from '#scripts/josh/process-identity'
|
|
2
2
|
import { lane_process_table, type TableRead } from '#scripts/lane/lane-process-table'
|
|
3
3
|
import type { CarryRead } from '#scripts/run/carry/run-carry'
|
|
4
|
-
import { run_wake } from '#scripts/run/wake/run-wake'
|
|
4
|
+
import { run_wake, type RunWake } from '#scripts/run/wake/run-wake'
|
|
5
5
|
import type { ProcessRoots } from './run-board-process-groups'
|
|
6
6
|
|
|
7
7
|
// The run's own processes the 💻 section names: the supervisor from its wake stamp and the parent
|
|
@@ -38,6 +38,29 @@ function roots_of(
|
|
|
38
38
|
return { supervisor: supervisor_of(repository, is_same), parent: parent_of(read, is_same) }
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
// A handed-back budget or the supervisor's own driver is no judgment session. Codex's pid-less
|
|
42
|
+
// carry uses the launch pid already recorded by the wake supervisor instead.
|
|
43
|
+
function is_session_owner(read: CarryRead): boolean {
|
|
44
|
+
return read.kind === 'carried' && read.carry.is_handed_off !== true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function live_session_pid(
|
|
48
|
+
pid: number | undefined,
|
|
49
|
+
start: string | undefined,
|
|
50
|
+
wake: RunWake | undefined,
|
|
51
|
+
is_same: SameProcess,
|
|
52
|
+
): boolean {
|
|
53
|
+
return pid !== undefined && pid !== wake?.pid && is_same(pid, start) !== false
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function session_is_active(repository: string, read: CarryRead, is_same: SameProcess): boolean {
|
|
57
|
+
if (read.kind !== 'carried' || !is_session_owner(read)) return false
|
|
58
|
+
const wake = run_wake.read_wake(run_wake.wake_path(repository))
|
|
59
|
+
const pid = read.carry.owner_pid ?? wake?.woke_pid
|
|
60
|
+
|
|
61
|
+
return live_session_pid(pid, read.carry.owner_start, wake, is_same)
|
|
62
|
+
}
|
|
63
|
+
|
|
41
64
|
// `is_same_process` with each start time answered from the redraw's own `ps` snapshot, so the board's
|
|
42
65
|
// read runs no `ps` of its own per pid (joshuafolkken/kit#4263). Without a snapshot no start is known,
|
|
43
66
|
// and a recorded start reads as "cannot tell".
|
|
@@ -48,7 +71,7 @@ async function same_in(table: TableRead | undefined): Promise<SameProcess> {
|
|
|
48
71
|
return (pid, start) => process_identity.is_same_process(pid, start, read)
|
|
49
72
|
}
|
|
50
73
|
|
|
51
|
-
const run_board_roots = { roots_of, same_in }
|
|
74
|
+
const run_board_roots = { roots_of, same_in, session_is_active }
|
|
52
75
|
|
|
53
76
|
export { run_board_roots }
|
|
54
77
|
export type { SameProcess }
|
|
@@ -21,19 +21,25 @@ interface SetupRead {
|
|
|
21
21
|
|
|
22
22
|
const NO_SETUP: SetupRead = { setup: undefined, setup_ms: undefined }
|
|
23
23
|
|
|
24
|
+
// Only these stages depend on the judgment session owning the carry.
|
|
25
|
+
const SESSION_STAGES: ReadonlySet<string> = new Set([STAGE.JUDGING, STAGE.SESSION])
|
|
26
|
+
|
|
24
27
|
// The stages of a hand-back to a session, and of the retrospective unit the driver waits on at a drain
|
|
25
28
|
// (joshuafolkken/kit#6745). Only the run's next stage ends one, whatever the session or the unit writes
|
|
26
29
|
// to the stream meanwhile.
|
|
27
|
-
const
|
|
28
|
-
STAGE.JUDGING,
|
|
29
|
-
STAGE.SESSION,
|
|
30
|
-
STAGE.RETROSPECTIVE,
|
|
31
|
-
])
|
|
30
|
+
const RETAINED_STAGES: ReadonlySet<string> = new Set([...SESSION_STAGES, STAGE.RETROSPECTIVE])
|
|
32
31
|
|
|
33
32
|
function is_setup(event: RunEvent): boolean {
|
|
34
33
|
return event.kind === KIND.SETUP
|
|
35
34
|
}
|
|
36
35
|
|
|
36
|
+
// Session stages describe the last hand-off even after its owner has returned the budget.
|
|
37
|
+
function is_working(setup: string | undefined, is_session_active: boolean | undefined): boolean {
|
|
38
|
+
if (setup === undefined) return false
|
|
39
|
+
|
|
40
|
+
return !SESSION_STAGES.has(setup) || is_session_active !== false
|
|
41
|
+
}
|
|
42
|
+
|
|
37
43
|
// A launch that returned without a child (`run_event_setup.no_child`): it ends its own lane's stage,
|
|
38
44
|
// and prepares nothing a person waits on.
|
|
39
45
|
function is_refusal(event: RunEvent): boolean {
|
|
@@ -65,7 +71,7 @@ function is_opening(events: ReadonlyArray<RunEvent>, stage: RunEvent): boolean {
|
|
|
65
71
|
// Whether the run is at `stage` now: at any stage while it is starting; after that only at one it is
|
|
66
72
|
// itself working through.
|
|
67
73
|
function is_standing(events: ReadonlyArray<RunEvent>, stage: RunEvent): boolean {
|
|
68
|
-
if (!has_started(events) ||
|
|
74
|
+
if (!has_started(events) || RETAINED_STAGES.has(stage.text)) return true
|
|
69
75
|
|
|
70
76
|
return is_opening(events, stage)
|
|
71
77
|
}
|
|
@@ -119,7 +125,7 @@ function lane_stage(events: ReadonlyArray<RunEvent>, issue: number): LaneStage |
|
|
|
119
125
|
return { text: step.text, at_ms: Date.parse(step.at) }
|
|
120
126
|
}
|
|
121
127
|
|
|
122
|
-
const run_board_setup = { is_refusal, lane_stage, read }
|
|
128
|
+
const run_board_setup = { is_refusal, is_working, lane_stage, read }
|
|
123
129
|
|
|
124
130
|
export { run_board_setup }
|
|
125
131
|
export type { LaneStage, SetupRead }
|
|
@@ -82,6 +82,8 @@ interface LatestEvent {
|
|
|
82
82
|
// The run as a whole, read off the same stream. The setup half is `run-board-setup.ts`'s, absent
|
|
83
83
|
// where a stream carries no stage.
|
|
84
84
|
interface RunActivity extends Partial<SetupRead> {
|
|
85
|
+
// Runtime evidence for the stage, independent of its retained description.
|
|
86
|
+
is_setup_working?: boolean | undefined
|
|
85
87
|
last_event_ms: number | undefined
|
|
86
88
|
// The newest thing the run did — its newest position, or its newest event where it has none yet —
|
|
87
89
|
// in the event's own words, and when.
|
|
@@ -14,6 +14,7 @@ import { run_board_reason, type ReasonRead } from './run-board-reason'
|
|
|
14
14
|
import { run_board_released } from './run-board-released'
|
|
15
15
|
import { run_board_render } from './run-board-render'
|
|
16
16
|
import { run_board_seat, type SeatRead } from './run-board-seat'
|
|
17
|
+
import { run_board_setup } from './run-board-setup'
|
|
17
18
|
import type { Known } from './run-board-snapshot'
|
|
18
19
|
import { run_board_spin, type Spun } from './run-board-spin'
|
|
19
20
|
import { run_board_state, type BoardPorts, type BoardState, type Pace } from './run-board-state'
|
|
@@ -82,10 +83,15 @@ function titles_of(state: BoardState): Titles {
|
|
|
82
83
|
|
|
83
84
|
// A run `run:carry --end` closed and one nobody drives any more are both drawn as stopped.
|
|
84
85
|
function activity_here(local: LocalRead): RunActivity {
|
|
85
|
-
|
|
86
|
+
const activity = run_board_status.activity_of(
|
|
86
87
|
local.events,
|
|
87
88
|
local.ended_ms !== undefined || local.is_stranded,
|
|
88
89
|
)
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
...activity,
|
|
93
|
+
is_setup_working: run_board_setup.is_working(activity.setup, local.is_session_active),
|
|
94
|
+
}
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
// The already-read supervisor or parent drives retries until the run stops or becomes stranded.
|