jackherd 1.8.1 → 1.10.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 +60 -0
- package/INSTALL.md +3 -1
- package/README.md +75 -64
- package/dist/{chunk-OU2KALXP.js → chunk-5MQBCUQ5.js} +24 -4
- package/dist/config.d.ts +45 -4
- package/dist/config.js +84 -27
- package/dist/plan-format.d.ts +63 -7
- package/dist/plan-format.js +66 -12
- package/docs/workflow-dark.svg +67 -63
- package/docs/workflow.svg +67 -63
- package/herdr-plugin/herdr-plugin.toml +1 -1
- package/install.sh +1 -1
- package/kit/hooks/ask-rules.json +15 -0
- package/kit/hooks/hooks/approval-gate/index.ts +22 -4
- package/kit/hooks/hooks/approval-gate/run.ts +29 -6
- package/kit/hooks/hooks/approval-gate/subagent.ts +18 -0
- package/kit/hooks/hooks/ask-hint/decision.ts +82 -14
- package/kit/hooks/hooks/ask-hint/index.ts +15 -19
- package/kit/hooks/hooks/ask-hint/settings.ts +3 -18
- package/kit/hooks/hooks/git-guard/decision.ts +50 -102
- package/kit/hooks/hooks/merge-guard/always-ask.ts +63 -0
- package/kit/hooks/hooks/merge-guard/{plan-approval-settings.ts → board-settings.ts} +21 -67
- package/kit/hooks/hooks/merge-guard/check-free.ts +20 -0
- package/kit/hooks/hooks/merge-guard/decision.ts +127 -140
- package/kit/hooks/hooks/merge-guard/index.ts +6 -3
- package/kit/hooks/hooks/merge-guard/lane-plan.ts +79 -0
- package/kit/hooks/hooks/merge-guard/run.ts +59 -54
- package/kit/hooks/hooks/merge-guard/settings.ts +13 -1
- package/kit/hooks/hooks/merge-guard/standing-approval.ts +142 -0
- package/kit/hooks/hooks/open-question/index.ts +26 -0
- package/kit/hooks/hooks/open-question/record.ts +135 -0
- package/kit/hooks/hooks/open-question/run.ts +52 -0
- package/kit/hooks/hooks/open-question/store.ts +39 -0
- package/kit/hooks/hooks/sent-file/index.ts +19 -0
- package/kit/hooks/hooks/sent-file/record.ts +128 -0
- package/kit/hooks/hooks/sent-file/run.ts +48 -0
- package/kit/hooks/hooks/sent-file/store.ts +9 -0
- package/kit/hooks/hooks/shared/board-lanes.ts +15 -2
- package/kit/hooks/hooks/shared/config.ts +7 -0
- package/kit/hooks/hooks/shared/dialog-answers.ts +9 -9
- package/kit/hooks/hooks/shared/files.ts +7 -0
- package/kit/hooks/hooks/shared/lane.ts +1 -1
- package/kit/hooks/hooks/shared/newest-verdict.ts +10 -0
- package/kit/hooks/hooks/shared/private-directory.ts +56 -9
- package/kit/hooks/hooks/shared/program-position.ts +2 -75
- package/kit/hooks/hooks/shared/shell-aliases.ts +1 -71
- package/kit/hooks/hooks/{ask-hint → shared}/transcript.ts +37 -6
- package/kit/hooks/hooks/{merge-guard → shared}/xargs-program.ts +10 -8
- package/kit/hooks/hooks/task-hint/decision.ts +49 -0
- package/kit/hooks/hooks/task-hint/index.ts +79 -0
- package/kit/hooks/hooks/task-hint/run.ts +62 -0
- package/kit/hooks/hooks/task-hint/store.ts +51 -0
- package/kit/hooks/hooks.json +21 -4
- package/kit/hooks/statusline.sh +1 -1
- package/kit/review/agents/skill-review.md +34 -0
- package/kit/review/skills/pre-commit/SKILL.md +1 -1
- package/kit/workflow/skills/follow/SKILL.md +1 -8
- package/kit/workflow/skills/implement/SKILL.md +10 -6
- package/kit/workflow/skills/orchestrate/SKILL.md +213 -412
- package/kit/workflow/skills/orchestrate/handover/decision.ts +43 -8
- package/kit/workflow/skills/orchestrate/handover/index.ts +32 -4
- package/kit/workflow/skills/orchestrate/handover/standing-approval.ts +84 -0
- package/kit/workflow/skills/orchestrate/references/acceptance.md +15 -0
- package/kit/workflow/skills/orchestrate/references/close-lane.md +17 -0
- package/kit/workflow/skills/orchestrate/references/coordinator-handover.md +43 -17
- package/kit/workflow/skills/orchestrate/references/draft-review.md +19 -0
- package/kit/workflow/skills/orchestrate/references/events.md +86 -0
- package/kit/workflow/skills/orchestrate/references/herd.md +6 -6
- package/kit/workflow/skills/orchestrate/references/lane-handover.md +18 -0
- package/kit/workflow/skills/orchestrate/references/lane-session.md +25 -0
- package/kit/workflow/skills/orchestrate/references/lane-setup.md +37 -0
- package/kit/workflow/skills/orchestrate/references/plan-commit.md +22 -10
- package/kit/workflow/skills/orchestrate/references/sensitive-input.md +5 -7
- package/kit/workflow/skills/plan/SKILL.md +6 -5
- package/kit/workflow/skills/plan/references/template-English.md +4 -4
- package/kit/workflow/skills/plan/references/template-German.md +4 -4
- package/package.json +4 -1
- package/recipes/README.md +2 -1
- package/recipes/sources.md +1 -1
- package/schemas/jackherd.schema.json +85 -7
- package/src/check/agent-text-reviewers.ts +23 -0
- package/src/check/command.ts +2 -0
- package/src/check/plan-structure-check.ts +49 -2
- package/src/check/plan.ts +8 -1
- package/src/check/schema.ts +9 -0
- package/src/check/skill-budget-defaults.ts +55 -0
- package/src/check/skill-budgets.ts +185 -0
- package/src/cli.ts +4 -0
- package/src/config/auto-window.ts +8 -0
- package/src/config/link-kinds.ts +7 -1
- package/src/config/schema.ts +80 -26
- package/src/context/fill.ts +12 -0
- package/src/context/session-log.ts +43 -1
- package/src/lane/close-board.ts +106 -0
- package/src/lane/close-check.ts +183 -0
- package/src/lane/close-command-line.ts +11 -0
- package/src/lane/close-command.ts +217 -0
- package/src/lane/close-options.ts +43 -0
- package/src/lane/close-survey.ts +83 -0
- package/src/lane/close.ts +141 -0
- package/src/lane/command.ts +13 -0
- package/src/lane-prompt/build.ts +74 -0
- package/src/lane-prompt/command.ts +87 -0
- package/src/lane-prompt/input.ts +116 -0
- package/src/lane-prompt/options.ts +68 -0
- package/src/lane-prompt/texts.ts +101 -0
- package/src/plan-format/clock.ts +12 -0
- package/src/plan-format/dependencies.ts +9 -9
- package/src/plan-format/index.ts +1 -0
- package/src/plan-format/lanes.ts +30 -5
- package/src/plan-format/short-names.ts +71 -0
- package/src/plan-format/terminal-text.ts +4 -0
- package/src/plan-format/waiting.ts +53 -0
- package/src/plans/active-tasks.ts +60 -0
- package/src/plans/appointment-rows.ts +59 -0
- package/src/plans/ask-coordinator.ts +77 -0
- package/src/plans/ask-target.ts +25 -0
- package/src/plans/child-stop.ts +51 -0
- package/src/plans/closable-records.ts +34 -0
- package/src/plans/command.ts +3 -2
- package/src/plans/current-phase.ts +17 -7
- package/src/plans/current-task.ts +63 -5
- package/src/plans/fetch.ts +26 -3
- package/src/plans/git.ts +19 -5
- package/src/plans/herd-claim.ts +173 -0
- package/src/plans/herd-memory.ts +36 -25
- package/src/plans/lane-plans.ts +44 -13
- package/src/plans/lane-standing.ts +9 -4
- package/src/plans/lane-summary.ts +367 -92
- package/src/plans/lane-tickets.ts +15 -0
- package/src/plans/layout-phase.ts +80 -19
- package/src/plans/layout-summary.ts +163 -74
- package/src/plans/layout.ts +472 -114
- package/src/plans/link-chips.ts +1 -0
- package/src/plans/live.ts +119 -10
- package/src/plans/phase-ids.ts +8 -0
- package/src/plans/phase-models.ts +1 -1
- package/src/plans/phase-ranges.ts +45 -0
- package/src/plans/phase-source.ts +15 -0
- package/src/plans/plan-cache.ts +28 -0
- package/src/plans/plan-heads.ts +54 -0
- package/src/plans/pull-requests.ts +23 -2
- package/src/plans/question-records.ts +48 -0
- package/src/plans/questions-read.ts +13 -0
- package/src/plans/read-cache.ts +8 -0
- package/src/plans/record-id.ts +4 -0
- package/src/plans/restart-decision.ts +13 -4
- package/src/plans/selection.ts +117 -34
- package/src/plans/sent-files-read.ts +13 -0
- package/src/plans/sent-files.ts +114 -0
- package/src/plans/settings.ts +2 -1
- package/src/plans/signalled-phase.ts +42 -0
- package/src/plans/signals-read.ts +62 -0
- package/src/plans/snapshot.ts +279 -60
- package/src/plans/sprint-export.ts +11 -11
- package/src/plans/sprint-page.ts +5 -5
- package/src/plans/subagent-phases.ts +95 -0
- package/src/plans/subagent-tasks.ts +51 -0
- package/src/plans/subagents-read.ts +131 -0
- package/src/plans/subagents.ts +190 -0
- package/src/plans/supervisor.ts +14 -4
- package/src/plans/symbols.ts +3 -0
- package/src/plans/task-name.ts +34 -0
- package/src/plans/texts.ts +36 -14
- package/src/plans/unlisted-lanes.ts +10 -5
- package/src/plans/view.ts +20 -12
- package/src/plans/waiting-click.ts +231 -0
- package/src/plans/waiting-records.ts +39 -0
- package/src/plans/waiting-window.ts +8 -0
- package/src/preview/command.ts +105 -0
- package/src/preview/embed.ts +209 -0
- package/src/preview/images.ts +89 -0
- package/src/preview/open.ts +12 -0
- package/src/preview/options.ts +32 -0
- package/src/preview/page.ts +89 -0
- package/src/preview/render.ts +41 -0
- package/src/settled/board-row.ts +1 -2
- package/src/shared/is-record.ts +2 -0
- package/src/shared/private-location.ts +89 -0
- package/src/shared/private-records.ts +48 -0
- package/src/shared/stat-cache.ts +48 -0
- package/src/sync/kit-source.ts +29 -10
- package/src/sync/kit.ts +2 -0
- package/src/sync/manifest.ts +2 -0
- package/src/sync/plan-ask-rules.ts +94 -0
- package/src/sync/plan-hooks.ts +2 -0
- package/src/sync/render.ts +3 -3
- package/src/sync/settings-hooks.ts +4 -1
- package/src/sync/sync-plan.ts +1 -0
- package/src/sync/sync.ts +24 -3
- package/src/task-signals/agent.ts +15 -0
- package/src/task-signals/claude-read.ts +89 -0
- package/src/task-signals/claude-signals.ts +112 -0
- package/src/task-signals/command.ts +71 -0
- package/src/task-signals/fixtures/session.jsonl +7 -0
- package/src/task-signals/matcher.ts +96 -0
- package/src/task-signals/record-store.ts +40 -0
- package/src/task-signals/record.ts +68 -0
- package/src/task-signals/text.ts +13 -0
- package/src/task-signals/types.ts +14 -0
- package/src/terminal/open.ts +13 -6
- package/src/terminal/text.ts +16 -4
- package/src/terminal/width.ts +2 -1
- package/src/version/skill-diff.ts +46 -0
- package/src/vocabulary/index.ts +44 -6
- package/src/waiting/command.ts +50 -0
- package/src/watch/appointments.ts +2 -4
- package/src/watch/approvals.ts +2 -2
- package/src/watch/asking-lanes.ts +40 -0
- package/src/watch/base-tip.ts +11 -0
- package/src/watch/command.ts +401 -90
- package/src/watch/failed-tests.ts +56 -10
- package/src/watch/failure-read.ts +18 -6
- package/src/watch/failures.ts +29 -5
- package/src/watch/feedback.ts +1 -1
- package/src/watch/gh-process.ts +9 -3
- package/src/watch/heartbeat-progress.ts +6 -18
- package/src/watch/json-guards.ts +0 -3
- package/src/watch/kit-update.ts +28 -9
- package/src/watch/lane-fill.ts +1 -1
- package/src/watch/lane-model.ts +1 -1
- package/src/watch/lane-name.ts +6 -0
- package/src/watch/lane-parallel.ts +1 -1
- package/src/watch/lane-progress.ts +58 -14
- package/src/watch/lane-report-file.ts +20 -5
- package/src/watch/lane-report.ts +37 -5
- package/src/watch/lane-rest.ts +28 -0
- package/src/watch/lane-sources.ts +31 -3
- package/src/watch/main-checkout.ts +34 -0
- package/src/watch/plan-badges-read.ts +13 -7
- package/src/watch/plan-badges.ts +9 -2
- package/src/watch/previews.ts +1 -1
- package/src/watch/pull-requests.ts +8 -3
- package/src/watch/reference-paths.ts +87 -0
- package/src/watch/running-subagents.ts +43 -0
- package/src/watch/skill-change.ts +124 -32
- package/src/watch/source-change.ts +48 -0
- package/src/watch/source-path.ts +1 -1
- package/src/watch/sources.ts +7 -4
- package/src/watch/stream-output.ts +14 -8
- package/src/watch/task-parallel-auto.ts +208 -0
- package/src/watch/task-parallel-data-paths.ts +46 -0
- package/src/watch/task-parallel-input.ts +108 -0
- package/src/watch/task-parallel-read.ts +151 -0
- package/src/watch/task-parallel-touched.ts +39 -0
- package/src/watch/task-parallel.ts +235 -0
- package/src/watch/task-signal-missing.ts +69 -0
- package/src/watch/task-signal-read.ts +29 -0
- package/src/watch/texts.ts +10 -0
- package/src/watch/update-available.ts +6 -3
- package/src/watch/waiting-line.ts +19 -0
- package/src/watch/watch-events.ts +36 -1
- package/src/watch/watcher-lock.ts +25 -29
- package/src/watch/workflow-runs.ts +2 -1
- package/kit/hooks/hooks/merge-guard/plan-approval-record.ts +0 -23
- package/kit/hooks/hooks/merge-guard/plan-approval-sources.ts +0 -196
- package/kit/hooks/hooks/merge-guard/plan-approval.ts +0 -168
- package/kit/hooks/hooks/merge-guard/plan-growth.ts +0 -40
- package/kit/hooks/hooks/merge-guard/plan-pointers.ts +0 -194
- package/kit/hooks/hooks/shared/command-text-runners.ts +0 -71
- package/kit/hooks/hooks/shared/plan-open-phases.ts +0 -114
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Whether a plan still has an open phase, read the way the herd reads phases (`parsePlanPhases` in the package),
|
|
3
|
-
* which a hook cannot import. A test compares both on the repository's real plans.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** A task of a phase, a checkbox or a row with a ⬜/✅ cell: whether it is open, and its text without the state. */
|
|
7
|
-
export type PlanTask = { open: boolean; text: string }
|
|
8
|
-
|
|
9
|
-
type Phase = { id: string; items: boolean[]; deferredOpen: boolean; pointer?: string }
|
|
10
|
-
|
|
11
|
-
/** A phase's id, its heading without the leading hashes, and its lines up to the next heading that ends it. */
|
|
12
|
-
export type PhaseBlock = { id: string; heading: string; lines: string[] }
|
|
13
|
-
|
|
14
|
-
const PHASE_HEADING = /^###\s+Phase\s+(\d+[a-z]?)\b/i
|
|
15
|
-
/** `## 10 — title`, and `## P15 — title` as a board names the phase. */
|
|
16
|
-
const NUMBERED_SECTION = /^##\s+P?(\d+[a-z]?)\s*[—–:-]\s*(.*)$/
|
|
17
|
-
const PHASE_END = /^#{1,3}\s/
|
|
18
|
-
const SECTION_HEADING = /^##\s+(.+?)\s*$/
|
|
19
|
-
const TOP_HEADING = /^#\s/
|
|
20
|
-
const CHECKBOX = /^\s*[-*]\s+\[([ xX])\]\s+(.*)$/
|
|
21
|
-
const DEFERRED_TO = /\s→\s*P(\d+[a-z]?)\s*$/i
|
|
22
|
-
const SECTION_POINTER = /`##\s+([^`]+?)\s*`/
|
|
23
|
-
const STATUS = { done: '✅', open: '⬜' } as const
|
|
24
|
-
|
|
25
|
-
const collapsed = (text: string): string => text.trim().replace(/\s+/g, ' ')
|
|
26
|
-
|
|
27
|
-
/** The task a line holds, null for a line that is none. */
|
|
28
|
-
export const taskOf = (line: string): PlanTask | null => {
|
|
29
|
-
const checkbox = line.match(CHECKBOX)
|
|
30
|
-
if (checkbox) return { open: checkbox[1] === ' ', text: collapsed(checkbox[2]) }
|
|
31
|
-
const trimmed = line.trim()
|
|
32
|
-
if (!trimmed.startsWith('|')) return null
|
|
33
|
-
const cells = trimmed.replace(/^\|/, '').replace(/\|$/, '').split('|').map((cell) => cell.trim())
|
|
34
|
-
const status = cells.find((cell) => cell === STATUS.done || cell === STATUS.open)
|
|
35
|
-
if (status === undefined) return null
|
|
36
|
-
const text = cells.filter((cell) => cell !== STATUS.done && cell !== STATUS.open).join(' | ')
|
|
37
|
-
return { open: status === STATUS.open, text: collapsed(text) }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** An item of a phase: `true` while open, `false` when done, null for a line that is none. */
|
|
41
|
-
const itemOf = (line: string): boolean | null => taskOf(line)?.open ?? null
|
|
42
|
-
|
|
43
|
-
/** An open checkbox moved on to another phase with `→ P<n>` at its end; it stays open, in that phase. */
|
|
44
|
-
const isDeferred = (line: string, phaseId: string): boolean => {
|
|
45
|
-
const checkbox = line.match(CHECKBOX)
|
|
46
|
-
const target = checkbox?.[1] === ' ' ? checkbox[2].match(DEFERRED_TO)?.[1]?.toLowerCase() : undefined
|
|
47
|
-
return target !== undefined && target !== phaseId
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const phaseIdOf = (line: string): string | undefined =>
|
|
51
|
-
(line.match(PHASE_HEADING) ?? line.match(NUMBERED_SECTION))?.[1]?.toLowerCase()
|
|
52
|
-
|
|
53
|
-
const fileLine = (phase: Phase, line: string): void => {
|
|
54
|
-
phase.pointer ??= line.match(SECTION_POINTER)?.[1]
|
|
55
|
-
if (isDeferred(line, phase.id)) {
|
|
56
|
-
phase.deferredOpen = true
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
const item = itemOf(line)
|
|
60
|
-
if (item !== null) phase.items.push(item)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** The phases of a plan as they stand, `### Phase <id>` and `## <id> — title` alike. */
|
|
64
|
-
export const phaseBlocksOf = (markdown: string): PhaseBlock[] => {
|
|
65
|
-
const blocks: PhaseBlock[] = []
|
|
66
|
-
let open: PhaseBlock | null = null
|
|
67
|
-
for (const line of markdown.split('\n')) {
|
|
68
|
-
const id = phaseIdOf(line)
|
|
69
|
-
if (id !== undefined) {
|
|
70
|
-
open = { id, heading: collapsed(line.replace(/^#+/, '')), lines: [] }
|
|
71
|
-
blocks.push(open)
|
|
72
|
-
} else if (PHASE_END.test(line)) open = null
|
|
73
|
-
else open?.lines.push(line)
|
|
74
|
-
}
|
|
75
|
-
return blocks
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const phasesOf = (markdown: string): Phase[] =>
|
|
79
|
-
phaseBlocksOf(markdown).map(({ id, lines }) => {
|
|
80
|
-
const phase: Phase = { id, items: [], deferredOpen: false }
|
|
81
|
-
for (const line of lines) fileLine(phase, line)
|
|
82
|
-
return phase
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
/** The items of every `## ` section by heading, sub-headings included; the last of equal headings wins. */
|
|
86
|
-
const sectionItems = (markdown: string): Map<string, boolean[]> => {
|
|
87
|
-
const sections = new Map<string, boolean[]>()
|
|
88
|
-
let open: boolean[] | null = null
|
|
89
|
-
for (const line of markdown.split('\n')) {
|
|
90
|
-
const heading = line.match(SECTION_HEADING)
|
|
91
|
-
if (heading) {
|
|
92
|
-
open = []
|
|
93
|
-
sections.set(heading[1], open)
|
|
94
|
-
} else if (TOP_HEADING.test(line)) open = null
|
|
95
|
-
else {
|
|
96
|
-
const item = itemOf(line)
|
|
97
|
-
if (item !== null) open?.push(item)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return sections
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* True when a phase (`### Phase <id>` or `## <id> — title`) holds an open checkbox or ⬜ row, a deferred one included;
|
|
105
|
-
* a phase without items of its own counts the section it points at (``Siehe `## Dokumentation` ``).
|
|
106
|
-
*/
|
|
107
|
-
export const hasOpenPhase = (markdown: string): boolean => {
|
|
108
|
-
const phases = phasesOf(markdown)
|
|
109
|
-
if (phases.some((phase) => phase.deferredOpen || phase.items.includes(true))) return true
|
|
110
|
-
const pointed = phases.filter((phase) => phase.items.length === 0 && phase.pointer !== undefined)
|
|
111
|
-
if (pointed.length === 0) return false
|
|
112
|
-
const sections = sectionItems(markdown)
|
|
113
|
-
return pointed.some((phase) => (sections.get(phase.pointer ?? '') ?? []).includes(true))
|
|
114
|
-
}
|