@erclx/canon 4.114.0 → 4.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/document-health/references/axes.md +1 -1
- package/claude/skills/target-setup/SKILL.md +1 -1
- package/claude/skills/target-setup/references/detect.md +43 -9
- package/claude/skills/teach-workspace/SKILL.md +5 -3
- package/docs/agents/audits.md +4 -2
- package/docs/agents/commands.md +1 -1
- package/docs/agents/context-audit-checks.md +6 -6
- package/docs/agents/context-audit.md +1 -1
- package/docs/agents/context-classify.md +1 -1
- package/docs/agents/teach.md +6 -0
- package/docs/target-projects.md +4 -2
- package/package.json +1 -1
- package/src/audits/catalog.ts +52 -0
- package/src/commands/context.ts +30 -10
- package/src/commands/teach.ts +4 -1
- package/src/context/audit.ts +54 -18
- package/src/teach/nav.ts +203 -9
- package/standards/teach.md +13 -12
- package/tooling/go/configs/.golangci.yml +25 -0
- package/tooling/go/configs/scripts/verify.sh +95 -0
- package/tooling/go/manifest.toml +13 -0
- package/tooling/go/reference.md +60 -0
- package/tooling/go/seeds/.cspell/tech-stack.txt +16 -0
- package/tooling/go/seeds/smoke_test.go +9 -0
- package/tooling/php/configs/.php-cs-fixer.dist.php +18 -0
- package/tooling/php/configs/phpstan.neon +5 -0
- package/tooling/php/configs/phpunit.xml +18 -0
- package/tooling/php/configs/scripts/verify.sh +100 -0
- package/tooling/php/manifest.toml +15 -0
- package/tooling/php/reference.md +74 -0
- package/tooling/php/seeds/.cspell/tech-stack.txt +5 -0
- package/tooling/php/seeds/tests/SmokeTest.php +13 -0
|
@@ -0,0 +1,100 @@
|
|
|
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 php >/dev/null 2>&1 || log_error "php is not installed"
|
|
26
|
+
command -v composer >/dev/null 2>&1 || log_error "composer is not installed"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
check_package() {
|
|
30
|
+
[ -f package.json ] || log_error "No package.json here. Run 'bun init', then sync the stack again"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
check_vendor() {
|
|
34
|
+
[ -x vendor/bin/phpunit ] || log_error "No vendor/bin/phpunit here. Run 'composer install'"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
has_script() {
|
|
38
|
+
bun -e 'process.exit(require(process.cwd() + "/package.json").scripts?.[process.argv[1]] ? 0 : 1)' "$1"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# A subfolder synced with --skip base declares none of base's scripts, since
|
|
42
|
+
# the repository root owns them. Each base phase runs only where its script is
|
|
43
|
+
# declared, so this script passes on its own in that subfolder.
|
|
44
|
+
run_base_phase() {
|
|
45
|
+
local title=$1
|
|
46
|
+
local script=$2
|
|
47
|
+
local err_msg=$3
|
|
48
|
+
local pass_msg=$4
|
|
49
|
+
|
|
50
|
+
log_step "$title"
|
|
51
|
+
if ! has_script "$script"; then
|
|
52
|
+
log_skip "Skipped: $script is not declared here, so the repository root runs it"
|
|
53
|
+
return
|
|
54
|
+
fi
|
|
55
|
+
run_check "bun run $script" "$err_msg"
|
|
56
|
+
log_info "$pass_msg"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
run_check() {
|
|
60
|
+
local cmd=$1
|
|
61
|
+
local err_msg=$2
|
|
62
|
+
local output
|
|
63
|
+
if ! output=$(eval "$cmd" 2>&1); then
|
|
64
|
+
echo "$output" | pipe_output
|
|
65
|
+
log_error "$err_msg"
|
|
66
|
+
fi
|
|
67
|
+
echo "$output" | pipe_output
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
main() {
|
|
71
|
+
check_dependencies
|
|
72
|
+
check_package
|
|
73
|
+
check_vendor
|
|
74
|
+
|
|
75
|
+
if [ "$NESTED" = false ]; then echo -e "${GREY}┌${NC}"; fi
|
|
76
|
+
|
|
77
|
+
echo -e "${GREY}├${NC} ${WHITE}Typecheck${NC}"
|
|
78
|
+
run_check "bun run typecheck" "Typecheck failed"
|
|
79
|
+
log_info "Typecheck passed"
|
|
80
|
+
|
|
81
|
+
log_step "Lint"
|
|
82
|
+
run_check "bun run lint" "Lint failed"
|
|
83
|
+
log_info "Lint passed"
|
|
84
|
+
|
|
85
|
+
run_base_phase "Formatting" "format" "Format failed" "Format applied"
|
|
86
|
+
run_base_phase "Format check" "check:format" "Format check failed" "Format check passed"
|
|
87
|
+
run_base_phase "Spelling" "check:spell" "Spell check failed" "Spell check passed"
|
|
88
|
+
run_base_phase "Shell" "check:shell" "Shell check failed" "Shell check passed"
|
|
89
|
+
|
|
90
|
+
log_step "Unit tests"
|
|
91
|
+
run_check "bun run test:run" "Unit tests failed"
|
|
92
|
+
log_info "Unit tests passed"
|
|
93
|
+
|
|
94
|
+
if [ "$NESTED" = false ]; then
|
|
95
|
+
echo -e "${GREY}└${NC}\n"
|
|
96
|
+
echo -e "${GREEN}✓ Verification passed${NC}"
|
|
97
|
+
fi
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
main "$@"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[stack]
|
|
2
|
+
name = "php"
|
|
3
|
+
extends = "base"
|
|
4
|
+
runtime = "composer"
|
|
5
|
+
scaffold = "mkdir {{name}} && cd {{name}} && composer init -n --name example/{{name}} --autoload src/"
|
|
6
|
+
|
|
7
|
+
[scripts]
|
|
8
|
+
"lint" = "vendor/bin/php-cs-fixer check --diff"
|
|
9
|
+
"lint:fix" = "vendor/bin/php-cs-fixer fix"
|
|
10
|
+
"typecheck" = "vendor/bin/phpstan analyse --no-progress"
|
|
11
|
+
"test" = "vendor/bin/phpunit"
|
|
12
|
+
"test:run" = "vendor/bin/phpunit --testdox"
|
|
13
|
+
|
|
14
|
+
[gitignore]
|
|
15
|
+
"# PHP" = ["vendor/", ".php-cs-fixer.cache", ".phpunit.cache/", ".phpunit.result.cache"]
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Tooling PHP reference
|
|
2
|
+
|
|
3
|
+
> Extends: `base`. Apply base stack first.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The php stack covers Composer projects on PHP 8.3 or later, formatted by PHP CS Fixer, analysed by PHPStan, and tested by PHPUnit. It ships the three tools' configs, a PHP-aware `verify.sh`, and a copy-once smoke test.
|
|
8
|
+
|
|
9
|
+
## Scaffold checklist
|
|
10
|
+
|
|
11
|
+
1. Scaffold with `composer init -n --name <vendor>/<name> --autoload src/`. The package name and namespace are the project's own identity, so this stack never ships a `composer.json`.
|
|
12
|
+
2. Seed `package.json` so the base layer's bun-side tools (husky, prettier, cspell, commitlint) have a target to install into: `bun init -y`.
|
|
13
|
+
3. Install base tooling: `canon tooling sync base . --write`
|
|
14
|
+
4. Install php tooling: `canon tooling sync php . --write`
|
|
15
|
+
5. Install the dev tools: `composer require --dev friendsofphp/php-cs-fixer phpstan/phpstan phpunit/phpunit`. The manifest declares no `[dependencies.dev]`, because manifest injection runs `bun add -D`, which cannot install a Composer package. This step stays manual.
|
|
16
|
+
6. Run `bun run lint:fix` then `bun run check`.
|
|
17
|
+
|
|
18
|
+
Use PHP 8.3 or later, since PHPUnit 12 requires it.
|
|
19
|
+
|
|
20
|
+
Keep both `src/` and `tests/` in place. All three tools read both paths and fail when either is missing. The scaffold creates `src/`, but git does not commit an empty folder, so a fresh clone with no source yet fails `lint` and `typecheck` until the first class lands there.
|
|
21
|
+
|
|
22
|
+
The php stack also ships `tests/SmokeTest.php` as a copy-once seed, so `bun run check` passes on a fresh scaffold. Delete or replace it with real tests.
|
|
23
|
+
|
|
24
|
+
## PHP CS Fixer
|
|
25
|
+
|
|
26
|
+
- Scan `src` and `tests`.
|
|
27
|
+
- Allow risky rules.
|
|
28
|
+
- Apply `@PER-CS`, plus `declare_strict_types`, `strict_comparison`, `no_unused_imports`, and `ordered_imports`.
|
|
29
|
+
- Write the cache to `.php-cs-fixer.cache` beside the config.
|
|
30
|
+
|
|
31
|
+
## PHPStan
|
|
32
|
+
|
|
33
|
+
- Set `level: max`.
|
|
34
|
+
- Analyse `src` and `tests`.
|
|
35
|
+
|
|
36
|
+
## PHPUnit
|
|
37
|
+
|
|
38
|
+
- Bootstrap from `vendor/autoload.php` and validate against the vendored schema.
|
|
39
|
+
- Set `colors`, `failOnWarning`, and `failOnRisky`.
|
|
40
|
+
- Run one `unit` suite over `tests`, with `src` as the source.
|
|
41
|
+
|
|
42
|
+
## verify.sh
|
|
43
|
+
|
|
44
|
+
- Stop and name `composer install` when `vendor/bin/phpunit` is missing.
|
|
45
|
+
- Run Typecheck (`phpstan analyse`), Lint (`php-cs-fixer check`), and Unit tests (`phpunit --testdox`), plus the four base phases wherever the folder declares their scripts.
|
|
46
|
+
|
|
47
|
+
## Gitignore
|
|
48
|
+
|
|
49
|
+
- `# PHP`: `vendor/`, `.php-cs-fixer.cache`, `.phpunit.cache/`, `.phpunit.result.cache`
|
|
50
|
+
|
|
51
|
+
## CI
|
|
52
|
+
|
|
53
|
+
- Install PHP with `shivammathur/setup-php` and `tools: composer`.
|
|
54
|
+
- Run `composer install`, then `bun run typecheck`, `bun run lint`, and `bun run test:run`.
|
|
55
|
+
|
|
56
|
+
## Anti-patterns
|
|
57
|
+
|
|
58
|
+
- Do not ship `composer.json` or `composer.lock` from tooling. Both belong to the project, and a golden copy would overwrite its package name on every sync.
|
|
59
|
+
- Do not add a `phpstan-baseline.neon` to reach `level: max`. Fix the finding or lower the level in the project.
|
|
60
|
+
- Do not ship a `Dockerfile`, `.dockerignore`, or `compose.yaml` under tooling. Those are deployment choices and belong in the project itself.
|
|
61
|
+
|
|
62
|
+
## Development docs (extend)
|
|
63
|
+
|
|
64
|
+
Append to the `## Scripts` table:
|
|
65
|
+
|
|
66
|
+
| `bun run lint` | Run `php-cs-fixer check --diff`. |
|
|
67
|
+
| `bun run lint:fix` | Auto-fix with `php-cs-fixer fix`. |
|
|
68
|
+
| `bun run typecheck` | Run `phpstan analyse`. |
|
|
69
|
+
| `bun run test` | Run `phpunit`. |
|
|
70
|
+
| `bun run test:run` | Run `phpunit --testdox` (used by `verify`). |
|
|
71
|
+
|
|
72
|
+
## CI docs (extend)
|
|
73
|
+
|
|
74
|
+
In `canon/context/ci.md`, the Typecheck row's assertion reads: `` `phpstan analyse` passes ``. Add a Lint row whose assertion reads: `` `php-cs-fixer check` passes ``. Add a Tests row whose assertion reads: `` `phpunit` exits 0 ``.
|