@erclx/canon 5.8.0 → 5.9.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.
Files changed (70) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/git-followup/SKILL.md +1 -1
  3. package/claude/skills/git-pr/references/evidence.md +1 -1
  4. package/claude/skills/review-craft/REQUIREMENT.md +8 -2
  5. package/claude/skills/review-craft/SKILL.md +63 -7
  6. package/claude/skills/review-craft/references/adopted.md +49 -0
  7. package/docs/agents/commands.md +2 -0
  8. package/docs/agents/hooks.md +56 -0
  9. package/docs/agents/index.md +1 -0
  10. package/docs/agents/install-and-sync.md +1 -1
  11. package/docs/agents/markdown-audit.md +1 -1
  12. package/docs/agents/pr-evidence.md +33 -17
  13. package/docs/agents/records-push.md +1 -1
  14. package/docs/agents/records-validate.md +1 -1
  15. package/docs/agents/scripting.md +6 -0
  16. package/docs/agents/tasks-archive.md +4 -2
  17. package/docs/agents/tasks.md +1 -1
  18. package/docs/agents/worktrees.md +2 -2
  19. package/docs/target/scenarios.md +2 -2
  20. package/package.json +1 -1
  21. package/src/claude/skills-audit.ts +1 -0
  22. package/src/cli.ts +2 -0
  23. package/src/commands/claude.ts +1 -1
  24. package/src/commands/docs.ts +51 -11
  25. package/src/commands/hooks.ts +67 -0
  26. package/src/commands/pr.ts +146 -76
  27. package/src/commands/standards.ts +33 -2
  28. package/src/commands/tasks.ts +45 -0
  29. package/src/commands/tooling.ts +3 -3
  30. package/src/commands/upgrade.ts +3 -2
  31. package/src/commands/worktrees.ts +4 -3
  32. package/src/docs/list.ts +103 -0
  33. package/src/docs/read.ts +63 -19
  34. package/src/gov/stacks.ts +1 -1
  35. package/src/help.ts +2 -0
  36. package/src/hooks/post-merge.ts +331 -0
  37. package/src/pr/evidence.ts +21 -0
  38. package/src/records/validate.ts +1 -38
  39. package/src/standards/list.ts +33 -0
  40. package/src/standards/read.ts +13 -0
  41. package/src/standards/scope.ts +56 -0
  42. package/src/sync/check.ts +38 -4
  43. package/src/tasks/archive.ts +168 -3
  44. package/src/tooling/inject.ts +4 -3
  45. package/src/tooling/manifest.ts +62 -8
  46. package/src/tooling/scan.ts +4 -3
  47. package/src/tooling/stamp.ts +11 -2
  48. package/src/tooling/subfolder.ts +7 -3
  49. package/tooling/astro/reference.md +1 -1
  50. package/tooling/base/configs/scripts/verify.json +3 -0
  51. package/tooling/base/configs/scripts/verify.sh +1 -110
  52. package/tooling/base/configs/scripts/verify.ts +378 -0
  53. package/tooling/base/manifest.toml +1 -0
  54. package/tooling/base/reference.md +5 -3
  55. package/tooling/go/configs/scripts/verify.json +10 -0
  56. package/tooling/go/reference.md +5 -4
  57. package/tooling/php/configs/scripts/verify.json +7 -0
  58. package/tooling/php/reference.md +5 -4
  59. package/tooling/python/configs/scripts/verify.json +4 -0
  60. package/tooling/python/reference.md +3 -3
  61. package/tooling/web/configs/scripts/verify.json +3 -0
  62. package/tooling/web/reference.md +3 -3
  63. package/scripts/docs/list.sh +0 -184
  64. package/scripts/lib/frontmatter.sh +0 -30
  65. package/scripts/standards/list.sh +0 -115
  66. package/src/commands/pass-through.ts +0 -39
  67. package/tooling/go/configs/scripts/verify.sh +0 -142
  68. package/tooling/php/configs/scripts/verify.sh +0 -147
  69. package/tooling/python/configs/scripts/verify.sh +0 -141
  70. package/tooling/web/configs/scripts/verify.sh +0 -153
