jackherd 1.23.2 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/INSTALL.md +16 -0
- package/README.md +20 -19
- package/dist/config.d.ts +9 -1
- package/dist/config.js +174 -131
- package/herdr-plugin/herdr-plugin.toml +1 -1
- package/install.sh +1 -1
- package/kit/hooks/hooks/merge-guard/decision.ts +1 -1
- package/kit/workflow/skills/orchestrate/SKILL.md +2 -1
- package/kit/workflow/skills/orchestrate/references/backend.md +30 -0
- package/kit/workflow/skills/orchestrate/references/close-lane.md +1 -0
- package/kit/workflow/skills/orchestrate/references/start-lane.md +5 -1
- package/package.json +1 -1
- package/schemas/jackherd.schema.json +42 -0
- package/src/backend/command-line.ts +116 -0
- package/src/backend/command.ts +14 -0
- package/src/backend/control.ts +194 -0
- package/src/backend/handover.ts +28 -0
- package/src/backend/herdr.ts +147 -0
- package/src/backend/lock.ts +84 -0
- package/src/backend/process-cwd.ts +32 -0
- package/src/backend/schema.ts +47 -0
- package/src/backend/state.ts +57 -0
- package/src/backend/step.ts +93 -0
- package/src/backend/system.ts +150 -0
- package/src/backend/watch.ts +75 -0
- package/src/check/skill-budget-defaults.ts +2 -1
- package/src/cli.ts +1 -0
- package/src/config/schema.ts +3 -0
- package/src/lane/dev.ts +2 -2
- package/src/plans/plan-panes.ts +1 -1
- package/src/plans/settings.ts +3 -0
- package/src/shared/shell-word.ts +2 -0
- package/src/watch/command.ts +27 -0
- package/src/watch/reference-paths.ts +4 -0
package/src/watch/command.ts
CHANGED
|
@@ -32,6 +32,14 @@ import { existsSync, readFileSync } from 'node:fs'
|
|
|
32
32
|
import { homedir } from 'node:os'
|
|
33
33
|
import { basename, dirname, join, relative } from 'node:path'
|
|
34
34
|
import { writePrivateFile } from '../../kit/hooks/hooks/shared/private-directory'
|
|
35
|
+
import {
|
|
36
|
+
type BackendWatch,
|
|
37
|
+
backendCheckOf,
|
|
38
|
+
INITIAL_BACKEND_WATCH,
|
|
39
|
+
keepBackend,
|
|
40
|
+
type MainCheckoutBackend,
|
|
41
|
+
mainCheckoutBackendOf,
|
|
42
|
+
} from '../backend/watch'
|
|
35
43
|
import { sourcesWithPersonal } from '../config/personal-sources'
|
|
36
44
|
import { readConfig, readResolvedConfig } from '../config/read-config'
|
|
37
45
|
import { readRepositoryIdentity } from '../config/repository-identity'
|
|
@@ -200,6 +208,7 @@ import { recordedReadsOf } from './recorded-reads'
|
|
|
200
208
|
import {
|
|
201
209
|
annotateEach,
|
|
202
210
|
annotateFirstLine,
|
|
211
|
+
BACKEND_REFERENCE,
|
|
203
212
|
eventReference,
|
|
204
213
|
laneSetEventLines,
|
|
205
214
|
REFERENCE,
|
|
@@ -295,6 +304,8 @@ type Watch = {
|
|
|
295
304
|
selfMergeMinutes: number
|
|
296
305
|
/** Runs inside herdr with the herdr adapter, so missing herd panes can be brought back. */
|
|
297
306
|
herdr: boolean
|
|
307
|
+
/** `lanes.backend` and the worktree directory of the main checkout's config; undefined without one, then the backend is never touched. */
|
|
308
|
+
backend: MainCheckoutBackend | undefined
|
|
298
309
|
}
|
|
299
310
|
|
|
300
311
|
/** The coordinator's agent name (null when none is found), its last read (null before the first one) and the tokens of that read (null without a value). */
|
|
@@ -372,6 +383,8 @@ type Watching = {
|
|
|
372
383
|
/** The questions of each watched lane's report at the last poll (`questionsFingerprint`); null before the first read, so the stored ones stay. */
|
|
373
384
|
reportQuestions: Record<string, string> | null
|
|
374
385
|
planViews: PlanViews
|
|
386
|
+
/** When the backend pane was last checked and whether a failure of it was already said. */
|
|
387
|
+
backend: BackendWatch
|
|
375
388
|
}
|
|
376
389
|
|
|
377
390
|
/** What the duty lines of one return are made of. */
|
|
@@ -1134,6 +1147,16 @@ const keepViews = (watch: Watch, watching: Watching, trigger: EnsureTrigger) =>
|
|
|
1134
1147
|
})
|
|
1135
1148
|
}
|
|
1136
1149
|
|
|
1150
|
+
/** Keeps the shared backend pane once it is due (`BACKEND_CHECK_MS`); only inside herdr and only with `lanes.backend`. */
|
|
1151
|
+
const keepBackendPane = async (watch: Watch, watching: Watching) => {
|
|
1152
|
+
if (!watch.herdr || !watch.backend) return
|
|
1153
|
+
watching.backend = await keepBackend(watching.backend, Date.now(), {
|
|
1154
|
+
check: backendCheckOf(watch.root, watch.backend),
|
|
1155
|
+
log: console.log,
|
|
1156
|
+
hint: hintFor(watch, BACKEND_REFERENCE),
|
|
1157
|
+
})
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1137
1160
|
/** Takes up lanes that were found or dropped since the last poll and returns the lanes it added; named lanes never change. */
|
|
1138
1161
|
const followLaneSet = (watch: Watch, watching: Watching): string[] => {
|
|
1139
1162
|
if (watch.options.lanes !== null) return []
|
|
@@ -1570,6 +1593,7 @@ const initialWatching = (
|
|
|
1570
1593
|
appointments: null,
|
|
1571
1594
|
reportQuestions: null,
|
|
1572
1595
|
planViews: { failureReported: false },
|
|
1596
|
+
backend: INITIAL_BACKEND_WATCH,
|
|
1573
1597
|
})
|
|
1574
1598
|
|
|
1575
1599
|
/** Saves the state a stop leaves behind: the one from before an unfinished report or an unread GitHub answer, else the latest. */
|
|
@@ -1593,6 +1617,7 @@ const watchLanes = async (watch: Watch): Promise<boolean> => {
|
|
|
1593
1617
|
|
|
1594
1618
|
const watching = initialWatching(watch, { lanes, sprintLanes, state: { ...state, armed: arm.state }, armed, agents })
|
|
1595
1619
|
keepViews(watch, watching, { kind: ENSURE_TRIGGER.start })
|
|
1620
|
+
await keepBackendPane(watch, watching)
|
|
1596
1621
|
const resumeRecord = keepRecord(
|
|
1597
1622
|
{ root: watch.root, board: watch.sprintFile, coordinator: coordinatorNameFor(watch, agents), pid: process.pid },
|
|
1598
1623
|
Date.now(),
|
|
@@ -1638,6 +1663,7 @@ const watchLanes = async (watch: Watch): Promise<boolean> => {
|
|
|
1638
1663
|
while (await pollOnce(watch, watching)) {
|
|
1639
1664
|
await Bun.sleep(POLL_MS)
|
|
1640
1665
|
pollLanes(watch, watching)
|
|
1666
|
+
await keepBackendPane(watch, watching)
|
|
1641
1667
|
resumeRecord.follow(watching.current, Date.now(), observed())
|
|
1642
1668
|
await announceUpdate?.()
|
|
1643
1669
|
if (endedByKitUpdate(kit, effects)) return true
|
|
@@ -1710,6 +1736,7 @@ const watchOf = (options: WatchOptions): Watch => {
|
|
|
1710
1736
|
stageTools: stageToolsOf(config.guard.approvals.standing),
|
|
1711
1737
|
selfMergeMinutes: config.guard.selfMerge.approvalMinutes,
|
|
1712
1738
|
herdr: insideHerdr(settings.adapter, process.env),
|
|
1739
|
+
backend: mainCheckoutBackendOf(root, checkoutRoot, config),
|
|
1713
1740
|
}
|
|
1714
1741
|
}
|
|
1715
1742
|
|
|
@@ -24,10 +24,14 @@ export const REFERENCE = {
|
|
|
24
24
|
watchWithoutMonitor: 'references/watch-without-monitor.md',
|
|
25
25
|
adoptPlan: 'references/adopt-plan.md',
|
|
26
26
|
waiting: 'references/waiting.md',
|
|
27
|
+
backend: 'references/backend.md',
|
|
27
28
|
} as const
|
|
28
29
|
|
|
29
30
|
export type Reference = (typeof REFERENCE)[keyof typeof REFERENCE]
|
|
30
31
|
|
|
32
|
+
/** Where the coordinator reads what a `backend:` line of the watcher asks for: the shared backend. */
|
|
33
|
+
export const BACKEND_REFERENCE: Reference = REFERENCE.backend
|
|
34
|
+
|
|
31
35
|
/** A copy of the orchestrate skill: the directory as the session reads it, and where that is on disk. */
|
|
32
36
|
export type SkillCopy = { shown: string; path: string }
|
|
33
37
|
|