fix(kyberforge): address independent review of #154
Quote the template description so the raw scaffold is valid YAML, reject newline-containing names in new-instructions.sh, correct the empty-compile facts (exit 1, --clean exits 0), and finish removing commit steps from the skill-author, agent-author and forge references. Adds regression tests. Refs #148 Co-Authored-By: Claude Code <[email protected]> Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
This commit is contained in:
1 parent
d576695bb9
commit
68fa2abb62
11 files changed
+34
-17
No files matched your search
@@ -7,8 +7,8 @@ source_keys:
|
|||||||
|
|
||||||
# Creating a new agent
|
# Creating a new agent
|
||||||
|
|
||||||
Return to `SKILL.md` Step 4 once Step 3 below is done — validation, the version bump and commit
|
Return to `SKILL.md` Step 4 once Step 3 below is done — validation and the version bump
|
||||||
verification are shared with the improve flow and are not repeated here.
|
are shared with the improve flow and are not repeated here.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ source_keys:
|
|||||||
|
|
||||||
# Improving an existing agent
|
# Improving an existing agent
|
||||||
|
|
||||||
Return to `SKILL.md` Step 4 once Step 4 below is done — validation, the version bump and commit
|
Return to `SKILL.md` Step 4 once Step 4 below is done — validation and the version bump
|
||||||
verification are shared with the create flow and are not repeated here.
|
are shared with the create flow and are not repeated here.
|
||||||
|
|
||||||
## Step 1 — Verify inputs
|
## Step 1 — Verify inputs
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Fall back to an **inline invocation** — same conversation, no subagent — whe
|
|||||||
|
|
||||||
## Two-tier verification
|
## Two-tier verification
|
||||||
|
|
||||||
Both author skills already close out with their own inline audit, in the same context as the
|
The skill and agent author skills already close out with their own inline audit, in the same context as the
|
||||||
authoring work: `skill-author` and `agent-author` each invoke `factory-audit` on what they wrote.
|
authoring work: `skill-author` and `agent-author` each invoke `factory-audit` on what they wrote.
|
||||||
That is tier one, and forge does not change it.
|
That is tier one, and forge does not change it.
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ brief:
|
|||||||
> "The package at `<package-path>` gained a new `<artifact-type>` (`<artifact-name>`). Bump the
|
> "The package at `<package-path>` gained a new `<artifact-type>` (`<artifact-name>`). Bump the
|
||||||
> `version` field in that package's `apm.yml`. Determine whether to bump minor (0.1.0) or patch
|
> `version` field in that package's `apm.yml`. Determine whether to bump minor (0.1.0) or patch
|
||||||
> (0.0.1) based on whether this is a new capability (minor) or a fix/refactor (patch). Do not
|
> (0.0.1) based on whether this is a new capability (minor) or a fix/refactor (patch). Do not
|
||||||
> release or tag — just update `apm.yml` and commit."
|
> release or tag — just update `apm.yml`."
|
||||||
|
|
||||||
Clean context rather than a fork is the point: the bump decision is made independently, without
|
Clean context rather than a fork is the point: the bump decision is made independently, without
|
||||||
anchoring on the authoring conversation that just argued for the artifact's significance.
|
anchoring on the authoring conversation that just argued for the artifact's significance.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# Delete these comments once filled in; Copilot receives this file verbatim.
|
# Delete these comments once filled in; Copilot receives this file verbatim.
|
||||||
description: FILL IN: one line on what this rule covers. Only Copilot and Cursor keep it.
|
description: "FILL IN: one line on what this rule covers. Only Copilot and Cursor keep it."
|
||||||
applyTo: "FILL IN: quoted glob, e.g. **/*.py"
|
applyTo: "FILL IN: quoted glob, e.g. **/*.py"
|
||||||
# applyTo is always quoted: an unquoted ** is a YAML alias error and the rule
|
# applyTo is always quoted: an unquoted ** is a YAML alias error and the rule
|
||||||
# deploys unscoped. Several globs: "**/*.css,**/*.scss". Delete the line only
|
# deploys unscoped. Several globs: "**/*.css,**/*.scss". Delete the line only
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ For Claude Code the body's first line or heading is the only descriptive text th
|
|||||||
- `--target claude` writes `CLAUDE.md`; Gemini writes `GEMINI.md` and `AGENTS.md`; every other target writes `AGENTS.md`.
|
- `--target claude` writes `CLAUDE.md`; Gemini writes `GEMINI.md` and `AGENTS.md`; every other target writes `AGENTS.md`.
|
||||||
- Compile skips instructions already deployed natively, for Claude, Copilot and Antigravity only. With rules populated, `--target claude` exits 0, prints "produced no output files" and writes nothing. `--force-instructions` (alias `--no-dedup`) overrides.
|
- Compile skips instructions already deployed natively, for Claude, Copilot and Antigravity only. With rules populated, `--target claude` exits 0, prints "produced no output files" and writes nothing. `--force-instructions` (alias `--no-dedup`) overrides.
|
||||||
- Cursor, Windsurf, Kiro, Grok, Codex and OpenCode have no dedup: compile writes `AGENTS.md` that repeats rules the tool already loads natively.
|
- Cursor, Windsurf, Kiro, Grok, Codex and OpenCode have no dedup: compile writes `AGENTS.md` that repeats rules the tool already loads natively.
|
||||||
- A compile with no instruction primitives exits 0.
|
- A package with no instruction primitives (skills only) makes plain `apm compile` exit 1 with "No instruction files found"; `apm compile --clean` exits 0.
|
||||||
|
|
||||||
## Native format facts
|
## Native format facts
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fi
|
|||||||
NAME="$1"
|
NAME="$1"
|
||||||
ROOT="${2/#\~/$HOME}"
|
ROOT="${2/#\~/$HOME}"
|
||||||
|
|
||||||
if ! grep -qE '^[a-z0-9]+(-[a-z0-9]+)*$' <<< "$NAME"; then
|
if [[ ! $NAME =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
|
||||||
echo "Error: name must use lowercase letters, numbers, and hyphens only." >&2
|
echo "Error: name must use lowercase letters, numbers, and hyphens only." >&2
|
||||||
echo " No leading, trailing, or consecutive hyphens." >&2
|
echo " No leading, trailing, or consecutive hyphens." >&2
|
||||||
echo " Received: '$NAME'" >&2
|
echo " Received: '$NAME'" >&2
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ make_package() {
|
|||||||
fill() {
|
fill() {
|
||||||
sed -i -E \
|
sed -i -E \
|
||||||
-e '/^#/{/^# FILL IN/!d}' \
|
-e '/^#/{/^# FILL IN/!d}' \
|
||||||
-e 's/^description: FILL IN.*/description: Python style rules/' \
|
-e 's/^description: .?FILL IN.*/description: Python style rules/' \
|
||||||
-e 's/^applyTo: .*/applyTo: "**\/*.py"/' \
|
-e 's/^applyTo: .*/applyTo: "**\/*.py"/' \
|
||||||
-e 's/^# FILL IN.*/# Python style/' \
|
-e 's/^# FILL IN.*/# Python style/' \
|
||||||
-e 's/^- FILL IN.*/- Use type hints./' \
|
-e 's/^- FILL IN.*/- Use type hints./' \
|
||||||
@@ -217,3 +217,21 @@ need_apm() {
|
|||||||
assert_output --partial "Missing 'description'"
|
assert_output --partial "Missing 'description'"
|
||||||
assert_output --partial "Empty content"
|
assert_output --partial "Empty content"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "rejects a name containing a newline" {
|
||||||
|
make_package
|
||||||
|
run bash "$SCRIPT" $'my-rule\nextra' "$ROOT"
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial "lowercase letters"
|
||||||
|
assert [ ! -d "$ROOT/.apm" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "the raw scaffold is valid YAML and compiles with no parse warnings" {
|
||||||
|
need_apm
|
||||||
|
make_package
|
||||||
|
run bash "$SCRIPT" my-rule "$ROOT"
|
||||||
|
assert_success
|
||||||
|
cd "$ROOT"
|
||||||
|
run apm compile --dry-run --target claude
|
||||||
|
refute_output --partial "Failed to parse"
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@ source_keys:
|
|||||||
|
|
||||||
# Creating a new skill
|
# Creating a new skill
|
||||||
|
|
||||||
Return to `SKILL.md` Step 4 once Step 6 below is done — validation, versioning and commit
|
Return to `SKILL.md` Step 4 once Step 6 below is done — validation and versioning
|
||||||
verification are shared with the improve flow and are not repeated here.
|
are shared with the improve flow and are not repeated here.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ source_keys:
|
|||||||
|
|
||||||
# Improving an existing skill
|
# Improving an existing skill
|
||||||
|
|
||||||
Return to `SKILL.md` Step 4 once Step 4 below is done — validation, versioning and commit
|
Return to `SKILL.md` Step 4 once Step 4 below is done — validation and versioning
|
||||||
verification are shared with the create flow and are not repeated here.
|
are shared with the create flow and are not repeated here.
|
||||||
|
|
||||||
## Step 1 — Verify inputs
|
## Step 1 — Verify inputs
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ For cursor, windsurf, kiro, codex (and grok, opencode by source) compile still w
|
|||||||
|
|
||||||
For claude, cursor, windsurf, kiro and antigravity, an existing file at the deployed path is replaced without warning. Copilot skips it and asks for `--force`.
|
For claude, cursor, windsurf, kiro and antigravity, an existing file at the deployed path is replaced without warning. Copilot skips it and asks for `--force`.
|
||||||
|
|
||||||
### Empty-source compile is not an error
|
### Empty-source compile
|
||||||
|
|
||||||
Plain `apm compile` and `--target all` in a project with no instruction primitives print "no source primitives remain" and exit 0. The apm-workflow compile reference currently says this hard-fails with exit 1 and "No instruction files found in .apm/ directory"; that does not hold in 0.28.0 (see contradictions).
|
In a package with no instruction primitives, plain `apm compile --target claude` prints "No instruction files found in .apm/ directory" and exits 1; `apm compile --clean` exits 0. This matches the apm-workflow compile reference. Exit 0 with no output is a different case: instructions exist but are already deployed natively (above).
|
||||||
|
|
||||||
## Cursor-specific
|
## Cursor-specific
|
||||||
|
|
||||||
@@ -66,7 +66,6 @@ Plain `apm compile` and `--target all` in a project with no instruction primitiv
|
|||||||
| `applyTo` | Listed as required and also as optional | Optional, warning only |
|
| `applyTo` | Listed as required and also as optional | Optional, warning only |
|
||||||
| Instruction with no `applyTo` | Folded into compiled root files instead of a per-file rule | Still deployed per-file on every rule-directory target (Claude: no frontmatter; Cursor: description only; Windsurf: `always_on`; Kiro: `always`) and also compiled |
|
| Instruction with no `applyTo` | Folded into compiled root files instead of a per-file rule | Still deployed per-file on every rule-directory target (Claude: no frontmatter; Cursor: description only; Windsurf: `always_on`; Kiro: `always`) and also compiled |
|
||||||
| Grok deployed name | `.grok/rules/<name>.md` | `.grok/rules/<name>.instructions.md` |
|
| Grok deployed name | `.grok/rules/<name>.md` | `.grok/rules/<name>.instructions.md` |
|
||||||
| Compile with nothing to compile | apm-workflow compile reference: exit 1 with a "No instruction files found" message | Exit 0 |
|
|
||||||
| Compile scope | Docs say compile "only handles instructions" | Consistent for content, but compile also emits GEMINI.md and honours the agents_md mode |
|
| Compile scope | Docs say compile "only handles instructions" | Consistent for content, but compile also emits GEMINI.md and honours the agents_md mode |
|
||||||
| Cursor and Windsurf at user scope | Two fetches of the docs disagreed | Source excludes both at user scope; the source was preferred |
|
| Cursor and Windsurf at user scope | Two fetches of the docs disagreed | Source excludes both at user scope; the source was preferred |
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user