fix(kyberforge): resolve PR #144 review and audit round 1

- factory-audit: no-op hooks, ./ after interpreters, split-quote and
  spaced ${PLUGIN_ROOT} paths, camelCase events in Claude-targeted flat
  files, case-insensitive routing stems, and non-string YAML keys are
  now caught; input: forms and prompt boundary clauses align with
  primitive-author; bats 347 -> 367
- primitive-author: routing forms, quoting guidance, install exit on
  hidden Unicode, argument-hint exception
- forge: drop duplicated gotcha, fit description and body budgets (#143)
- skill-author: primitive-author boundary, Claude-only env vars
- hook: exit unless CLAUDE_PROJECT_DIR is set, so Copilot/Codex never
  run apm update; ADR-0019 correction, ADR-0025 amendment, docs fixes

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
This commit is contained in:
2026-09-28 20:13:43 +00:00
parent b2d77b2945
commit df28351d3e
23 changed files with 591 additions and 147 deletions

View File

@@ -10,16 +10,22 @@
# Refreshes in place and asks the host to re-scan, so the running session picks
# the new content up without a restart.
#
# Inert in any project that does not consume packages through apm.
# Inert under any host but Claude Code, and in any project that does not
# consume packages through apm.
set -uo pipefail
# Anchor on the project root, not the session's cwd. Claude Code exports
# CLAUDE_PROJECT_DIR for SessionStart hooks; a session opened in a subdirectory
# would otherwise miss the lockfile, no-op silently, and — worse — run the apm
# calls below against that wrong directory. Fall back to the cwd when the
# variable is absent, which keeps the hook inert-but-harmless under a host that
# does not set it.
project_dir="${CLAUDE_PROJECT_DIR:-$PWD}"
# Claude Code only. apm deploys this hook to Copilot and Codex too, and there
# the lockfile guard below would pass — apm wrote the lock — so without this
# guard a non-Claude session start would run `apm update --yes` and rewrite the
# working tree with nothing to re-scan it. Claude Code exports
# CLAUDE_PROJECT_DIR for SessionStart hooks and the other targets do not
# document it, so its absence is the exit (ADR-0019, amendment 2026-09-28).
[[ -n "${CLAUDE_PROJECT_DIR:-}" ]] || exit 0
# Anchor on the project root, not the session's cwd: a session opened in a
# subdirectory would otherwise miss the lockfile, no-op silently, and — worse —
# run the apm calls below against that wrong directory.
project_dir="$CLAUDE_PROJECT_DIR"
# No lockfile means nothing was installed through apm here — e.g. a host that
# installed this plugin natively. Say nothing and cost nothing.