jackherd 0.0.1 → 1.0.1

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.
Files changed (250) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE +38 -0
  4. package/README.md +1122 -3
  5. package/assets/branding/README.md +62 -0
  6. package/assets/branding/jackherd-icon-256.png +0 -0
  7. package/assets/branding/jackherd-icon-512.png +0 -0
  8. package/assets/branding/jackherd-icon-64.png +0 -0
  9. package/assets/branding/jackherd-icon-small-32.png +0 -0
  10. package/assets/branding/jackherd-icon-small-64.png +0 -0
  11. package/assets/branding/jackherd-icon-small.svg +1 -0
  12. package/assets/branding/jackherd-icon.svg +1 -0
  13. package/assets/branding/jackherd-logo-1024.png +0 -0
  14. package/assets/branding/jackherd-logo-512.png +0 -0
  15. package/assets/branding/jackherd-logo-dark-1024.png +0 -0
  16. package/assets/branding/jackherd-logo-dark-512.png +0 -0
  17. package/assets/branding/jackherd-logo-dark.svg +1 -0
  18. package/assets/branding/jackherd-logo-mark-1024.png +0 -0
  19. package/assets/branding/jackherd-logo-mark-512.png +0 -0
  20. package/assets/branding/jackherd-logo-mark.svg +1 -0
  21. package/assets/branding/jackherd-logo.svg +1 -0
  22. package/dist/chunk-R6MGHCD7.js +93 -0
  23. package/dist/config.d.ts +167 -0
  24. package/dist/config.js +401 -0
  25. package/dist/plan-format.d.ts +325 -0
  26. package/dist/plan-format.js +636 -0
  27. package/docs/lanes.mmd +9 -0
  28. package/docs/lanes.svg +1 -0
  29. package/docs/skills.mmd +10 -0
  30. package/docs/skills.svg +1 -0
  31. package/docs/workflow.svg +172 -0
  32. package/herdr-plugin/herdr-plugin.toml +22 -0
  33. package/herdr-plugin/open-plans.ts +43 -0
  34. package/herdr-plugin/restore-plans.ts +107 -0
  35. package/install.sh +157 -0
  36. package/kit/hooks/hooks/git-guard/decision.ts +438 -0
  37. package/kit/hooks/hooks/git-guard/index.ts +38 -0
  38. package/kit/hooks/hooks/git-guard/shell.ts +407 -0
  39. package/kit/hooks/hooks/watch-guard/background.ts +36 -0
  40. package/kit/hooks/hooks/watch-guard/decision.ts +53 -0
  41. package/kit/hooks/hooks/watch-guard/index.ts +11 -0
  42. package/kit/hooks/hooks/watch-guard/shell-input.ts +32 -0
  43. package/kit/hooks/hooks/watch-guard/starts.ts +154 -0
  44. package/kit/hooks/hooks/watch-guard/text-fallback.ts +40 -0
  45. package/kit/hooks/hooks.json +30 -0
  46. package/kit/hooks/statusline.sh +72 -0
  47. package/kit/review/agents/devops.md +11 -0
  48. package/kit/review/agents/public-content.md +39 -0
  49. package/kit/review/agents/security-audit.md +11 -0
  50. package/kit/review/agents/uncle-bob.md +11 -0
  51. package/kit/review/skills/devops/SKILL.md +50 -0
  52. package/kit/review/skills/diagnose/SKILL.md +140 -0
  53. package/kit/review/skills/diagnose/references/feedback-loops.md +59 -0
  54. package/kit/review/skills/diagnose/scripts/hitl-loop.template.sh +71 -0
  55. package/kit/review/skills/pre-commit/SKILL.md +100 -0
  56. package/kit/review/skills/review/SKILL.md +43 -0
  57. package/kit/review/skills/security-audit/SKILL.md +65 -0
  58. package/kit/review/skills/uncle-bob/SKILL.md +43 -0
  59. package/kit/rules/rules/kit/arc42.md +89 -0
  60. package/kit/rules/rules/kit/architecture-files.md +87 -0
  61. package/kit/rules/rules/kit/code-style.md +159 -0
  62. package/kit/rules/rules/kit/pull-requests.md +59 -0
  63. package/kit/rules/rules/kit/testing.md +91 -0
  64. package/kit/rules/rules/kit/writing-for-agents.md +110 -0
  65. package/kit/workflow/agents/explore.md +25 -0
  66. package/kit/workflow/agents/implement.md +16 -0
  67. package/kit/workflow/agents/plan.md +13 -0
  68. package/kit/workflow/agents/spec-review.md +96 -0
  69. package/kit/workflow/skills/follow/SKILL.md +48 -0
  70. package/kit/workflow/skills/grill/SKILL.md +60 -0
  71. package/kit/workflow/skills/implement/SKILL.md +107 -0
  72. package/kit/workflow/skills/orchestrate/SKILL.md +565 -0
  73. package/kit/workflow/skills/orchestrate/handover/decision.ts +247 -0
  74. package/kit/workflow/skills/orchestrate/handover/index.ts +171 -0
  75. package/kit/workflow/skills/plan/SKILL.md +118 -0
  76. package/kit/workflow/skills/plan/references/template-English.md +92 -0
  77. package/kit/workflow/skills/plan/references/template-German.md +92 -0
  78. package/kit/workflow/skills/start/SKILL.md +47 -0
  79. package/package.json +63 -5
  80. package/schemas/jackherd.schema.json +601 -0
  81. package/src/check/changes.ts +45 -0
  82. package/src/check/command-line.ts +12 -0
  83. package/src/check/command.ts +136 -0
  84. package/src/check/deferral-arrows.ts +41 -0
  85. package/src/check/execute.ts +29 -0
  86. package/src/check/glob.ts +15 -0
  87. package/src/check/plan-structure-check.ts +135 -0
  88. package/src/check/plan.ts +106 -0
  89. package/src/check/public-content-check.ts +32 -0
  90. package/src/check/public-content-facts.ts +177 -0
  91. package/src/check/public-content.ts +216 -0
  92. package/src/check/report.ts +55 -0
  93. package/src/check/result.ts +42 -0
  94. package/src/check/roots.ts +36 -0
  95. package/src/check/routing.ts +22 -0
  96. package/src/check/schema.ts +83 -0
  97. package/src/check/settings.ts +44 -0
  98. package/src/claude/paths.ts +14 -0
  99. package/src/cli.ts +46 -0
  100. package/src/config/command.ts +45 -0
  101. package/src/config/detect.ts +196 -0
  102. package/src/config/index.ts +2 -0
  103. package/src/config/json-schema.ts +5 -0
  104. package/src/config/legacy-names.ts +56 -0
  105. package/src/config/link-kinds.ts +25 -0
  106. package/src/config/location.ts +46 -0
  107. package/src/config/read-config.ts +42 -0
  108. package/src/config/repository-facts.ts +19 -0
  109. package/src/config/repository-values.ts +46 -0
  110. package/src/config/schema.ts +302 -0
  111. package/src/context/command.ts +39 -0
  112. package/src/context/coordinator-name.ts +16 -0
  113. package/src/context/fill.ts +69 -0
  114. package/src/context/index.ts +10 -0
  115. package/src/context/level.ts +22 -0
  116. package/src/context/options.ts +29 -0
  117. package/src/context/report.ts +42 -0
  118. package/src/context/session-log.ts +91 -0
  119. package/src/plan-format/drift.ts +69 -0
  120. package/src/plan-format/header.ts +27 -0
  121. package/src/plan-format/index.ts +9 -0
  122. package/src/plan-format/lanes.ts +128 -0
  123. package/src/plan-format/markdown.ts +98 -0
  124. package/src/plan-format/phase-tally.ts +55 -0
  125. package/src/plan-format/phases.ts +224 -0
  126. package/src/plan-format/plan-structure.ts +150 -0
  127. package/src/plan-format/progress.ts +202 -0
  128. package/src/plan-format/sprint-document.ts +69 -0
  129. package/src/plan-format/terminal-text.ts +28 -0
  130. package/src/plans/board-choice.ts +60 -0
  131. package/src/plans/board-pick.ts +72 -0
  132. package/src/plans/board-rows.ts +62 -0
  133. package/src/plans/command.ts +60 -0
  134. package/src/plans/ensure-panes.ts +71 -0
  135. package/src/plans/error-text.ts +5 -0
  136. package/src/plans/fetch.ts +96 -0
  137. package/src/plans/git.ts +145 -0
  138. package/src/plans/github.ts +35 -0
  139. package/src/plans/lane-discovery.ts +34 -0
  140. package/src/plans/lane-plans.ts +80 -0
  141. package/src/plans/layout.ts +881 -0
  142. package/src/plans/link-chips.ts +74 -0
  143. package/src/plans/live.ts +336 -0
  144. package/src/plans/markdown-html.ts +140 -0
  145. package/src/plans/options.ts +15 -0
  146. package/src/plans/phase-source.ts +71 -0
  147. package/src/plans/plan-chips.ts +75 -0
  148. package/src/plans/plan-panes.ts +206 -0
  149. package/src/plans/planned.ts +117 -0
  150. package/src/plans/pull-requests.ts +107 -0
  151. package/src/plans/restart-decision.ts +42 -0
  152. package/src/plans/selection.ts +352 -0
  153. package/src/plans/settings.ts +68 -0
  154. package/src/plans/single-flight.ts +25 -0
  155. package/src/plans/snapshot.ts +300 -0
  156. package/src/plans/sprint-export.ts +103 -0
  157. package/src/plans/sprint-html.ts +301 -0
  158. package/src/plans/sprint-page.ts +287 -0
  159. package/src/plans/supervisor.ts +124 -0
  160. package/src/plans/symbols.ts +54 -0
  161. package/src/plans/texts.ts +103 -0
  162. package/src/plans/unlisted-lanes.ts +45 -0
  163. package/src/plans/view.ts +68 -0
  164. package/src/plans/worked-phases.ts +53 -0
  165. package/src/sync/checksum.ts +13 -0
  166. package/src/sync/choice.ts +14 -0
  167. package/src/sync/command-context.ts +113 -0
  168. package/src/sync/command.ts +94 -0
  169. package/src/sync/error-message.ts +1 -0
  170. package/src/sync/gitignore.ts +45 -0
  171. package/src/sync/global-kit.ts +176 -0
  172. package/src/sync/herdr-plugin.ts +175 -0
  173. package/src/sync/if-changed.ts +109 -0
  174. package/src/sync/init-command.ts +239 -0
  175. package/src/sync/init.ts +136 -0
  176. package/src/sync/kit-hooks.ts +18 -0
  177. package/src/sync/kit-path.ts +77 -0
  178. package/src/sync/kit-source.ts +169 -0
  179. package/src/sync/kit.ts +9 -0
  180. package/src/sync/legacy-files.ts +116 -0
  181. package/src/sync/manifest.ts +44 -0
  182. package/src/sync/next-steps.ts +42 -0
  183. package/src/sync/plan-file.ts +154 -0
  184. package/src/sync/plan-hooks.ts +165 -0
  185. package/src/sync/project-fs.ts +132 -0
  186. package/src/sync/render.ts +60 -0
  187. package/src/sync/report.ts +96 -0
  188. package/src/sync/settings-hooks.ts +90 -0
  189. package/src/sync/settings-migration.ts +94 -0
  190. package/src/sync/settings-offer.ts +168 -0
  191. package/src/sync/setup-questions.ts +70 -0
  192. package/src/sync/setup.ts +52 -0
  193. package/src/sync/sync-plan.ts +120 -0
  194. package/src/sync/sync-result.ts +9 -0
  195. package/src/sync/sync.ts +307 -0
  196. package/src/sync/tools.ts +52 -0
  197. package/src/terminal/herdr.ts +91 -0
  198. package/src/terminal/index.ts +13 -0
  199. package/src/terminal/none.ts +7 -0
  200. package/src/terminal/open.ts +39 -0
  201. package/src/terminal/text.ts +159 -0
  202. package/src/terminal/types.ts +30 -0
  203. package/src/terminal/width.ts +90 -0
  204. package/src/update/command.ts +65 -0
  205. package/src/update/package-manager.ts +56 -0
  206. package/src/update/update.ts +105 -0
  207. package/src/version/installed-version.ts +32 -0
  208. package/src/version/release.ts +22 -0
  209. package/src/version/skill-diff.ts +63 -0
  210. package/src/version/started-kit.ts +14 -0
  211. package/src/vocabulary/index.ts +132 -0
  212. package/src/watch/base-tip.ts +18 -0
  213. package/src/watch/command.ts +919 -0
  214. package/src/watch/coordinator-fill.ts +76 -0
  215. package/src/watch/feedback-read.ts +73 -0
  216. package/src/watch/feedback.ts +308 -0
  217. package/src/watch/gh.ts +22 -0
  218. package/src/watch/github-read.ts +175 -0
  219. package/src/watch/herdr.ts +11 -0
  220. package/src/watch/json-guards.ts +9 -0
  221. package/src/watch/kit-update.ts +18 -0
  222. package/src/watch/lane-fill.ts +36 -0
  223. package/src/watch/lane-message.ts +99 -0
  224. package/src/watch/lane-progress.ts +44 -0
  225. package/src/watch/lane-report-file.ts +53 -0
  226. package/src/watch/lane-report.ts +270 -0
  227. package/src/watch/lane-search.ts +41 -0
  228. package/src/watch/lane-sources.ts +46 -0
  229. package/src/watch/lane-watch.ts +121 -0
  230. package/src/watch/monitor-tool.ts +19 -0
  231. package/src/watch/options.ts +79 -0
  232. package/src/watch/plan-badges-read.ts +30 -0
  233. package/src/watch/plan-badges.ts +66 -0
  234. package/src/watch/plan-views.ts +59 -0
  235. package/src/watch/preview-read.ts +60 -0
  236. package/src/watch/previews.ts +234 -0
  237. package/src/watch/pull-requests.ts +117 -0
  238. package/src/watch/single-report.ts +15 -0
  239. package/src/watch/skill-change.ts +61 -0
  240. package/src/watch/source-dry-run-command.ts +35 -0
  241. package/src/watch/source-dry-run.ts +124 -0
  242. package/src/watch/source-fields.ts +9 -0
  243. package/src/watch/source-path.ts +40 -0
  244. package/src/watch/source-run.ts +90 -0
  245. package/src/watch/sources.ts +344 -0
  246. package/src/watch/stream-output.ts +14 -0
  247. package/src/watch/texts.ts +76 -0
  248. package/src/watch/watch-events.ts +399 -0
  249. package/src/watch/watcher-lock.ts +145 -0
  250. package/src/watch/workflow-runs.ts +96 -0
