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.
- package/CHANGELOG.md +65 -0
- package/LICENSE +21 -0
- package/NOTICE +38 -0
- package/README.md +1122 -3
- package/assets/branding/README.md +62 -0
- package/assets/branding/jackherd-icon-256.png +0 -0
- package/assets/branding/jackherd-icon-512.png +0 -0
- package/assets/branding/jackherd-icon-64.png +0 -0
- package/assets/branding/jackherd-icon-small-32.png +0 -0
- package/assets/branding/jackherd-icon-small-64.png +0 -0
- package/assets/branding/jackherd-icon-small.svg +1 -0
- package/assets/branding/jackherd-icon.svg +1 -0
- package/assets/branding/jackherd-logo-1024.png +0 -0
- package/assets/branding/jackherd-logo-512.png +0 -0
- package/assets/branding/jackherd-logo-dark-1024.png +0 -0
- package/assets/branding/jackherd-logo-dark-512.png +0 -0
- package/assets/branding/jackherd-logo-dark.svg +1 -0
- package/assets/branding/jackherd-logo-mark-1024.png +0 -0
- package/assets/branding/jackherd-logo-mark-512.png +0 -0
- package/assets/branding/jackherd-logo-mark.svg +1 -0
- package/assets/branding/jackherd-logo.svg +1 -0
- package/dist/chunk-R6MGHCD7.js +93 -0
- package/dist/config.d.ts +167 -0
- package/dist/config.js +401 -0
- package/dist/plan-format.d.ts +325 -0
- package/dist/plan-format.js +636 -0
- package/docs/lanes.mmd +9 -0
- package/docs/lanes.svg +1 -0
- package/docs/skills.mmd +10 -0
- package/docs/skills.svg +1 -0
- package/docs/workflow.svg +172 -0
- package/herdr-plugin/herdr-plugin.toml +22 -0
- package/herdr-plugin/open-plans.ts +43 -0
- package/herdr-plugin/restore-plans.ts +107 -0
- package/install.sh +157 -0
- package/kit/hooks/hooks/git-guard/decision.ts +438 -0
- package/kit/hooks/hooks/git-guard/index.ts +38 -0
- package/kit/hooks/hooks/git-guard/shell.ts +407 -0
- package/kit/hooks/hooks/watch-guard/background.ts +36 -0
- package/kit/hooks/hooks/watch-guard/decision.ts +53 -0
- package/kit/hooks/hooks/watch-guard/index.ts +11 -0
- package/kit/hooks/hooks/watch-guard/shell-input.ts +32 -0
- package/kit/hooks/hooks/watch-guard/starts.ts +154 -0
- package/kit/hooks/hooks/watch-guard/text-fallback.ts +40 -0
- package/kit/hooks/hooks.json +30 -0
- package/kit/hooks/statusline.sh +72 -0
- package/kit/review/agents/devops.md +11 -0
- package/kit/review/agents/public-content.md +39 -0
- package/kit/review/agents/security-audit.md +11 -0
- package/kit/review/agents/uncle-bob.md +11 -0
- package/kit/review/skills/devops/SKILL.md +50 -0
- package/kit/review/skills/diagnose/SKILL.md +140 -0
- package/kit/review/skills/diagnose/references/feedback-loops.md +59 -0
- package/kit/review/skills/diagnose/scripts/hitl-loop.template.sh +71 -0
- package/kit/review/skills/pre-commit/SKILL.md +100 -0
- package/kit/review/skills/review/SKILL.md +43 -0
- package/kit/review/skills/security-audit/SKILL.md +65 -0
- package/kit/review/skills/uncle-bob/SKILL.md +43 -0
- package/kit/rules/rules/kit/arc42.md +89 -0
- package/kit/rules/rules/kit/architecture-files.md +87 -0
- package/kit/rules/rules/kit/code-style.md +159 -0
- package/kit/rules/rules/kit/pull-requests.md +59 -0
- package/kit/rules/rules/kit/testing.md +91 -0
- package/kit/rules/rules/kit/writing-for-agents.md +110 -0
- package/kit/workflow/agents/explore.md +25 -0
- package/kit/workflow/agents/implement.md +16 -0
- package/kit/workflow/agents/plan.md +13 -0
- package/kit/workflow/agents/spec-review.md +96 -0
- package/kit/workflow/skills/follow/SKILL.md +48 -0
- package/kit/workflow/skills/grill/SKILL.md +60 -0
- package/kit/workflow/skills/implement/SKILL.md +107 -0
- package/kit/workflow/skills/orchestrate/SKILL.md +565 -0
- package/kit/workflow/skills/orchestrate/handover/decision.ts +247 -0
- package/kit/workflow/skills/orchestrate/handover/index.ts +171 -0
- package/kit/workflow/skills/plan/SKILL.md +118 -0
- package/kit/workflow/skills/plan/references/template-English.md +92 -0
- package/kit/workflow/skills/plan/references/template-German.md +92 -0
- package/kit/workflow/skills/start/SKILL.md +47 -0
- package/package.json +63 -5
- package/schemas/jackherd.schema.json +601 -0
- package/src/check/changes.ts +45 -0
- package/src/check/command-line.ts +12 -0
- package/src/check/command.ts +136 -0
- package/src/check/deferral-arrows.ts +41 -0
- package/src/check/execute.ts +29 -0
- package/src/check/glob.ts +15 -0
- package/src/check/plan-structure-check.ts +135 -0
- package/src/check/plan.ts +106 -0
- package/src/check/public-content-check.ts +32 -0
- package/src/check/public-content-facts.ts +177 -0
- package/src/check/public-content.ts +216 -0
- package/src/check/report.ts +55 -0
- package/src/check/result.ts +42 -0
- package/src/check/roots.ts +36 -0
- package/src/check/routing.ts +22 -0
- package/src/check/schema.ts +83 -0
- package/src/check/settings.ts +44 -0
- package/src/claude/paths.ts +14 -0
- package/src/cli.ts +46 -0
- package/src/config/command.ts +45 -0
- package/src/config/detect.ts +196 -0
- package/src/config/index.ts +2 -0
- package/src/config/json-schema.ts +5 -0
- package/src/config/legacy-names.ts +56 -0
- package/src/config/link-kinds.ts +25 -0
- package/src/config/location.ts +46 -0
- package/src/config/read-config.ts +42 -0
- package/src/config/repository-facts.ts +19 -0
- package/src/config/repository-values.ts +46 -0
- package/src/config/schema.ts +302 -0
- package/src/context/command.ts +39 -0
- package/src/context/coordinator-name.ts +16 -0
- package/src/context/fill.ts +69 -0
- package/src/context/index.ts +10 -0
- package/src/context/level.ts +22 -0
- package/src/context/options.ts +29 -0
- package/src/context/report.ts +42 -0
- package/src/context/session-log.ts +91 -0
- package/src/plan-format/drift.ts +69 -0
- package/src/plan-format/header.ts +27 -0
- package/src/plan-format/index.ts +9 -0
- package/src/plan-format/lanes.ts +128 -0
- package/src/plan-format/markdown.ts +98 -0
- package/src/plan-format/phase-tally.ts +55 -0
- package/src/plan-format/phases.ts +224 -0
- package/src/plan-format/plan-structure.ts +150 -0
- package/src/plan-format/progress.ts +202 -0
- package/src/plan-format/sprint-document.ts +69 -0
- package/src/plan-format/terminal-text.ts +28 -0
- package/src/plans/board-choice.ts +60 -0
- package/src/plans/board-pick.ts +72 -0
- package/src/plans/board-rows.ts +62 -0
- package/src/plans/command.ts +60 -0
- package/src/plans/ensure-panes.ts +71 -0
- package/src/plans/error-text.ts +5 -0
- package/src/plans/fetch.ts +96 -0
- package/src/plans/git.ts +145 -0
- package/src/plans/github.ts +35 -0
- package/src/plans/lane-discovery.ts +34 -0
- package/src/plans/lane-plans.ts +80 -0
- package/src/plans/layout.ts +881 -0
- package/src/plans/link-chips.ts +74 -0
- package/src/plans/live.ts +336 -0
- package/src/plans/markdown-html.ts +140 -0
- package/src/plans/options.ts +15 -0
- package/src/plans/phase-source.ts +71 -0
- package/src/plans/plan-chips.ts +75 -0
- package/src/plans/plan-panes.ts +206 -0
- package/src/plans/planned.ts +117 -0
- package/src/plans/pull-requests.ts +107 -0
- package/src/plans/restart-decision.ts +42 -0
- package/src/plans/selection.ts +352 -0
- package/src/plans/settings.ts +68 -0
- package/src/plans/single-flight.ts +25 -0
- package/src/plans/snapshot.ts +300 -0
- package/src/plans/sprint-export.ts +103 -0
- package/src/plans/sprint-html.ts +301 -0
- package/src/plans/sprint-page.ts +287 -0
- package/src/plans/supervisor.ts +124 -0
- package/src/plans/symbols.ts +54 -0
- package/src/plans/texts.ts +103 -0
- package/src/plans/unlisted-lanes.ts +45 -0
- package/src/plans/view.ts +68 -0
- package/src/plans/worked-phases.ts +53 -0
- package/src/sync/checksum.ts +13 -0
- package/src/sync/choice.ts +14 -0
- package/src/sync/command-context.ts +113 -0
- package/src/sync/command.ts +94 -0
- package/src/sync/error-message.ts +1 -0
- package/src/sync/gitignore.ts +45 -0
- package/src/sync/global-kit.ts +176 -0
- package/src/sync/herdr-plugin.ts +175 -0
- package/src/sync/if-changed.ts +109 -0
- package/src/sync/init-command.ts +239 -0
- package/src/sync/init.ts +136 -0
- package/src/sync/kit-hooks.ts +18 -0
- package/src/sync/kit-path.ts +77 -0
- package/src/sync/kit-source.ts +169 -0
- package/src/sync/kit.ts +9 -0
- package/src/sync/legacy-files.ts +116 -0
- package/src/sync/manifest.ts +44 -0
- package/src/sync/next-steps.ts +42 -0
- package/src/sync/plan-file.ts +154 -0
- package/src/sync/plan-hooks.ts +165 -0
- package/src/sync/project-fs.ts +132 -0
- package/src/sync/render.ts +60 -0
- package/src/sync/report.ts +96 -0
- package/src/sync/settings-hooks.ts +90 -0
- package/src/sync/settings-migration.ts +94 -0
- package/src/sync/settings-offer.ts +168 -0
- package/src/sync/setup-questions.ts +70 -0
- package/src/sync/setup.ts +52 -0
- package/src/sync/sync-plan.ts +120 -0
- package/src/sync/sync-result.ts +9 -0
- package/src/sync/sync.ts +307 -0
- package/src/sync/tools.ts +52 -0
- package/src/terminal/herdr.ts +91 -0
- package/src/terminal/index.ts +13 -0
- package/src/terminal/none.ts +7 -0
- package/src/terminal/open.ts +39 -0
- package/src/terminal/text.ts +159 -0
- package/src/terminal/types.ts +30 -0
- package/src/terminal/width.ts +90 -0
- package/src/update/command.ts +65 -0
- package/src/update/package-manager.ts +56 -0
- package/src/update/update.ts +105 -0
- package/src/version/installed-version.ts +32 -0
- package/src/version/release.ts +22 -0
- package/src/version/skill-diff.ts +63 -0
- package/src/version/started-kit.ts +14 -0
- package/src/vocabulary/index.ts +132 -0
- package/src/watch/base-tip.ts +18 -0
- package/src/watch/command.ts +919 -0
- package/src/watch/coordinator-fill.ts +76 -0
- package/src/watch/feedback-read.ts +73 -0
- package/src/watch/feedback.ts +308 -0
- package/src/watch/gh.ts +22 -0
- package/src/watch/github-read.ts +175 -0
- package/src/watch/herdr.ts +11 -0
- package/src/watch/json-guards.ts +9 -0
- package/src/watch/kit-update.ts +18 -0
- package/src/watch/lane-fill.ts +36 -0
- package/src/watch/lane-message.ts +99 -0
- package/src/watch/lane-progress.ts +44 -0
- package/src/watch/lane-report-file.ts +53 -0
- package/src/watch/lane-report.ts +270 -0
- package/src/watch/lane-search.ts +41 -0
- package/src/watch/lane-sources.ts +46 -0
- package/src/watch/lane-watch.ts +121 -0
- package/src/watch/monitor-tool.ts +19 -0
- package/src/watch/options.ts +79 -0
- package/src/watch/plan-badges-read.ts +30 -0
- package/src/watch/plan-badges.ts +66 -0
- package/src/watch/plan-views.ts +59 -0
- package/src/watch/preview-read.ts +60 -0
- package/src/watch/previews.ts +234 -0
- package/src/watch/pull-requests.ts +117 -0
- package/src/watch/single-report.ts +15 -0
- package/src/watch/skill-change.ts +61 -0
- package/src/watch/source-dry-run-command.ts +35 -0
- package/src/watch/source-dry-run.ts +124 -0
- package/src/watch/source-fields.ts +9 -0
- package/src/watch/source-path.ts +40 -0
- package/src/watch/source-run.ts +90 -0
- package/src/watch/sources.ts +344 -0
- package/src/watch/stream-output.ts +14 -0
- package/src/watch/texts.ts +76 -0
- package/src/watch/watch-events.ts +399 -0
- package/src/watch/watcher-lock.ts +145 -0
- package/src/watch/workflow-runs.ts +96 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const renderConfigJsonSchema: () => string;
|
|
4
|
+
|
|
5
|
+
declare const TERMINAL_ADAPTER: {
|
|
6
|
+
readonly none: "none";
|
|
7
|
+
readonly herdr: "herdr";
|
|
8
|
+
};
|
|
9
|
+
type TerminalAdapter = (typeof TERMINAL_ADAPTER)[keyof typeof TERMINAL_ADAPTER];
|
|
10
|
+
declare const MODEL_ROLE: {
|
|
11
|
+
readonly plan: "plan";
|
|
12
|
+
readonly implement: "implement";
|
|
13
|
+
readonly review: "review";
|
|
14
|
+
readonly explore: "explore";
|
|
15
|
+
readonly orchestrate: "orchestrate";
|
|
16
|
+
};
|
|
17
|
+
type ModelRole = (typeof MODEL_ROLE)[keyof typeof MODEL_ROLE];
|
|
18
|
+
declare const isTerminalAdapter: (value: string) => value is TerminalAdapter;
|
|
19
|
+
declare const isModelRole: (value: string) => value is ModelRole;
|
|
20
|
+
/** Lower-case letters and digits ending in a dash, so a prefixed name stays one plain path segment. */
|
|
21
|
+
declare const SKILL_PREFIX: RegExp;
|
|
22
|
+
declare const sourceSchema: z.ZodObject<{
|
|
23
|
+
name: z.ZodString;
|
|
24
|
+
command: z.ZodArray<z.ZodString>;
|
|
25
|
+
every: z.ZodDefault<z.ZodNumber>;
|
|
26
|
+
items: z.ZodOptional<z.ZodString>;
|
|
27
|
+
map: z.ZodObject<{
|
|
28
|
+
id: z.ZodString;
|
|
29
|
+
updatedAt: z.ZodString;
|
|
30
|
+
title: z.ZodOptional<z.ZodString>;
|
|
31
|
+
url: z.ZodOptional<z.ZodString>;
|
|
32
|
+
body: z.ZodOptional<z.ZodString>;
|
|
33
|
+
author: z.ZodOptional<z.ZodString>;
|
|
34
|
+
}, z.core.$catchall<z.ZodString>>;
|
|
35
|
+
ignoreAuthors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
36
|
+
reportLimit: z.ZodDefault<z.ZodNumber>;
|
|
37
|
+
lane: z.ZodOptional<z.ZodString>;
|
|
38
|
+
reportOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
declare const jackherdConfigSchema: z.ZodObject<{
|
|
41
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
42
|
+
responseLanguage: z.ZodDefault<z.ZodEnum<{
|
|
43
|
+
de: "de";
|
|
44
|
+
en: "en";
|
|
45
|
+
}>>;
|
|
46
|
+
planLanguage: z.ZodDefault<z.ZodEnum<{
|
|
47
|
+
de: "de";
|
|
48
|
+
en: "en";
|
|
49
|
+
}>>;
|
|
50
|
+
planDirectory: z.ZodDefault<z.ZodString>;
|
|
51
|
+
board: z.ZodPrefault<z.ZodObject<{
|
|
52
|
+
pattern: z.ZodDefault<z.ZodString>;
|
|
53
|
+
file: z.ZodDefault<z.ZodString>;
|
|
54
|
+
term: z.ZodDefault<z.ZodString>;
|
|
55
|
+
}, z.core.$strict>>;
|
|
56
|
+
sprintPattern: z.ZodOptional<z.ZodNever>;
|
|
57
|
+
worktreeDirectory: z.ZodDefault<z.ZodString>;
|
|
58
|
+
baseBranch: z.ZodDefault<z.ZodString>;
|
|
59
|
+
skillPrefix: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"">, z.ZodString]>>;
|
|
60
|
+
commands: z.ZodPrefault<z.ZodObject<{
|
|
61
|
+
test: z.ZodDefault<z.ZodString>;
|
|
62
|
+
typecheck: z.ZodDefault<z.ZodString>;
|
|
63
|
+
lint: z.ZodDefault<z.ZodString>;
|
|
64
|
+
format: z.ZodDefault<z.ZodString>;
|
|
65
|
+
install: z.ZodDefault<z.ZodString>;
|
|
66
|
+
dev: z.ZodDefault<z.ZodString>;
|
|
67
|
+
}, z.core.$strict>>;
|
|
68
|
+
lanes: z.ZodPrefault<z.ZodObject<{
|
|
69
|
+
copy: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
70
|
+
lockFile: z.ZodDefault<z.ZodString>;
|
|
71
|
+
}, z.core.$strict>>;
|
|
72
|
+
models: z.ZodRecord<z.ZodEnum<{
|
|
73
|
+
plan: "plan";
|
|
74
|
+
implement: "implement";
|
|
75
|
+
review: "review";
|
|
76
|
+
explore: "explore";
|
|
77
|
+
orchestrate: "orchestrate";
|
|
78
|
+
}>, z.ZodString>;
|
|
79
|
+
terminal: z.ZodPrefault<z.ZodObject<{
|
|
80
|
+
adapter: z.ZodDefault<z.ZodEnum<{
|
|
81
|
+
none: "none";
|
|
82
|
+
herdr: "herdr";
|
|
83
|
+
}>>;
|
|
84
|
+
}, z.core.$strict>>;
|
|
85
|
+
plans: z.ZodPrefault<z.ZodObject<{
|
|
86
|
+
fetchIntervalMinutes: z.ZodDefault<z.ZodNumber>;
|
|
87
|
+
linkKinds: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
88
|
+
pattern: z.ZodString;
|
|
89
|
+
label: z.ZodString;
|
|
90
|
+
icon: z.ZodString;
|
|
91
|
+
}, z.core.$strict>>>;
|
|
92
|
+
context: z.ZodPrefault<z.ZodObject<{
|
|
93
|
+
warnAt: z.ZodDefault<z.ZodNumber>;
|
|
94
|
+
alertAt: z.ZodDefault<z.ZodNumber>;
|
|
95
|
+
windows: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
96
|
+
defaultWindow: z.ZodDefault<z.ZodNumber>;
|
|
97
|
+
coordinator: z.ZodPrefault<z.ZodObject<{
|
|
98
|
+
warnAt: z.ZodDefault<z.ZodNumber>;
|
|
99
|
+
alertAt: z.ZodDefault<z.ZodNumber>;
|
|
100
|
+
}, z.core.$strict>>;
|
|
101
|
+
}, z.core.$strict>>;
|
|
102
|
+
}, z.core.$strict>>;
|
|
103
|
+
watch: z.ZodPrefault<z.ZodObject<{
|
|
104
|
+
deploy: z.ZodOptional<z.ZodObject<{
|
|
105
|
+
workflow: z.ZodString;
|
|
106
|
+
environments: z.ZodArray<z.ZodString>;
|
|
107
|
+
}, z.core.$strict>>;
|
|
108
|
+
feedback: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
109
|
+
ignore: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
110
|
+
}, z.core.$strict>]>>;
|
|
111
|
+
previews: z.ZodOptional<z.ZodObject<{
|
|
112
|
+
deployments: z.ZodDefault<z.ZodBoolean>;
|
|
113
|
+
authors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
114
|
+
urlPattern: z.ZodOptional<z.ZodString>;
|
|
115
|
+
}, z.core.$strict>>;
|
|
116
|
+
sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
117
|
+
name: z.ZodString;
|
|
118
|
+
command: z.ZodArray<z.ZodString>;
|
|
119
|
+
every: z.ZodDefault<z.ZodNumber>;
|
|
120
|
+
items: z.ZodOptional<z.ZodString>;
|
|
121
|
+
map: z.ZodObject<{
|
|
122
|
+
id: z.ZodString;
|
|
123
|
+
updatedAt: z.ZodString;
|
|
124
|
+
title: z.ZodOptional<z.ZodString>;
|
|
125
|
+
url: z.ZodOptional<z.ZodString>;
|
|
126
|
+
body: z.ZodOptional<z.ZodString>;
|
|
127
|
+
author: z.ZodOptional<z.ZodString>;
|
|
128
|
+
}, z.core.$catchall<z.ZodString>>;
|
|
129
|
+
ignoreAuthors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
130
|
+
reportLimit: z.ZodDefault<z.ZodNumber>;
|
|
131
|
+
lane: z.ZodOptional<z.ZodString>;
|
|
132
|
+
reportOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
133
|
+
}, z.core.$strict>>>;
|
|
134
|
+
}, z.core.$strict>>;
|
|
135
|
+
check: z.ZodOptional<z.ZodObject<{
|
|
136
|
+
lintFilesCommand: z.ZodDefault<z.ZodString>;
|
|
137
|
+
checks: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
138
|
+
name: z.ZodString;
|
|
139
|
+
command: z.ZodString;
|
|
140
|
+
globs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
141
|
+
}, z.core.$strict>>>;
|
|
142
|
+
generatorOwned: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
143
|
+
glob: z.ZodString;
|
|
144
|
+
generator: z.ZodString;
|
|
145
|
+
}, z.core.$strict>>>;
|
|
146
|
+
buildArtifacts: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
147
|
+
reviewerRoutes: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
148
|
+
reviewer: z.ZodString;
|
|
149
|
+
globs: z.ZodArray<z.ZodString>;
|
|
150
|
+
why: z.ZodString;
|
|
151
|
+
}, z.core.$strict>>>;
|
|
152
|
+
publicContent: z.ZodOptional<z.ZodObject<{
|
|
153
|
+
globs: z.ZodArray<z.ZodString>;
|
|
154
|
+
exclude: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
155
|
+
reviewer: z.ZodDefault<z.ZodString>;
|
|
156
|
+
}, z.core.$strict>>;
|
|
157
|
+
looseTests: z.ZodDefault<z.ZodBoolean>;
|
|
158
|
+
}, z.core.$strict>>;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
type JackherdConfig = z.infer<typeof jackherdConfigSchema>;
|
|
161
|
+
declare const parseJackherdConfig: (raw: unknown) => JackherdConfig;
|
|
162
|
+
/** `parseJackherdConfig` for a file: an invalid one throws with `label` (its path) and the issues in words. */
|
|
163
|
+
declare const parseConfigFile: (raw: unknown, label: string) => JackherdConfig;
|
|
164
|
+
/** One `watch.sources` entry outside the config, such as a draft to try; invalid throws with `label` and the issues. */
|
|
165
|
+
declare const parseSourceDraft: (raw: unknown, label: string) => z.infer<typeof sourceSchema>;
|
|
166
|
+
|
|
167
|
+
export { type JackherdConfig, MODEL_ROLE, type ModelRole, SKILL_PREFIX, TERMINAL_ADAPTER, type TerminalAdapter, isModelRole, isTerminalAdapter, jackherdConfigSchema, parseConfigFile, parseJackherdConfig, parseSourceDraft, renderConfigJsonSchema };
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PLAN_LANGUAGE
|
|
3
|
+
} from "./chunk-R6MGHCD7.js";
|
|
4
|
+
|
|
5
|
+
// src/config/json-schema.ts
|
|
6
|
+
import { z as z3 } from "zod";
|
|
7
|
+
|
|
8
|
+
// src/config/schema.ts
|
|
9
|
+
import { z as z2 } from "zod";
|
|
10
|
+
|
|
11
|
+
// src/check/schema.ts
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
14
|
+
// src/version/release.ts
|
|
15
|
+
var PACKAGE_NAME = "jackherd";
|
|
16
|
+
|
|
17
|
+
// src/config/location.ts
|
|
18
|
+
import { dirname, join, resolve } from "path";
|
|
19
|
+
var TOOL_DIRECTORY = ".jackherd";
|
|
20
|
+
var CONFIG_FILE = "config.json";
|
|
21
|
+
var CONFIG_SCHEMA_REFERENCE = `../node_modules/${PACKAGE_NAME}/schemas/${PACKAGE_NAME}.schema.json`;
|
|
22
|
+
var PROJECT_CONFIG_PATH = `${TOOL_DIRECTORY}/${CONFIG_FILE}`;
|
|
23
|
+
|
|
24
|
+
// src/config/detect.ts
|
|
25
|
+
var PACKAGE_MANAGER = { bun: "bun", yarn: "yarn", pnpm: "pnpm", npm: "npm" };
|
|
26
|
+
var LOCK_FILES = {
|
|
27
|
+
"bun.lock": PACKAGE_MANAGER.bun,
|
|
28
|
+
"bun.lockb": PACKAGE_MANAGER.bun,
|
|
29
|
+
"yarn.lock": PACKAGE_MANAGER.yarn,
|
|
30
|
+
"pnpm-lock.yaml": PACKAGE_MANAGER.pnpm,
|
|
31
|
+
"package-lock.json": PACKAGE_MANAGER.npm
|
|
32
|
+
};
|
|
33
|
+
var DEFAULT_BASE_BRANCH = "main";
|
|
34
|
+
var DERIVED_COMMANDS = {
|
|
35
|
+
bun: {
|
|
36
|
+
test: "bun test",
|
|
37
|
+
typecheck: "bunx -p typescript tsc --noEmit",
|
|
38
|
+
lint: "bunx @biomejs/biome check .",
|
|
39
|
+
format: "bunx @biomejs/biome format --write .",
|
|
40
|
+
install: "bun install",
|
|
41
|
+
dev: "bun run dev",
|
|
42
|
+
lintFiles: "bunx @biomejs/biome check --no-errors-on-unmatched"
|
|
43
|
+
},
|
|
44
|
+
yarn: {
|
|
45
|
+
test: "yarn test",
|
|
46
|
+
typecheck: "yarn tsc --noEmit",
|
|
47
|
+
lint: "yarn biome check .",
|
|
48
|
+
format: "yarn biome format --write .",
|
|
49
|
+
install: "yarn install",
|
|
50
|
+
dev: "yarn dev",
|
|
51
|
+
lintFiles: "yarn biome check --no-errors-on-unmatched"
|
|
52
|
+
},
|
|
53
|
+
pnpm: {
|
|
54
|
+
test: "pnpm test",
|
|
55
|
+
typecheck: "pnpm exec tsc --noEmit",
|
|
56
|
+
lint: "pnpm exec biome check .",
|
|
57
|
+
format: "pnpm exec biome format --write .",
|
|
58
|
+
install: "pnpm install",
|
|
59
|
+
dev: "pnpm dev",
|
|
60
|
+
lintFiles: "pnpm exec biome check --no-errors-on-unmatched"
|
|
61
|
+
},
|
|
62
|
+
npm: {
|
|
63
|
+
test: "npm test",
|
|
64
|
+
typecheck: "npx tsc --noEmit",
|
|
65
|
+
lint: "npx @biomejs/biome check .",
|
|
66
|
+
format: "npx @biomejs/biome format --write .",
|
|
67
|
+
install: "npm install",
|
|
68
|
+
dev: "npm run dev",
|
|
69
|
+
lintFiles: "npx @biomejs/biome check --no-errors-on-unmatched"
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var BUN_COMMANDS = DERIVED_COMMANDS.bun;
|
|
73
|
+
|
|
74
|
+
// src/check/command-line.ts
|
|
75
|
+
var TOKEN = /(?:"[^"]*"|'[^']*'|\S)+/g;
|
|
76
|
+
var QUOTED = /"([^"]*)"|'([^']*)'/g;
|
|
77
|
+
var tokenize = (command3) => (command3.match(TOKEN) ?? []).map((token) => {
|
|
78
|
+
if (/["']/.test(token.replace(QUOTED, ""))) throw new Error(`Unterminated quote in command: ${command3}`);
|
|
79
|
+
return token.replace(QUOTED, "$1$2");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// src/check/schema.ts
|
|
83
|
+
var nonEmpty = z.string().min(1);
|
|
84
|
+
var isTokenizable = (command3) => {
|
|
85
|
+
try {
|
|
86
|
+
tokenize(command3);
|
|
87
|
+
return true;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var command = nonEmpty.refine(isTokenizable, "Unterminated quote in command");
|
|
93
|
+
var glob = nonEmpty.refine((value) => !/[{}[\]]/.test(value), "Braces and brackets are not supported in globs");
|
|
94
|
+
var globs = z.array(glob).min(1);
|
|
95
|
+
var DEFAULT_BUILD_ARTIFACT_GLOBS = [
|
|
96
|
+
"**/tsup.config.bundled_*",
|
|
97
|
+
"**/dist/**",
|
|
98
|
+
"**/.turbo/**",
|
|
99
|
+
"**/node_modules/**",
|
|
100
|
+
"**/*.tsbuildinfo"
|
|
101
|
+
];
|
|
102
|
+
var reviewerRoute = z.strictObject({
|
|
103
|
+
reviewer: nonEmpty,
|
|
104
|
+
globs,
|
|
105
|
+
why: nonEmpty
|
|
106
|
+
});
|
|
107
|
+
var projectCheck = z.strictObject({
|
|
108
|
+
name: nonEmpty,
|
|
109
|
+
command,
|
|
110
|
+
/** Without globs the check runs on every change; with them, only when a changed path matches. */
|
|
111
|
+
globs: globs.optional()
|
|
112
|
+
});
|
|
113
|
+
var generatorOwned = z.strictObject({
|
|
114
|
+
glob,
|
|
115
|
+
generator: nonEmpty
|
|
116
|
+
});
|
|
117
|
+
var publicContent = z.strictObject({
|
|
118
|
+
/** The published files: a change here gets the reviewer and the scan for names of neighbouring projects. */
|
|
119
|
+
globs,
|
|
120
|
+
/** Files among them that never ship, such as tests. */
|
|
121
|
+
exclude: z.array(glob).default([]),
|
|
122
|
+
/** The agent that judges such a change; a global install names it with its prefix. */
|
|
123
|
+
reviewer: nonEmpty.default("public-content")
|
|
124
|
+
});
|
|
125
|
+
var checkConfigSchema = z.strictObject({
|
|
126
|
+
/**
|
|
127
|
+
* Run once over the changed files, which are appended as arguments. Separate from `commands.lint`,
|
|
128
|
+
* which lints the whole project.
|
|
129
|
+
*/
|
|
130
|
+
lintFilesCommand: command.default(BUN_COMMANDS.lintFiles),
|
|
131
|
+
/** Project checks, run alongside lint; add repository-specific scripts here. */
|
|
132
|
+
checks: z.array(projectCheck).default([]),
|
|
133
|
+
generatorOwned: z.array(generatorOwned).default([]),
|
|
134
|
+
buildArtifacts: z.array(glob).default([...DEFAULT_BUILD_ARTIFACT_GLOBS]),
|
|
135
|
+
reviewerRoutes: z.array(reviewerRoute).default([]),
|
|
136
|
+
publicContent: publicContent.optional(),
|
|
137
|
+
/** Also run tests in directories that hold test files but belong to no package. */
|
|
138
|
+
looseTests: z.boolean().default(false)
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// src/claude/paths.ts
|
|
142
|
+
var CLAUDE_DIRECTORY = ".claude";
|
|
143
|
+
var WORKTREES_DIRECTORY = "worktrees";
|
|
144
|
+
var claudePath = (...segments) => [CLAUDE_DIRECTORY, ...segments].join("/");
|
|
145
|
+
|
|
146
|
+
// src/watch/source-fields.ts
|
|
147
|
+
var SOURCE_FIELD = {
|
|
148
|
+
id: "id",
|
|
149
|
+
updatedAt: "updatedAt",
|
|
150
|
+
title: "title",
|
|
151
|
+
url: "url",
|
|
152
|
+
body: "body",
|
|
153
|
+
author: "author"
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// src/watch/source-path.ts
|
|
157
|
+
var ROOT_PATH = ".";
|
|
158
|
+
var PATH_STEP = /\.([^\s.[\]|]+)|\[(-?\d+)\]/y;
|
|
159
|
+
var pathSteps = (path) => {
|
|
160
|
+
if (path === ROOT_PATH) return [];
|
|
161
|
+
const steps = [];
|
|
162
|
+
PATH_STEP.lastIndex = 0;
|
|
163
|
+
while (PATH_STEP.lastIndex < path.length) {
|
|
164
|
+
const match = PATH_STEP.exec(path);
|
|
165
|
+
if (!match) return null;
|
|
166
|
+
steps.push(match[1] === void 0 ? { index: Number(match[2]) } : { key: match[1] });
|
|
167
|
+
}
|
|
168
|
+
return steps.length > 0 ? steps : null;
|
|
169
|
+
};
|
|
170
|
+
var isSourcePath = (path) => pathSteps(path) !== null;
|
|
171
|
+
|
|
172
|
+
// src/config/link-kinds.ts
|
|
173
|
+
var DEFAULT_LINK_KINDS = [
|
|
174
|
+
{ pattern: "^https://github\\.com/[^/]+/[^/]+/(pull|issues)/\\d+", label: "GitHub", icon: "\u2442" },
|
|
175
|
+
{ pattern: "^https://(www\\.)?figma\\.com/", label: "Figma", icon: "\u25C8" },
|
|
176
|
+
{ pattern: "^https://claude\\.ai/(code/)?artifact/", label: "Artifact", icon: "\u2726" }
|
|
177
|
+
];
|
|
178
|
+
var isRegularExpression = (source) => {
|
|
179
|
+
try {
|
|
180
|
+
new RegExp(source);
|
|
181
|
+
return true;
|
|
182
|
+
} catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// src/config/schema.ts
|
|
188
|
+
var TERMINAL_ADAPTER = { none: "none", herdr: "herdr" };
|
|
189
|
+
var MODEL_ROLE = {
|
|
190
|
+
plan: "plan",
|
|
191
|
+
implement: "implement",
|
|
192
|
+
review: "review",
|
|
193
|
+
explore: "explore",
|
|
194
|
+
orchestrate: "orchestrate"
|
|
195
|
+
};
|
|
196
|
+
var isTerminalAdapter = (value) => Object.values(TERMINAL_ADAPTER).includes(value);
|
|
197
|
+
var isModelRole = (value) => Object.values(MODEL_ROLE).includes(value);
|
|
198
|
+
var SKILL_PREFIX = /^[a-z0-9]+-$/;
|
|
199
|
+
var FULL_MODEL_ID = /^claude-[a-z0-9][a-z0-9.-]*$/;
|
|
200
|
+
var language = z2.enum(Object.values(PLAN_LANGUAGE));
|
|
201
|
+
var modelId = z2.string().regex(FULL_MODEL_ID, "Use a full model ID such as claude-opus-5-5, not an alias like opus or sonnet");
|
|
202
|
+
var command2 = z2.string().min(1);
|
|
203
|
+
var share = z2.number().gt(0).lt(1);
|
|
204
|
+
var laneCopyPath = z2.string().regex(
|
|
205
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: the class exists to refuse control characters
|
|
206
|
+
/^(?![/-])(?!(?:.*\/)?\.\.(?:\/|$))[^'\x00-\x1f\x7f]+$/,
|
|
207
|
+
"a relative path inside the checkout: no leading / or -, no .. segment, no quote or control character"
|
|
208
|
+
);
|
|
209
|
+
var warnBelowAlert = ({ warnAt, alertAt }) => warnAt < alertAt;
|
|
210
|
+
var WARN_BELOW_ALERT = { message: "warnAt must be below alertAt", path: ["warnAt"] };
|
|
211
|
+
var lockFilePath = z2.string().regex(/^(?![/-])(?!(?:.*\/)?\.\.(?:\/|$))[A-Za-z0-9._/-]+$/, "a plain relative file name such as yarn.lock");
|
|
212
|
+
var branchName = z2.string().regex(
|
|
213
|
+
/^(?![-/.])(?!.*(?:\.\.|\/\/|@\{|\.lock(?:\/|$)))[A-Za-z0-9._/-]+(?<![./])$/,
|
|
214
|
+
"a branch name such as main: no leading - / or ., no .. and no spaces"
|
|
215
|
+
);
|
|
216
|
+
var workflowFile = z2.string().regex(/^(?![-.])[A-Za-z0-9._-]+\.ya?ml$/, "a workflow file name such as deploy.yml");
|
|
217
|
+
var boardPattern = z2.string().regex(/^(?![-.])[A-Za-z0-9._*?-]+$/, "one directory name such as board-*: no / and no leading - or .");
|
|
218
|
+
var boardFile = z2.string().regex(/^(?![-.])[A-Za-z0-9._-]+\.md$/, "one markdown file name such as board.md: no / and no leading - or .");
|
|
219
|
+
var boardSchema = z2.strictObject({
|
|
220
|
+
/** The directories under `planDirectory` that hold a board; the newest board is the default of `plans` and `watch`. */
|
|
221
|
+
pattern: boardPattern.default("board-*"),
|
|
222
|
+
/** The board document inside each of those directories. */
|
|
223
|
+
file: boardFile.default("board.md"),
|
|
224
|
+
/** What the project calls a board: the plans view, its page and the watcher print it as written. */
|
|
225
|
+
term: z2.string().min(1).default("board")
|
|
226
|
+
});
|
|
227
|
+
var deploySchema = z2.strictObject({
|
|
228
|
+
/** The workflow whose runs on the base branch the watcher reports as `deploy`. */
|
|
229
|
+
workflow: workflowFile,
|
|
230
|
+
/** The deployment environments the watcher names as a run's target; any other reads `unknown`. */
|
|
231
|
+
environments: z2.array(z2.string().min(1)).min(1)
|
|
232
|
+
});
|
|
233
|
+
var feedbackSchema = z2.strictObject({
|
|
234
|
+
/** GitHub logins whose feedback does not wake the coordinator, such as a status bot; case is ignored. */
|
|
235
|
+
ignore: z2.array(z2.string().min(1)).default([])
|
|
236
|
+
});
|
|
237
|
+
var previewsSchema = z2.strictObject({
|
|
238
|
+
/** Reads the GitHub deployments of each head commit; a successful one outside production and `deploy.environments` names its `environment_url`. */
|
|
239
|
+
deployments: z2.boolean().default(false),
|
|
240
|
+
/**
|
|
241
|
+
* GitHub logins whose pull request comments link a preview; nothing they write counts as feedback, so name a bot that
|
|
242
|
+
* only posts previews, not one that also reviews. Case is ignored.
|
|
243
|
+
*/
|
|
244
|
+
authors: z2.array(z2.string().min(1)).default([]),
|
|
245
|
+
/** Finds the URL in such a comment: its first group, else its match; without it the first https link. */
|
|
246
|
+
urlPattern: z2.string().min(1).refine(isRegularExpression, "not a valid regular expression").optional()
|
|
247
|
+
});
|
|
248
|
+
var sourcePath = z2.string().refine(isSourcePath, "not a source path: `.`, or `.key`, `[n]` and `[-n]` in a chain");
|
|
249
|
+
var SOURCE_FIELD_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
250
|
+
var sourceMapSchema = z2.object({
|
|
251
|
+
[SOURCE_FIELD.id]: sourcePath,
|
|
252
|
+
/** Changes whenever the entry changes; compared as text, so any stable form of a time or version works. */
|
|
253
|
+
[SOURCE_FIELD.updatedAt]: sourcePath,
|
|
254
|
+
[SOURCE_FIELD.title]: sourcePath.optional(),
|
|
255
|
+
/** Shown only as an `https:` URL without user name or password. */
|
|
256
|
+
[SOURCE_FIELD.url]: sourcePath.optional(),
|
|
257
|
+
/** The first line with text is shown. */
|
|
258
|
+
[SOURCE_FIELD.body]: sourcePath.optional(),
|
|
259
|
+
[SOURCE_FIELD.author]: sourcePath.optional()
|
|
260
|
+
}).catchall(sourcePath).refine((map) => Object.keys(map).every((field) => SOURCE_FIELD_NAME.test(field)), {
|
|
261
|
+
message: "a map field is a letter, then letters, digits and `_`"
|
|
262
|
+
});
|
|
263
|
+
var sourceSchema = z2.strictObject({
|
|
264
|
+
/** Printed in every report of the source and the key of its saved state. */
|
|
265
|
+
name: z2.string().regex(/^[A-Za-z0-9][\w.-]*$/, "letters, digits, `_`, `.` and `-`"),
|
|
266
|
+
/** Program and arguments, run without a shell in the main checkout; it prints JSON on stdout and only reads. */
|
|
267
|
+
command: z2.array(z2.string().min(1)).min(1),
|
|
268
|
+
/** Minutes between two runs, at least 1. */
|
|
269
|
+
every: z2.number().int().min(1).default(5),
|
|
270
|
+
/** The path of the list in the output; without it the output is the list. */
|
|
271
|
+
items: sourcePath.optional(),
|
|
272
|
+
map: sourceMapSchema,
|
|
273
|
+
/** Values of `map.author` whose changes wake nobody, such as the account the command runs as; case is ignored. */
|
|
274
|
+
ignoreAuthors: z2.array(z2.string().min(1)).default([]),
|
|
275
|
+
/** The most new or changed entries one report shows of this source; the rest is one line `+<n> more`. */
|
|
276
|
+
reportLimit: z2.number().int().min(1).default(5),
|
|
277
|
+
/** The lane the source's reports name. */
|
|
278
|
+
lane: z2.string().min(1).optional(),
|
|
279
|
+
/**
|
|
280
|
+
* The mapped fields whose change reports, with the old and the new value, in place of the content of `title`,
|
|
281
|
+
* `author`, `body` and `url`; without it a change of that content reports.
|
|
282
|
+
*/
|
|
283
|
+
reportOn: z2.array(z2.string().min(1)).min(1).max(10).optional()
|
|
284
|
+
}).refine((source) => source.ignoreAuthors.length === 0 || source.map.author !== void 0, {
|
|
285
|
+
message: "ignoreAuthors needs map.author",
|
|
286
|
+
path: ["ignoreAuthors"]
|
|
287
|
+
}).refine((source) => !source.reportOn?.includes(SOURCE_FIELD.id), {
|
|
288
|
+
message: "reportOn cannot name id",
|
|
289
|
+
path: ["reportOn"]
|
|
290
|
+
}).refine((source) => (source.reportOn ?? []).every((field) => Object.hasOwn(source.map, field)), {
|
|
291
|
+
message: "reportOn names a field map does not have",
|
|
292
|
+
path: ["reportOn"]
|
|
293
|
+
});
|
|
294
|
+
var hasUniqueNames = (sources) => new Set(sources.map(({ name }) => name)).size === sources.length;
|
|
295
|
+
var coordinatorSchema = z2.strictObject({
|
|
296
|
+
/** Share of the coordinator's context window from which the watcher reports `coordinator warn`. */
|
|
297
|
+
warnAt: share.default(0.5),
|
|
298
|
+
/** Share of the coordinator's context window from which the watcher reports `coordinator alert`. */
|
|
299
|
+
alertAt: share.default(0.7)
|
|
300
|
+
}).refine(warnBelowAlert, WARN_BELOW_ALERT);
|
|
301
|
+
var contextSchema = z2.strictObject({
|
|
302
|
+
/** Share of the context window from which a lane's fill shows yellow and `/implement` offers a new chat. */
|
|
303
|
+
warnAt: share.default(0.6),
|
|
304
|
+
/** Share of the context window from which a lane's fill shows red. */
|
|
305
|
+
alertAt: share.default(0.8),
|
|
306
|
+
/** Context window in tokens by full model ID; the log does not say which window a session ran with. */
|
|
307
|
+
windows: z2.record(modelId, z2.number().int().positive()).default({}),
|
|
308
|
+
/** The window assumed for a model not listed in `windows`. */
|
|
309
|
+
defaultWindow: z2.number().int().positive().default(2e5),
|
|
310
|
+
/** The coordinator's own thresholds, used by `jh context --coordinator`; the lanes keep `warnAt` and `alertAt`. */
|
|
311
|
+
coordinator: coordinatorSchema.prefault({})
|
|
312
|
+
}).refine(warnBelowAlert, WARN_BELOW_ALERT);
|
|
313
|
+
var jackherdConfigSchema = z2.strictObject({
|
|
314
|
+
$schema: z2.string().optional(),
|
|
315
|
+
responseLanguage: language.default(PLAN_LANGUAGE.en),
|
|
316
|
+
planLanguage: language.default(PLAN_LANGUAGE.en),
|
|
317
|
+
planDirectory: z2.string().min(1).default("docs/plans"),
|
|
318
|
+
/** Where the boards live and what the project calls them. */
|
|
319
|
+
board: boardSchema.prefault({}),
|
|
320
|
+
/** Replaced by `board.pattern` in 0.13.0; named here only so an old config is refused with that hint. */
|
|
321
|
+
sprintPattern: z2.never({ error: "sprintPattern was replaced by board.pattern (with board.file and board.term)" }).optional(),
|
|
322
|
+
worktreeDirectory: z2.string().min(1).default(claudePath(WORKTREES_DIRECTORY)),
|
|
323
|
+
baseBranch: branchName.default(DEFAULT_BASE_BRANCH),
|
|
324
|
+
/**
|
|
325
|
+
* Put before every skill and agent name. `jh sync --global` refuses to run without one: a personal skill
|
|
326
|
+
* shadows a project skill of the same name. In a project it is optional and keeps the project's own skills of a
|
|
327
|
+
* kit name (`implement`, `plan`, …) apart from the kit's.
|
|
328
|
+
*/
|
|
329
|
+
skillPrefix: z2.union([z2.literal(""), z2.string().regex(SKILL_PREFIX, "lower-case letters and digits ending in a dash, e.g. kit-")]).default(""),
|
|
330
|
+
commands: z2.strictObject({
|
|
331
|
+
test: command2.default(BUN_COMMANDS.test),
|
|
332
|
+
typecheck: command2.default(BUN_COMMANDS.typecheck),
|
|
333
|
+
lint: command2.default(BUN_COMMANDS.lint),
|
|
334
|
+
format: command2.default(BUN_COMMANDS.format),
|
|
335
|
+
/** Installs a new lane's dependencies. */
|
|
336
|
+
install: command2.default(BUN_COMMANDS.install),
|
|
337
|
+
/** Starts a lane's dev server, run as `PORT=<port> <dev>`; a project supplement may name another. */
|
|
338
|
+
dev: command2.default(BUN_COMMANDS.dev)
|
|
339
|
+
}).prefault({}),
|
|
340
|
+
/** How `/orchestrate` sets up a lane's worktree. */
|
|
341
|
+
lanes: z2.strictObject({
|
|
342
|
+
/** Untracked files copied into every new worktree; empty means the files `.worktreeinclude` lists. */
|
|
343
|
+
copy: z2.array(laneCopyPath).default([]),
|
|
344
|
+
/** The dependency lock file a rebase takes from the base branch and regenerates, never merges by hand. */
|
|
345
|
+
lockFile: lockFilePath.default("bun.lock")
|
|
346
|
+
}).prefault({}),
|
|
347
|
+
models: z2.record(z2.enum(Object.values(MODEL_ROLE)), modelId),
|
|
348
|
+
terminal: z2.strictObject({ adapter: z2.enum(Object.values(TERMINAL_ADAPTER)).default(TERMINAL_ADAPTER.none) }).prefault({}),
|
|
349
|
+
plans: z2.strictObject({
|
|
350
|
+
/** Minutes between background fetches of the base branch while `jh plans` runs; 0 turns them off. */
|
|
351
|
+
fetchIntervalMinutes: z2.number().min(0).default(5),
|
|
352
|
+
/** Links in a plan that the sprint page shows as chips; the list replaces the built-in kinds. */
|
|
353
|
+
linkKinds: z2.array(
|
|
354
|
+
z2.strictObject({
|
|
355
|
+
pattern: z2.string().min(1).refine(isRegularExpression, "not a valid regular expression"),
|
|
356
|
+
label: z2.string().min(1),
|
|
357
|
+
icon: z2.string().min(1)
|
|
358
|
+
})
|
|
359
|
+
).default(DEFAULT_LINK_KINDS.map((kind) => ({ ...kind }))),
|
|
360
|
+
context: contextSchema.prefault({})
|
|
361
|
+
}).prefault({}),
|
|
362
|
+
/**
|
|
363
|
+
* Read by `jh watch`; without `deploy` it reports no deploy runs. `feedback` is on unless set to `false`:
|
|
364
|
+
* it reports new feedback on the lanes' pull requests except from the account the watcher runs as and `ignore`.
|
|
365
|
+
* Without `previews` it reads no deploy preview; with it, one `preview` per new head commit. Each of `sources` is a
|
|
366
|
+
* command whose JSON output reports `source` for a new or changed entry.
|
|
367
|
+
*/
|
|
368
|
+
watch: z2.strictObject({
|
|
369
|
+
deploy: deploySchema.optional(),
|
|
370
|
+
feedback: z2.union([z2.literal(false), feedbackSchema]).default({ ignore: [] }),
|
|
371
|
+
previews: previewsSchema.optional(),
|
|
372
|
+
sources: z2.array(sourceSchema).refine(hasUniqueNames, "source names must be unique").default([])
|
|
373
|
+
}).prefault({}),
|
|
374
|
+
/** Read by `jh check`; validated here too, so a typo fails every command alike. */
|
|
375
|
+
check: checkConfigSchema.optional()
|
|
376
|
+
});
|
|
377
|
+
var parseJackherdConfig = (raw) => jackherdConfigSchema.parse(raw);
|
|
378
|
+
var parseLabelled = (schema, raw, label) => {
|
|
379
|
+
const parsed = schema.safeParse(raw);
|
|
380
|
+
if (!parsed.success) throw new Error(`${label} is invalid:
|
|
381
|
+
${z2.prettifyError(parsed.error)}`);
|
|
382
|
+
return parsed.data;
|
|
383
|
+
};
|
|
384
|
+
var parseConfigFile = (raw, label) => parseLabelled(jackherdConfigSchema, raw, label);
|
|
385
|
+
var parseSourceDraft = (raw, label) => parseLabelled(sourceSchema, raw, label);
|
|
386
|
+
|
|
387
|
+
// src/config/json-schema.ts
|
|
388
|
+
var renderConfigJsonSchema = () => `${JSON.stringify(z3.toJSONSchema(jackherdConfigSchema, { io: "input" }), null, 2)}
|
|
389
|
+
`;
|
|
390
|
+
export {
|
|
391
|
+
MODEL_ROLE,
|
|
392
|
+
SKILL_PREFIX,
|
|
393
|
+
TERMINAL_ADAPTER,
|
|
394
|
+
isModelRole,
|
|
395
|
+
isTerminalAdapter,
|
|
396
|
+
jackherdConfigSchema,
|
|
397
|
+
parseConfigFile,
|
|
398
|
+
parseJackherdConfig,
|
|
399
|
+
parseSourceDraft,
|
|
400
|
+
renderConfigJsonSchema
|
|
401
|
+
};
|