chore(kyberforge): remove skill-write and skill-improve (AC6)
Completes issue #5. skill-author now covers both create and improve flows; skill-write and skill-improve are superseded and removed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016z2ZFYHQCex8yZAMVMTZzZ
This commit is contained in:
@@ -1,25 +0,0 @@
|
|||||||
# skill-improve
|
|
||||||
|
|
||||||
Apply evidence-based improvements to an existing skill using signals from the current session.
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
Takes an existing skill directory and one or more improvement signals — grill output, audit findings, eval failures, human feedback, or inline session context — and applies targeted edits to the skill files. Groups signals by root cause before editing to avoid per-symptom patching. Hands off to `/skill-audit` when done.
|
|
||||||
|
|
||||||
## Before you start
|
|
||||||
|
|
||||||
Have at least one improvement signal ready: a grill session output, `/skill-audit` report, eval results, feedback.json, or inline feedback describing what went wrong. If you have no signals and want a blind review, use `/skill-audit` instead.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
/skill-improve
|
|
||||||
```
|
|
||||||
|
|
||||||
Provide the skill directory path and any signal files in the conversation. The skill gathers signals from context — you don't need to paste them in a specific format.
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `SKILL.md` | Skill instructions for agents |
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
---
|
|
||||||
name: skill-improve
|
|
||||||
description: >
|
|
||||||
Use when the user says "improve this skill", "fix this skill based on
|
|
||||||
feedback", "apply these audit findings", or "update the skill based on this
|
|
||||||
grill output". Also use when the user provides inline feedback about a skill's
|
|
||||||
behavior and wants it applied, or when a grill session, eval run, or audit has
|
|
||||||
produced findings the user wants acted on — even if they don't say "improve"
|
|
||||||
explicitly. Applies evidence-based improvements to an existing skill. Do not
|
|
||||||
use when the user wants a read-only review only — use /skill-audit instead.
|
|
||||||
Do not use when no improvement signals are present in the conversation or
|
|
||||||
referenced files.
|
|
||||||
allowed-tools: Bash Read Write Edit
|
|
||||||
metadata:
|
|
||||||
category: factory
|
|
||||||
---
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- Patching per symptom is the default failure mode. Three eval failures may all trace to one missing instruction — always identify the root cause before editing.
|
|
||||||
- Do not create new scripts unless a signal explicitly calls for it. Writing scripts from scratch requires transcript analysis that is out of scope here; flag the opportunity as a suggestion instead.
|
|
||||||
|
|
||||||
## Step 1 — Verify inputs
|
|
||||||
|
|
||||||
Confirm the skill directory path exists and that at least one improvement signal is present in the conversation or a referenced file.
|
|
||||||
|
|
||||||
If the skill dir is missing, ask for it. If no signals are present, stop: "This skill applies existing signals to a skill. For a blind review without signals, use `/skill-audit` instead."
|
|
||||||
|
|
||||||
Signals can come from anywhere in the conversation or referenced files:
|
|
||||||
- Grill session output (most common predecessor in the factory sequence)
|
|
||||||
- `/skill-audit` findings (PASS/FAIL/SUGGESTION punch list)
|
|
||||||
- Human feedback (feedback.json, inline in conversation, PR or issue comments)
|
|
||||||
- Session context describing what went wrong
|
|
||||||
|
|
||||||
## Step 2 — Gather and group signals
|
|
||||||
|
|
||||||
Read the current skill files (SKILL.md and any files in scripts/, references/, assets/, tests/). Then collect all signals from the conversation and any file paths the user has referenced.
|
|
||||||
|
|
||||||
Group signals by **root cause**, not symptom. Ask: "What single gap in the skill causes this cluster of failures?" One root cause → one fix. Do not make a separate edit for each symptom.
|
|
||||||
|
|
||||||
```text
|
|
||||||
Example:
|
|
||||||
- Session context: output format is wrong on every run
|
|
||||||
- Audit finding: no output template defined
|
|
||||||
- User feedback: "I always have to ask it to format the output"
|
|
||||||
→ Root cause: SKILL.md has no output format specification → one fix: add an output template
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 3 — Announce planned changes
|
|
||||||
|
|
||||||
Before editing, state:
|
|
||||||
- Which root causes were identified and what evidence supports each
|
|
||||||
- Which files will be changed and what will change in each
|
|
||||||
|
|
||||||
Then proceed — edits are reversible via git, no approval checkpoint needed.
|
|
||||||
|
|
||||||
## Step 4 — Apply changes
|
|
||||||
|
|
||||||
Edit any file in the skill directory that the signals point to: SKILL.md, scripts/, references/, assets/, tests/, README.md.
|
|
||||||
|
|
||||||
**Generalize, don't patch.** Find the underlying gap, not the specific example that failed. A fix scoped only to the test cases you've seen will overfit and perform worse on new inputs.
|
|
||||||
|
|
||||||
**Keep it lean.** Remove instructions that aren't pulling their weight. For every sentence you add, ask: "Would the agent get this wrong without it?" A shorter, focused skill consistently outperforms an exhaustive one.
|
|
||||||
|
|
||||||
**Explain the why.** Reasoning-based instructions outperform rigid directives. If you find yourself writing a rule in all caps (ALWAYS/NEVER), reframe it: explain why the behavior matters so the agent can apply judgment in edge cases.
|
|
||||||
|
|
||||||
If a signal points to a script or reference file, edit that file directly rather than adding a workaround in SKILL.md.
|
|
||||||
|
|
||||||
**On scripts**: Fix and edit existing scripts freely when signals point to them.
|
|
||||||
|
|
||||||
## Step 5 — Validate and close
|
|
||||||
|
|
||||||
Run `/skill-audit` on the skill directory. Resolve any FAIL findings before considering the improvement complete.
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# skill-write
|
|
||||||
|
|
||||||
Author a new skill conforming to the [agentskills.io](https://agentskills.io) specification.
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
1. Scaffolds a full skill directory from annotated templates
|
|
||||||
2. Guides filling in `SKILL.md` and supporting files
|
|
||||||
3. Validates the result against the spec
|
|
||||||
|
|
||||||
## Before you start
|
|
||||||
|
|
||||||
This skill produces its best output when you arrive with rich context:
|
|
||||||
|
|
||||||
- Run `/grill-me` to resolve design decisions (scope, triggers, patterns)
|
|
||||||
- Collect domain research, examples, and reference docs
|
|
||||||
- Know the skill name (kebab-case) and destination path
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
/skill-write
|
|
||||||
```
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `SKILL.md` | Skill instructions for agents |
|
|
||||||
| `scripts/new-skill.sh` | Copies annotated templates to the destination |
|
|
||||||
| `references/scripts.md` | Package runner table and inline dependency patterns (loaded on demand) |
|
|
||||||
| `references/deployment-modes.md` | Plugin vs standalone differences and cache isolation rules (loaded on demand) |
|
|
||||||
| `assets/templates/SKILL.md` | Annotated SKILL.md template |
|
|
||||||
| `assets/templates/README.md` | Annotated README template for the new skill |
|
|
||||||
| `assets/templates/scripts/README.md` | Placeholder for bundled scripts |
|
|
||||||
| `assets/templates/references/README.md` | Placeholder for reference docs |
|
|
||||||
| `assets/templates/assets/README.md` | Placeholder for static assets |
|
|
||||||
| `assets/templates/tests/README.md` | Placeholder for test files |
|
|
||||||
| `tests/new-skill.bats` | Bats test suite for new-skill.sh |
|
|
||||||
| `tests/README.md` | Setup instructions for bats-support and bats-assert test dependencies |
|
|
||||||
|
|
||||||
## Placement
|
|
||||||
|
|
||||||
Skills can be installed in two locations:
|
|
||||||
|
|
||||||
| Type | Path |
|
|
||||||
|------|------|
|
|
||||||
| Direct (available immediately) | `~/.agents/skills/<name>/` |
|
|
||||||
| Plugin (installed via marketplace) | `plugins/<plugin>/skills/<name>/` |
|
|
||||||
|
|
||||||
## Spec reference
|
|
||||||
|
|
||||||
[agentskills.io specification](https://agentskills.io/specification.md)
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
---
|
|
||||||
name: skill-write
|
|
||||||
description: >
|
|
||||||
Use when the user wants to create a new skill from scratch, says "write a skill
|
|
||||||
for X", "build a skill that does Y", or "create a SKILL.md for Z", or wants to
|
|
||||||
make a workflow repeatable or shareable as a reusable command. Authors a new
|
|
||||||
skill following the agentskills.io specification — scaffolds the directory
|
|
||||||
structure from annotated templates, fills in SKILL.md and supporting files, then
|
|
||||||
validates the result. Performs best when preceded by a grill session and domain
|
|
||||||
research. Do not use to update an existing well-formed skill — use /skill-improve
|
|
||||||
instead. Do not use to author agent definition files.
|
|
||||||
allowed-tools: Bash Read Write
|
|
||||||
metadata:
|
|
||||||
category: factory
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
Run `/grill-me` on the skill's design and research the target domain first.
|
|
||||||
Share those outputs in this conversation: grill context, research docs, examples, constraints.
|
|
||||||
|
|
||||||
**Before touching the filesystem, verify you have:**
|
|
||||||
- [ ] A clear purpose — what specific task will this skill handle?
|
|
||||||
- [ ] Trigger scenarios — when should an agent activate it, including indirect cases?
|
|
||||||
- [ ] Skill name (kebab-case) and destination path
|
|
||||||
|
|
||||||
If any are missing, stop and ask the user before proceeding.
|
|
||||||
|
|
||||||
**Requires `/skill-audit`** — used in Step 5 for final validation. Both skills ship in the kyberforge plugin and are co-installed. If `/skill-audit` is unavailable, stop and ask the user to install the kyberforge plugin before continuing.
|
|
||||||
|
|
||||||
## Step 1 — Scaffold
|
|
||||||
|
|
||||||
Run the copy script with the skill name and destination directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bash scripts/new-skill.sh <skill-name> <destination-dir>
|
|
||||||
```
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
```bash
|
|
||||||
bash scripts/new-skill.sh my-tool ~/.agents/skills/
|
|
||||||
bash scripts/new-skill.sh data-analyzer plugins/myplugin/skills/
|
|
||||||
```
|
|
||||||
|
|
||||||
This creates `<destination-dir>/<skill-name>/` with annotated templates ready to fill in.
|
|
||||||
|
|
||||||
If the destination is inside a plugin directory (path contains a `plugin.json`), read `references/deployment-modes.md` before adding any file references to SKILL.md.
|
|
||||||
|
|
||||||
## Step 2 — Fill in SKILL.md
|
|
||||||
|
|
||||||
Open `<destination-dir>/<skill-name>/SKILL.md`. Replace every `FILL IN:` placeholder.
|
|
||||||
|
|
||||||
### Frontmatter
|
|
||||||
|
|
||||||
**`name`** — already set by the scaffold script. Must exactly match the directory name.
|
|
||||||
|
|
||||||
**`description`** — carries the entire triggering burden. Rules:
|
|
||||||
- Imperative: "Use when..." not "This skill..."
|
|
||||||
- Specific about capabilities ("parses and validates OpenAPI specs", not "helps with APIs")
|
|
||||||
- Include indirect triggers: "even if the user doesn't mention X explicitly"
|
|
||||||
- Add "Do not use when..." only if a near-miss skill exists that could steal activations
|
|
||||||
- Hard limit: 1024 characters — count before finalizing
|
|
||||||
|
|
||||||
**Optional fields** — uncomment and fill in or remove entirely:
|
|
||||||
- `license` — include when distributing the skill externally
|
|
||||||
- `compatibility` — include if the skill requires specific tools, runtimes, or network access
|
|
||||||
- `metadata` — key-value map; use `author`, `version`, `category`
|
|
||||||
- `allowed-tools` — space-separated pre-approved tools; reduces permission prompts
|
|
||||||
|
|
||||||
### Body — include only what the agent lacks
|
|
||||||
|
|
||||||
Rename the placeholder section heading to one that fits the skill's structure — `## Step 1`, `## Workflow`, `## Instructions`, etc.
|
|
||||||
|
|
||||||
Ask of every sentence: "Would the agent get this wrong without it?" Cut anything that answers "no."
|
|
||||||
|
|
||||||
**Include:**
|
|
||||||
- Non-obvious sequences or ordering constraints — the agent may skip or reorder steps without this
|
|
||||||
- Domain conventions the agent cannot infer from general knowledge — this is the core value a skill adds
|
|
||||||
- One default per decision point, plus one escape hatch — never a menu; menus cause the agent to pause or pick arbitrarily
|
|
||||||
- Gotchas — facts that defy reasonable assumptions; the agent will get these wrong every time without them
|
|
||||||
|
|
||||||
**Exclude:**
|
|
||||||
- Concepts the agent already knows (what JSON is, how HTTP works) — adds tokens without changing behavior
|
|
||||||
- Exhaustive option lists — pick a default; the agent doesn't benefit from choosing
|
|
||||||
- Steps the agent handles independently — over-specifying leads agents to follow unproductive paths
|
|
||||||
- Restatements of the description — it's already in context; repeating it wastes the token budget
|
|
||||||
|
|
||||||
### Patterns
|
|
||||||
|
|
||||||
**Gotchas** — highest value; place near the top:
|
|
||||||
```markdown
|
|
||||||
## Gotchas
|
|
||||||
- <Fact that defies a reasonable assumption>
|
|
||||||
- <Non-obvious naming discrepancy or hidden constraint>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Default with escape hatch** (not a menu):
|
|
||||||
```markdown
|
|
||||||
Use <X> for <task>. For <edge case>, use <Y> instead.
|
|
||||||
```
|
|
||||||
|
|
||||||
**Prescriptive sequence** (when order is critical or fragile):
|
|
||||||
```markdown
|
|
||||||
Run exactly:
|
|
||||||
\`\`\`bash
|
|
||||||
<command>
|
|
||||||
\`\`\`
|
|
||||||
Do not modify flags.
|
|
||||||
```
|
|
||||||
|
|
||||||
**Checklist** (multi-step workflows):
|
|
||||||
```markdown
|
|
||||||
- [ ] Step 1: ...
|
|
||||||
- [ ] Step 2: ...
|
|
||||||
```
|
|
||||||
|
|
||||||
**Conditional reference** (progressive disclosure — load only when needed):
|
|
||||||
```
|
|
||||||
If <condition>, read `references/<file>.md`.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Size budget
|
|
||||||
|
|
||||||
Keep `SKILL.md` under 500 lines. When approaching the limit:
|
|
||||||
- Move reference material to `references/<topic>.md` and load it conditionally
|
|
||||||
- Bundle repeated executable logic into `scripts/` rather than reinventing each run
|
|
||||||
|
|
||||||
## Step 3 — Add scripts (if needed)
|
|
||||||
|
|
||||||
Place executable scripts in `scripts/`. Rules for agentic scripts:
|
|
||||||
|
|
||||||
- **No interactive prompts** — agents run non-interactive; blocking on TTY input hangs indefinitely. Accept all input via flags, env vars, or stdin.
|
|
||||||
- **Expose `--help`** — concise usage output; keep it short (it enters the agent's context)
|
|
||||||
- **Structured output** — data (JSON, CSV) to stdout; diagnostics and progress to stderr
|
|
||||||
- **Idempotent** — "create if not exists"; agents may retry on failure
|
|
||||||
- **Meaningful exit codes** — `0` success, non-zero failure; document in `--help`
|
|
||||||
- **Dry-run support** — add `--dry-run` for destructive operations
|
|
||||||
|
|
||||||
If the skill needs scripts with external package dependencies or language-specific tooling (Python, TypeScript, Ruby, Go), read `references/scripts.md` for package runner patterns and inline dependency formats.
|
|
||||||
|
|
||||||
If no scripts are needed, delete `scripts/README.md` and the `scripts/` directory.
|
|
||||||
|
|
||||||
## Step 4 — Add references, assets, and tests (if needed)
|
|
||||||
|
|
||||||
**`references/`** — additional documentation loaded on demand. One topic per file.
|
|
||||||
Reference conditionally from SKILL.md: `If <condition>, read references/<file>.md`.
|
|
||||||
|
|
||||||
**`assets/`** — static resources: templates, schemas, lookup tables.
|
|
||||||
Reference by relative path from SKILL.md.
|
|
||||||
|
|
||||||
**`tests/`** — test files for scripts in `scripts/`. Use when scripts are complex
|
|
||||||
enough to break silently. Test infrastructure (`.bats`, `*_test.*`) belongs here,
|
|
||||||
not in `scripts/`. See `tests/README.md` for setup instructions.
|
|
||||||
|
|
||||||
If not needed, delete the placeholder READMEs and their directories.
|
|
||||||
|
|
||||||
## Step 5 — Validate
|
|
||||||
|
|
||||||
Run `/skill-audit` on `<destination-dir>/<skill-name>`.
|
|
||||||
|
|
||||||
All FAIL findings must be resolved before the skill is considered done.
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# SKILL_NAME
|
|
||||||
|
|
||||||
<!-- FILL IN: One sentence describing what this skill does. -->
|
|
||||||
|
|
||||||
## What it does
|
|
||||||
|
|
||||||
<!-- FILL IN: 2–4 sentences. What task does this skill handle?
|
|
||||||
What does the agent produce or accomplish when it runs? -->
|
|
||||||
|
|
||||||
## Before you start
|
|
||||||
|
|
||||||
<!-- FILL IN: List any prerequisites the user should have ready.
|
|
||||||
Examples: research docs, a grill session, specific input files, credentials.
|
|
||||||
Delete this section if the skill has no meaningful prerequisites. -->
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
/SKILL_NAME
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- FILL IN: Add any required or common arguments.
|
|
||||||
If the skill takes no arguments, delete the code block above and just keep the slash command. -->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: Manual (human) workflow — include if the skill bundles scripts a human can run directly.
|
|
||||||
|
|
||||||
**Manual workflow:**
|
|
||||||
```bash
|
|
||||||
# FILL IN: step-by-step commands
|
|
||||||
```
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
<!-- FILL IN: List each file individually. Remove rows for directories you deleted.
|
|
||||||
Replace the example rows below with your actual files. -->
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `SKILL.md` | Skill instructions for agents |
|
|
||||||
| `scripts/your-script.sh` | FILL IN: what this script does |
|
|
||||||
| `references/your-doc.md` | FILL IN: what this reference covers |
|
|
||||||
| `assets/your-asset.json` | FILL IN: what this asset is |
|
|
||||||
| `tests/your-test.bats` | FILL IN: what this test covers |
|
|
||||||
|
|
||||||
<!-- OPTIONAL: Spec reference — include if this skill implements or follows an external standard.
|
|
||||||
|
|
||||||
## Spec reference
|
|
||||||
|
|
||||||
[FILL IN: Spec name](FILL IN: URL)
|
|
||||||
-->
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
---
|
|
||||||
# SKILL.md — agentskills.io skill definition
|
|
||||||
# Fill in all FILL IN: placeholders. Remove comment blocks that don't apply.
|
|
||||||
|
|
||||||
name: SKILL_NAME
|
|
||||||
# Required. Must exactly match the parent directory name.
|
|
||||||
# Valid characters: lowercase letters, numbers, hyphens.
|
|
||||||
# Invalid: uppercase, leading/trailing/consecutive hyphens.
|
|
||||||
# Max length: 64 characters.
|
|
||||||
# Examples: my-tool, data-analyzer, pdf-processor
|
|
||||||
|
|
||||||
description: >
|
|
||||||
FILL IN: What does this skill do? State capabilities specifically
|
|
||||||
(e.g. "parses and validates OpenAPI specs", not "helps with APIs").
|
|
||||||
Use when FILL IN: when should an agent activate this skill?
|
|
||||||
Include indirect triggers: even if the user doesn't mention X explicitly.
|
|
||||||
Do not use when FILL IN: near-miss exclusions — remove this line if none apply.
|
|
||||||
|
|
||||||
# license: MIT
|
|
||||||
# Optional. License name (e.g. MIT, Apache-2.0) or relative path to a bundled
|
|
||||||
# license file. Include when distributing this skill. Omit for private/internal use.
|
|
||||||
|
|
||||||
# compatibility: Requires python3 >= 3.10 and uv
|
|
||||||
# Optional. 1–500 characters. State tool requirements, runtime versions,
|
|
||||||
# and network access needs. Omit for skills with no special environment requirements.
|
|
||||||
|
|
||||||
# metadata:
|
|
||||||
# author: your-name
|
|
||||||
# version: "1.0"
|
|
||||||
# category: general
|
|
||||||
# Optional. Arbitrary key-value map. Common keys: author, version, category.
|
|
||||||
# No restrictions on keys or values.
|
|
||||||
|
|
||||||
# allowed-tools: Bash Read Write
|
|
||||||
# Optional (experimental — support varies by client).
|
|
||||||
# Space-separated list of pre-approved tools.
|
|
||||||
# Use when tool usage is known and bounded, to reduce permission prompts.
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- ============================================================
|
|
||||||
SKILL BODY
|
|
||||||
|
|
||||||
Include only what the agent lacks:
|
|
||||||
- Domain conventions the agent cannot infer from general knowledge
|
|
||||||
- Non-obvious sequences or ordering constraints
|
|
||||||
- One default per decision point + one escape hatch (never a menu)
|
|
||||||
- Gotchas — facts that defy reasonable assumptions
|
|
||||||
|
|
||||||
Omit:
|
|
||||||
- Concepts the agent already knows
|
|
||||||
- Exhaustive option lists
|
|
||||||
- Steps the agent handles independently
|
|
||||||
- Restatements of the description
|
|
||||||
|
|
||||||
Size budget: under 500 lines / 5000 tokens.
|
|
||||||
Move reference material to references/ and load it conditionally.
|
|
||||||
Bundle repeated executable logic into scripts/.
|
|
||||||
|
|
||||||
Delete this comment block before shipping.
|
|
||||||
============================================================ -->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: Gotchas section — highest-value content. Place near the top.
|
|
||||||
Add facts that defy reasonable assumptions or non-obvious constraints.
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- FILL IN: fact that defies a reasonable assumption
|
|
||||||
- FILL IN: non-obvious naming discrepancy or hidden constraint
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: Multi-step workflow checklist.
|
|
||||||
|
|
||||||
## Workflow
|
|
||||||
|
|
||||||
- [ ] Step 1: FILL IN
|
|
||||||
- [ ] Step 2: FILL IN
|
|
||||||
- [ ] Step 3: FILL IN
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: Output format template — use when the agent must produce a specific format.
|
|
||||||
|
|
||||||
## Output format
|
|
||||||
|
|
||||||
Use this structure:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# [FILL IN: Title]
|
|
||||||
|
|
||||||
## FILL IN: Section
|
|
||||||
FILL IN: what goes here
|
|
||||||
```
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- OPTIONAL: Conditional reference — load documentation only when needed.
|
|
||||||
|
|
||||||
If FILL IN: condition, read `references/FILL IN: filename.md`.
|
|
||||||
-->
|
|
||||||
|
|
||||||
## FILL IN: <section-name (e.g. Step 1, Workflow, Instructions)>
|
|
||||||
|
|
||||||
FILL IN: Add your skill instructions here. Replace this section header and body with your skill content.
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# assets/
|
|
||||||
|
|
||||||
Static resources bundled with this skill: templates, schemas, lookup tables,
|
|
||||||
sample data, images.
|
|
||||||
|
|
||||||
## When to add an asset
|
|
||||||
|
|
||||||
Add a file here when the skill needs a static resource that:
|
|
||||||
- Would be tedious to reproduce in instructions (a full JSON schema, a CSV
|
|
||||||
lookup table, a binary template)
|
|
||||||
- Needs to be referenced by path rather than inlined in SKILL.md
|
|
||||||
|
|
||||||
## How to reference from SKILL.md
|
|
||||||
|
|
||||||
Use a relative path from the skill root:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
Use the schema at `assets/response-schema.json` to validate output.
|
|
||||||
```
|
|
||||||
|
|
||||||
Or instruct the agent to load it conditionally:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
If validating output format, use `assets/response-schema.json`.
|
|
||||||
```
|
|
||||||
|
|
||||||
## If no assets are needed
|
|
||||||
|
|
||||||
Delete this README and the `assets/` directory entirely.
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# references/
|
|
||||||
|
|
||||||
Additional documentation agents load on demand. Files here extend SKILL.md
|
|
||||||
without bloating its core context.
|
|
||||||
|
|
||||||
## When to add a reference file
|
|
||||||
|
|
||||||
Move content here when SKILL.md is approaching 500 lines, or when a topic
|
|
||||||
is only relevant in specific circumstances (error handling, edge cases,
|
|
||||||
domain-specific sub-procedures).
|
|
||||||
|
|
||||||
## How to reference from SKILL.md
|
|
||||||
|
|
||||||
Load conditionally — tell the agent exactly when to read each file:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
If the API returns a non-200 status, read `references/api-errors.md`.
|
|
||||||
```
|
|
||||||
|
|
||||||
Avoid generic "see references/ for details" — the agent loads context on
|
|
||||||
demand, so give it a precise trigger condition.
|
|
||||||
|
|
||||||
## File conventions
|
|
||||||
|
|
||||||
- One topic per file — focused files mean less unnecessary context loaded
|
|
||||||
- Kebab-case filenames (e.g. `api-errors.md`, `output-formats.md`)
|
|
||||||
- Keep files under 200 lines where possible
|
|
||||||
|
|
||||||
## If no reference files are needed
|
|
||||||
|
|
||||||
Delete this README and the `references/` directory entirely.
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# scripts/
|
|
||||||
|
|
||||||
Executable code bundled with this skill. Agents run scripts in this directory
|
|
||||||
to perform repeatable operations rather than reinventing the logic each run.
|
|
||||||
|
|
||||||
## When to add a script
|
|
||||||
|
|
||||||
Add a script when agents independently reinvent the same logic across runs —
|
|
||||||
building the same parser, chart, or validation routine from scratch each time.
|
|
||||||
Bundle it here once, tested and reliable.
|
|
||||||
|
|
||||||
## Script requirements (agentskills.io)
|
|
||||||
|
|
||||||
Scripts must be designed for non-interactive, agentic execution:
|
|
||||||
|
|
||||||
- **No interactive prompts** — agents run in non-interactive shells.
|
|
||||||
Accept all input via flags, env vars, or stdin. A script that blocks on
|
|
||||||
TTY input hangs indefinitely.
|
|
||||||
- **Expose `--help`** — this is how agents learn your script's interface.
|
|
||||||
Keep the output concise; it enters the agent's context window.
|
|
||||||
- **Structured output** — write data (JSON, CSV, TSV) to stdout.
|
|
||||||
Write progress, warnings, and diagnostics to stderr.
|
|
||||||
- **Idempotent** — prefer "create if not exists" over "create and fail on
|
|
||||||
duplicate". Agents may retry on failure.
|
|
||||||
- **Meaningful exit codes** — `0` for success, non-zero for failure.
|
|
||||||
Use distinct codes for different failure types; document them in `--help`.
|
|
||||||
- **Dry-run support** — add `--dry-run` for destructive operations.
|
|
||||||
|
|
||||||
## Self-contained scripts
|
|
||||||
|
|
||||||
Bundle dependencies inline so the agent can run the script with a single command.
|
|
||||||
|
|
||||||
Python (PEP 723 + uv):
|
|
||||||
```python
|
|
||||||
# /// script
|
|
||||||
# dependencies = ["requests>=2.31,<3"]
|
|
||||||
# requires-python = ">=3.11"
|
|
||||||
# ///
|
|
||||||
import requests
|
|
||||||
```
|
|
||||||
```bash
|
|
||||||
uv run scripts/my-script.py
|
|
||||||
```
|
|
||||||
|
|
||||||
## If no scripts are needed
|
|
||||||
|
|
||||||
Delete this README and the `scripts/` directory entirely.
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# tests/
|
|
||||||
|
|
||||||
Test files for scripts bundled with this skill.
|
|
||||||
|
|
||||||
## When to add tests
|
|
||||||
|
|
||||||
Add tests here when the skill has scripts in `scripts/` that are complex enough
|
|
||||||
to break silently — validators, parsers, generators, anything with branching
|
|
||||||
logic or edge cases. Test infrastructure (`.bats`, `*_test.*`, `test_*.sh`)
|
|
||||||
belongs here, not in `scripts/`.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
Tests require [bats-support](https://github.com/bats-core/bats-support) and
|
|
||||||
[bats-assert](https://github.com/bats-core/bats-assert). The test files load
|
|
||||||
helpers from the repo root's `tests/test_helper/`.
|
|
||||||
|
|
||||||
From the repo root:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support
|
|
||||||
git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
|
|
||||||
```
|
|
||||||
|
|
||||||
Run all tests for this skill (from the repo root):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bats <destination-dir>/SKILL_NAME/tests/
|
|
||||||
```
|
|
||||||
|
|
||||||
## If no tests are needed
|
|
||||||
|
|
||||||
Delete this README and the `tests/` directory entirely.
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# Deployment Modes
|
|
||||||
|
|
||||||
Skills deploy in two modes. Both resolve relative paths from the skill root — the SKILL.md body works the same in either. Differences only arise when referencing files *outside* the skill directory.
|
|
||||||
|
|
||||||
## Cache isolation (plugin mode)
|
|
||||||
|
|
||||||
When a plugin is installed, its directory is copied to a cache. Only the plugin's own files are copied. **Any path that leaves the skill directory breaks post-install:**
|
|
||||||
|
|
||||||
```
|
|
||||||
../other-skill/validate.sh # breaks
|
|
||||||
plugins/kyberforge/skills/other-skill/ # breaks
|
|
||||||
../../shared/utils.sh # breaks
|
|
||||||
```
|
|
||||||
|
|
||||||
Fix: duplicate the file into the skill's own `scripts/` or `assets/`. There is no plugin-level `shared/` mechanism — the spec defines no cross-skill sharing, and `../` paths are broken by construction.
|
|
||||||
|
|
||||||
## Env vars (plugin mode only)
|
|
||||||
|
|
||||||
These variables are injected when the plugin is loaded from an install cache. They are **not available in standalone mode.**
|
|
||||||
|
|
||||||
| Variable | Value |
|
|
||||||
|----------|-------|
|
|
||||||
| `${CLAUDE_PLUGIN_ROOT}` | Absolute path to the plugin's install directory. Changes on update. |
|
|
||||||
| `${CLAUDE_PLUGIN_DATA}` | Persistent directory that survives updates. Use for `node_modules`, generated state, caches. |
|
|
||||||
|
|
||||||
Use `${CLAUDE_PLUGIN_ROOT}` only in hook commands and `.mcp.json` configs — not in SKILL.md body text, since standalone deployments won't have it.
|
|
||||||
|
|
||||||
## Standalone mode
|
|
||||||
|
|
||||||
Deployed directly to `~/.agents/skills/<name>/`. No plugin context, no env vars injected. All file references must resolve within the skill directory. Skill invocations (e.g. `/skill-audit`) work if the called skill is also installed.
|
|
||||||
|
|
||||||
## Cross-tool portability
|
|
||||||
|
|
||||||
`SKILL.md` is portable — the same file works in Claude Code and Copilot CLI. Agent definitions and manifest files (`plugin.json`, `hooks.json`) are tool-specific and must be authored separately per tool.
|
|
||||||
|
|
||||||
## Shared assets between skills
|
|
||||||
|
|
||||||
If two skills in the same plugin need the same file, duplicate it into each skill's `assets/` or `scripts/`. Add a comment in both copies noting the mirror relationship so they stay in sync when the spec changes.
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# Scripts Reference
|
|
||||||
|
|
||||||
## Package runners (no install required)
|
|
||||||
|
|
||||||
When an existing package does what you need, use a runner directly in SKILL.md without writing a script file.
|
|
||||||
|
|
||||||
| Runner | Language | Notes |
|
|
||||||
|--------|----------|-------|
|
|
||||||
| `uvx package@version` | Python | Recommended. Aggressive caching via uv. |
|
|
||||||
| `pipx run 'package==version'` | Python | Broader OS availability. |
|
|
||||||
| `npx package@version` | Node.js | Ships with npm/Node.js. |
|
|
||||||
| `bunx package@version` | Node.js | Bun environments only. |
|
|
||||||
| `deno run npm:package@version` | TypeScript | Requires permission flags (`--allow-read`, etc.). |
|
|
||||||
| `go run golang.org/x/...@version` | Go | Built into Go toolchain. |
|
|
||||||
|
|
||||||
Always pin versions. Never use `pip install` or `npm install -g` at runtime — they are not idempotent and pollute the environment.
|
|
||||||
|
|
||||||
## Inline dependency patterns
|
|
||||||
|
|
||||||
Use these when the script requires packages but should remain a single portable file.
|
|
||||||
|
|
||||||
**Python (PEP 723 + uv):**
|
|
||||||
```python
|
|
||||||
# /// script
|
|
||||||
# dependencies = [
|
|
||||||
# "beautifulsoup4>=4.12,<5",
|
|
||||||
# ]
|
|
||||||
# requires-python = ">=3.12"
|
|
||||||
# ///
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
```
|
|
||||||
```bash
|
|
||||||
uv run scripts/extract.py
|
|
||||||
```
|
|
||||||
|
|
||||||
**TypeScript (Deno):**
|
|
||||||
```typescript
|
|
||||||
#!/usr/bin/env -S deno run
|
|
||||||
import * as cheerio from "npm:cheerio@1.0.0";
|
|
||||||
```
|
|
||||||
```bash
|
|
||||||
deno run scripts/extract.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
**TypeScript (Bun):**
|
|
||||||
```typescript
|
|
||||||
#!/usr/bin/env bun
|
|
||||||
import * as cheerio from "cheerio@1.0.0";
|
|
||||||
```
|
|
||||||
```bash
|
|
||||||
bun run scripts/extract.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ruby (bundler/inline):**
|
|
||||||
```ruby
|
|
||||||
require 'bundler/inline'
|
|
||||||
gemfile do
|
|
||||||
source 'https://rubygems.org'
|
|
||||||
gem 'nokogiri', '~> 1.16'
|
|
||||||
end
|
|
||||||
```
|
|
||||||
```bash
|
|
||||||
ruby scripts/extract.rb
|
|
||||||
```
|
|
||||||
|
|
||||||
## Output size
|
|
||||||
|
|
||||||
Many harnesses truncate tool output beyond 10–30K characters. Default to a summary or a reasonable output limit. For scripts that can produce large output: support `--offset N` for pagination, or use `--output FILE` to write to disk and keep stdout clean.
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
TEMPLATES_DIR="$SKILL_DIR/../assets/templates"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: new-skill.sh <skill-name> <destination-dir>
|
|
||||||
|
|
||||||
Create a new skill scaffold by copying annotated templates to the destination.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
skill-name Kebab-case skill identifier (e.g. my-tool, data-analyzer).
|
|
||||||
Must match the directory name exactly.
|
|
||||||
destination-dir Parent directory to create the skill in.
|
|
||||||
Examples: ~/.agents/skills/ plugins/myplugin/skills/
|
|
||||||
|
|
||||||
Output:
|
|
||||||
Creates <destination-dir>/<skill-name>/ with annotated templates ready to fill in.
|
|
||||||
|
|
||||||
Exit codes:
|
|
||||||
0 Scaffold created successfully
|
|
||||||
1 Invalid arguments or destination already exists
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $# -lt 2 ]]; then
|
|
||||||
echo "Error: skill-name and destination-dir are required." >&2
|
|
||||||
echo "" >&2
|
|
||||||
usage >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
SKILL_NAME="$1"
|
|
||||||
DEST_DIR="$2"
|
|
||||||
|
|
||||||
# Validate skill name format
|
|
||||||
if ! echo "$SKILL_NAME" | grep -qE '^[a-z0-9]+(-[a-z0-9]+)*$'; then
|
|
||||||
echo "Error: skill-name must use lowercase letters, numbers, and hyphens only." >&2
|
|
||||||
echo " No leading, trailing, or consecutive hyphens." >&2
|
|
||||||
echo " Received: '$SKILL_NAME'" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Validate templates directory exists
|
|
||||||
if [[ ! -d "$TEMPLATES_DIR" ]]; then
|
|
||||||
echo "Error: templates directory not found at '$TEMPLATES_DIR'." >&2
|
|
||||||
echo " Run this script from its original location inside the skill-write skill." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Validate destination exists
|
|
||||||
if [[ ! -d "$DEST_DIR" ]]; then
|
|
||||||
echo "Error: destination directory '$DEST_DIR' does not exist." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TARGET="$DEST_DIR/$SKILL_NAME"
|
|
||||||
|
|
||||||
# Refuse to overwrite existing directory
|
|
||||||
if [[ -d "$TARGET" ]]; then
|
|
||||||
echo "Error: '$TARGET' already exists." >&2
|
|
||||||
echo " Remove it first or choose a different name." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy templates to destination
|
|
||||||
cp -r "$TEMPLATES_DIR" "$TARGET"
|
|
||||||
|
|
||||||
# Set skill name in templates
|
|
||||||
sed -i "s/SKILL_NAME/$SKILL_NAME/g" "$TARGET/SKILL.md"
|
|
||||||
sed -i "s/SKILL_NAME/$SKILL_NAME/g" "$TARGET/README.md"
|
|
||||||
sed -i "s/SKILL_NAME/$SKILL_NAME/g" "$TARGET/tests/README.md"
|
|
||||||
|
|
||||||
echo "Scaffold created: $TARGET"
|
|
||||||
echo ""
|
|
||||||
echo "Next steps:"
|
|
||||||
echo " 1. Fill in $TARGET/SKILL.md — replace all FILL IN: placeholders"
|
|
||||||
echo " 2. Add scripts to scripts/ if needed (or delete the directory)"
|
|
||||||
echo " 3. Add docs to references/ if needed (or delete the directory)"
|
|
||||||
echo " 4. Add resources to assets/ if needed (or delete the directory)"
|
|
||||||
echo " 5. Add tests to tests/ if the skill has scripts (or delete the directory)"
|
|
||||||
echo " 6. Validate: run /skill-audit on $TARGET"
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# tests/
|
|
||||||
|
|
||||||
Test files for scripts bundled with this skill.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
Tests require [bats-support](https://github.com/bats-core/bats-support) and
|
|
||||||
[bats-assert](https://github.com/bats-core/bats-assert). The test files load
|
|
||||||
helpers from the repo root's `tests/test_helper/`.
|
|
||||||
|
|
||||||
From the repo root:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support
|
|
||||||
git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
|
|
||||||
```
|
|
||||||
|
|
||||||
Run all tests for this skill (from the repo root):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bats plugins/kyberforge/skills/skill-write/tests/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| `new-skill.bats` | Bats test suite for `scripts/new-skill.sh` |
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
#!/usr/bin/env bats
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)"
|
|
||||||
load "$REPO_ROOT/tests/test_helper/bats-support/load"
|
|
||||||
load "$REPO_ROOT/tests/test_helper/bats-assert/load"
|
|
||||||
|
|
||||||
SCRIPT="$(cd "$BATS_TEST_DIRNAME/../scripts" && pwd)/new-skill.sh"
|
|
||||||
DEST="$(mktemp -d)"
|
|
||||||
}
|
|
||||||
|
|
||||||
teardown() {
|
|
||||||
rm -rf "$DEST"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Passing cases
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@test "--help exits 0" {
|
|
||||||
run bash "$SCRIPT" --help
|
|
||||||
assert_success
|
|
||||||
assert_output --partial "Usage:"
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "creates scaffold directory at destination" {
|
|
||||||
run bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
assert_success
|
|
||||||
assert [ -d "$DEST/my-tool" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "scaffold contains SKILL.md" {
|
|
||||||
bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
assert [ -f "$DEST/my-tool/SKILL.md" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "scaffold contains README.md" {
|
|
||||||
bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
assert [ -f "$DEST/my-tool/README.md" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "scaffold contains scripts/, references/, assets/, tests/ directories" {
|
|
||||||
bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
assert [ -d "$DEST/my-tool/scripts" ]
|
|
||||||
assert [ -d "$DEST/my-tool/references" ]
|
|
||||||
assert [ -d "$DEST/my-tool/assets" ]
|
|
||||||
assert [ -d "$DEST/my-tool/tests" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "substitutes skill name in SKILL.md" {
|
|
||||||
bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
run grep "my-tool" "$DEST/my-tool/SKILL.md"
|
|
||||||
assert_success
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "substitutes skill name in README.md" {
|
|
||||||
bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
run grep "my-tool" "$DEST/my-tool/README.md"
|
|
||||||
assert_success
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "substitutes skill name in tests/README.md" {
|
|
||||||
bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
run grep "my-tool" "$DEST/my-tool/tests/README.md"
|
|
||||||
assert_success
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "skill name with numbers is valid" {
|
|
||||||
run bash "$SCRIPT" my-tool-2 "$DEST"
|
|
||||||
assert_success
|
|
||||||
assert [ -d "$DEST/my-tool-2" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "next-steps output references /skill-audit not validate.sh" {
|
|
||||||
run bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
assert_output --partial "/skill-audit"
|
|
||||||
refute_output --partial "validate.sh"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Failing cases
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@test "fails when no arguments given" {
|
|
||||||
run bash "$SCRIPT"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fails when skill name contains uppercase" {
|
|
||||||
run bash "$SCRIPT" MyTool "$DEST"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fails when skill name has consecutive hyphens" {
|
|
||||||
run bash "$SCRIPT" my--tool "$DEST"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fails when skill name has a leading hyphen" {
|
|
||||||
run bash "$SCRIPT" -my-tool "$DEST"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fails when skill name has a trailing hyphen" {
|
|
||||||
run bash "$SCRIPT" my-tool- "$DEST"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fails when destination directory does not exist" {
|
|
||||||
run bash "$SCRIPT" my-tool "/nonexistent/path"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "fails when target already exists" {
|
|
||||||
mkdir -p "$DEST/my-tool"
|
|
||||||
run bash "$SCRIPT" my-tool "$DEST"
|
|
||||||
assert_failure
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user