Install
$ agentstack add skill-aspenkit-aspens-cli-shell ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
You are working on the CLI shell — the entry point that wires Commander subcommands, prints the welcome screen, warns about missing Claude hooks, dispatches to handlers, and translates CliError into a clean exit. Also the public programmatic surface re-exported from src/index.js.
Domain purpose
This layer is what a user actually invokes (aspens …) and what programmatic consumers import. It owns argument parsing, top-level error handling, and the welcome UX. All real work lives in src/commands/*.js — the shell only routes.
Business rules / invariants
- Handlers must throw
CliError, never callprocess.exit(). The top-level handler inbin/cli.js:250catches it, printsError:(unlesslogged: true) in red, and exits witherr.exitCode(default 1). PlainErrorfalls through to the same printer but always exits 1. logged: truemeans "I already printed a user-friendly message" — top level then exits silently with the given code. Use it when the handler rendered a clackoutroor multi-line failure already.checkMissingHooks(repoPath)runs beforedoc sync,add, andcustomize— warns (does not throw) when.claude/skills/exists but.claude/hooks/skill-activation-prompt.shor.claude/skills/skill-rules.jsonis absent. Skipped entirely when.claude/skills/is missing (nothing to activate).- No-command invocation shows
showWelcome()— listing essential commands, generate/sync, Claude add-ons, utilities, options, typical workflow, and target notes. Adding a new subcommand requires updating this screen too. - Template counts in the welcome are filesystem-derived —
countTemplates(subdir)readssrc/templates/{agents,commands,hooks}and filters dotfiles; returns'?'on read failure (never throws). - Version comes from
package.jsonat runtime viareadFileSync; falls back to'0.0.0'silently if parse/read fails. Do not hardcode. - Numeric option parsers throw
InvalidArgumentError(Commander-native) —parsePositiveIntrejects ≤0/NaN;parseCommitsadditionally caps at 50. - Signal handlers exit with conventional codes — SIGINT→130, SIGTERM→143. Used to clean up spawned
claude -p/codex execchildren.
Non-obvious behaviors
- Action wrappers chain
checkMissingHooksbefore the handler fordoc sync,add,customize— done inline via arrow(args, options) => { checkMissingHooks(resolve(path)); return handler(...) }. Don't move this into the handler — the warning should fire even if the handler later fails or short-circuits. program.parseAsync()is required (not.parse()) — handlers are async;.catch()on the returned promise is the only place plain errors are surfaced.src/index.jsis the public programmatic API — only re-exportsscanRepo,runClaude,loadPrompt,parseFileOutput,writeSkillFiles,buildContext,buildBaseContext,buildDomainContext,analyzeImpact. Adding/removing a re-export is a breaking change for embedders; treat it as such.
Critical files
bin/cli.js— Commander setup, option parsers, welcome screen, signal handlers, top-levelCliErrorcatch.src/lib/errors.js—CliErrorclass withexitCodeandloggedoptions (plus optionalcause).src/index.js— Stable programmatic surface for library consumers.
Critical Rules
- New subcommand → register on
program(or thedocsubgroup) and add it toshowWelcome()so users discover it. - Never swallow a handler error in the action wrapper — let it bubble to
program.parseAsync().catch(). - When a handler renders its own failure UX (clack/picocolors), throw
new CliError(msg, { logged: true, exitCode })so the top level does not double-print.
Last Updated: 2026-05-11
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: aspenkit
- Source: aspenkit/aspens
- License: MIT
- Homepage: https://www.npmjs.com/package/aspens
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.