Canonical repository for agent skills, scripts, and shared instructions. This is the source of truth for coding standards.
# Setup
bun install # Install dependencies
# Verification (run before completing work)
bun run check # Lint with ultracite (type-aware)
bun run check-types # Typecheck with tsgo (native TS)
bun run test:unit # Run all unit tests
# Fixing
bun run fix # Auto-fix lint/format issues
# Running scripts
bun scripts/<file>.ts # Run utility scripts
# Single test file
bun run test:unit <path> # Run a single test fileknowledge-base/
├── skills/ # Skill definitions (source of truth)
│ └── <skill>/SKILL.md # Skill instructions + optional refs/scripts
├── .claude/skills/ # Symlinks to skills/ (activates them)
├── scripts/ # Utility scripts (run from repo root)
├── AGENTS.md # Shared agent instructions
└── CLAUDE.md -> AGENTS.md # Symlink for Claude Code
Skills in skills/<name>/SKILL.md are templates. Symlink to activate:
ln -s ../../skills/<skill> .claude/skills/<skill>- Line width: 80 characters
- Indent: 2 spaces (no tabs)
- Quotes: Double quotes (
") - Semicolons: Always
- Trailing commas: ES5 style
- Bracket spacing: Yes (
{ foo }) - Arrow parens: Always (
(x) => x)
- Sorted alphabetically, case-insensitive
- Newlines between import groups
- Use named imports, avoid namespace imports (
import * as) - Avoid barrel files (index re-exports)
import { Args, Command, Options } from "@effect/cli";
import { BunContext, BunRuntime } from "@effect/platform-bun";
import * as FileSystem from "@effect/platform/FileSystem";
import { Array as Arr, Effect, Option } from "effect";
import { formatOutput, parseRepoParts } from "./utils";- Strict mode enabled: All strict flags on
- No
any: Useunknownwhen type is genuinely unknown - No type assertions: Prefer type narrowing over
as - No suppression comments: Never use
@ts-ignore,@ts-expect-error - Readonly by default: Use
readonlyfor object properties - Explicit return types: Optional but encouraged for public APIs
// Types as documentation - make invalid states unrepresentable
export type RepoParts = {
readonly org: string;
readonly repo: string;
};
// Use const assertions for literals
const config = { mode: "production" } as const;- Functions/variables: camelCase
- Types/Classes: PascalCase
- Constants: camelCase (not SCREAMING_CASE)
- Files: kebab-case for scripts, camelCase for modules
In Effect code: Always use Data.TaggedError:
class NotFoundError extends Data.TaggedError("NotFoundError")<{
readonly id: string;
}> {}
// Use with Effect.fail
Effect.fail(new NotFoundError({ id: "123" }));
// Handle with catchTag
Effect.catchTag("NotFoundError", (e) => Effect.succeed(null));In plain TypeScript: Throw Error objects with descriptive messages.
- Functional: Prefer pure functions, avoid mutation
- Small: No god functions, single responsibility
- Arrow functions: For callbacks and short functions
- Early returns: Reduce nesting with guard clauses
// Pure, small, focused
export const stripGitSuffix = (value: string): string =>
value.endsWith(".git") ? value.slice(0, -4) : value;
// Early return pattern
export const parseRepoParts = (raw: string): Option.Option<RepoParts> => {
const segments = extractPath(raw).split("/").filter(Boolean);
if (segments.length < 2) return Option.none();
// ...
};- File naming:
*.test.tsadjacent to source - Structure:
describefor grouping,itfor cases - No
.only/.skipin committed code - Async: Use async/await, not done callbacks
import { describe, expect, it } from "vitest";
import { stripGitSuffix } from "./utils";
describe("stripGitSuffix", () => {
it("removes .git suffix", () => {
expect(stripGitSuffix("repo.git")).toBe("repo");
});
it("leaves strings without .git unchanged", () => {
expect(stripGitSuffix("repo")).toBe("repo");
});
});- Functional > imperative: Avoid mutation, prefer pure functions
- Types as documentation: Make invalid states unrepresentable
- Modular: Reusable, focused functions with injected deps
- Verifiable: Lint, typecheck, test. CI must pass.
- Effect-TS: Use for services, typed errors, and composition
Use Conventional Commits: type(scope): description
| Type | When |
|---|---|
feat |
New functionality |
fix |
Bug fix |
refactor |
Restructure without behavior change |
docs |
Documentation only |
test |
Adding/updating tests |
chore |
Maintenance (deps, config) |
Rules:
- Lowercase type and description
- No period at end
- Imperative mood ("add" not "added")
- No AI disclaimers or co-author tags
feat: add user authentication
fix(api): handle null response
refactor: extract validation module
Before implementing Effect features, consult effect-solutions list.
Effect Source Reference: ~/.local/share/effect-solutions/effect
Core patterns:
- TaggedError: Always use for typed errors
- Services: Use
Context.Tagfor dependency injection - Layers: Compose services with
Layer.succeed,Layer.effect - Pipes: Use
pipefor composition
import { Context, Effect, Layer, Data } from "effect";
// Service definition
class Database extends Context.Tag("Database")<
Database,
{ readonly query: (sql: string) => Effect.Effect<unknown[]> }
>() {}
// Layer implementation
const DatabaseLive = Layer.succeed(Database, {
query: (sql) => Effect.succeed([]),
});
// Typed error
class DbError extends Data.TaggedError("DbError")<{
readonly message: string;
}> {}Lefthook runs bun fix on staged files before commit. Files are auto-formatted and re-staged.
On push/PR to main:
- Install deps (
bun install --frozen-lockfile) - Lint (
bun run check) - Typecheck (
bun run check-types) - Test (
bun run test:unit)
All checks must pass before work is considered complete.
Source code for dependencies is available in opensrc/ for deeper understanding of implementation details.
See opensrc/sources.json for the list of available packages and their versions.
Use this source code when you need to understand how a package works internally, not just its types/interface.
To fetch source code for a package or repository you need to understand, run:
npx opensrc <package> # npm package (e.g., npx opensrc zod)
npx opensrc pypi:<package> # Python package (e.g., npx opensrc pypi:requests)
npx opensrc crates:<package> # Rust crate (e.g., npx opensrc crates:serde)
npx opensrc <owner>/<repo> # GitHub repo (e.g., npx opensrc vercel/ai)