@@ -1,141 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
- set -o pipefail
4
-
5
- GREEN='\033[0;32m'
6
- RED='\033[0;31m'
7
- WHITE='\033[1;37m'
8
- GREY='\033[0;90m'
9
- NC='\033[0m'
10
-
11
- NESTED="${VERIFY_NESTED:-false}"
12
-
13
- log_info() { echo -e "${GREY}│${NC} ${GREEN}✓${NC} $1"; }
14
- log_error() {
15
- echo -e "${GREY}│${NC} ${RED}✗${NC} $1"
16
- exit 1
17
- }
18
- log_step() { echo -e "${GREY}│${NC}\n${GREY}├${NC} ${WHITE}$1${NC}"; }
19
- log_skip() { echo -e "${GREY}│ - $1${NC}"; }
20
-
21
- pipe_output() { while IFS= read -r line; do echo -e "${GREY}│${NC} $line"; done; }
22
-
23
- check_dependencies() {
24
- command -v bun >/dev/null 2>&1 || log_error "bun is not installed"
25
- command -v uv >/dev/null 2>&1 || log_error "uv is not installed"
26
- }
27
-
28
- check_package() {
29
- [ -f package.json ] || log_error "No package.json here. Run 'bun init', then sync the stack again"
30
- }
31
-
32
- has_script() {
33
- bun -e 'process.exit(require(process.cwd() + "/package.json").scripts?.[process.argv[1]] ? 0 : 1)' "$1"
34
- }
35
-
36
- # A subfolder synced with --skip base declares none of base's scripts, since
37
- # the repository root owns them. Each base phase runs only where its script is
38
- # declared, so this script passes on its own in that subfolder.
39
- run_base_phase() {
40
- local title=$1
41
- local script=$2
42
- local err_msg=$3
43
- local pass_msg=$4
44
-
45
- log_step "$title"
46
- if ! has_script "$script"; then
47
- log_skip "Skipped: $script is not declared here, so the repository root runs it"
48
- return
49
- fi
50
- run_check "bun run $script" "$err_msg"
51
- log_info "$pass_msg"
52
- }
53
-
54
- check_markdown_bans() {
55
- if ! command -v canon >/dev/null 2>&1; then
56
- log_info "Skipped: no canon binary on PATH. Install with \`bun install --global @erclx/canon\`."
57
- return 0
58
- fi
59
-
60
- local files=()
61
- while IFS= read -r file; do
62
- files+=("$file")
63
- done < <(git ls-files --cached --others --exclude-standard -- '*.md' ':(exclude)CHANGELOG.md' ':(exclude)**/CHANGELOG.md')
64
-
65
- if [ ${#files[@]} -eq 0 ]; then
66
- log_info "No markdown file to check outside the exclusion set."
67
- return 0
68
- fi
69
-
70
- local output code
71
- if output=$(canon markdown audit "${files[@]}" 2>&1); then
72
- code=0
73
- else
74
- code=$?
75
- fi
76
-
77
- case "$code" in
78
- 0)
79
- log_info "No banned character"
80
- ;;
81
- 1)
82
- log_info "Skipped: canon markdown audit refused and measured nothing."
83
- ;;
84
- 2)
85
- echo "$output" | pipe_output
86
- log_error "Markdown prose carries a banned character, or a relative link resolves to nothing on disk"
87
- ;;
88
- 3)
89
- echo "$output" | pipe_output
90
- log_error "The markdown audit shipped an empty ban set, so the corpus was walked and nothing was looked for"
91
- ;;
92
- *)
93
- log_error "canon markdown audit exited $code, which is neither a pass nor a finding"
94
- ;;
95
- esac
96
- }
97
-
98
- run_check() {
99
- local cmd=$1
100
- local err_msg=$2
101
- local output
102
- if ! output=$(eval "$cmd" 2>&1); then
103
- echo "$output" | pipe_output
104
- log_error "$err_msg"
105
- fi
106
- echo "$output" | pipe_output
107
- }
108
-
109
- main() {
110
- check_dependencies
111
- check_package
112
-
113
- if [ "$NESTED" = false ]; then echo -e "${GREY}┌${NC}"; fi
114
-
115
- echo -e "${GREY}├${NC} ${WHITE}Typecheck${NC}"
116
- run_check "bun run typecheck" "Typecheck failed"
117
- log_info "Typecheck passed"
118
-
119
- log_step "Lint"
120
- run_check "bun run lint" "Lint failed"
121
- log_info "Lint passed"
122
-
123
- run_base_phase "Formatting" "format" "Format failed" "Format applied"
124
- run_base_phase "Format check" "check:format" "Format check failed" "Format check passed"
125
- run_base_phase "Spelling" "check:spell" "Spell check failed" "Spell check passed"
126
- run_base_phase "Shell" "check:shell" "Shell check failed" "Shell check passed"
127
-
128
- log_step "Unit tests"
129
- run_check "bun run test:run" "Unit tests failed"
130
- log_info "Unit tests passed"
131
-
132
- log_step "Markdown bans"
133
- check_markdown_bans
134
-
135
- if [ "$NESTED" = false ]; then
136
- echo -e "${GREY}└${NC}\n"
137
- echo -e "${GREEN}✓ Verification passed${NC}"
138
- fi
139
- }
140
-
141
- main "$@"
@@ -1,153 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
- set -o pipefail
4
-
5
- GREEN='\033[0;32m'
6
- RED='\033[0;31m'
7
- WHITE='\033[1;37m'
8
- GREY='\033[0;90m'
9
- NC='\033[0m'
10
-
11
- NESTED="${VERIFY_NESTED:-false}"
12
-
13
- log_info() { echo -e "${GREY}│${NC} ${GREEN}✓${NC} $1"; }
14
- log_error() {
15
- echo -e "${GREY}│${NC} ${RED}✗${NC} $1"
16
- exit 1
17
- }
18
- log_step() { echo -e "${GREY}│${NC}\n${GREY}├${NC} ${WHITE}$1${NC}"; }
19
- log_skip() { echo -e "${GREY}│ - $1${NC}"; }
20
-
21
- pipe_output() { while IFS= read -r line; do echo -e "${GREY}│${NC} $line"; done; }
22
-
23
- check_dependencies() {
24
- command -v bun >/dev/null 2>&1 || log_error "bun is not installed"
25
- }
26
-
27
- check_package() {
28
- [ -f package.json ] || log_error "No package.json here. Run 'bun init', then sync the stack again"
29
- }
30
-
31
- has_script() {
32
- bun -e 'process.exit(require(process.cwd() + "/package.json").scripts?.[process.argv[1]] ? 0 : 1)' "$1"
33
- }
34
-
35
- # A subfolder synced with --skip base declares none of base's scripts, since
36
- # the repository root owns them. Each base phase runs only where its script is
37
- # declared, so this script passes on its own in that subfolder.
38
- run_base_phase() {
39
- local title=$1
40
- local script=$2
41
- local err_msg=$3
42
- local pass_msg=$4
43
-
44
- log_step "$title"
45
- if ! has_script "$script"; then
46
- log_skip "Skipped: $script is not declared here, so the repository root runs it"
47
- return
48
- fi
49
- run_check "bun run $script" "$err_msg"
50
- log_info "$pass_msg"
51
- }
52
-
53
- check_markdown_bans() {
54
- if ! command -v canon >/dev/null 2>&1; then
55
- log_info "Skipped: no canon binary on PATH. Install with \`bun install --global @erclx/canon\`."
56
- return 0
57
- fi
58
-
59
- local files=()
60
- while IFS= read -r file; do
61
- files+=("$file")
62
- done < <(git ls-files --cached --others --exclude-standard -- '*.md' ':(exclude)CHANGELOG.md' ':(exclude)**/CHANGELOG.md')
63
-
64
- if [ ${#files[@]} -eq 0 ]; then
65
- log_info "No markdown file to check outside the exclusion set."
66
- return 0
67
- fi
68
-
69
- local output code
70
- if output=$(canon markdown audit "${files[@]}" 2>&1); then
71
- code=0
72
- else
73
- code=$?
74
- fi
75
-
76
- case "$code" in
77
- 0)
78
- log_info "No banned character"
79
- ;;
80
- 1)
81
- log_info "Skipped: canon markdown audit refused and measured nothing."
82
- ;;
83
- 2)
84
- echo "$output" | pipe_output
85
- log_error "Markdown prose carries a banned character, or a relative link resolves to nothing on disk"
86
- ;;
87
- 3)
88
- echo "$output" | pipe_output
89
- log_error "The markdown audit shipped an empty ban set, so the corpus was walked and nothing was looked for"
90
- ;;
91
- *)
92
- log_error "canon markdown audit exited $code, which is neither a pass nor a finding"
93
- ;;
94
- esac
95
- }
96
-
97
- run_check() {
98
- local cmd=$1
99
- local err_msg=$2
100
- local output
101
- if ! output=$(eval "$cmd" 2>&1); then
102
- echo "$output" | pipe_output
103
- log_error "$err_msg"
104
- fi
105
- echo "$output" | pipe_output
106
- }
107
-
108
- main() {
109
- check_dependencies
110
- check_package
111
-
112
- if [ "$NESTED" = false ]; then echo -e "${GREY}┌${NC}"; fi
113
-
114
- echo -e "${GREY}├${NC} ${WHITE}Typecheck${NC}"
115
- run_check "bun run typecheck" "Typecheck failed"
116
- log_info "Typecheck passed"
117
-
118
- log_step "Lint"
119
- run_check "bun run lint" "Lint failed"
120
- log_info "Lint passed"
121
-
122
- run_base_phase "Formatting" "format" "Format failed" "Format applied"
123
- run_base_phase "Format check" "check:format" "Format check failed" "Format check passed"
124
- run_base_phase "Spelling" "check:spell" "Spell check failed" "Spell check passed"
125
- run_base_phase "Shell" "check:shell" "Shell check failed" "Shell check passed"
126
-
127
- log_step "Unit tests"
128
- run_check "bun run test:run" "Unit tests failed"
129
- log_info "Unit tests passed"
130
-
131
- log_step "Build"
132
- run_check "bun run build" "Build failed"
133
- log_info "Build passed"
134
-
135
- log_step "Markdown bans"
136
- check_markdown_bans
137
-
138
- # Runs whenever the stack shipped a card exclusion check, which keeps the
139
- # stage stack-agnostic here and the check itself in the stack that owns the
140
- # card route's shape. It reads the build above, so it sits after it.
141
- if [ -f scripts/check-card-exclusion.sh ]; then
142
- log_step "Card exclusion"
143
- run_check "bash scripts/check-card-exclusion.sh" "Card exclusion check failed"
144
- log_info "Card exclusion passed"
145
- fi
146
-
147
- if [ "$NESTED" = false ]; then
148
- echo -e "${GREY}└${NC}\n"
149
- echo -e "${GREEN}✓ Verification passed${NC}"
150
- fi
151
- }
152
-
153
- main "$@"