Agent Skills
awaitly ships Agent Skills: procedural instructions that teach a coding agent the awaitly patterns, rules, and APIs. They work with Claude Code, Codex, Cursor, and any other agent the skills CLI supports.
Installation
Section titled “Installation”npx skills add jagreehal/awaitlyOr pick one:
npx skills add jagreehal/awaitly --listnpx skills add jagreehal/awaitly --skill awaitly-patternsWhat’s included
Section titled “What’s included”| Skill | Use it for |
|---|---|
awaitly-patterns |
Writing workflows, migrating from try/catch, debugging Result types |
awaitly-analyze |
Static analysis: complexity, path enumeration, IR, diagram generation |
awaitly-visualizer |
Event capture, renderers, collectors, time-travel, export URLs |
What awaitly-patterns teaches
Section titled “What awaitly-patterns teaches”- step() forms - when to use direct vs thunk form
- Error handling - how
step()handles early exit, no manual checking - Step helpers -
step.try(),step.retry(),step.withTimeout() - Concurrency -
step.all/allAsync()instead ofPromise.all() - Migration patterns - converting try/catch code to Result types
- Testing -
unwrapOk/unwrapErrassertions
Agents load installed skills automatically and use them contextually when you ask about writing workflows, migrating from try/catch, or debugging Result types. In Claude Code you can also invoke one explicitly:
/awaitly-patternsKey rules the agent learns
Section titled “Key rules the agent learns”R1: step() requires a string ID; use thunk form
Section titled “R1: step() requires a string ID; use thunk form”step() requires a string ID as the first argument: step('id', fn, opts?).
// Canonical form - deferred, enables retry/cachingawait step('getUser', () => deps.getUser(id));Rule: Use thunk form by default for consistent execution semantics. Every step type takes an ID as the first argument: step(id, fn, opts), step.retry(id, operation, options), step.withTimeout(id, operation, options), step.try(id, fn, opts), step.fromResult(id, fn, opts), step.sleep(id, duration, opts?).
R2: step() handles early exit
Section titled “R2: step() handles early exit”// Correct - step handles errors automaticallyconst user = await step('getUser', () => deps.getUser(id));const order = await step('createOrder', () => deps.createOrder(user));
// Wrong - never check result.ok inside workflowsconst userResult = await deps.getUser(id);if (!userResult.ok) return userResult; // Don't do this!R3: All async work through step()
Section titled “R3: All async work through step()”// Correctconst user = await step('getUser', () => deps.getUser(id));const data = await step.try('fetch', () => fetch(url), { error: 'FETCH_ERROR' });
// Wrong - bare await bypasses error handlingconst user = await deps.getUser(id); // Don't do this!R4: No Promise.all()
Section titled “R4: No Promise.all()”// Correct - allAsync preserves Result typesconst [user, posts] = await step('fetchUserData', () => allAsync([ deps.getUser(id), deps.getPosts(id),]));
// Wrong - Promise.all loses type informationconst [user, posts] = await Promise.all([...]); // Don't do this!Example conversation
Section titled “Example conversation”You: Help me migrate this function to awaitly:
async function getOrder(id: string) { try { const user = await fetchUser(id); const order = await createOrder(user); return order; } catch (e) { throw new Error('Order failed'); }}Agent (with skill): I’ll migrate this to awaitly patterns…
import { ok, err, type AsyncResult, run } from 'awaitly';
// 1. Convert deps to return Resultsasync function fetchUser(id: string): AsyncResult<User, 'NOT_FOUND'> { const user = await db.find(id); return user ? ok(user) : err('NOT_FOUND');}
async function createOrder(user: User): AsyncResult<Order, 'ORDER_FAILED'> { // ...}
// 2. Use run() with step()async function getOrder(id: string) { return run(async ({ step }) => { const user = await step('fetchUser', () => fetchUser(id)); const order = await step('createOrder', () => createOrder(user)); return order; });}Customizing
Section titled “Customizing”Skills install into your project (.claude/skills/<name>/SKILL.md for Claude Code). Edit them to add project-specific conventions, examples from your codebase, or emphasis on the patterns your team uses most.
Without the skills
Section titled “Without the skills”Agents tend to:
- Suggest
Promise.all()instead ofallAsync() - Forget to use thunks for retry/caching
- Add manual
if (!result.ok)checks inside workflows - Mix throwing and Result patterns inconsistently
The skills prevent that from the start.