@delorenj/pjangler 1.1.4 → 1.2.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 (140) hide show
  1. package/.mise/scripts/link-agentfiles.sh +9 -0
  2. package/.mise/scripts/versioning.sh +236 -0
  3. package/dist/index.js +498 -277
  4. package/dist/mcp-server.js +1706 -163
  5. package/package.json +4 -2
  6. package/templates/commonproject/.mise/scripts/create-plane-project.sh +26 -0
  7. package/templates/commonproject/copier.yml +2 -0
  8. package/templates/commonproject/template/.agents/hooks/README.md +151 -0
  9. package/templates/commonproject/template/.agents/hooks/hermes/hindsight-hook.sh +63 -0
  10. package/templates/commonproject/template/.agents/hooks/hindsight/hindsight-journal-write.sh +327 -0
  11. package/templates/commonproject/template/.agents/hooks/hindsight/hindsight-recall.sh +180 -0
  12. package/templates/commonproject/template/.agents/hooks/hindsight/hindsight-retain.sh +74 -0
  13. package/templates/commonproject/template/.agents/hooks/hindsight/hindsight-session-end.sh +57 -0
  14. package/templates/commonproject/template/.agents/hooks/hindsight/lib/hindsight-bank.sh +57 -0
  15. package/templates/commonproject/template/.agents/hooks/hindsight/lib/hindsight-journal.sh +48 -0
  16. package/templates/commonproject/template/.agents/hooks/hooks.master.json +97 -0
  17. package/templates/commonproject/template/.agents/hooks/lib/hook-guard.sh +30 -0
  18. package/templates/commonproject/template/.agents/hooks/lib/local-config.sh +51 -0
  19. package/templates/commonproject/template/.agents/hooks/reminder-for-skill-check.sh +20 -0
  20. package/templates/commonproject/template/.agents/hooks/sync.py +618 -0
  21. package/templates/commonproject/template/.agents/local.example.json +15 -0
  22. package/templates/commonproject/template/.mise/scripts/hindsight-setup.sh +62 -0
  23. package/templates/commonproject/template/.mise/scripts/link-project-skills-to-clis.sh +110 -0
  24. package/templates/commonproject/template/.mise/scripts/unlink-project-skills-from-clis.sh +45 -0
  25. package/templates/commonproject/template/mise.toml.jinja +42 -0
  26. package/templates/hermes-agent/.codegraph/daemon.pid +6 -0
  27. package/templates/hermes-agent/.omo/run-continuation/ses_0e5b28303ffeXxL53hZjKggXDW.json +10 -0
  28. package/templates/hermes-agent/README.md +16 -14
  29. package/templates/hermes-agent/copier.yml +7 -25
  30. package/templates/hermes-agent/docs/architecture.md +16 -18
  31. package/templates/hermes-agent/docs/fleet-control-plane/README.md +35 -0
  32. package/templates/hermes-agent/docs/fleet-control-plane/architecture.md +253 -0
  33. package/templates/hermes-agent/docs/fleet-control-plane/epics-and-stories.md +280 -0
  34. package/templates/hermes-agent/docs/fleet-control-plane/implementation-readiness-report-2026-06-27.md +118 -0
  35. package/templates/hermes-agent/docs/fleet-control-plane/prd.md +141 -0
  36. package/templates/hermes-agent/docs/operations.md +17 -19
  37. package/templates/hermes-agent/docs/runbooks/runtime-checkpoint-repair.md +17 -13
  38. package/templates/hermes-agent/docs/{scrum-master → sentinel}/README.md +47 -46
  39. package/templates/hermes-agent/docs/{scrum-master → sentinel}/architecture.md +39 -38
  40. package/templates/hermes-agent/docs/{scrum-master → sentinel}/development.md +63 -99
  41. package/templates/hermes-agent/docs/{scrum-master → sentinel}/providers.md +2 -2
  42. package/templates/hermes-agent/docs/sentinel.md +18 -0
  43. package/templates/hermes-agent/install-local.sh +22 -20
  44. package/templates/hermes-agent/runtime-scaffold/README.md +10 -9
  45. package/templates/hermes-agent/scripts/backfill-fleet-sot.sh +12 -21
  46. package/templates/hermes-agent/scripts/fleet-sync.sh +369 -0
  47. package/templates/hermes-agent/scripts/migrate-unify.sh +252 -0
  48. package/templates/hermes-agent/scripts/unify-pm.sh +148 -0
  49. package/templates/hermes-agent/template/.runtime-scaffold/README.md +10 -9
  50. package/templates/hermes-agent/template/.scripts/01-config.sh +2 -3
  51. package/templates/hermes-agent/template/.scripts/05-fleet-env.sh +0 -2
  52. package/templates/hermes-agent/template/.scripts/10-hermes-profile.sh +47 -19
  53. package/templates/hermes-agent/template/.scripts/20-runtime-repo.sh +71 -27
  54. package/templates/hermes-agent/template/.scripts/30-telegram.sh +3 -3
  55. package/templates/hermes-agent/template/.scripts/42-ticket-provider.sh +3 -3
  56. package/templates/hermes-agent/template/.scripts/70-systemd.sh +48 -43
  57. package/templates/hermes-agent/template/.scripts/80-registry.sh +2 -2
  58. package/templates/hermes-agent/template/.scripts/99-summary.sh +3 -4
  59. package/templates/hermes-agent/template/.scripts/_lib.sh +4 -19
  60. package/templates/hermes-agent/template/.scripts/checkpoint.sh +36 -0
  61. package/templates/hermes-agent/template/.scripts/config.example.toml +11 -5
  62. package/templates/hermes-agent/template/.scripts/{scrum-master/continuous-ticket-sentinel.sh → heartbeat.sh} +84 -31
  63. package/templates/hermes-agent/template/.scripts/lib/ticket-provider.sh +1 -1
  64. package/templates/hermes-agent/template/.scripts/providers/plane.sh +9 -3
  65. package/templates/hermes-agent/template/.scripts/{scrum-master → sentinel}/bin/emit-event.py +5 -5
  66. package/templates/hermes-agent/template/.scripts/{scrum-master → sentinel}/bin/issue-autonomous-review.sh +6 -6
  67. package/templates/hermes-agent/template/.scripts/{scrum-master → sentinel}/bin/issue-close-gate.sh +2 -2
  68. package/templates/hermes-agent/template/.scripts/{scrum-master → sentinel}/docs/autonomous-delegated-review.md +7 -7
  69. package/templates/hermes-agent/template/.scripts/{scrum-master → sentinel}/docs/bloodbank-events.md +3 -3
  70. package/templates/hermes-agent/template/.scripts/{scrum-master → sentinel}/docs/continuous-ticket-orchestration.md +6 -6
  71. package/templates/hermes-agent/template/.scripts/{scrum-master/continuous-ticket-sentinel.prompt.md.jinja → sentinel.prompt.md.jinja} +5 -4
  72. package/templates/hermes-agent/template/SOUL.md.jinja +3 -6
  73. package/templates/hermes-agent/template/hermes.jinja +6 -15
  74. package/templates/hermes-agent/template/role.yaml.jinja +9 -8
  75. package/templates/commonproject/.claude/commands/bmad/bmb/agents/agent-builder.md +0 -14
  76. package/templates/commonproject/.claude/commands/bmad/bmb/agents/module-builder.md +0 -14
  77. package/templates/commonproject/.claude/commands/bmad/bmb/agents/workflow-builder.md +0 -14
  78. package/templates/commonproject/.claude/commands/bmad/bmb/workflows/agent.md +0 -5
  79. package/templates/commonproject/.claude/commands/bmad/bmb/workflows/module.md +0 -5
  80. package/templates/commonproject/.claude/commands/bmad/bmb/workflows/workflow.md +0 -5
  81. package/templates/commonproject/.claude/commands/bmad/bmm/agents/analyst.md +0 -14
  82. package/templates/commonproject/.claude/commands/bmad/bmm/agents/architect.md +0 -14
  83. package/templates/commonproject/.claude/commands/bmad/bmm/agents/dev.md +0 -14
  84. package/templates/commonproject/.claude/commands/bmad/bmm/agents/pm.md +0 -14
  85. package/templates/commonproject/.claude/commands/bmad/bmm/agents/quick-flow-solo-dev.md +0 -14
  86. package/templates/commonproject/.claude/commands/bmad/bmm/agents/sm.md +0 -14
  87. package/templates/commonproject/.claude/commands/bmad/bmm/agents/tea.md +0 -14
  88. package/templates/commonproject/.claude/commands/bmad/bmm/agents/tech-writer.md +0 -14
  89. package/templates/commonproject/.claude/commands/bmad/bmm/agents/ux-designer.md +0 -14
  90. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/check-implementation-readiness.md +0 -5
  91. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/code-review.md +0 -13
  92. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/correct-course.md +0 -13
  93. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-architecture.md +0 -5
  94. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +0 -5
  95. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-excalidraw-dataflow.md +0 -13
  96. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-excalidraw-diagram.md +0 -13
  97. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-excalidraw-flowchart.md +0 -13
  98. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-excalidraw-wireframe.md +0 -13
  99. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-product-brief.md +0 -5
  100. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-story.md +0 -13
  101. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/create-ux-design.md +0 -5
  102. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/dev-story.md +0 -13
  103. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/document-project.md +0 -13
  104. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/generate-project-context.md +0 -5
  105. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/prd.md +0 -5
  106. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/quick-dev.md +0 -5
  107. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/quick-spec.md +0 -5
  108. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/research.md +0 -5
  109. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/retrospective.md +0 -13
  110. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/sprint-planning.md +0 -13
  111. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/sprint-status.md +0 -13
  112. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-atdd.md +0 -13
  113. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-automate.md +0 -13
  114. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-ci.md +0 -13
  115. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-framework.md +0 -13
  116. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-nfr.md +0 -13
  117. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-test-design.md +0 -13
  118. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-test-review.md +0 -13
  119. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/testarch-trace.md +0 -13
  120. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/workflow-init.md +0 -13
  121. package/templates/commonproject/.claude/commands/bmad/bmm/workflows/workflow-status.md +0 -13
  122. package/templates/commonproject/.claude/commands/bmad/cis/agents/brainstorming-coach.md +0 -14
  123. package/templates/commonproject/.claude/commands/bmad/cis/agents/creative-problem-solver.md +0 -14
  124. package/templates/commonproject/.claude/commands/bmad/cis/agents/design-thinking-coach.md +0 -14
  125. package/templates/commonproject/.claude/commands/bmad/cis/agents/innovation-strategist.md +0 -14
  126. package/templates/commonproject/.claude/commands/bmad/cis/agents/presentation-master.md +0 -14
  127. package/templates/commonproject/.claude/commands/bmad/cis/agents/storyteller.md +0 -14
  128. package/templates/commonproject/.claude/commands/bmad/cis/workflows/design-thinking.md +0 -13
  129. package/templates/commonproject/.claude/commands/bmad/cis/workflows/innovation-strategy.md +0 -13
  130. package/templates/commonproject/.claude/commands/bmad/cis/workflows/problem-solving.md +0 -13
  131. package/templates/commonproject/.claude/commands/bmad/cis/workflows/storytelling.md +0 -13
  132. package/templates/commonproject/.claude/commands/bmad/core/agents/bmad-master.md +0 -14
  133. package/templates/commonproject/.claude/commands/bmad/core/tasks/index-docs.md +0 -9
  134. package/templates/commonproject/.claude/commands/bmad/core/tasks/shard-doc.md +0 -9
  135. package/templates/commonproject/.claude/commands/bmad/core/workflows/brainstorming.md +0 -5
  136. package/templates/commonproject/.claude/commands/bmad/core/workflows/party-mode.md +0 -5
  137. package/templates/commonproject/.claude/commands/bmad/custom/workflows/ticket-lifecycle.md +0 -5
  138. package/templates/hermes-agent/docs/scrum-master-sentinel.md +0 -17
  139. package/templates/hermes-agent/template/.scripts/75-scrum-master.sh +0 -117
  140. package/templates/hermes-agent/template/.scripts/90-chain-scrum-master.sh +0 -45
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ if [ -f AGENTS.md ]; then
4
+ ln -sf AGENTS.md CLAUDE.md
5
+ ln -sf AGENTS.md GEMINI.md
6
+ echo "✅ AI agent symlinks verified"
7
+ else
8
+ echo "No AGENTS.md file found. Can't symlink."
9
+ fi
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env bash
2
+ # versioning.sh — single source of all repo versioning logic.
3
+ #
4
+ # Installed by the `mise-versioning` skill. All version read/write/bump logic
5
+ # lives here; mise tasks are thin wrappers that call into it.
6
+ #
7
+ # Canonical version = the HIGHEST semver across every file in the manifest.
8
+ # All manifest files are kept in parity on every write (bump / set / sync).
9
+ #
10
+ # Usage:
11
+ # versioning.sh current Print canonical version as vX.Y.Z
12
+ # versioning.sh bump <patch|minor|major>
13
+ # versioning.sh set <X.Y.Z|vX.Y.Z> Force all files to an explicit version
14
+ # versioning.sh check Exit 0 if all files in parity, else list drift
15
+ # versioning.sh sync Force every file up to the canonical (highest) version
16
+ # versioning.sh files List the manifest
17
+ #
18
+ # Manifest: .mise/version-files.conf — lines of "<type> <path>" (see file-types).
19
+ # types: json toml cargo csproj gradle plain gittag
20
+ #
21
+ # Storage format per type:
22
+ # json/toml/cargo/csproj/gradle/plain -> bare "X.Y.Z"
23
+ # gittag -> tag "vX.Y.Z"
24
+ # `current` always prints with the leading "v".
25
+
26
+ set -euo pipefail
27
+
28
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
29
+ MANIFEST="${VERSION_FILES_CONF:-$REPO_ROOT/.mise/version-files.conf}"
30
+
31
+ die() { printf 'versioning: %s\n' "$1" >&2; exit 1; }
32
+
33
+ # Friendly display path for a manifest entry.
34
+ rel() { # $1=type $2=abspath
35
+ [[ "$1" == gittag ]] && { printf '(git tags)'; return; }
36
+ local p="${2#"$REPO_ROOT"/}"; printf '%s' "${p:-$2}"
37
+ }
38
+
39
+ # ---- semver helpers ---------------------------------------------------------
40
+
41
+ # Strip a leading v/V and surrounding whitespace; validate X.Y.Z.
42
+ normalize() {
43
+ local v="${1#[vV]}"
44
+ v="$(printf '%s' "$v" | tr -d '[:space:]')"
45
+ [[ "$v" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 1
46
+ printf '%s' "$v"
47
+ }
48
+
49
+ # Return 0 if $1 > $2 (strict), comparing X.Y.Z numerically.
50
+ semver_gt() {
51
+ local a b
52
+ IFS=. read -r a1 a2 a3 <<<"$1"
53
+ IFS=. read -r b1 b2 b3 <<<"$2"
54
+ ((a1 != b1)) && { ((a1 > b1)); return; }
55
+ ((a2 != b2)) && { ((a2 > b2)); return; }
56
+ ((a3 > b3))
57
+ }
58
+
59
+ bump_semver() {
60
+ local ver="$1" part="$2" x y z
61
+ IFS=. read -r x y z <<<"$ver"
62
+ case "$part" in
63
+ major) x=$((x + 1)); y=0; z=0 ;;
64
+ minor) y=$((y + 1)); z=0 ;;
65
+ patch) z=$((z + 1)) ;;
66
+ *) die "unknown bump part: $part (expected patch|minor|major)" ;;
67
+ esac
68
+ printf '%s.%s.%s' "$x" "$y" "$z"
69
+ }
70
+
71
+ # ---- manifest ---------------------------------------------------------------
72
+
73
+ [[ -f "$MANIFEST" ]] || die "manifest not found: $MANIFEST (run the mise-versioning init)"
74
+
75
+ # Emits "type<TAB>abspath" per manifest line, skipping blanks/comments.
76
+ manifest_entries() {
77
+ while read -r type path _rest; do
78
+ [[ -z "${type:-}" || "$type" == \#* ]] && continue
79
+ case "$path" in
80
+ /*) : ;;
81
+ .|"") path="$REPO_ROOT" ;;
82
+ *) path="$REPO_ROOT/$path" ;;
83
+ esac
84
+ printf '%s\t%s\n' "$type" "$path"
85
+ done <"$MANIFEST"
86
+ }
87
+
88
+ # ---- per-type read -----------------------------------------------------------
89
+
90
+ read_version() { # $1=type $2=path -> bare X.Y.Z on stdout, or nothing
91
+ local type="$1" path="$2" raw=""
92
+ case "$type" in
93
+ json)
94
+ [[ -f "$path" ]] || return 0
95
+ raw="$(jq -r '.version // empty' "$path" 2>/dev/null || true)" ;;
96
+ toml|cargo)
97
+ [[ -f "$path" ]] || return 0
98
+ raw="$(grep -m1 -E '^version[[:space:]]*=' "$path" 2>/dev/null \
99
+ | sed -E 's/^version[[:space:]]*=[[:space:]]*["'\'']?([^"'\'' ]+).*/\1/' || true)" ;;
100
+ csproj)
101
+ [[ -f "$path" ]] || return 0
102
+ raw="$(grep -m1 -oE '<Version>[^<]+</Version>' "$path" 2>/dev/null \
103
+ | sed -E 's#</?Version>##g' || true)" ;;
104
+ gradle)
105
+ [[ -f "$path" ]] || return 0
106
+ raw="$(grep -m1 -E '^[[:space:]]*version[[:space:]]*[=]?[[:space:]]*["'\'']' "$path" 2>/dev/null \
107
+ | sed -E 's/.*["'\'']([0-9]+\.[0-9]+\.[0-9]+)["'\''].*/\1/' || true)" ;;
108
+ plain)
109
+ [[ -f "$path" ]] || return 0
110
+ raw="$(head -n1 "$path" 2>/dev/null || true)" ;;
111
+ gittag)
112
+ raw="$(git -C "$REPO_ROOT" tag --list 'v[0-9]*' --sort=-v:refname 2>/dev/null | head -n1 || true)" ;;
113
+ *) die "unknown manifest type: $type" ;;
114
+ esac
115
+ [[ -z "$raw" ]] && return 0
116
+ normalize "$raw" 2>/dev/null || return 0
117
+ }
118
+
119
+ # ---- per-type write ----------------------------------------------------------
120
+
121
+ write_version() { # $1=type $2=path $3=bare-new-version
122
+ local type="$1" path="$2" new="$3" tmp
123
+ case "$type" in
124
+ json)
125
+ [[ -f "$path" ]] || return 0
126
+ tmp="$(mktemp)"
127
+ jq --indent 2 --arg v "$new" '.version = $v' "$path" >"$tmp" && mv "$tmp" "$path" ;;
128
+ toml|cargo)
129
+ [[ -f "$path" ]] || return 0
130
+ # Replace only the first top-level `version = "..."` line.
131
+ sed -i -E "0,/^version[[:space:]]*=/{s/^(version[[:space:]]*=[[:space:]]*[\"']?)[^\"' ]+([\"']?)/\1$new\2/}" "$path" ;;
132
+ csproj)
133
+ [[ -f "$path" ]] || return 0
134
+ sed -i -E "0,/<Version>[^<]+<\/Version>/{s#<Version>[^<]+</Version>#<Version>$new</Version>#}" "$path" ;;
135
+ gradle)
136
+ [[ -f "$path" ]] || return 0
137
+ sed -i -E "0,/^[[:space:]]*version[[:space:]]*[=]?[[:space:]]*[\"']/{s/([\"'])[0-9]+\.[0-9]+\.[0-9]+([\"'])/\1$new\2/}" "$path" ;;
138
+ plain)
139
+ printf '%s\n' "$new" >"$path" ;;
140
+ gittag)
141
+ if git -C "$REPO_ROOT" rev-parse "v$new" >/dev/null 2>&1; then
142
+ printf 'versioning: git tag v%s already exists, skipping\n' "$new" >&2
143
+ else
144
+ git -C "$REPO_ROOT" tag -a "v$new" -m "v$new"
145
+ printf 'versioning: created git tag v%s\n' "$new" >&2
146
+ fi ;;
147
+ *) die "unknown manifest type: $type" ;;
148
+ esac
149
+ }
150
+
151
+ # ---- canonical resolution ----------------------------------------------------
152
+
153
+ canonical() { # highest version across the manifest -> bare X.Y.Z (empty if none)
154
+ local best="" v
155
+ while IFS=$'\t' read -r type path; do
156
+ v="$(read_version "$type" "$path")" || true
157
+ [[ -z "$v" ]] && continue
158
+ if [[ -z "$best" ]] || semver_gt "$v" "$best"; then best="$v"; fi
159
+ done < <(manifest_entries)
160
+ printf '%s' "$best"
161
+ }
162
+
163
+ write_all() { # $1=bare-new-version : write to every manifest file
164
+ local new="$1" type path
165
+ while IFS=$'\t' read -r type path; do
166
+ write_version "$type" "$path" "$new"
167
+ printf ' %-7s %s -> %s\n' "$type" "$(rel "$type" "$path")" "$new" >&2
168
+ done < <(manifest_entries)
169
+ }
170
+
171
+ # ---- commands ----------------------------------------------------------------
172
+
173
+ cmd_current() {
174
+ local v; v="$(canonical)"
175
+ printf 'v%s\n' "${v:-0.0.0}"
176
+ }
177
+
178
+ cmd_bump() {
179
+ local part="${1:-patch}" cur new
180
+ cur="$(canonical)"; [[ -z "$cur" ]] && cur="0.0.0"
181
+ new="$(bump_semver "$cur" "$part")"
182
+ printf 'versioning: %s bump v%s -> v%s\n' "$part" "$cur" "$new" >&2
183
+ write_all "$new"
184
+ printf 'v%s\n' "$new"
185
+ }
186
+
187
+ cmd_set() {
188
+ local new; new="$(normalize "${1:?usage: set <X.Y.Z>}")" || die "invalid version: $1"
189
+ printf 'versioning: set -> v%s\n' "$new" >&2
190
+ write_all "$new"
191
+ printf 'v%s\n' "$new"
192
+ }
193
+
194
+ cmd_check() {
195
+ local canon drift=0 v type path; canon="$(canonical)"
196
+ [[ -z "$canon" ]] && { echo "versioning: no version found in any manifest file" >&2; return 0; }
197
+ while IFS=$'\t' read -r type path; do
198
+ v="$(read_version "$type" "$path")" || true
199
+ [[ -z "$v" ]] && continue
200
+ if [[ "$v" != "$canon" ]]; then
201
+ printf 'DRIFT %-7s %s = v%s (canonical v%s)\n' "$type" "$(rel "$type" "$path")" "$v" "$canon" >&2
202
+ drift=1
203
+ fi
204
+ done < <(manifest_entries)
205
+ if ((drift)); then echo "versioning: files out of parity; run 'versioning.sh sync'" >&2; return 1; fi
206
+ printf 'versioning: all files in parity at v%s\n' "$canon"
207
+ }
208
+
209
+ cmd_sync() {
210
+ local canon; canon="$(canonical)"
211
+ [[ -z "$canon" ]] && die "no version found in any manifest file"
212
+ printf 'versioning: syncing all files to v%s\n' "$canon" >&2
213
+ write_all "$canon"
214
+ printf 'v%s\n' "$canon"
215
+ }
216
+
217
+ cmd_files() {
218
+ while IFS=$'\t' read -r type path; do
219
+ printf '%s\t%s\n' "$type" "$(rel "$type" "$path")"
220
+ done < <(manifest_entries)
221
+ }
222
+
223
+ main() {
224
+ local cmd="${1:-current}"; shift || true
225
+ case "$cmd" in
226
+ current|cur) cmd_current ;;
227
+ bump) cmd_bump "$@" ;;
228
+ set) cmd_set "$@" ;;
229
+ check) cmd_check ;;
230
+ sync) cmd_sync ;;
231
+ files) cmd_files ;;
232
+ *) die "unknown command: $cmd (current|bump|set|check|sync|files)" ;;
233
+ esac
234
+ }
235
+
236
+ main "$@"