Skip to main content
stack-patterns Reference for Outfitter Stack patterns including Result types, Handler contract, Error taxonomy, and @outfitter/* package conventions. Use when learning the stack, looking up patterns, understanding packages, or when "Result", "Handler", "error taxonomy", "OutfitterError", "CLI output", "pagination", "MCP server", "MCP tool", "structured logging", "redaction", "test handler", "daemon", "IPC", or "@outfitter/*" are mentioned.
Jump to install Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/outfitter-dev/agents --skill stack-patternsThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository gitbutler-complete-branch This skill should be used when the user asks to "complete a branch", "merge to main", "finish my feature", "ship this branch", "integrate to main", "create a PR from GitButler", or when `--complete-branch` flag is mentioned. Guides completion of GitButler virtual branches with safety snapshots, integration workflows, and cleanup.
This skill should be used when coordinating multiple AI agents working concurrently, handling agent handoffs, transferring commits between agents, or when "multi-agent", "concurrent agents", "parallel agents", "agent collaboration", or "parallel execution" are mentioned with GitButler. Provides virtual branch patterns for parallel execution without coordination overhead.
This skill should be used when creating stacks, dependent branches, or when "stack", "stacked branches", "anchor", "--anchor", "but branch new -a", "create dependent branch", or "break feature into PRs" are mentioned with GitButler. Covers anchor-based stacking for dependent features and reviewable PR breakdown.
Related occupations SOC
Based on SOC occupation classification
name stack-patterns version 0.1.0 description Reference for Outfitter Stack patterns including Result types, Handler contract, Error taxonomy, and @outfitter/* package conventions. Use when learning the stack, looking up patterns, understanding packages, or when "Result", "Handler", "error taxonomy", "OutfitterError", "CLI output", "pagination", "MCP server", "MCP tool", "structured logging", "redaction", "test handler", "daemon", "IPC", or "@outfitter/*" are mentioned. allowed-tools Read Grep Glob
Outfitter Stack Patterns
Primary reference for @outfitter/* package conventions.
Handler Contract
Handlers are pure functions that:
Accept typed input and context
Return Result<TOutput, TError>
Know nothing about transport (CLI flags, HTTP headers, MCP tool schemas)
type Handler <TInput , TOutput , TError extends OutfitterError > = (
input : TInput ,
ctx : HandlerContext
) => < < , >>;
Promise
Result
TOutput
TError
Example import { Result , NotFoundError , type Handler } from "@outfitter/contracts" ;
export const getUser : Handler <{ id : string }, User , NotFoundError > = async (input, ctx) => {
ctx.logger .debug ("Fetching user" , { userId : input.id });
const user = await db.users .findById (input.id );
if (!user) {
return Result .err (new NotFoundError ("user" , input.id ));
}
return Result .ok (user);
};
Why? Testability (just call the function), reusability (same handler for CLI/MCP/HTTP), type safety (explicit types), composability (handlers wrap handlers).
Result Types Uses Result<T, E> from better-result for explicit error handling.
import { Result } from "@outfitter/contracts" ;
const ok = Result .ok ({ name : "Alice" });
const err = Result .err (new NotFoundError ("user" , "123" ));
if (result.isOk ()) {
console .log (result.value );
} else {
console .log (result.error );
}
const message = result.match ({
ok : (user ) => `Found ${user.name} ` ,
err : (error ) => `Error: ${error.message} ` ,
});
const combined = combine2 (result1, result2);
Error Taxonomy Ten categories map to exit codes and HTTP status:
Category Exit HTTP When to Use validation1 400 Invalid input, schema failures not_found2 404 Resource doesn't exist conflict3 409 Already exists, version mismatch permission4 403 Forbidden action timeout5 504 Operation took too long rate_limit6 429 Too many requests network7 503 Connection failures internal8 500 Unexpected errors, bugs auth9 401 Authentication required cancelled130 499 User interrupted (Ctrl+C)
import { ValidationError , NotFoundError , getExitCode } from "@outfitter/contracts" ;
new ValidationError ("Invalid email" , { field : "email" });
new NotFoundError ("user" , "user-123" );
getExitCode (error.category );
getStatusCode (error.category );
Validation Use Zod with createValidator for type-safe validation returning Results:
import { createValidator } from "@outfitter/contracts" ;
import { z } from "zod" ;
const InputSchema = z.object ({
name : z.string ().min (1 ),
email : z.string ().email (),
});
const validateInput = createValidator (InputSchema );
const inputResult = validateInput (rawInput);
if (inputResult.isErr ()) return inputResult;
const input = inputResult.value ;
Context HandlerContext carries cross-cutting concerns:
import { createContext } from "@outfitter/contracts" ;
const ctx = createContext ({
logger : myLogger,
config : resolvedConfig,
signal : controller.signal ,
workspaceRoot : "/project" ,
});
Field Type Description requestIdstringAuto-generated UUIDv7 loggerLoggerStructured logger configResolvedConfigMerged config signalAbortSignalCancellation signal workspaceRootstringProject root cwdstringCurrent directory
Package Reference Package Purpose When to Use @outfitter/contractsResult types, errors, Handler contract Always (foundation) @outfitter/typesType utilities, collection helpers Type manipulation @outfitter/cliCLI commands, output modes, formatting CLI applications @outfitter/mcpMCP server, tool registration, Zod schemas AI agent tools @outfitter/configXDG paths, config loading, env handling Configuration needed @outfitter/loggingStructured logging, sinks, redaction Logging needed @outfitter/daemonBackground services, IPC, health checks Long-running services @outfitter/file-opsSecure paths, atomic writes, file locking File operations @outfitter/statePagination, cursor state Paginated data @outfitter/testingTest harnesses, fixtures, Bun test Testing
All projects start with @outfitter/contracts
CLI apps add @outfitter/cli (includes UI components)
MCP servers add @outfitter/mcp
Projects with config add @outfitter/config
File operations need @outfitter/file-ops for safety
Type Utilities @outfitter/types provides collection helpers and type utilities:
Collection Helpers import { sortBy, dedupe, chunk } from "@outfitter/types" ;
const users = [{ name : "Bob" }, { name : "Alice" }];
sortBy (users, "name" );
sortBy (users, u => u.name );
dedupe ([1 , 2 , 2 , 3 , 3 , 3 ]);
dedupe (users, u => u.name );
chunk ([1 , 2 , 3 , 4 , 5 ], 2 );
Type Utilities Standard TypeScript utility types for common patterns:
import type { Prettify , DeepPartial , Nullable } from "@outfitter/types" ;
type Combined = { a : string } & { b : number };
type Pretty = Prettify <Combined >;
type Config = { db : { host : string ; port : number } };
type PartialConfig = DeepPartial <Config >;
type MaybeUser = Nullable <User >;
Domain Error Mapping Map your domain errors to the 10 taxonomy categories:
Domain Error Stack Category Error Class Exit HTTP Not found not_foundNotFoundError2 404 Invalid input validationValidationError1 400 Already exists conflictConflictError3 409 No permission permissionPermissionError4 403 Auth required authAuthError9 401 Timed out timeoutTimeoutError5 504 Connection failed networkNetworkError7 503 Limit exceeded rate_limitRateLimitError6 429 Bug/unexpected internalInternalError8 500 User cancelled cancelledCancelledError130 499
new NotFoundError ("user" , userId);
new ValidationError ("Invalid email" , { field : "email" });
new ConflictError ("Email already registered" , { email });
new PermissionError ("Cannot delete admin users" );
new InternalError ("Database connection failed" , { cause : error });
Bun-First APIs Need Bun API Hashing Bun.hash()Globbing Bun.GlobSemver Bun.semverShell Bun.$Colors Bun.color()String width Bun.stringWidth()SQLite bun:sqliteUUID v7 Bun.randomUUIDv7()
References
Core Patterns
Package Deep Dives
CLI Patterns - Output modes, pagination, formatting utilities
MCP Patterns - Tool registration, resources, schemas
File Operations - Atomic writes, locking, secure paths
Logging Patterns - Structured logging, sinks, redaction
Testing Patterns - Test harnesses, fixtures
Daemon Patterns - Lifecycle, IPC, health checks