@@ -0,0 +1,132 @@
1
+ export const PLAN_LANGUAGE = { de: 'de', en: 'en' } as const
2
+
3
+ export type PlanLanguage = (typeof PLAN_LANGUAGE)[keyof typeof PLAN_LANGUAGE]
4
+
5
+ /** The language's name as a reply or a question says it. */
6
+ export const LANGUAGE_NAME: Record<PlanLanguage, string> = {
7
+ [PLAN_LANGUAGE.en]: 'English',
8
+ [PLAN_LANGUAGE.de]: 'German',
9
+ }
10
+
11
+ export const isPlanLanguage = (value: string): value is PlanLanguage =>
12
+ (Object.values(PLAN_LANGUAGE) as string[]).includes(value)
13
+
14
+ export const PLAN_STATUS = {
15
+ done: 'done',
16
+ abandoned: 'abandoned',
17
+ inProgress: 'inProgress',
18
+ draft: 'draft',
19
+ other: 'other',
20
+ none: 'none',
21
+ } as const
22
+
23
+ export type PlanStatus = (typeof PLAN_STATUS)[keyof typeof PLAN_STATUS]
24
+
25
+ export type StatusWord = {
26
+ label: string
27
+ /** Lower-case words a `Status:` line starts with; empty for `other` and `none`. */
28
+ leading: readonly string[]
29
+ /** Lower-case fragments that classify a `Status:` line wherever they appear. */
30
+ anywhere: readonly string[]
31
+ }
32
+
33
+ export type PlanVocabulary = {
34
+ header: { date: string; status: string; scope: string }
35
+ sections: {
36
+ decisions: string
37
+ implementation: string
38
+ modelRecommendations: string
39
+ dependencies: string
40
+ documentation: string
41
+ lanes: string
42
+ goal: string
43
+ history: string
44
+ plans: string
45
+ }
46
+ columns: { dependsOn: string; writes: string; serialMarker: string }
47
+ phase: string
48
+ /** Opens the line by which a phase says it has no review gate on purpose: `**Kein Review-Gate:** <reason>`. */
49
+ noReviewGate: string
50
+ /** Marks a lane as closed when its name cell contains it. */
51
+ laneClosed: string
52
+ /** Words that may stand between two phases of one entry (`P1 Rule und P2 Monitor`). */
53
+ phaseConnectors: readonly string[]
54
+ statusWords: Record<PlanStatus, StatusWord>
55
+ }
56
+
57
+ export const PLAN_VOCABULARY: Record<PlanLanguage, PlanVocabulary> = {
58
+ de: {
59
+ header: { date: 'Date', status: 'Status', scope: 'Scope' },
60
+ sections: {
61
+ decisions: 'Entscheidungen',
62
+ implementation: 'Umsetzung',
63
+ modelRecommendations: 'Model-Empfehlungen pro Phase',
64
+ dependencies: 'Abhängigkeiten und Parallelisierung',
65
+ documentation: 'Dokumentation',
66
+ lanes: 'Spuren',
67
+ goal: 'Sprintziel',
68
+ history: 'Verlauf',
69
+ plans: 'Pläne',
70
+ },
71
+ columns: { dependsOn: 'Hängt ab von', writes: 'Schreibt', serialMarker: 'Seriell-Marker' },
72
+ phase: 'Phase',
73
+ noReviewGate: 'Kein Review-Gate',
74
+ laneClosed: 'abgeräumt',
75
+ phaseConnectors: ['danach', 'und', 'dann', 'sowie'],
76
+ statusWords: {
77
+ done: { label: 'Done', leading: ['done'], anywhere: ['abgeschlossen'] },
78
+ abandoned: { label: 'Abandoned', leading: ['abandoned'], anywhere: ['verworfen'] },
79
+ inProgress: { label: 'In Arbeit', leading: ['in progress'], anywhere: ['umgesetzt', 'phase'] },
80
+ draft: { label: 'Draft', leading: ['draft'], anywhere: [] },
81
+ other: { label: 'Sonstiges', leading: [], anywhere: [] },
82
+ none: { label: 'Ohne Status', leading: [], anywhere: [] },
83
+ },
84
+ },
85
+ en: {
86
+ header: { date: 'Date', status: 'Status', scope: 'Scope' },
87
+ sections: {
88
+ decisions: 'Decisions',
89
+ implementation: 'Implementation',
90
+ modelRecommendations: 'Model recommendations per phase',
91
+ dependencies: 'Dependencies and parallelization',
92
+ documentation: 'Documentation',
93
+ lanes: 'Lanes',
94
+ goal: 'Sprint goal',
95
+ history: 'History',
96
+ plans: 'Plans',
97
+ },
98
+ columns: { dependsOn: 'Depends on', writes: 'Writes', serialMarker: 'Serial marker' },
99
+ phase: 'Phase',
100
+ noReviewGate: 'No review gate',
101
+ laneClosed: 'cleaned up',
102
+ phaseConnectors: ['then', 'and', 'after'],
103
+ statusWords: {
104
+ done: { label: 'Done', leading: ['done'], anywhere: ['completed'] },
105
+ abandoned: { label: 'Abandoned', leading: ['abandoned'], anywhere: ['dropped'] },
106
+ inProgress: { label: 'In progress', leading: ['in progress'], anywhere: ['implemented', 'phase'] },
107
+ draft: { label: 'Draft', leading: ['draft'], anywhere: [] },
108
+ other: { label: 'Other', leading: [], anywhere: [] },
109
+ none: { label: 'No status', leading: [], anywhere: [] },
110
+ },
111
+ },
112
+ }
113
+
114
+ const STATUS_PRECEDENCE = [PLAN_STATUS.done, PLAN_STATUS.abandoned, PLAN_STATUS.inProgress, PLAN_STATUS.draft] as const
115
+
116
+ /** Classifies a free-text `Status:` line; the first matching status in precedence order wins. */
117
+ export const classifyStatus = (language: PlanLanguage, statusText: string): PlanStatus => {
118
+ const { statusWords } = PLAN_VOCABULARY[language]
119
+ const lowerStatus = statusText.toLowerCase()
120
+ const matches = ({ leading, anywhere }: StatusWord) =>
121
+ leading.some((word) => lowerStatus.startsWith(word)) || anywhere.some((fragment) => lowerStatus.includes(fragment))
122
+ const matched = STATUS_PRECEDENCE.find((status) => matches(statusWords[status]))
123
+ if (matched) return matched
124
+ return statusText.trim() ? PLAN_STATUS.other : PLAN_STATUS.none
125
+ }
126
+
127
+ /** `### Phase 3: Title` as the plan spells it in `language`. */
128
+ export const phaseHeading = (language: PlanLanguage, id: string, title: string): string =>
129
+ `### ${PLAN_VOCABULARY[language].phase} ${id}: ${title}`
130
+
131
+ export const sectionHeading = (language: PlanLanguage, section: keyof PlanVocabulary['sections']): string =>
132
+ `## ${PLAN_VOCABULARY[language].sections[section]}`
@@ -0,0 +1,18 @@
1
+ const COMMIT = /^[0-9a-f]{40}$/
2
+
3
+ /** The commit of `refs/heads/<branch>` in a `git ls-remote` answer; null when it is not listed. */
4
+ export const remoteTipOf = (lsRemote: string, branch: string): string | null => {
5
+ const ref = `refs/heads/${branch}`
6
+ for (const line of lsRemote.split('\n')) {
7
+ const [commit, name] = line.trim().split(/\s+/)
8
+ if (name === ref && commit && COMMIT.test(commit)) return commit
9
+ }
10
+ return null
11
+ }
12
+
13
+ /**
14
+ * Whether the base branch has to be fetched: the remote moved past the local remote-tracking ref, or
15
+ * there is none yet. A remote that could not be read is no reason to fetch.
16
+ */
17
+ export const baseFetchNeeded = (remoteTip: string | null, localTip: string | null): boolean =>
18
+ remoteTip !== null && remoteTip !== localTip