Skip to content

Commit be8b790

Browse files
zrosenbauerclaude
andcommitted
chore: init
Extracted from internal tooling and rebuilt as an open-source CLI framework. Includes core runtime, middleware system, config loader, bundler, CLI scaffolding tooling, utilities, examples, documentation, and contributing standards. Co-Authored-By: Claude <noreply@anthropic.com>
0 parents  commit be8b790

File tree

276 files changed

+35419
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

276 files changed

+35419
-0
lines changed

.changeset/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changesets
2+
3+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4+
with multi-package repos, or single-package repos to help you version and publish your code. You can
5+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6+
7+
We have a quick list of common questions to get you started engaging with this project in
8+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

.changeset/config.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
3+
"changelog": "@changesets/cli/changelog",
4+
"commit": false,
5+
"fixed": [],
6+
"linked": [],
7+
"access": "public",
8+
"baseBranch": "main",
9+
"updateInternalDependencies": "patch",
10+
"ignore": []
11+
}

.changeset/tall-bears-relate.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

.claude/rules/documentation.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
paths:
3+
- '**/*.md'
4+
- '!CLAUDE.md'
5+
- '!.claude/**'
6+
---
7+
8+
# Documentation Rules
9+
10+
## Principles
11+
12+
- **Succinct** — no fluff, get to the point
13+
- **Actionable** — lead with what to do, not background
14+
- **Scannable** — tables, headers, and lists over paragraphs
15+
- **Consistent** — use the same structure across all documents
16+
17+
## Templates
18+
19+
Use the correct template based on document type. See `contributing/standards/documentation/writing.md` for full templates:
20+
21+
| Type | Structure | Title Convention |
22+
|---|---|---|
23+
| Standard | Overview > Rules > Resources > References | Noun phrase |
24+
| Guide | Prerequisites > Steps > Verification > Troubleshooting | Starts with verb |
25+
| Overview | Architecture > Key Concepts > Usage > Configuration | Topic name |
26+
| Troubleshooting | Issue sections with Fix blocks | "Domain Troubleshooting" |
27+
28+
## Sections
29+
30+
- **Resources** — external URLs only
31+
- **References** — internal relative links only
32+
- Never mix external and internal links in the same section
33+
34+
## Formatting
35+
36+
- Code examples: minimal snippets showing the pattern, not full files
37+
- Specify language on all fenced code blocks (```ts, ```bash, etc.)
38+
- Use tables for structured comparisons (Correct vs Incorrect, options, conventions)
39+
- Prefer relative links for internal docs, full URLs for external
40+
41+
## Diagrams
42+
43+
- Use Mermaid with Catppuccin Mocha theme
44+
- See `contributing/standards/documentation/diagrams.md` for color palette and conventions

.claude/rules/errors.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
paths:
3+
- 'packages/**/src/**/*.ts'
4+
---
5+
6+
# Error Handling Rules
7+
8+
All expected failures use the `Result<T, E>` tuple type. Never throw exceptions.
9+
10+
## Result Type
11+
12+
```ts
13+
type Result<T, E = Error> = readonly [E, null] | readonly [null, T]
14+
```
15+
16+
- Success: `[null, value]`
17+
- Failure: `[error, null]`
18+
19+
## Conventions
20+
21+
- Define domain-specific error interfaces with a descriptive `type` or `reason` field
22+
- Create type aliases for domain results (e.g., `type ConfigResult<T> = Result<T, ConfigError>`)
23+
- Use `ok()` and `fail()` constructors where available (e.g., `HandlerResult` in kidd package)
24+
- Wrap async operations that can reject with a try/catch that returns a Result tuple
25+
26+
## Chaining with Early Returns
27+
28+
```ts
29+
const [configError, config] = loadConfig(workspace)
30+
if (configError) return [configError, null]
31+
32+
const [resolveError, script] = resolveScript(config, name)
33+
if (resolveError) return [resolveError, null]
34+
35+
return [null, script]
36+
```
37+
38+
## Error Type Pattern
39+
40+
```ts
41+
interface ConfigError {
42+
readonly type: 'invalid_toml' | 'missing_field' | 'unknown_workspace'
43+
readonly message: string
44+
}
45+
```
46+
47+
## Rules
48+
49+
- Never throw inside a function that returns `Result`
50+
- Always check the error element before accessing the value
51+
- Use `ts-pattern` `match` for exhaustive handling of multiple error variants
52+
- Map low-level errors (e.g., jose errors) to domain-specific error reasons

