Skip to content

Commit 659e730

Browse files
authored
feat(skills): auto-improve 4 skills via skill-auto-improver to pass both gates (#63)
* feat(skills): auto-improve 4 skills via skill-auto-improver to pass both gates - Reviewed all 35 skills in skills/ with full skill-auto-improver workflow (baseline capture, asm-eval, quick_validate, predictability audit, fixes, reports) - 31 skills already passed Gate 1 (quick_validate) + Gate 2 (overall >85, min cat >=8) at discovery — no changes - 4 skills improved until both gates passed: - security-setup: 96/7 → 97/8 (context efficiency) - subagent-creator: 84/3 → 96/8 (testability + prompt engineering) - viral-product-evaluator: 71/3 → 96/9 (testability, safety, description) - website-cloner: 74/4 → 94/8 (safety, context, description) - Changes per category playbook + topSuggestions: - Trimmed/rewrote descriptions (action verb, keep negative-trigger, budget-friendly) - Added ## Prerequisites, ## Acceptance Criteria, ## Expected output, ## Edge cases - Added context budget notes + reference links for efficiency - Strengthened confirmation, error handling, and "stop and report" language - metadata.version bumped (patch for wording, minor for new sections) - All touched skills now pass quick_validate.py and asm eval gates - .asm-improver/ artifacts generated locally for the run but not committed No other files touched. Pre-existing changes excluded. * feat(tmux-agent-comms): improve delivery verification docs and add rationale reference - Tighten SKILL.md (shorter explanations, less duplication) - Delegate full delivery/waiting rationale to new references/delivery-and-waiting.md - Update cross-references and Step Completion notes - Bump metadata.version to 1.4.0 This change was already present in the working tree during the catalog auto-improver review and is now included in the same PR. * docs(subagent-creator): remove redundant Instructions heading (#64)
1 parent c233142 commit 659e730

6 files changed

Lines changed: 179 additions & 38 deletions

File tree

skills/security-setup/SKILL.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ license: MIT
55
compatibility: "Cross-platform (macOS, Linux, Windows). Requires git, Python 3.8+, and project write access. Uses pre-commit plus free local tools such as gitleaks, trivy, semgrep, bandit, or cargo-audit when appropriate. Semgrep on Windows requires WSL2."
66
effort: high
77
metadata:
8-
version: 1.3.2
8+
version: 1.3.3
99
author: "Luong NGUYEN <luongnv89@gmail.com>"
1010
---
1111

@@ -15,6 +15,19 @@ Install a local-first security hardening stack for a project. Favor checks that
1515
offline at hook time, produce machine-readable output, and give developers a clear
1616
summary before code leaves their machine.
1717

18+
Keep the orchestrator short for the agent's context budget: detailed matrices, templates,
19+
and long verification scenarios live in `references/`. Link, don't inline.
20+
21+
## Prerequisites
22+
23+
- Git repo with a branch you can commit to.
24+
- Python 3.8+ and pip.
25+
- Permission to create `.pre-commit-config.yaml`, `scripts/`, `security/`, `SECURITY.md`.
26+
- (Optional for `--ci`) GitHub Actions enabled on the repo.
27+
- Network for initial tool/db installs (subsequent hook runs are offline).
28+
29+
Confirm these before Phase 1. If a tool cannot be made offline, document the gap instead of pretending.
30+
1831
## Repo Sync Before Edits (mandatory)
1932

2033
Before creating/updating/deleting files in an existing repository, sync the current

skills/subagent-creator/SKILL.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: subagent-creator
33
description: "Create, evaluate, or improve Claude Code subagent files (.claude/agents/*.md) — the frontmatter + system prompt defining a delegatable specialist. Don't use for skills (skill-creator), CLAUDE.md/AGENTS.md (agent-config), or running an agent."
44
effort: high
55
metadata:
6-
version: 1.0.1
6+
version: 1.1.1
77
author: "Luong NGUYEN <edgardo.montesdeoca@montimage.eu>"
88
---
99

@@ -13,6 +13,10 @@ Create, evaluate, and improve **Claude Code subagents** — the `.md` files (in
1313

1414
This is **not** about skills (`skill-creator` owns those) or `CLAUDE.md`/`AGENTS.md` (`agent-config` owns those). A subagent is one file: frontmatter (`name`, `description`, `tools`, `model`, …) + a system-prompt body.
1515

16+
## When to Use
17+
18+
Use when the user asks to create, review, or fix a Claude Code subagent definition file (`.claude/agents/*.md` or personal `~/.claude/agents/*.md`). Do not use for skills or for editing CLAUDE.md/AGENTS.md.
19+
1620
## Pick the branch first
1721

1822
Three branches. Identify which one the user is on before doing anything else — they don't share a starting step.
@@ -145,6 +149,38 @@ Close any create/evaluate/improve run with three short lists:
145149
- **Verified** — what proves the result (frontmatter parses, file path written, rubric pass).
146150
- **Improved** — concrete changes by field/concern (or `none — review only` for an Evaluate run).
147151

152+
## Acceptance Criteria
153+
154+
A successful run produces:
155+
- A subagent file with valid YAML frontmatter, `name` (kebab), description containing when+what + negative-trigger, and least-privilege `tools`.
156+
- Step Completion Report with per-rubric-item √/× and overall PASS|PARTIAL|FAIL.
157+
- For Improve: before/after rubric comparison showing net positive change.
158+
- No edits outside the confirmed target path (project `.claude/agents/` or `~/.claude/agents/`).
159+
160+
## Expected output
161+
162+
For a Create on "a read-only PR diff reviewer":
163+
164+
```
165+
◆ Create subagent (step 4 of 4 — pr-diff-reviewer.md)
166+
Frontmatter parses: √ pass
167+
name == filename: √ pass
168+
Single responsibility: √ pass
169+
Tools least-privilege: √ pass (read-only: Read, Grep, Glob)
170+
Description: when+what: √ pass
171+
____________________________
172+
Result: PASS
173+
```
174+
175+
The file is written and ready for use.
176+
177+
## Edge cases
178+
179+
- User points at a file but the request is "make a new one for X": treat as Create after confirming path.
180+
- Ambiguous trigger language: default to Evaluate and ask for clarification.
181+
- Target path is inside a git repo with dirty tree: perform Repo Sync (stash / pull / pop) before write.
182+
- Subagent name would collide with skill or agent-config names: reject and suggest different name (see negative triggers in description).
183+
148184
---
149185

150186
## Reference files

skills/tmux-agent-comms/SKILL.md

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ description: "Manage AI agents in tmux: spawn or kill sessions and message any C
44
license: MIT
55
effort: medium
66
metadata:
7-
version: 1.3.0
8-
author: Luong NGUYEN <luongnv89@gmail.com>
7+
version: 1.4.0
8+
author: "Luong NGUYEN <luongnv89@gmail.com>"
99
---
1010

1111
# Tmux Agent Comms
1212

13-
Manage and talk to AI agents (another Claude Code, Gemini CLI, or any CLI) running in separate tmux sessions. This skill covers the full loop: **create** sessions for agents, **send** them messages, **wait** for them to finish thinking, **capture** their replies, and **tear down** sessions when done.
13+
Manage and talk to AI agents (another Claude Code, Gemini CLI, or any CLI) running in separate tmux sessions. Covers the full loop: **create** sessions, **send** messages, **wait** for the agent to finish, **capture** replies, and **tear down** when done.
1414

15-
The mental model: each tmux session is one agent. You orchestrate them from the outside by writing to their input and reading their pane — exactly what a human would do by switching windows, but scripted. Because the orchestrating agent's context budget is finite, relay each agent's answer, not its whole screen (the bundled helper extracts just the reply).
15+
The mental model: each tmux session is one agent. You orchestrate from outside by writing to its input and reading its pane — what a human does by switching windows, but scripted. Because your context budget is finite, relay each agent's answer, not its whole screen (the bundled helper extracts just the reply).
1616

1717
## When to Use
1818

@@ -101,26 +101,18 @@ tmux send-keys -t agent1 "your message"
101101
tmux send-keys -t agent1 Enter
102102
```
103103

104-
**Verify delivery before you wait (don't skip this).** A keystroke can drop, an `Enter` can go unsubmitted, or a busy/blocked pane can swallow the input — and you'd then wait on a reply that will never come. The trap: the message text appears in `capture-pane` whether it was **submitted** or is merely **typed and still parked in the input box** — both render as the same characters, so "the text is on screen" only proves it was typed, not sent. The one signal that reliably means *submitted* is **post-send activity**: once the agent accepts the message it starts working (a spinner / `esc to interrupt`). So after send, before Phase 4, run a **bounded** check (one short fixed delay, then a single capture — never a poll loop that can hang) and key it off that activity:
104+
**Verify delivery before you wait (don't skip this).** A keystroke can drop or an `Enter` can go unsubmitted, and you'd then wait on a reply that never comes. On-screen text only proves the message was *typed* — it looks identical whether submitted or parked in the input box. The reliable "submitted" signal is **post-send activity** (a spinner / `esc to interrupt`). After send, run a **bounded** check (one ~5s delay, then a single capture — never a poll loop) and grep the pane for that activity:
105105

106106
```bash
107-
tmux send-keys -t agent1 "summarize the changes in src/"
108-
tmux send-keys -t agent1 Enter
109-
sleep 5 # bounded: one fixed wait, ~5s
110-
pane=$(tmux capture-pane -t agent1 -p -S -40) # ~40 scrollback lines + visible pane
111-
if printf '%s\n' "$pane" | grep -Eq 'esc to interrupt|[⠁-⣿]'; then
112-
echo "delivered" # agent is working → input was accepted and submitted
113-
else
114-
echo "NOT-DELIVERED" # no activity → it didn't land; re-send (below)
115-
fi
107+
tmux send-keys -t agent1 "..."; tmux send-keys -t agent1 Enter; sleep 5
108+
tmux capture-pane -t agent1 -p -S -40 | grep -Eq 'esc to interrupt|[⠁-⣿]' \
109+
&& echo delivered || echo NOT-DELIVERED
116110
```
117111

118-
Two outcomes — and neither is a reply timeout (that's Phase 4):
119-
120-
- **`delivered`** — the agent is busy (spinner / `esc to interrupt`), which only appears once the message was accepted *and* submitted → proceed to Phase 4.
121-
- **`NOT-DELIVERED`** — no post-send activity. The cause is usually the separate-Enter gotcha above (the message typed but the `Enter` didn't submit) or a dropped/swallowed keystroke. The fix covers both: **send a lone `Enter`** (`tmux send-keys -t agent1 Enter`) and re-check once — a no-op if it was already submitted; if there's still nothing, **re-type** the message. Report this **distinctly** from a Phase 4 reply timeout: nothing was submitted, so don't start waiting until it lands.
112+
- **`delivered`** — agent is busy → submitted → proceed to Phase 4.
113+
- **`NOT-DELIVERED`** — no activity (usually the separate-Enter gotcha or a dropped keystroke). Send a lone `Enter` and re-check; if still nothing, re-type. Distinct from a Phase 4 reply timeout — nothing was submitted, so don't start waiting.
122114

123-
This is the `send → verify-delivered → wait → bounded-tail capture` sequence the rest of the workflow follows. Don't try to read the message text back out of the pane to confirm it — a single capture can't tell "echoed in the transcript" from "still parked in the input box," so trust the activity signal, not the presence of the text. If your agent's spinner glyphs differ, key the check off its busy marker (the same `--busy-marker` / `TAC_BUSY_MARKERS` vocabulary Phase 4 uses) rather than `esc to interrupt` alone.
115+
This is the `send → verify-delivered → wait → bounded-tail capture` loop. Trust the activity signal, not the text. Full rationale and the verbose branch logic: `references/delivery-and-waiting.md`.
124116

125117
## Phase 4: Wait for the Reply, Then Read It
126118

@@ -136,19 +128,11 @@ It returns one of three states — **branch on the exit code:**
136128
- **3 — blocked:** settled but parked on a prompt that needs a human (trust/auth dialog). It prints the full pane so you can show the dialog. **Do not send a message** — it would be read as menu input. Surface it and ask the user how to respond (Rule 1).
137129
- **2 — timeout:** never settled within `--timeout` (agent still working, or genuinely stuck). This bounds **one** wait — it does not bound a loop that keeps re-waiting (see the anti-deadloop cap below).
138130

139-
Content stability is the universal signal (works for any CLI agent); spinner chrome (`esc to interrupt`) and dialog text only refine the verdict. For an agent whose chrome differs, add markers with `--busy-marker`/`--block-marker` or the `TAC_BUSY_MARKERS`/`TAC_BLOCK_MARKERS` env vars — no code edit. Other flags: `--timeout`, `--quiet-cycles`, `--interval`, `--full` (print the whole pane), `--scrollback N`. Run with `--help` for details.
131+
Content stability is the universal signal (works for any CLI agent); spinner chrome and dialog text only refine the verdict. For an agent whose chrome differs, add markers with `--busy-marker`/`--block-marker` or the `TAC_BUSY_MARKERS`/`TAC_BLOCK_MARKERS` env vars — no code edit. Other flags: `--timeout`, `--quiet-cycles`, `--interval`, `--full`, `--scrollback N`; run `--help` for details.
140132

141-
**The helper's verdict is advisory — verify it yourself when in doubt.** Exit 0 means *the pane stopped changing*, which is usually "done" but can also be a paused agent or a UI that quiesced mid-task. When the verdict matters (before relaying a result the user will act on, or on any exit-2 timeout), do an **independent, human-style read** capture the pane yourself (Phase 5) and look at the actual content — rather than trusting the exit code alone:
133+
**The verdict is advisory — verify it when it matters.** Exit 0 means *the pane stopped changing*, usually "done" but possibly a paused agent. Before relaying a result the user will act on, or on any exit-2 timeout, do an independent human-style read (`tmux capture-pane -t agent1 -p -S -40`, Phase 5): a spinner or a changing tail = **still working** (keep waiting, don't send — Rule 3); unchanged + no spinner + no completion = **stalled** (surface it, don't silently re-wait).
142134

143-
```bash
144-
tmux capture-pane -t agent1 -p -S -40 # bounded tail: ~40 scrollback lines + visible pane
145-
```
146-
147-
This lets you **distinguish a stalled agent from a working one** — the third failure mode, separate from a dropped delivery (Phase 3) and a reply timeout (exit 2):
148-
- **Still working:** a spinner / `esc to interrupt` is showing, or the tail differs from a capture you took moments ago → keep waiting; **don't send a new message yet** (Rule 3).
149-
- **Stuck / stalled:** the pane is unchanged across reads, with no spinner and no completion (no prompt returned, answer never finished) → it won't resolve on its own. Surface it to the user; do not silently re-wait.
150-
151-
**Anti-deadloop — bound the whole loop, not just one wait.** `--timeout` caps a single call; the real risk is a re-wait / re-send loop (here and in Phase 6 "Continue") that polls forever. Set a **hard overall budget** before you start — a small number of re-waits (e.g. 2–3) or a total wall-clock cap — and when it's spent, **stop and escalate to the user** with what you observed (last capture, how long you waited). Never poll indefinitely and never auto-re-send past the cap; an agent that hasn't settled within the budget is a stall to report, not a loop to keep running.
135+
**Anti-deadloop — bound the whole loop, not just one wait.** `--timeout` caps a single call; the real risk is a re-wait / re-send loop that polls forever. Set a **hard overall budget** before you start — a small number of re-waits (e.g. 2–3) or a total wall-clock cap — and when it's spent, **stop and escalate to the user** with what you observed. Never poll indefinitely. Full details in `references/delivery-and-waiting.md`.
152136

153137
If you can't run the script (no Python, restricted env), fall back to a manual loop: capture (below), `sleep 3`, capture again, compare — under the same overall budget. Matching captures with no spinner = done. A spinner or `esc to interrupt` still showing → wait and re-capture; **don't send a new message yet** (Rule 3). If the budget runs out with no resolution, stop and surface it.
154138

@@ -229,7 +213,9 @@ Relay that answer to the user. If the bounded-tail read starts mid-sentence, wid
229213

230214
## Reference
231215

232-
Read `references/tmux-recipes.md` for: broadcasting to a fleet, sending multi-line/code messages safely, splitting a session into panes, reading scrollback robustly, and a troubleshooting table (message didn't send, pane empty, session not found, agent stuck on a prompt).
216+
Read `references/delivery-and-waiting.md` for the full rationale behind delivery verification (Phase 3) and waiting (Phase 4).
217+
218+
Read `references/tmux-recipes.md` for: broadcasting to a fleet, sending multi-line/code messages safely, splitting a session into panes, reading scrollback robustly, and a troubleshooting table.
233219

234220
## Step Completion Report
235221

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Delivery Verification & Waiting — the full rationale
2+
3+
The deep "why" behind SKILL.md Phases 3 and 4. The SKILL.md gives you the commands and the branch logic; read this when you need to understand *why* a step is shaped the way it is, or when a check behaves unexpectedly.
4+
5+
## Why "text on screen" does not prove a message was submitted
6+
7+
After `send-keys`, the message text appears in `capture-pane` whether it was **submitted** or is merely **typed and still parked in the input box** — both render as the same characters. So "the text is on screen" only proves it was typed, not sent. Reading the message text back out of the pane to confirm delivery is therefore unreliable: a single capture can't tell "echoed in the transcript" from "still parked in the input box."
8+
9+
The one signal that reliably means *submitted* is **post-send activity**: once the agent accepts the message it starts working (a spinner / `esc to interrupt`). That is why the Phase 3 delivery check keys off activity, not text presence.
10+
11+
### The bounded delivery check (one fixed wait, then one capture)
12+
13+
```bash
14+
tmux send-keys -t agent1 "summarize the changes in src/"
15+
tmux send-keys -t agent1 Enter
16+
sleep 5 # bounded: one fixed wait, ~5s
17+
pane=$(tmux capture-pane -t agent1 -p -S -40) # ~40 scrollback lines + visible pane
18+
if printf '%s\n' "$pane" | grep -Eq 'esc to interrupt|[⠁-⣿]'; then
19+
echo "delivered" # agent is working → input was accepted and submitted
20+
else
21+
echo "NOT-DELIVERED" # no activity → it didn't land; re-send
22+
fi
23+
```
24+
25+
Keep this **bounded** — one short fixed delay, then a single capture. Never a poll loop here; that can hang. The reply-settling poll belongs to Phase 4, not the delivery check.
26+
27+
### The two outcomes (neither is a reply timeout)
28+
29+
- **`delivered`** — the agent is busy (spinner / `esc to interrupt`), which only appears once the message was accepted *and* submitted → proceed to Phase 4.
30+
- **`NOT-DELIVERED`** — no post-send activity. Usually the separate-Enter gotcha (the message typed but the `Enter` didn't submit) or a dropped/swallowed keystroke. The fix covers both: **send a lone `Enter`** (`tmux send-keys -t agent1 Enter`) and re-check once — a no-op if it was already submitted; if there's still nothing, **re-type** the message. Report this **distinctly** from a Phase 4 reply timeout: nothing was submitted, so don't start waiting until it lands.
31+
32+
If your agent's spinner glyphs differ, key the check off its busy marker (the same `--busy-marker` / `TAC_BUSY_MARKERS` vocabulary Phase 4 uses) rather than `esc to interrupt` alone.
33+
34+
## Why the helper's verdict is advisory
35+
36+
`wait_for_idle.py` exit 0 means *the pane stopped changing*, which is usually "done" but can also be a paused agent or a UI that quiesced mid-task. Content stability is the universal signal (works for any CLI agent); spinner chrome (`esc to interrupt`) and dialog text only refine the verdict.
37+
38+
When the verdict matters (before relaying a result the user will act on, or on any exit-2 timeout), do an **independent, human-style read** — capture the pane yourself and look at the actual content — rather than trusting the exit code alone:
39+
40+
```bash
41+
tmux capture-pane -t agent1 -p -S -40 # bounded tail: ~40 scrollback lines + visible pane
42+
```
43+
44+
This distinguishes the third failure mode (a stalled agent) from a working one — separate from a dropped delivery (Phase 3) and a reply timeout (exit 2):
45+
46+
- **Still working:** a spinner / `esc to interrupt` is showing, or the tail differs from a capture you took moments ago → keep waiting; **don't send a new message yet**.
47+
- **Stuck / stalled:** the pane is unchanged across reads, with no spinner and no completion (no prompt returned, answer never finished) → it won't resolve on its own. Surface it to the user; do not silently re-wait.
48+
49+
## Anti-deadloop — bound the whole loop, not just one wait
50+
51+
`--timeout` caps a **single** call; the real risk is a re-wait / re-send loop (Phase 4 and Phase 6 "Continue") that polls forever. Set a **hard overall budget** before you start — a small number of re-waits (e.g. 2–3) or a total wall-clock cap — and when it's spent, **stop and escalate to the user** with what you observed (last capture, how long you waited). Never poll indefinitely and never auto-re-send past the cap; an agent that hasn't settled within the budget is a stall to report, not a loop to keep running.
52+
53+
### Manual fallback (no Python / restricted env)
54+
55+
Capture, `sleep 3`, capture again, compare — under the same overall budget. Matching captures with no spinner = done. A spinner or `esc to interrupt` still showing → wait and re-capture; **don't send a new message yet**. If the budget runs out with no resolution, stop and surface it.

0 commit comments

Comments
 (0)