diff --git a/CHANGELOG.md b/CHANGELOG.md index 23c0b18..6d9cf43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,28 @@ For each entry, **Upgrade impact** classifies the change against the [three-buck ## Unreleased +## v1.0.6 — 2026-10-04 — Closing the Claude Directory work, for now + +A patch release, and the last of the Directory fixes for now. Its validator still reports one blocking +finding, `COMMAND_PATH_COMPUTED` at `.`, with no file or line. Scans of this branch showed the +reminder change below removed the `.` the validator listed after `triage-first.sh`; the other changes +showed no effect. The blocking finding's source, which v1.0.2 to v1.0.6 looked for, is still unknown. +The listing is paused. Installing from GitHub, per project, is unaffected. + +#### Changed +- **`triage-first.sh`'s reminder** quotes the one-line triage with single quotes and ends it without + a period after `>`. The text is the same. +- **`session-context.sh`**'s detached-HEAD line no longer ends `.` +- **`/aplyca-adf:adopt` and `/aplyca-adf:upgrade`** no longer name `${CLAUDE_PLUGIN_ROOT}/../..`, a + path outside the plugin — from `plugins/aplyca-adf`, the repository root, which the validator reports + as `.`. A development install finds the framework through the marketplace's `installLocation`, + which is the local checkout when the marketplace was added from one. +- **The static check** refuses a `>` before a period in the plugin's hooks, and any path that climbs + out of the plugin. + +#### Upgrade impact +- **Overwrite:** `session-context.sh`, `triage-first.sh`. + ## v1.0.5 — 2026-10-04 — What the Directory's validator was pointing at A patch release. The validator lists the files it couldn't check in a fixed order — the hooks in the diff --git a/README.md b/README.md index e6deb49..da16c73 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ Updates are deliberate: `/aplyca-adf:upgrade` moves a project from one release t pull request and keeps its customizations. Read the **Upgrade impact** of each release in [CHANGELOG.md](CHANGELOG.md) first. From v1.0.0, releases follow semantic versioning ([decision 0017](docs/decisions/0017-semantic-versioning.md)), so a major release asks something of -your team. The latest, **v1.0.5** (2026-10-04), is a patch for the Claude Directory. **v1.0.0** +your team. The latest, **v1.0.6** (2026-10-04), is a patch for the Claude Directory. **v1.0.0** (2026-10-02) renamed the plugin `aplyca-adf` and opens with the order to upgrade in. A baseline older than `7383422` takes that release's order first, and one older than `3eb7777` takes its three fixes before that — they affect every adopted repository. diff --git a/evals/static/check-skills.sh b/evals/static/check-skills.sh index 587cd88..3070144 100755 --- a/evals/static/check-skills.sh +++ b/evals/static/check-skills.sh @@ -781,6 +781,7 @@ rules = [ (r'\bcd\s+"\$\(', "changes into a computed directory"), (r'\b(jq|python3?)\b[^|]*\s"\$(?!1"|\{CLAUDE_PLUGIN_ROOT\})', "hands a program interpreter a computed path"), (r'\$\{TMPDIR:-/tmp\}', "builds a path from a defaulted variable"), + (r'>\.', "has a greater-than sign before a period, read as a redirect to the folder"), ] for path in sorted(glob.glob(os.path.join(hooks_dir, "*.sh"))): for number, line in enumerate(open(path, encoding="utf-8"), 1): @@ -791,8 +792,9 @@ for path in sorted(glob.glob(os.path.join(hooks_dir, "*.sh"))): print(f"{os.path.basename(path)}:{number} {what}") PY ) + bad+=$(git -C "$REPO_ROOT" grep -n -F '${CLAUDE_PLUGIN_ROOT}/..' -- plugins/aplyca-adf | sed 's/$/ reaches outside the plugin/') if [ -z "$links" ] && [ -z "$bad" ]; then - pass "the Claude Directory's checks: no symlinks; the plugin's hooks name every file they load or run literally, with no inline programs" + pass "the Claude Directory's checks: no symlinks; the plugin's hooks name every file they load or run literally, with no inline programs; nothing reaches outside the plugin" else fail "the Claude Directory's checks: symlinks [$links] ${bad//$'\n'/; }" fi diff --git a/plugins/aplyca-adf/.claude-plugin/plugin.json b/plugins/aplyca-adf/.claude-plugin/plugin.json index 4447334..c2b8188 100644 --- a/plugins/aplyca-adf/.claude-plugin/plugin.json +++ b/plugins/aplyca-adf/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "aplyca-adf", "description": "The Agentic Development Framework for Claude Code. /adopt bootstraps a repository — skeleton, optional modules, guardrail hooks, verified facts — committed or packaged; /upgrade moves an adopted repository to a newer release; /cost-report shows what agent sessions cost, from local transcripts. In a packaged project it also carries the framework's skills, agents, workflows, and hooks, pinned to a release; in a committed project those step aside for the committed copies.", - "version": "1.0.5", + "version": "1.0.6", "author": { "name": "Aplyca", "email": "dev@aplyca.com" diff --git a/plugins/aplyca-adf/README.md b/plugins/aplyca-adf/README.md index bdacca3..bc8e7a3 100644 --- a/plugins/aplyca-adf/README.md +++ b/plugins/aplyca-adf/README.md @@ -141,7 +141,7 @@ the plugin by a relative path. A machine where nobody trusts the folder — CI { "extraKnownMarketplaces": { "aplyca": { - "source": { "source": "github", "repo": "aplyca/AgenticDevelopmentFramework", "ref": "v1.0.5" } + "source": { "source": "github", "repo": "aplyca/AgenticDevelopmentFramework", "ref": "v1.0.6" } } }, "enabledPlugins": { "aplyca-adf@aplyca": true } diff --git a/plugins/aplyca-adf/hooks/session-context.sh b/plugins/aplyca-adf/hooks/session-context.sh index 88b8b9e..96f1620 100755 --- a/plugins/aplyca-adf/hooks/session-context.sh +++ b/plugins/aplyca-adf/hooks/session-context.sh @@ -96,7 +96,7 @@ if [ -x "$root/scripts/agent/worktree-new.sh" ]; then if [[ $branch =~ $generated_name ]] || [ "${branch#*/}" = "$branch" ]; then generated=1; fi fi if [ "$branch" = "detached HEAD" ]; then - echo "- Detached HEAD: after triage, create the task's branch — git switch -c /." + echo "- Detached HEAD: after triage, create the task's branch with git switch -c /" elif [ -n "$generated" ]; then echo "- The branch name is generated ($branch): after triage, rename it — git branch -m / — so it joins its spec folder and /aplyca-adf:open-pr takes it." fi diff --git a/plugins/aplyca-adf/hooks/triage-first.sh b/plugins/aplyca-adf/hooks/triage-first.sh index 56e6605..3ec25e6 100755 --- a/plugins/aplyca-adf/hooks/triage-first.sh +++ b/plugins/aplyca-adf/hooks/triage-first.sh @@ -41,4 +41,4 @@ if [ -z "$(printf '%s' "$replies" | tr -d '[:space:]')" ]; then else seen="none of your replies in this session names a lane (fast, careful, or full), so the developer has seen no triage — what you decided while thinking isn't shown to anyone" fi -block "$seen. Before $change, write the triage as your next message. For a small change, one line: \"Fast lane — ; done when ; files: ; model: .\" Then run it again; this reminder shows once." +block "$seen. Before $change, write the triage as your next message. For a small change, one line: 'Fast lane — ; done when ; files: ; model: ' — then run it again; this reminder shows once." diff --git a/plugins/aplyca-adf/skills/adopt/SKILL.md b/plugins/aplyca-adf/skills/adopt/SKILL.md index e964c6d..ec5cdbc 100644 --- a/plugins/aplyca-adf/skills/adopt/SKILL.md +++ b/plugins/aplyca-adf/skills/adopt/SKILL.md @@ -29,12 +29,12 @@ read the source doc (locations in step 1). Resolve the framework root, in order: -1. `${CLAUDE_PLUGIN_ROOT}/../..` — only when the plugin runs from a checkout of the framework repo. -2. The marketplace checkout: the `installLocation` of the marketplace (usually `aplyca`) in - `claude plugin marketplace list --json` — by default `~/.claude/plugins/marketplaces/aplyca/`. - **The normal case on installed machines** — installed plugins run from a version cache, so - `${CLAUDE_PLUGIN_ROOT}` isn't inside the repo. Run `claude plugin marketplace update ` first. -3. Otherwise clone: `git clone --depth 1 https://github.com/aplyca/AgenticDevelopmentFramework`. +1. The marketplace checkout: the `installLocation` of the marketplace (usually `aplyca`) in + `claude plugin marketplace list --json` — by default `~/.claude/plugins/marketplaces/aplyca/`, or + the framework repository itself when the marketplace was added from a local checkout. Installed + plugins run from a version cache, never from the repository. Run + `claude plugin marketplace update ` first. +2. Otherwise clone: `git clone --depth 1 https://github.com/aplyca/AgenticDevelopmentFramework`. You need `/skeleton/`, `/modules/`, and `/docs/`. Record the source release, SHA, and date: `git -C describe --tags --abbrev=0 --match 'v*'` diff --git a/plugins/aplyca-adf/skills/upgrade/SKILL.md b/plugins/aplyca-adf/skills/upgrade/SKILL.md index e0c140b..06d84f1 100644 --- a/plugins/aplyca-adf/skills/upgrade/SKILL.md +++ b/plugins/aplyca-adf/skills/upgrade/SKILL.md @@ -43,11 +43,11 @@ agents) and confirm the inferred SHA with the user before proceeding. ## Step 2 — Locate the framework source and NEW_SHA -Same resolution order as `/adopt` Step 1: repo checkout via `${CLAUDE_PLUGIN_ROOT}/../..` -(development installs), else a **full** clone of `https://github.com/aplyca/AgenticDevelopmentFramework` -(not shallow — the diff needs history). The marketplace checkout (`installLocation` in -`claude plugin marketplace list --json`) sits at the release the project pins, so it can't show what's -newer. +A framework checkout with its full history: the marketplace's `installLocation` (in +`claude plugin marketplace list --json`) when the marketplace was added from a local checkout of the +framework repository, else a **full** clone of `https://github.com/aplyca/AgenticDevelopmentFramework` +(not shallow — the diff needs history). A marketplace added from GitHub sits at the release the +project pins, so it can't show what's newer. A project moves **from release to release** (decision 0017): NEW_SHA is the commit of the newest release tag (`git -C tag --list 'v*' --sort=-v:refname | head -1`), unless the diff --git a/skeleton/.claude/hooks/session-context.sh b/skeleton/.claude/hooks/session-context.sh index c167fc2..fab8535 100755 --- a/skeleton/.claude/hooks/session-context.sh +++ b/skeleton/.claude/hooks/session-context.sh @@ -96,7 +96,7 @@ if [ -x "$root/scripts/agent/worktree-new.sh" ]; then if [[ $branch =~ $generated_name ]] || [ "${branch#*/}" = "$branch" ]; then generated=1; fi fi if [ "$branch" = "detached HEAD" ]; then - echo "- Detached HEAD: after triage, create the task's branch — git switch -c /." + echo "- Detached HEAD: after triage, create the task's branch with git switch -c /" elif [ -n "$generated" ]; then echo "- The branch name is generated ($branch): after triage, rename it — git branch -m / — so it joins its spec folder and /open-pr takes it." fi diff --git a/skeleton/.claude/hooks/triage-first.sh b/skeleton/.claude/hooks/triage-first.sh index 8431716..b7052d5 100755 --- a/skeleton/.claude/hooks/triage-first.sh +++ b/skeleton/.claude/hooks/triage-first.sh @@ -41,4 +41,4 @@ if [ -z "$(printf '%s' "$replies" | tr -d '[:space:]')" ]; then else seen="none of your replies in this session names a lane (fast, careful, or full), so the developer has seen no triage — what you decided while thinking isn't shown to anyone" fi -block "$seen. Before $change, write the triage as your next message. For a small change, one line: \"Fast lane — ; done when ; files: ; model: .\" Then run it again; this reminder shows once." +block "$seen. Before $change, write the triage as your next message. For a small change, one line: 'Fast lane — ; done when ; files: ; model: ' — then run it again; this reminder shows once."