.claude/rules/testing.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
paths:
3+
- '**/*.test.ts'
4+
---
5+
6+
# Testing Rules
7+
8+
All tests use [Vitest](https://vitest.dev). Follow these conventions in every test file.
9+
10+
## Structure
11+
12+
- Place test files in `test/` directory within the package (e.g., `packages/js/test/verifier.test.ts`)
13+
- Name `describe` blocks after the module or function under test
14+
- Name test cases as `should + expected behavior`
15+
- One assertion focus per test case
16+
17+
```ts
18+
import { describe, it, expect } from 'vitest'
19+
20+
describe('resolveScript', () => {
21+
it('should resolve path relative to workspace root', () => {
22+
const result = resolveScriptPath('build', '/project')
23+
expect(result).toBe('/project/scripts/build.ts')
24+
})
25+
})
26+
```
27+
28+
## Mocking
29+
30+
- Use `vi.mock` for module-level mocks and `vi.fn` for individual functions
31+
- Mock all external I/O (file system, network, timers)
32+
- Reset mocks in `beforeEach` with `vi.clearAllMocks()`
33+
- Use `vi.mocked()` for type-safe mock access
34+
35+
## Organization
36+
37+
- Group related tests with nested `describe` blocks
38+
- Use `beforeEach` for shared setup, never shared mutable state across tests
39+
- Delete or fix skipped tests — never leave `it.skip` without a reason
40+
41+
## Error Testing
42+
43+
- Test Result tuples by destructuring `[error, value]`
44+
- Assert the error element before accessing the value
45+
- Use `toMatchObject` for partial matching on error shapes
46+
47+
```ts
48+
it('should return error result for missing config', async () => {
49+
const [error] = await loadConfig('/missing')
50+
expect(error).toMatchObject({ type: 'parse_error' })
51+
})
52+
```
53+
54+
## Coverage Targets
55+
56+
| Area | Minimum |
57+
|---|---|
58+
| Critical paths (config, auth) | 100% |
59+
| Business logic | 80% |
60+
| Utilities | 70% |
61+
62+
## Anti-patterns
63+
64+
- Do not test implementation details — test behavior and outcomes
65+
- Do not test framework code — trust dependencies
66+
- Do not use shared mutable state between tests
67+
- Do not create large monolithic test files — split by feature

.claude/rules/typescript.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
paths:
3+
- 'packages/**/*.ts'
4+
---
5+
6+
# TypeScript Rules
7+
8+
These rules are enforced by OXLint (`.oxlintrc.json`) and must be followed in all code under `packages/`:
9+
10+
## Functional programming
11+
12+
- **No `let`** — use `const` only. No reassignment, no mutation.
13+
- **No loops** (`for`, `while`, `do...while`, `for...in`, `for...of`) — use `map`, `filter`, `reduce`, `flatMap`, etc. Prefer `es-toolkit` utilities.
14+
- **No classes** — use plain objects, closures, and factory functions.
15+
- **No `this`** — never reference `this`.
16+
- **No `throw`** — no throw statements or throw expressions. Return errors as values.
17+
- **No IIFEs** — no immediately invoked function expressions. Extract into a named function and call it.
18+
- **No expression statements** — every expression must be used (assigned, returned, or passed). Config files (`.config.ts`) are exempt.
19+
- **Immutable data** — no mutating objects or arrays after creation. Config files are exempt.
20+
- **Prefer tacit (point-free)** — e.g. `arr.filter(isEven)` not `arr.filter((x) => isEven(x))`.
21+
- **Functional parameters** — functions must declare explicit parameters (no `arguments`, no rest-only patterns).
22+
23+
## TypeScript strictness
24+
25+
- **No `any`** — use `unknown`, generics, or proper types.
26+
- **No non-null assertions** (`!`) — use explicit null checks.
27+
- **No optional chaining** (`?.`) — use explicit `if`/`else` or pattern matching.
28+
- **No ternaries** — use `if`/`else` or `match` expressions.
29+
- **ESM only** with `verbatimModuleSyntax` — use `import type` for type-only imports.
30+
31+
## General
32+
33+
- **No `eval`**, `new Function()`, or implied eval.
34+
- **No `var`** — use `const`.
35+
- **No param reassignment** — parameters are immutable.
36+
- **No bitwise operators**, `++`/`--`, `void`, `with`, `continue`, or multi-assign.
37+
- **No circular imports**, self-imports, or duplicate imports.
38+
- **Prefer `node:` protocol** for Node.js builtins (e.g. `import fs from 'node:fs'`).
39+
- **Use `es-toolkit`** over hand-rolling utility functions.
40+
41+
## File structure
42+
43+
Every source file follows this order:
44+
1. **Imports** — node builtins, blank line, external packages, blank line, internal (farthest-to-closest, alphabetical). Top-level `import type`, no inline type specifiers.
45+
2. **Module-level constants**
46+
3. **Exported functions** — public API first, each with full JSDoc
47+
4. **Section separator** (`// ---------------------------------------------------------------------------`)
48+
5. **Private helpers** — non-exported functions, each with JSDoc including `@private`
49+
50+
## Exports
51+
52+
- **Inline exports only** — use `export` directly on declarations (`export function`, `export interface`, `export const`). Never batch-export local declarations with `export { foo, bar }`.
53+
- **Re-exports allowed** — barrel/index files may use `export { foo } from './bar.js'` and `export type { Baz } from './baz.js'`.
54+
55+
## JSDoc
56+
57+
- **All functions** require JSDoc — exported and non-exported.
58+
- **Non-exported functions** must include the `@private` tag.
59+
- **Test files** are exempt.
60+
61+
## Formatting (OXFmt)
62+
63+
- 100-char line width, 2-space indent, semicolons, single quotes, trailing commas
64+
- Import sorting: builtin > external > internal > parent/sibling/index

.github/workflows/ci.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
ci:
13+
name: CI
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout Repo
17+
uses: actions/checkout@v4
18+
19+
- name: Setup pnpm
20+
uses: pnpm/action-setup@v4
21+
22+
- name: Setup Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: 22
26+
cache: 'pnpm'
27+
28+
- name: Install Dependencies
29+
run: pnpm install --frozen-lockfile
30+
31+
- name: Lint
32+
run: pnpm lint
33+
34+
- name: Typecheck
35+
run: pnpm typecheck
36+
37+
- name: Test
38+
run: pnpm test
39+
40+
- name: Build
41+
run: pnpm build

.github/workflows/release.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
concurrency: ${{ github.workflow }}-${{ github.ref }}
9+
10+
jobs:
11+
release:
12+
name: Release
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout Repo
16+
uses: actions/checkout@v4
17+
18+
- name: Setup pnpm
19+
uses: pnpm/action-setup@v4
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 22
25+
cache: 'pnpm'
26+
27+
- name: Install Dependencies
28+
run: pnpm install --frozen-lockfile
29+
30+
- name: Build
31+
run: pnpm build
32+
33+
- name: Create Release Pull Request or Publish
34+
id: changesets
35+
uses: changesets/action@v1
36+
with:
37+
publish: pnpm release
38+
version: pnpm version
39+
env:
40+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

0 commit comments

Comments
 (0)