📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-05-29 08:33:53 +00:00
parent fdb52f1e96
commit 06e0d13d57
1615 changed files with 232858 additions and 0 deletions
@@ -0,0 +1,87 @@
# Migration Overview
**Project:** {{PROJECT_NAME}}
**Started:** {{DATE}}
**Last Updated:** {{DATE}}
## Status Dashboard
| Stage | Status | Progress | Blocked By |
|-------|--------|----------|------------|
| 1. Foundation | ⬜ Not Started | 0/4 | — |
| 2. Handlers | ⬜ Not Started | 0/{{HANDLER_COUNT}} | Foundation |
| 3. Errors | ⬜ Not Started | 0/{{ERROR_CLASS_COUNT}} | Handlers |
| 4. Paths | ⬜ Not Started | 0/{{PATH_COUNT}} | — |
| 5. Adapters | ⬜ Not Started | 0/{{ADAPTER_COUNT}} | Handlers |
| 6. Documents | ⬜ Not Started | 0/{{DOC_COUNT}} | All |
| 99. Unknowns | ⬜ Review | 0/{{UNKNOWN_COUNT}} | — |
**Status Key:** ⬜ Not Started · 🟡 In Progress · ✅ Complete · 🔴 Blocked · ⏭️ Skipped
## Stage Dependencies
```
┌─────────────┐
│ Foundation │
└──────┬──────┘
┌─────────────┐ ┌─────────────┐
│ Handlers │────▶│ Adapters │
└──────┬──────┘ └─────────────┘
┌─────────────┐
│ Errors │
└─────────────┘
┌─────────────┐
│ Paths │ (independent)
└─────────────┘
┌─────────────┐
│ Documents │ (after all stages)
└─────────────┘
┌─────────────┐
│ Unknowns │ (review anytime)
└─────────────┘
```
## Recommended Order
1. **Foundation** — Must be first (context, logger)
2. **Paths** — Can run parallel with Handlers
3. **Handlers** — Core conversion work
4. **Errors** — After handlers identify error cases
5. **Adapters** — After handlers are converted
6. **Unknowns** — Review throughout, resolve before Documents
7. **Documents** — Last, after code is stable
## Progress Log
| Date | Stage | Work Done | Notes |
|------|-------|-----------|-------|
| {{DATE}} | — | Generated migration plan | Initial scan |
## Decisions
| Decision | Rationale | Date |
|----------|-----------|------|
## Blockers
| Blocker | Stage | Status | Resolution |
|---------|-------|--------|------------|
## Completion Criteria
- [ ] All handlers return `Result<T, E>`
- [ ] No `throw` statements in application code
- [ ] No `console.log` in production code
- [ ] All paths use XDG conventions
- [ ] All user paths validated with `securePath()`
- [ ] CLI uses `output()` and `exitWithError()`
- [ ] Documentation reflects new patterns
- [ ] All unknowns resolved or documented
- [ ] Tests updated and passing
@@ -0,0 +1,81 @@
# Stage 1: Foundation
**Status:** ⬜ Not Started
**Blocked By:** None
**Unlocks:** Handlers, Errors, Adapters
## Objective
Install dependencies and create shared infrastructure (context, logger).
## Tasks
### 1.1 Install Dependencies
- [ ] Install core packages
```bash
bun add @outfitter/contracts @outfitter/logging @outfitter/config
```
- [ ] Install optional packages (as needed)
```bash
bun add @outfitter/cli # CLI commands
bun add @outfitter/mcp # MCP server
bun add @outfitter/file-ops # File operations
bun add @outfitter/daemon # Background services
bun add @outfitter/testing # Test harnesses
```
### 1.2 Create Logger
- [ ] Create `src/logger.ts`
```typescript
import { createLogger, createConsoleSink } from "@outfitter/logging";
export const logger = createLogger({
name: "{{PROJECT_NAME}}",
level: process.env.LOG_LEVEL || "info",
sinks: [createConsoleSink()],
redaction: { enabled: true },
});
```
### 1.3 Create Context Factory
- [ ] Create `src/context.ts`
```typescript
import { createContext } from "@outfitter/contracts";
import { logger } from "./logger";
export const createAppContext = () => createContext({ logger });
export type AppContext = ReturnType<typeof createAppContext>;
```
### 1.4 Verify Setup
- [ ] Create smoke test
```typescript
import { describe, it, expect } from "bun:test";
import { createAppContext } from "../context";
describe("foundation", () => {
it("creates context with logger", () => {
const ctx = createAppContext();
expect(ctx.logger).toBeDefined();
expect(ctx.requestId).toBeDefined();
});
});
```
- [ ] Run test: `bun test`
## Completion Checklist
- [ ] Core packages installed
- [ ] Logger created with redaction enabled
- [ ] Context factory created
- [ ] Smoke test passing
## Notes
{{FOUNDATION_NOTES}}
@@ -0,0 +1,88 @@
# Stage 2: Handlers
**Status:** ⬜ Not Started
**Blocked By:** Foundation
**Unlocks:** Errors, Adapters
## Objective
Convert functions with `throw` to handlers returning `Result<T, E>`.
## Handlers to Convert
{{#each HANDLERS}}
### {{this.name}}
- **File:** `{{this.file}}:{{this.line}}`
- **Current:** `{{this.signature}}`
- **Throws:** {{this.throws}}
- **Priority:** {{this.priority}}
#### Conversion
- [ ] Define input schema (Zod)
- [ ] Define output type
- [ ] Identify error cases → taxonomy mapping
- [ ] Convert to Handler signature
- [ ] Replace `throw` with `Result.err()`
- [ ] Add `createValidator()` for input
- [ ] Update callers to use `isOk()` / `isErr()`
- [ ] Add/update tests
```typescript
// Target signature
const {{this.name}}: Handler<{{this.inputType}}, {{this.outputType}}, {{this.errorType}}> = async (input, ctx) => {
// ...
};
```
---
{{/each}}
## Conversion Pattern
### Before
```typescript
async function getUser(id: string): Promise<User> {
const user = await db.users.findById(id);
if (!user) throw new Error(`Not found: ${id}`);
return user;
}
try {
const user = await getUser("123");
} catch (error) {
console.error(error.message);
}
```
### After
```typescript
import { Result, NotFoundError, type Handler } from "@outfitter/contracts";
const getUser: Handler<{ id: string }, User, NotFoundError> = async (input, ctx) => {
const user = await db.users.findById(input.id);
if (!user) return Result.err(new NotFoundError("user", input.id));
return Result.ok(user);
};
const result = await getUser({ id: "123" }, ctx);
if (result.isErr()) {
ctx.logger.error("Failed", { error: result.error });
}
```
## Completion Checklist
- [ ] All handlers return `Result<T, E>`
- [ ] No `throw` in handler code
- [ ] Input validation with `createValidator()`
- [ ] Callers check `isOk()` / `isErr()`
- [ ] Tests updated for Result assertions
## Notes
{{HANDLER_NOTES}}
@@ -0,0 +1,78 @@
# Stage 3: Errors
**Status:** ⬜ Not Started
**Blocked By:** Handlers
**Unlocks:** Documents
## Objective
Replace custom error classes with Outfitter error taxonomy.
## Error Taxonomy Reference
| Category | Class | Exit | HTTP | Use For |
|----------|-------|------|------|---------|
| `validation` | `ValidationError` | 1 | 400 | Invalid input, schema failures |
| `not_found` | `NotFoundError` | 2 | 404 | Resource doesn't exist |
| `conflict` | `ConflictError` | 3 | 409 | Already exists, version mismatch |
| `permission` | `PermissionError` | 4 | 403 | Forbidden action |
| `timeout` | `TimeoutError` | 5 | 504 | Operation took too long |
| `rate_limit` | `RateLimitError` | 6 | 429 | Too many requests |
| `network` | `NetworkError` | 7 | 503 | Connection failures |
| `internal` | `InternalError` | 8 | 500 | Unexpected errors, bugs |
| `auth` | `AuthError` | 9 | 401 | Authentication required |
| `cancelled` | `CancelledError` | 130 | 499 | User interrupted |
## Error Classes to Migrate
{{#each ERROR_CLASSES}}
### {{this.name}}
- **File:** `{{this.file}}:{{this.line}}`
- **Usages:** {{this.usageCount}}
- **Suggested Mapping:** `{{this.suggestedMapping}}`
#### Migration
- [ ] Identify all usages of `{{this.name}}`
- [ ] Replace with `{{this.suggestedMapping}}`
- [ ] Update error metadata/details
- [ ] Remove original class definition
- [ ] Update tests
```typescript
// Before
throw new {{this.name}}({{this.exampleArgs}});
// After
return Result.err(new {{this.suggestedMapping}}({{this.newArgs}}));
```
---
{{/each}}
## Unmapped Errors
Errors that don't fit standard taxonomy:
{{#each UNMAPPED_ERRORS}}
- [ ] `{{this.name}}` — {{this.reason}}
{{/each}}
**Options for unmapped errors:**
1. Use `InternalError` with descriptive message
2. Create domain-specific error extending `OutfitterError`
3. Map to closest category with metadata
## Completion Checklist
- [ ] All custom errors mapped to taxonomy
- [ ] Original error classes removed
- [ ] Error messages include structured metadata
- [ ] Exit codes verified correct
- [ ] Tests updated
## Notes
{{ERROR_NOTES}}
@@ -0,0 +1,117 @@
# Stage 4: Paths
**Status:** ⬜ Not Started
**Blocked By:** None (can run parallel with Handlers)
**Unlocks:** Documents
## Objective
Replace hardcoded paths with XDG-compliant paths and add path security.
## XDG Directory Reference
| Function | Path | Purpose |
|----------|------|---------|
| `getConfigDir(name)` | `~/.config/{name}` | Configuration files |
| `getCacheDir(name)` | `~/.cache/{name}` | Cache files |
| `getDataDir(name)` | `~/.local/share/{name}` | Persistent data |
| `getStateDir(name)` | `~/.local/state/{name}` | Runtime state |
## Files to Migrate
{{#each PATH_FILES}}
### {{this.file}}
- **Line:** {{this.line}}
- **Current:** `{{this.current}}`
- **Pattern:** {{this.pattern}}
#### Migration
- [ ] Replace with XDG function
- [ ] Add `securePath()` if user-provided
- [ ] Update tests
```typescript
// Before
{{this.beforeCode}}
// After
{{this.afterCode}}
```
---
{{/each}}
## Path Security
For user-provided paths, use `securePath()`:
```typescript
import { securePath } from "@outfitter/file-ops";
const validatePath = (userPath: string, baseDir: string) => {
const result = securePath(userPath, { base: baseDir });
if (result.isErr()) {
return Result.err(new ValidationError("Invalid path", { path: userPath }));
}
return Result.ok(result.value);
};
```
**Security checks:**
- Path traversal (`../`)
- Symlink following
- Base directory escape
- Null bytes
## Common Patterns
### Config File
```typescript
// Before
const configPath = path.join(os.homedir(), ".myapp", "config.json");
// After
import { getConfigDir } from "@outfitter/config";
const configPath = path.join(getConfigDir("myapp"), "config.json");
```
### Cache Directory
```typescript
// Before
const cacheDir = path.join(os.homedir(), ".cache", "myapp");
// After
import { getCacheDir } from "@outfitter/config";
const cacheDir = getCacheDir("myapp");
```
### User-Provided Path
```typescript
// Before
const filePath = args.file;
await fs.readFile(filePath);
// After
import { securePath } from "@outfitter/file-ops";
const pathResult = securePath(args.file, { base: process.cwd() });
if (pathResult.isErr()) return pathResult;
await fs.readFile(pathResult.value);
```
## Completion Checklist
- [ ] All `os.homedir()` replaced with XDG functions
- [ ] All `~/` literals replaced
- [ ] User-provided paths validated with `securePath()`
- [ ] Tests use `withTempDir()` fixture
- [ ] No hardcoded absolute paths
## Notes
{{PATH_NOTES}}
@@ -0,0 +1,166 @@
# Stage 5: Adapters
**Status:** ⬜ Not Started
**Blocked By:** Handlers
**Unlocks:** Documents
## Objective
Wrap handlers with CLI and/or MCP transport adapters.
## CLI Commands
{{#each CLI_COMMANDS}}
### {{this.name}}
- **Handler:** `{{this.handler}}`
- **Current File:** `{{this.file}}`
#### Migration
- [ ] Create command with Zod schema
- [ ] Wrap handler
- [ ] Use `output()` for responses
- [ ] Use `exitWithError()` for errors
- [ ] Add integration test
```typescript
import { command, output, exitWithError } from "@outfitter/cli";
import { {{this.handler}} } from "../handlers/{{this.handlerFile}}";
import { createAppContext } from "../context";
import { z } from "zod";
const InputSchema = z.object({
{{this.inputFields}}
});
export const {{this.name}}Command = command("{{this.commandName}}")
.description("{{this.description}}")
{{this.options}}
.action(async ({ args, flags }) => {
const ctx = createAppContext();
const result = await {{this.handler}}({ {{this.inputMapping}} }, ctx);
if (result.isErr()) {
exitWithError(result.error);
}
await output(result.value);
})
.build();
```
---
{{/each}}
## MCP Tools
{{#each MCP_TOOLS}}
### {{this.name}}
- **Handler:** `{{this.handler}}`
- **Current File:** `{{this.file}}`
#### Migration
- [ ] Create tool with Zod schema
- [ ] Add `.describe()` to all fields
- [ ] Wrap handler
- [ ] Register with server
- [ ] Add integration test
```typescript
import { defineTool } from "@outfitter/mcp";
import { {{this.handler}} } from "../handlers/{{this.handlerFile}}";
import { z } from "zod";
export const {{this.name}}Tool = defineTool({
name: "{{this.toolName}}",
description: "{{this.description}}",
schema: z.object({
{{this.schemaFields}}
}),
handler: async (input, ctx) => {
return {{this.handler}}(input, ctx);
},
});
```
---
{{/each}}
## CLI Patterns
### Output Modes
```typescript
// Automatic mode detection (TTY vs pipe)
await output(data);
// Force specific mode
await output(data, { mode: "json" });
await output(data, { mode: "human" });
```
### Error Handling
```typescript
if (result.isErr()) {
exitWithError(result.error);
// Prints error message
// Exits with category-mapped code (1-9, 130)
}
```
### Testing CLI
```typescript
import { createCliHarness } from "@outfitter/testing";
const harness = createCliHarness(myCommand);
it("handles success", async () => {
const result = await harness.run(["--id", "123"]);
expect(result.exitCode).toBe(0);
expect(result.stdout).toContain("success");
});
```
## MCP Patterns
### Tool Registration
```typescript
import { createMcpServer } from "@outfitter/mcp";
const server = createMcpServer({ name: "myapp" });
server.registerTool(myTool);
server.start();
```
### Testing MCP
```typescript
import { createMcpHarness } from "@outfitter/testing";
const harness = createMcpHarness(server);
it("handles tool call", async () => {
const result = await harness.callTool("my-tool", { id: "123" });
expect(result.isOk()).toBe(true);
});
```
## Completion Checklist
- [ ] All CLI commands use `output()` and `exitWithError()`
- [ ] All MCP tools have `.describe()` on schema fields
- [ ] Handlers wrapped, not inlined
- [ ] Integration tests with harnesses
- [ ] Error codes verified
## Notes
{{ADAPTER_NOTES}}
@@ -0,0 +1,123 @@
# Stage 6: Documents
**Status:** ⬜ Not Started
**Blocked By:** All other stages
**Unlocks:** None (final stage)
## Objective
Update documentation to reflect new patterns and APIs.
## Files to Update
{{#each DOC_FILES}}
### {{this.file}}
- **Type:** {{this.type}}
- **Issues:** {{this.issues}}
#### Updates Needed
{{#each this.updates}}
- [ ] {{this}}
{{/each}}
---
{{/each}}
## README Updates
- [ ] Update installation instructions (add @outfitter/* packages)
- [ ] Update API examples (Result types, not exceptions)
- [ ] Update error handling section
- [ ] Add migration notes for consumers (if library)
### Example API Section
```markdown
## Usage
\`\`\`typescript
import { getUser } from "mylib";
import { createContext } from "@outfitter/contracts";
const ctx = createContext();
const result = await getUser({ id: "123" }, ctx);
if (result.isOk()) {
console.log(result.value);
} else {
console.error(result.error.message);
}
\`\`\`
```
## TSDoc/JSDoc Updates
Update function documentation to reflect Result return types:
```typescript
/**
* Fetches a user by ID.
*
* @param input - The input containing the user ID
* @param ctx - Handler context
* @returns Result with User on success, NotFoundError if user doesn't exist
*
* @example
* const result = await getUser({ id: "123" }, ctx);
* if (result.isOk()) {
* console.log(result.value.name);
* }
*/
```
## CHANGELOG Entry
```markdown
## [X.Y.Z] - {{DATE}}
### Changed
- **BREAKING**: All handlers now return `Result<T, E>` instead of throwing
- **BREAKING**: Error types use Outfitter taxonomy
- Paths now use XDG conventions
### Added
- Structured logging with `@outfitter/logging`
- Input validation with Zod schemas
### Migration
See [MIGRATION.md](./MIGRATION.md) for upgrade guide.
```
## Migration Guide (if library)
- [ ] Create `MIGRATION.md` for consumers
- [ ] Document breaking changes
- [ ] Provide before/after examples
- [ ] List error type mappings
## Inline Comments
Review and update comments that reference old patterns:
- [ ] Remove `// throws XError` comments
- [ ] Update `@throws` JSDoc tags to `@returns Result`
- [ ] Fix examples in code comments
## Completion Checklist
- [ ] README reflects new API patterns
- [ ] TSDoc/JSDoc updated for all public APIs
- [ ] CHANGELOG entry added
- [ ] Migration guide created (if library)
- [ ] Inline comments reviewed
- [ ] Examples compile and work
## Notes
{{DOC_NOTES}}
@@ -0,0 +1,126 @@
# Stage 99: Unknowns
**Status:** ⬜ Review Required
**Blocked By:** None
**Unlocks:** None (review throughout migration)
## Objective
Track items the scanner couldn't categorize or that need human judgment.
## Review Priority
| Priority | Meaning |
|----------|---------|
| 🔴 High | Blocks other work, needs immediate decision |
| 🟡 Medium | Should resolve before Documents stage |
| 🟢 Low | Can defer or skip with documentation |
## Unknowns
{{#each UNKNOWNS}}
### {{this.id}}: {{this.title}}
- **File:** `{{this.file}}:{{this.line}}`
- **Priority:** {{this.priority}}
- **Category:** {{this.category}}
#### Context
```typescript
{{this.code}}
```
#### Why Unknown
{{this.reason}}
#### Options
{{#each this.options}}
{{@index}}. {{this}}
{{/each}}
#### Decision
- [ ] Reviewed
- [ ] Decision: _____________
- [ ] Implemented
---
{{/each}}
## Common Unknown Categories
### Third-Party Libraries That Throw
Libraries that throw exceptions need wrapper decisions:
```typescript
// Option 1: Wrap at call site
const result = await wrapAsync(() => thirdPartyLib.doThing());
// Option 2: Create typed wrapper
const safeDoThing = wrapThirdParty(thirdPartyLib.doThing);
```
### Complex Try/Catch Blocks
Nested or multi-catch blocks that can't be auto-converted:
```typescript
// May need manual restructuring
try {
await step1();
await step2();
} catch (e) {
if (e instanceof TypeA) { ... }
else if (e instanceof TypeB) { ... }
else { throw e; }
}
```
### Async Patterns
Unusual async patterns (Promise.race, Promise.allSettled with throws):
```typescript
// May need Result-aware alternatives
const results = await Promise.all(items.map(processItem));
```
### Domain-Specific Errors
Errors that don't map cleanly to taxonomy:
- Consider if they're really `ValidationError` with metadata
- Consider if they're `InternalError` with descriptive message
- Consider creating domain error extending `OutfitterError`
## Resolution Log
| ID | Decision | Rationale | Date |
|----|----------|-----------|------|
## Stack Feedback
Issues discovered that should be reported to outfitter-dev/outfitter:
{{#each STACK_FEEDBACK}}
- [ ] {{this.title}} — {{this.type}}
{{/each}}
Use `outfitter-stack:stack-feedback` skill to create GitHub issues.
## Completion Checklist
- [ ] All unknowns reviewed
- [ ] Decisions documented
- [ ] High-priority items resolved
- [ ] Stack feedback reported
- [ ] Remaining items documented for future
## Notes
{{UNKNOWN_NOTES}}