Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add skills/aspenkit/aspens/claude-runnernpx skills add aspenkit/aspens --skill claude-runnergit clone --depth 1 https://github.com/aspenkit/aspensWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/aspenkit/aspens/claude-runner)<a href="https://agentmods.dev/skills/aspenkit/aspens/claude-runner"><img src="https://agentmods.dev/badge/skills/aspenkit/aspens/claude-runner.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00036 | $0.01742 |
| Opus 5 | $0.00018 | $0.00871 |
| Sonnet 5 | $0.00007 | $0.00348 |
| Haiku 4.5 | $0.00004 | $0.00174 |
Grade A, and why
claude-runner scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 4d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 58 lines — stays where its author put it; the contents beside it link to each section on GitHub.
You are working on the CLI execution layer — the bridge between assembled prompts and the claude -p / codex exec CLIs, plus skill file I/O.
Key Concepts
- Stream-JSON protocol (Claude):
runClaude()always passes--verbose --output-format stream-json. Output is NDJSON:type: 'result'has final text + usage;type: 'assistant'has text/tool_use blocks;type: 'user'has tool_result blocks. - JSONL protocol (Codex):
runCodex()spawnscodex exec --json --sandbox read-only --ephemeral. The--ask-for-approval neverflag is conditionally included based on capability detection (see below). Prompt is passed via stdin ('-'placeholder arg) to avoid shell arg length limits. Stdin write happens after event handlers are attached so fast failures are captured. Events:item.completed/item.updatedwith normalized types. - Codex capability detection:
getCodexExecCapabilities()(internal, cached) runscodex exec --helpand checks if--ask-for-approvalappears in the help text. Result is cached in module-levelcodexExecCapabilitiesvariable. If the help check fails (e.g., codex not installed), capabilities default to{ supportsAskForApproval: false }.runCodex()only adds--ask-for-approval neverwhensupportsAskForApprovalis true. - Unified routing:
runLLM(prompt, options, backendId)is the shared entry point — dispatches torunClaude()orrunCodex()based onbackendId. Exported fromrunner.jsso command handlers no longer need local routing helpers. - Codex internals (private):
normalizeCodexItemType()converts PascalCase/kebab-case to snake_case.collectCodexText()recursively extracts text from nested event content. Both are internal to runner.js. - Prompt templating:
loadPrompt(name, vars)resolves{{partial-name}}fromsrc/prompts/partials/first, then substitutes{{varName}}fromvars. Target-specific vars (skillsDir,skillFilename,instructionsFile,configDir) are passed by command handlers. - File output parsing: Primary:
<file path="...">content</file>XML tags. Fallback:<!-- file: path -->comment markers.parseFileOutput(output, allowedPaths)accepts optional{ dirPrefixes, exactFiles }to override default allowed paths. - Path sanitization:
sanitizePath(rawPath, allowedPaths)(internal) blocks..traversal, absolute paths. Defaults:.claude/prefix +AGENTS.mdexact. Multi-target callers pass expanded allowed paths viagetAllowedPaths()fromtarget.js. - Validation:
validateSkillFiles()checks for truncation (XML tag collisions), missing frontmatter, missing sections, bad file path references. - Skill rules generation:
extractRulesFromSkills()reads all skills viaskill-reader.js, producesskill-rules.json(v2.0) with file patterns, keywords, and intent patterns. - Domain patterns:
generateDomainPatterns()converts file patterns to bashdetect_skill_domain()function usingBEGIN/ENDmarkers. - Trigger parsing precedence:
parseTriggersFrontmatter(content)returns{ filePatterns, keywords, alwaysActivate }parsed from atriggers:block in YAML frontmatter (supports block lists, inline arrays, andalwaysActivate: truefor the base skill); returnsnullwhen notriggers:key exists.parseActivationPatternsandparseKeywordsprefer this frontmatter when present and fall back to legacy## Activation/Keywords:line parsing for older skills. - Settings merge:
mergeSettings()merges aspens hook config into existingsettings.json. Detects aspens-managed hooks byASPENS_HOOK_MARKERS(skill-activation-prompt,graph-context-prompt,post-tool-use-tracker,save-tokens-statusline,save-tokens-prompt-guard,save-tokens-precompact). Also handlesstatusLinemerging — replaces existing statusLine only if the current one is aspens-managed (detected byisAspensHook), preserving user-custom statusLine configs. After merging hooks,dedupeAspensHookEntries()removes duplicate aspens-managed entries per event type. - Directory-scoped writes:
writeTransformedFiles()handles files outside.claude/(e.g.,src/billing/AGENTS.md) with explicit path allowlist — onlyAGENTS.md,AGENTS.mdexact files and.claude/,.agents/,.codex/prefixes are permitted. findSkillFilesmatching: Only matches the exactskillFilename(e.g.,skill.mdorSKILL.md), not arbitrary.mdfiles in the skills directory.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 4d ago First seen · 58 lines · 36 tokens per session scan A 2f2301fbdc5d
claude-runner is a skill published in the GitHub repository aspenkit/aspens (99 stars, last pushed 19d ago), licensed MIT. It adds 36 tokens to every session and 1,742 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other skills, from other repositories
golden-rss
Use when testing the rss golden build.
golden-chat-topics
Use when testing the goldenchattopics golden build.
golden-chat-single
Use when testing the goldenchatsingle golden build.
decided-import
Reformat ONE existing document (a decision, requirement, design, roadmap, or prompt) into ONE valid RAC (requirements-as-code) artifact, with a mandatory human-review step before any file is written and decided validate as the deterministic close. Use when a user wants to add or import a single existing decision or…
keep-the-why
Extract and preserve the reasoning code cannot explain - decisions, rejected alternatives, workarounds, incidents, constraints - plus project setup/decline and maintainer interviews. Not for what changed (see Keep a Changelog) - only why.
summarize
Summarize conversations, logs, docs, or investigation notes into action-oriented text with evidence tags. Use for recap, handoff, CI failure digest, or MEMORY. Triggers: 总结, 汇总, summarize, 交接, 复盘, 调试总结.