From 62abf246ebe5ff16402560d907c1108fc1aa8ebb Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Tue, 10 Mar 2026 13:49:27 +0000 Subject: [PATCH 1/6] fix: fix @tanstack/intent skill discovery and consolidate skills The intent walker only recurses into directories that contain a SKILL.md. The skills/agentcrumbs/ namespace directory had no SKILL.md, so consumers saw 0 skills after installing. - Add top-level agentcrumbs SKILL.md covering workflow, core API, markers, CLI reference, and pointers to further discovery - Remove granular sub-skills (core, cli, scopes, sessions, testing) - Keep agentcrumbs/init as a separate action skill - Add prepublishOnly validation via @tanstack/intent validate - Add CLAUDE.md with changeset and skill validation guidelines --- .changeset/fix-skill-discovery.md | 9 + CLAUDE.md | 15 ++ packages/agentcrumbs/package.json | 3 +- .../agentcrumbs/skills/agentcrumbs/SKILL.md | 113 ++++++++ .../skills/agentcrumbs/cli/SKILL.md | 253 ------------------ .../skills/agentcrumbs/core/SKILL.md | 166 ------------ .../skills/agentcrumbs/init/SKILL.md | 4 +- .../agentcrumbs/scopes-and-context/SKILL.md | 218 --------------- .../agentcrumbs/sessions-and-tags/SKILL.md | 217 --------------- .../skills/agentcrumbs/testing/SKILL.md | 252 ----------------- 10 files changed, 141 insertions(+), 1109 deletions(-) create mode 100644 .changeset/fix-skill-discovery.md create mode 100644 CLAUDE.md create mode 100644 packages/agentcrumbs/skills/agentcrumbs/SKILL.md delete mode 100644 packages/agentcrumbs/skills/agentcrumbs/cli/SKILL.md delete mode 100644 packages/agentcrumbs/skills/agentcrumbs/core/SKILL.md delete mode 100644 packages/agentcrumbs/skills/agentcrumbs/scopes-and-context/SKILL.md delete mode 100644 packages/agentcrumbs/skills/agentcrumbs/sessions-and-tags/SKILL.md delete mode 100644 packages/agentcrumbs/skills/agentcrumbs/testing/SKILL.md diff --git a/.changeset/fix-skill-discovery.md b/.changeset/fix-skill-discovery.md new file mode 100644 index 0000000..f796e3f --- /dev/null +++ b/.changeset/fix-skill-discovery.md @@ -0,0 +1,9 @@ +--- +"agentcrumbs": minor +--- + +Fix @tanstack/intent skill discovery and consolidate skills + +- Add parent SKILL.md at the namespace level so the intent walker can recurse into skill subdirectories +- Consolidate 6 granular skills into 2: a top-level usage skill and the init skill +- Top-level skill covers workflow, core API, markers, CLI reference, and pointers to further discovery diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2d0629e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,15 @@ +# CLAUDE.md + +## Changesets + +Never run `changeset version` — that happens in CI. Only add changeset files via `pnpm changeset` or by creating a markdown file in `.changeset/`. + +## Skills + +After modifying any `SKILL.md` files, validate before committing: + +```bash +cd packages/agentcrumbs && npx @tanstack/intent@latest validate +``` + +This also runs automatically via `prepublishOnly` in the package. diff --git a/packages/agentcrumbs/package.json b/packages/agentcrumbs/package.json index 352e123..9b8fe4f 100644 --- a/packages/agentcrumbs/package.json +++ b/packages/agentcrumbs/package.json @@ -43,7 +43,8 @@ "build": "tsc", "dev": "tsc --watch", "test": "vitest", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "prepublishOnly": "npx @tanstack/intent@latest validate" }, "devDependencies": { "@types/node": "^25.3.3", diff --git a/packages/agentcrumbs/skills/agentcrumbs/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/SKILL.md new file mode 100644 index 0000000..8b04a4e --- /dev/null +++ b/packages/agentcrumbs/skills/agentcrumbs/SKILL.md @@ -0,0 +1,113 @@ +--- +name: agentcrumbs +description: > + Debug mode for AI coding agents. Drop structured traces inline while writing + code, query them when something breaks, strip before merge. Covers the core + workflow: trail, crumb, markers, collector, query, strip. Activate when using + agentcrumbs, adding debug tracing, or when an agent needs to understand + runtime behavior. +type: core +library: agentcrumbs +library_version: "0.2.0" +sources: + - "triggerdotdev/trigger-labs:debug-mode/README.md" + - "triggerdotdev/trigger-labs:debug-mode/src/trail.ts" + - "triggerdotdev/trigger-labs:debug-mode/src/types.ts" +--- + +# agentcrumbs + +Structured debug traces that agents drop inline while writing code, then query when something breaks. Stripped before merge, zero cost when off. + +## Workflow + +``` +1. Write code + crumbs → crumb("user verified", { userId }); // @crumbs +2. Run with collector → agentcrumbs collect & AGENTCRUMBS=1 node app.js +3. Something breaks → agentcrumbs query --since 5m +4. Fix the bug → (read the trail, find the cause, fix it) +5. Strip before merge → agentcrumbs strip +``` + +## Core API + +```typescript +import { trail } from "agentcrumbs"; // @crumbs +const crumb = trail("my-service"); // @crumbs — create once at module level + +// Basic crumb +crumb("checkout started", { cartId: "c_91" }); // @crumbs + +// With tags (third arg) for filtering +crumb("cache miss", { key }, { tags: ["perf"] }); // @crumbs + +// Child context for per-request tracing +const reqCrumb = crumb.child({ requestId: req.id }); // @crumbs +reqCrumb("handling request", { path: req.url }); // @crumbs + +// Scoped operations with automatic enter/exit/error tracking +const user = await crumb.scope("validate-token", async (ctx) => { // @crumbs + ctx.crumb("checking jwt"); // @crumbs + return await verifyToken(token); // @crumbs +}); // @crumbs + +// Guard expensive args +if (crumb.enabled) { crumb("dump", { state: structuredClone(big) }); } // @crumbs +``` + +## Markers + +Every crumb line needs a marker so `agentcrumbs strip` can remove it before merge. + +```typescript +// Single-line marker +crumb("event", { data }); // @crumbs + +// Block marker for multi-line sections +// #region @crumbs +const result = await crumb.scope("operation", async (ctx) => { + ctx.crumb("step 1"); + ctx.crumb("step 2"); + return value; +}); +// #endregion @crumbs +``` + +**Unmarked crumbs will leak into production code.** The strip command only removes lines with `// @crumbs` or code inside `#region @crumbs` blocks. + +## CLI quick reference + +```bash +agentcrumbs collect # Start HTTP collector (required for query/tail) +agentcrumbs tail # Live tail (--ns, --tag, --match filters) +agentcrumbs query --since 5m # Query history (--ns, --tag, --session, --json) +agentcrumbs strip # Remove all crumb markers from source +agentcrumbs strip --check # CI gate — exits 1 if markers found +agentcrumbs --help # Full command reference +``` + +Run `agentcrumbs --help` for detailed options on any command. + +## Enable tracing + +```bash +AGENTCRUMBS=1 node app.js # Enable all namespaces +AGENTCRUMBS='{"ns":"auth-*"}' node app.js # Filter by namespace +``` + +When `AGENTCRUMBS` is not set, `trail()` returns a frozen noop. No conditionals, no overhead. + +## Critical mistakes + +1. **Missing markers** — Every crumb line needs `// @crumbs` or a `#region @crumbs` block. Without them, `strip` can't clean up. +2. **Creating trail() in hot paths** — `trail()` parses the env var each call. Create once at module scope, use `child()` for per-request context. +3. **No collector running** — Without `agentcrumbs collect`, crumbs go to stderr only and can't be queried. Start the collector before reproducing issues. + +## Further discovery + +- **CLI details**: `agentcrumbs --help` and `agentcrumbs --help` +- **TypeScript types**: Check the type definitions in `node_modules/agentcrumbs/dist/index.d.ts` +- **Docs**: https://agentcrumbs.dev/docs +- **Sessions and tags**: `crumb.session()` for grouping, `{ tags: [...] }` as third arg for filtering +- **Testing**: `import { MemorySink, addSink } from "agentcrumbs"` to capture crumbs in tests +- **Scopes**: `crumb.scope()`, `crumb.wrap()`, `crumb.snapshot()`, `crumb.assert()` for structured tracing diff --git a/packages/agentcrumbs/skills/agentcrumbs/cli/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/cli/SKILL.md deleted file mode 100644 index e8230dc..0000000 --- a/packages/agentcrumbs/skills/agentcrumbs/cli/SKILL.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -name: agentcrumbs/cli -description: > - agentcrumbs CLI commands: collect, tail, query, follow, session, sessions, - replay, strip, stats, clear. HTTP collector, JSONL storage, live - tailing with namespace/tag/match/session filters, historical queries, - trace following, stripping @crumbs markers from source before merge. - Activate when running agentcrumbs CLI commands, setting up the collector, - tailing debug output, querying crumb history, or removing crumb code. -type: sub-skill -library: agentcrumbs -library_version: "0.1.0" -requires: - - agentcrumbs/core -sources: - - "triggerdotdev/trigger-labs:debug-mode/src/cli/index.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/cli/commands/*.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/collector/server.ts" - - "triggerdotdev/trigger-labs:debug-mode/README.md" ---- - -# agentcrumbs — CLI - -This skill builds on agentcrumbs/core. Read it first for foundational concepts. - -## Architecture - -``` -Services (with AGENTCRUMBS set) - └──> fetch() POST to http://localhost:8374/crumb - └──> agentcrumbs collect - └──> ~/.agentcrumbs/crumbs.jsonl - └──> agentcrumbs tail / query / replay -``` - -## Start the Collector - -The collector is an HTTP server. Without it running, crumbs fall back to -stderr only and can't be queried later. - -**When you want to debug code with crumbs, start the collector yourself.** -Run it in the background before launching the service under test, then -query or tail after reproducing the issue. Stop it when you're done. - -```bash -# Start collector, clear old crumbs, reproduce, query -agentcrumbs collect --quiet & -agentcrumbs clear -AGENTCRUMBS=1 node app.js -agentcrumbs query -``` - -Clear before reproducing so you only see crumbs from this run. -No `--since` needed when you clear first. - -```bash -agentcrumbs collect -# agentcrumbs collector -# http: http://localhost:8374/crumb -# store: ~/.agentcrumbs/crumbs.jsonl - -# Custom port and storage -agentcrumbs collect --port 9999 --dir /var/log/crumbs - -# Quiet mode (collect without printing to stdout) -agentcrumbs collect --quiet -``` - -Crumbs can also be sent from anywhere with a raw fetch — no library import needed: - -```javascript -fetch("http://localhost:8374/crumb", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ts: new Date().toISOString(), ns: "my-ns", msg: "hello", type: "crumb", dt: 0, pid: process.pid }) }).catch(() => {}); -``` - -## Live Tail - -```bash -# All crumbs -agentcrumbs tail - -# Filter by namespace (supports wildcards) -agentcrumbs tail --ns auth-service -agentcrumbs tail --ns "auth-*" - -# Filter by tag -agentcrumbs tail --tag perf - -# Filter by text content (searches full JSON) -agentcrumbs tail --match "userId:123" - -# Filter by session -agentcrumbs tail --session a1b2c3 - -# JSON output for piping -agentcrumbs tail --json | jq '.data' -``` - -Filters can be combined: - -```bash -agentcrumbs tail --ns auth-service --tag retry --json -``` - -## Query History - -```bash -# Time-based queries -agentcrumbs query --since 5m -agentcrumbs query --since 1h -agentcrumbs query --since 24h -agentcrumbs query --since 7d - -# Combined filters -agentcrumbs query --since 1h --ns auth-service --tag root-cause - -# Session queries -agentcrumbs query --session a1b2c3 - -# Text search -agentcrumbs query --since 1h --match "connection refused" - -# Limit results -agentcrumbs query --since 24h --limit 50 - -# JSON output -agentcrumbs query --since 5m --json -``` - -Time units: `s` (seconds), `m` (minutes), `h` (hours), `d` (days). - -## Trace Following - -Follow all crumbs that share a traceId (generated by `scope()`): - -```bash -agentcrumbs follow --trace a1b2c3 -agentcrumbs follow --trace a1b2c3 --json -``` - -## Session Management - -```bash -agentcrumbs session start "debugging-auth" -agentcrumbs session stop -agentcrumbs sessions -agentcrumbs replay a1b2c3 -agentcrumbs replay a1b2c3 --json -``` - -## Strip Crumb Code - -Remove all `// @crumbs` lines and `#region @crumbs` blocks from source files. Run before merging PRs. - -```bash -# Remove all crumb markers from source files -agentcrumbs strip - -# Preview what would be removed without changing files -agentcrumbs strip --dry-run - -# CI gate — exits 1 if any markers found -agentcrumbs strip --check - -# Custom directory and file extensions -agentcrumbs strip --dir src/ --ext ts,tsx,js -``` - -Default scans `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.mts`. Skips `node_modules`, `dist`, `.git`. - -## Other Commands - -```bash -agentcrumbs stats # Service list, crumb counts, file size -agentcrumbs clear # Delete all stored crumbs -agentcrumbs --help # Full help text -``` - -## Multi-Service Setup - -```bash -# Terminal 1 -agentcrumbs collect - -# Terminal 2 -AGENTCRUMBS=1 node auth-service.js & -AGENTCRUMBS=1 node api-gateway.js & -AGENTCRUMBS=1 node worker.js & - -# Terminal 3 -agentcrumbs tail -``` - -All services write to the same collector. Output is interleaved with color-coded namespace labels. - -## Common Mistakes - -### HIGH: Running services without starting the collector first - -Wrong: - -```bash -AGENTCRUMBS=1 node app.js -# Crumbs go to stderr only — not stored, not queryable -``` - -Correct: - -```bash -agentcrumbs collect & # Start collector first -AGENTCRUMBS=1 node app.js -agentcrumbs tail # Now you can tail and query -``` - -Without the collector running, the library falls back to stderr output. Crumbs won't be stored in the JSONL file, so `tail`, `query`, and `replay` won't find them. - -### HIGH: Using wrong time format in --since - -Wrong: - -```bash -agentcrumbs query --since 5min -agentcrumbs query --since "5 minutes" -agentcrumbs query --since 300 -``` - -Correct: - -```bash -agentcrumbs query --since 5m -agentcrumbs query --since 1h -agentcrumbs query --since 30s -agentcrumbs query --since 7d -``` - -Time values use a number followed by a single letter: `s`, `m`, `h`, or `d`. No spaces, no spelled-out units, no bare numbers. - -### MEDIUM: Expecting tail to show historical crumbs from before it started - -Wrong: - -```bash -# Service ran 10 minutes ago -agentcrumbs tail # expects to see old crumbs -``` - -Correct: - -```bash -agentcrumbs query --since 10m # query for historical crumbs -agentcrumbs tail # then tail for new crumbs -``` - -`tail` shows the last 50 crumbs from the file then watches for new ones. For comprehensive historical search, use `query` with `--since`. diff --git a/packages/agentcrumbs/skills/agentcrumbs/core/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/core/SKILL.md deleted file mode 100644 index 168b840..0000000 --- a/packages/agentcrumbs/skills/agentcrumbs/core/SKILL.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -name: agentcrumbs/core -description: > - Core debug tracing with agentcrumbs: trail(), crumb(), @crumbs markers, - #region @crumbs blocks, agentcrumbs strip, env var config, noop strategy, - structured data, child context, AGENTCRUMBS environment variable, - namespace filtering, zero-overhead disabled instrumentation. Activate - when importing agentcrumbs, setting up debug tracing, creating trail - functions, adding crumb markers, or stripping crumbs before merge. -type: core -library: agentcrumbs -library_version: "0.1.0" -sources: - - "triggerdotdev/trigger-labs:debug-mode/src/trail.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/env.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/noop.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/types.ts" - - "triggerdotdev/trigger-labs:debug-mode/README.md" ---- - -# agentcrumbs — Core Patterns - -Setup: `import { trail } from "agentcrumbs"; // @crumbs` then `const crumb = trail("ns"); // @crumbs` - -Markers: single-line `// @crumbs` | block `// #region @crumbs` ... `// #endregion @crumbs` - -## Patterns - -```typescript -crumb("token validated", { userId: "u_123", expiresIn: 3600 }); // @crumbs -crumb("cache miss", { key }, { tags: ["perf", "cache"] }); // @crumbs -const reqCrumb = crumb.child({ requestId: req.id }); // @crumbs — inherited context -crumb.time("op"); /* ... */ crumb.timeEnd("op", { rows }); // @crumbs — timing -if (crumb.enabled) { crumb("dump", { state: structuredClone(big) }); } // @crumbs — guard expensive args -``` - -## Noop Guarantee - -When disabled, `trail()` returns a frozen noop. No per-call check. `crumb.child()` returns same noop. `crumb.scope("op", fn)` calls `fn()` directly. `crumb.wrap("name", fn)` returns original `fn`. - -## Common Mistakes - -### CRITICAL: Checking enabled on every call instead of using the noop - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("my-service"); - -function handleRequest(req: Request) { - if (process.env.AGENTCRUMBS) { - crumb("handling request", { path: req.url }); - } -} -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("my-service"); - -function handleRequest(req: Request) { - crumb("handling request", { path: req.url }); -} -``` - -The `trail()` function already returns a noop when disabled. Adding manual checks defeats the zero-overhead design and adds unnecessary conditionals to every call site. - -### HIGH: Creating trail inside hot loops or request handlers - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -function handleRequest(req: Request) { - const crumb = trail("api"); // new trail on every request - crumb("handling", { path: req.url }); -} -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("api"); // created once at module level - -function handleRequest(req: Request) { - const reqCrumb = crumb.child({ requestId: req.id }); - reqCrumb("handling", { path: req.url }); -} -``` - -`trail()` reads and parses the env var on each call. Create it once at module scope and use `child()` for per-request context. - -### HIGH: Passing expensive arguments without checking enabled - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("processor"); - -// structuredClone runs even when disabled -crumb("state snapshot", { state: structuredClone(hugeObject) }); -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("processor"); - -if (crumb.enabled) { - crumb("state snapshot", { state: structuredClone(hugeObject) }); -} -``` - -JavaScript evaluates all arguments before calling the function. For cheap data like `{ userId }`, this is negligible. For expensive operations like `structuredClone` or `JSON.stringify` on large objects, guard with `crumb.enabled`. - -### HIGH: Adding crumbs without markers - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; -const crumb = trail("service"); - -crumb("debugging this issue", { data }); -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; // @crumbs -const crumb = trail("service"); // @crumbs - -crumb("debugging this issue", { data }); // @crumbs -``` - -Every crumb line needs a `// @crumbs` marker (or be inside a `#region @crumbs` block). Without markers, `agentcrumbs strip` can't find and remove the code before merge. Unmarked crumbs will leak into production code. - -### MEDIUM: Using wrong env var name - -Wrong: - -```bash -DEBUG=* node app.js -CRUMBS=1 node app.js -``` - -Correct: - -```bash -AGENTCRUMBS=1 node app.js -AGENTCRUMBS='{"ns":"*"}' node app.js -``` - -The env var is `AGENTCRUMBS`, not `DEBUG` or `CRUMBS`. The JSON config uses `ns` for namespace filter, not `namespace` or `debug`. diff --git a/packages/agentcrumbs/skills/agentcrumbs/init/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/init/SKILL.md index 32e394a..5aa1c04 100644 --- a/packages/agentcrumbs/skills/agentcrumbs/init/SKILL.md +++ b/packages/agentcrumbs/skills/agentcrumbs/init/SKILL.md @@ -9,9 +9,9 @@ description: > catalog in its agent config files. type: lifecycle library: agentcrumbs -library_version: "0.1.0" +library_version: "0.2.0" requires: - - agentcrumbs/core + - agentcrumbs sources: - "triggerdotdev/trigger-labs:debug-mode/README.md" - "triggerdotdev/trigger-labs:debug-mode/src/types.ts" diff --git a/packages/agentcrumbs/skills/agentcrumbs/scopes-and-context/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/scopes-and-context/SKILL.md deleted file mode 100644 index b8d348a..0000000 --- a/packages/agentcrumbs/skills/agentcrumbs/scopes-and-context/SKILL.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -name: agentcrumbs/scopes-and-context -description: > - Scoped operations, async context propagation, function wrapping, nested - scopes, traceId tracking, depth indentation, scope enter/exit/error, - snapshot, assert, wrap. Activate when using crumb.scope(), crumb.wrap(), - crumb.snapshot(), crumb.assert(), or when debugging async execution - flow across function boundaries. -type: sub-skill -library: agentcrumbs -library_version: "0.1.0" -requires: - - agentcrumbs/core -sources: - - "triggerdotdev/trigger-labs:debug-mode/src/trail.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/context.ts" - - "triggerdotdev/trigger-labs:debug-mode/README.md" ---- - -# agentcrumbs — Scopes and Context - -This skill builds on agentcrumbs/core. Read it first for foundational concepts. - -## Core Patterns - -### Wrap operations with automatic enter/exit/error tracking - -```typescript -import { trail } from "agentcrumbs"; // @crumbs -const crumb = trail("auth-service"); // @crumbs - -// #region @crumbs -const user = await crumb.scope("validate-token", async (ctx) => { - ctx.crumb("checking jwt", { tokenPrefix: token.slice(0, 8) }); - const result = await verifyToken(token); - ctx.crumb("token valid", { userId: result.id }); - return result; -}); -// #endregion @crumbs -// Emits: scope:enter -> crumb -> crumb -> scope:exit (with duration) -// If verifyToken throws: scope:enter -> crumb -> scope:error (with error details) -``` - -The scope callback receives `ctx` with `ctx.crumb` (a child trail) and `ctx.traceId` (unique ID for this scope). The return value passes through. - -### Nest scopes for hierarchical tracing - -```typescript -import { trail } from "agentcrumbs"; // @crumbs -const crumb = trail("order-service"); // @crumbs - -// #region @crumbs -await crumb.scope("process-order", async (ctx) => { - ctx.crumb("validating items", { count: order.items.length }); - - await ctx.crumb.scope("charge-payment", async (inner) => { - inner.crumb("calling payment API"); - await chargeCard(order.payment); - inner.crumb("payment confirmed"); - }); - - ctx.crumb("sending confirmation email"); -}); -// #endregion @crumbs -``` - -Output shows indented depth: - -``` -order-service [process-order] -> enter +0ms -order-service validating items +1ms -order-service [charge-payment] -> enter +0ms -order-service calling payment API +0ms -order-service payment confirmed +15ms -order-service [charge-payment] <- exit +15ms -order-service sending confirmation email +0ms -order-service [process-order] <- exit +16ms -``` - -### Wrap existing functions with scope tracking - -```typescript -import { trail } from "agentcrumbs"; // @crumbs -const crumb = trail("api"); // @crumbs - -const trackedFetch = crumb.wrap("fetch", fetch); // @crumbs -const response = await trackedFetch("https://api.example.com/users"); -// Automatically emits scope:enter and scope:exit with duration -``` - -### Capture state snapshots and debug assertions - -```typescript -import { trail } from "agentcrumbs"; // @crumbs -const crumb = trail("processor"); // @crumbs - -// #region @crumbs -crumb.snapshot("state-before", complexObject); -// #endregion @crumbs -mutate(complexObject); -// #region @crumbs -crumb.snapshot("state-after", complexObject); -crumb.assert(user != null, "user should exist after auth"); -crumb.assert(items.length > 0, "cart should not be empty at checkout"); -// #endregion @crumbs -``` - -## Context Propagation - -Scopes use `AsyncLocalStorage` internally. Context (traceId, depth, session) propagates automatically through async boundaries — no manual threading required. - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -await crumb.scope("request", async (ctx) => { - // traceId propagates into nested async calls - await processItems(ctx.crumb); -}); - -async function processItems(crumb: TrailFunction) { - // This scope inherits the parent's traceId and depth - await crumb.scope("process-batch", async (ctx) => { - ctx.crumb("processing"); - }); -} -``` - -## Common Mistakes - -### HIGH: Ignoring the scope return value - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -crumb.scope("fetch-user", async (ctx) => { - const user = await getUser(id); - ctx.crumb("got user", { userId: user.id }); - return user; -}); -// user is lost — scope returns a Promise that is not awaited -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -const user = await crumb.scope("fetch-user", async (ctx) => { - const user = await getUser(id); - ctx.crumb("got user", { userId: user.id }); - return user; -}); -``` - -`scope()` returns the callback's return value (or a Promise wrapping it for async callbacks). Forgetting to capture or await it loses the result. - -### HIGH: Using the parent crumb inside a scope instead of ctx.crumb - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -crumb.scope("operation", (ctx) => { - crumb("inside scope"); // uses parent, not scoped crumb -}); -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -crumb.scope("operation", (ctx) => { - ctx.crumb("inside scope"); // uses scoped crumb with correct depth/traceId -}); -``` - -Using the parent `crumb` instead of `ctx.crumb` inside a scope bypasses depth tracking and traceId propagation. The crumb will appear at the wrong indentation level and won't be linked to the scope's trace. - -### MEDIUM: Wrapping functions that return non-Promise thenables - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -// Custom thenable objects are detected as Promises -const wrapped = crumb.wrap("customAsync", myCustomThenable); -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -const wrapped = crumb.wrap("customAsync", (...args) => { - return Promise.resolve(myCustomThenable(...args)); -}); -``` - -`scope()` uses `instanceof Promise` to detect async results. Custom thenables that are not actual Promise instances will have their scope exit emitted synchronously before the operation completes. Wrap them in `Promise.resolve()` if you need proper async scope tracking. diff --git a/packages/agentcrumbs/skills/agentcrumbs/sessions-and-tags/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/sessions-and-tags/SKILL.md deleted file mode 100644 index 9fb29d5..0000000 --- a/packages/agentcrumbs/skills/agentcrumbs/sessions-and-tags/SKILL.md +++ /dev/null @@ -1,217 +0,0 @@ ---- -name: agentcrumbs/sessions-and-tags -description: > - Session management and tag-based filtering in agentcrumbs. crumb.session(), - session.crumb(), session.end(), tags option, CLI session start/stop, - sid field, session replay, tag filtering. Activate when grouping crumbs - into debug sessions, tagging crumbs for later filtering, using the - agentcrumbs session CLI, or replaying captured sessions. -type: sub-skill -library: agentcrumbs -library_version: "0.1.0" -requires: - - agentcrumbs/core -sources: - - "triggerdotdev/trigger-labs:debug-mode/src/trail.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/cli/commands/session.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/cli/commands/sessions.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/cli/commands/replay.ts" - - "triggerdotdev/trigger-labs:debug-mode/README.md" ---- - -# agentcrumbs — Sessions and Tags - -This skill builds on agentcrumbs/core. Read it first for foundational concepts. - -## Tags - -Tags are string labels attached to crumbs for filtering. Pass them as the third argument. - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("auth-service"); - -crumb("token expired", { userId: "u_123" }, { tags: ["auth-failure", "retry"] }); -crumb("cache miss", { key: "sessions:abc" }, { tags: ["perf", "cache"] }); -crumb("rate limited", { ip: "1.2.3.4" }, { tags: ["security", "rate-limit"] }); -``` - -Query by tag with the CLI: - -```bash -agentcrumbs query --tag auth-failure --since 10m -agentcrumbs tail --tag perf -agentcrumbs tail --ns auth-service --tag retry -``` - -Tags are omitted from the JSONL output when the array is empty (no wasted bytes). - -## Sessions — Programmatic - -Group crumbs into logical units with a unique session ID and start/end boundaries. - -### Manual session lifecycle - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("debugger"); - -const session = crumb.session("investigating-timeout"); -session.crumb("checking connection pool", { active: 5, idle: 0 }); -session.crumb("found stale connection", { age: "45s" }, { tags: ["root-cause"] }); -session.end(); - -// Query later: -// agentcrumbs query --session --tag root-cause -``` - -### Scoped session (auto-ends) - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("signup-flow"); - -await crumb.session("user-signup", async (s) => { - s.crumb("validating email", { email }); - await validateEmail(email); - s.crumb("creating account"); - const user = await createUser({ email }); - s.crumb("account created", { userId: user.id }); -}); -// session:end emitted automatically when the function returns -``` - -## Sessions — CLI - -Start and stop sessions from the terminal. All running services automatically tag crumbs with the active session ID. - -```bash -# Start a session -agentcrumbs session start "debugging-auth-timeout" -# Session started: a1b2c3 (debugging-auth-timeout) - -# ... reproduce the issue across any number of services ... - -# Stop the session -agentcrumbs session stop -# Session stopped: a1b2c3 (debugging-auth-timeout) - 2m 15s -``` - -How it works: the CLI writes the session ID to `/tmp/agentcrumbs.session`. Library instances read this file and attach the session ID to outgoing crumbs. No code changes needed. - -```bash -# List sessions -agentcrumbs sessions - -# Replay a session -agentcrumbs replay a1b2c3 -agentcrumbs replay a1b2c3 --json - -# Query within a session -agentcrumbs query --session a1b2c3 -agentcrumbs query --session a1b2c3 --tag root-cause -``` - -## Common Mistakes - -### HIGH: Forgetting to call session.end() on manual sessions - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -function debugIssue() { - const session = crumb.session("debug-flow"); - session.crumb("step 1"); - session.crumb("step 2"); - // session never ended — no session:end crumb emitted -} -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -function debugIssue() { - const session = crumb.session("debug-flow"); - session.crumb("step 1"); - session.crumb("step 2"); - session.end(); -} - -// Or use the scoped form which auto-ends: -async function debugIssueScoped() { - await crumb.session("debug-flow", async (s) => { - s.crumb("step 1"); - s.crumb("step 2"); - }); -} -``` - -Without `session.end()`, the `session:end` crumb is never emitted. The session will show as status `?` in `agentcrumbs sessions` and duration calculations will be wrong. Use the scoped form to guarantee cleanup. - -### MEDIUM: Confusing CLI sessions with programmatic sessions - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -// Trying to start a CLI session from code -import { writeFileSync } from "fs"; -writeFileSync("/tmp/agentcrumbs.session", "my-session-id"); -``` - -Correct: - -```bash -# CLI sessions are managed by the CLI -agentcrumbs session start "my-session" -``` - -```typescript -// Programmatic sessions are managed by code -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); -const session = crumb.session("my-session"); -``` - -CLI sessions and programmatic sessions are separate mechanisms. CLI sessions write a structured JSON file to `/tmp/agentcrumbs.session` that all library instances read. Don't write to this file directly from code — use `crumb.session()` for programmatic sessions, and the CLI for cross-service debug sessions. - -### MEDIUM: Passing tags as the second argument - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -crumb("event", { tags: ["important"] }); -// tags are in data, not in the tags field -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("service"); - -crumb("event", { someData: 123 }, { tags: ["important"] }); -// data is the second arg, options (with tags) is the third -``` - -Tags go in the third argument (options object), not in the data object. Putting them in data means they'll appear in the `data` field of the crumb but won't be filterable with `--tag` in the CLI. diff --git a/packages/agentcrumbs/skills/agentcrumbs/testing/SKILL.md b/packages/agentcrumbs/skills/agentcrumbs/testing/SKILL.md deleted file mode 100644 index 9967d8d..0000000 --- a/packages/agentcrumbs/skills/agentcrumbs/testing/SKILL.md +++ /dev/null @@ -1,252 +0,0 @@ ---- -name: agentcrumbs/testing -description: > - Testing with agentcrumbs MemorySink, addSink, removeSink, capturing - crumbs in tests, asserting on debug output, waitFor async crumbs, - test setup and teardown patterns. Activate when writing tests that - verify debug tracing behavior, using MemorySink, or testing code - that uses agentcrumbs trail functions. -type: sub-skill -library: agentcrumbs -library_version: "0.1.0" -requires: - - agentcrumbs/core -sources: - - "triggerdotdev/trigger-labs:debug-mode/src/sinks/memory.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/trail.ts" - - "triggerdotdev/trigger-labs:debug-mode/src/__tests__/trail.test.ts" ---- - -# agentcrumbs — Testing - -This skill builds on agentcrumbs/core. Read it first for foundational concepts. - -## Setup - -Use `MemorySink` to capture crumbs in tests. Set `AGENTCRUMBS=1` in the test environment to enable tracing. - -```typescript -import { describe, it, expect, beforeEach } from "vitest"; -import { trail, addSink, MemorySink } from "agentcrumbs"; - -describe("my feature", () => { - let sink: MemorySink; - - beforeEach(() => { - process.env.AGENTCRUMBS = "1"; - sink = new MemorySink(); - addSink(sink); - }); - - it("emits expected crumbs", () => { - const crumb = trail("test"); - crumb("something happened", { key: "value" }); - - expect(sink.entries).toHaveLength(1); - expect(sink.entries[0].msg).toBe("something happened"); - expect(sink.entries[0].data).toEqual({ key: "value" }); - }); -}); -``` - -## MemorySink API - -```typescript -import { MemorySink } from "agentcrumbs"; - -const sink = new MemorySink(); - -// All captured crumbs -sink.entries; // Crumb[] - -// Find first matching crumb -sink.find(c => c.msg === "user logged in"); - -// Filter crumbs -sink.filter(c => c.type === "scope:enter"); -sink.filter(c => c.tags?.includes("perf")); - -// Wait for a crumb (async, with timeout) -const crumb = await sink.waitFor( - c => c.type === "scope:exit", - 5000 // timeout in ms, default 5000 -); - -// Clear all entries -sink.clear(); -``` - -## Core Patterns - -### Assert on scope behavior - -```typescript -import { trail, addSink, MemorySink } from "agentcrumbs"; - -it("wraps operations with scope tracking", async () => { - process.env.AGENTCRUMBS = "1"; - const sink = new MemorySink(); - addSink(sink); - - const crumb = trail("test"); - const result = await crumb.scope("fetch-user", async (ctx) => { - ctx.crumb("querying database"); - return { id: "123", name: "Alice" }; - }); - - expect(result).toEqual({ id: "123", name: "Alice" }); - - const enter = sink.find(c => c.type === "scope:enter" && c.msg === "fetch-user"); - const exit = sink.find(c => c.type === "scope:exit" && c.msg === "fetch-user"); - expect(enter).toBeDefined(); - expect(exit).toBeDefined(); - expect(exit!.data).toHaveProperty("duration"); -}); -``` - -### Assert on tags - -```typescript -import { trail, addSink, MemorySink } from "agentcrumbs"; - -it("tags crumbs correctly", () => { - process.env.AGENTCRUMBS = "1"; - const sink = new MemorySink(); - addSink(sink); - - const crumb = trail("test"); - crumb("cache miss", { key: "x" }, { tags: ["perf", "cache"] }); - - const tagged = sink.filter(c => c.tags?.includes("perf")); - expect(tagged).toHaveLength(1); - expect(tagged[0].tags).toEqual(["perf", "cache"]); -}); -``` - -### Test that noop mode produces no output - -```typescript -import { trail, addSink, MemorySink, NOOP } from "agentcrumbs"; - -it("returns NOOP when disabled", () => { - delete process.env.AGENTCRUMBS; - const sink = new MemorySink(); - addSink(sink); - - const crumb = trail("test"); - expect(crumb).toBe(NOOP); - expect(crumb.enabled).toBe(false); - - crumb("should not appear"); - expect(sink.entries).toHaveLength(0); -}); -``` - -## Common Mistakes - -### CRITICAL: Not setting AGENTCRUMBS in test environment - -Wrong: - -```typescript -import { trail, addSink, MemorySink } from "agentcrumbs"; - -it("captures crumbs", () => { - const sink = new MemorySink(); - addSink(sink); - - const crumb = trail("test"); - crumb("hello"); - expect(sink.entries).toHaveLength(1); // FAILS — crumb is NOOP -}); -``` - -Correct: - -```typescript -import { trail, addSink, MemorySink } from "agentcrumbs"; - -it("captures crumbs", () => { - process.env.AGENTCRUMBS = "1"; - const sink = new MemorySink(); - addSink(sink); - - const crumb = trail("test"); - crumb("hello"); - expect(sink.entries).toHaveLength(1); -}); -``` - -Without `AGENTCRUMBS` set, `trail()` returns the noop. The noop never calls any sink. Set the env var before creating the trail. - -### HIGH: Reusing a MemorySink across tests without clearing - -Wrong: - -```typescript -import { trail, addSink, MemorySink } from "agentcrumbs"; - -const sink = new MemorySink(); - -it("test 1", () => { - process.env.AGENTCRUMBS = "1"; - addSink(sink); - trail("test")("first"); - expect(sink.entries).toHaveLength(1); -}); - -it("test 2", () => { - trail("test")("second"); - expect(sink.entries).toHaveLength(1); // FAILS — has 2 entries from both tests -}); -``` - -Correct: - -```typescript -import { trail, addSink, MemorySink } from "agentcrumbs"; - -let sink: MemorySink; - -beforeEach(() => { - process.env.AGENTCRUMBS = "1"; - sink = new MemorySink(); - addSink(sink); -}); - -it("test 1", () => { - trail("test")("first"); - expect(sink.entries).toHaveLength(1); -}); -``` - -Create a fresh `MemorySink` in `beforeEach` or call `sink.clear()` between tests. Sinks accumulate entries across all crumbs sent to them. - -### MEDIUM: Creating trail before setting the env var - -Wrong: - -```typescript -import { trail } from "agentcrumbs"; - -const crumb = trail("test"); // created at module load — AGENTCRUMBS not set yet - -it("captures crumbs", () => { - process.env.AGENTCRUMBS = "1"; - crumb("hello"); // crumb is already NOOP -}); -``` - -Correct: - -```typescript -import { trail } from "agentcrumbs"; - -it("captures crumbs", () => { - process.env.AGENTCRUMBS = "1"; - const crumb = trail("test"); // created after env var is set - crumb("hello"); -}); -``` - -`trail()` checks the env var at creation time. If you create it at module scope before the test sets `AGENTCRUMBS`, you get a noop that can't be re-enabled. Create trails inside test functions after setting the env var. From c89ffbae5d4dea00abb1e9cc11c126b4bcb0f409 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Tue, 10 Mar 2026 13:53:48 +0000 Subject: [PATCH 2/6] docs: update READMEs, docs, and homepage for new skill structure Remove references to old granular skills (core, cli, scopes-and-context, sessions-and-tags, testing) and replace with the two-skill setup: agentcrumbs (top-level) and agentcrumbs/init. --- README.md | 5 +---- docs/content/docs/skills.mdx | 34 ++++++++++++---------------------- docs/src/app/page.tsx | 2 +- packages/agentcrumbs/README.md | 5 +---- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 6d314a3..623cde0 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,8 @@ agentcrumbs ships with [@tanstack/intent](https://tanstack.com/blog/from-docs-to | Skill | What it teaches | | --- | --- | +| `agentcrumbs` | Core workflow, API, markers, CLI reference, common mistakes | | `agentcrumbs/init` | Scans repo, discovers namespaces, writes config | -| `agentcrumbs/core` | `trail()`, `crumb()`, markers, env var, noop guarantee | -| `agentcrumbs/scopes-and-context` | `scope()`, `wrap()`, `child()`, `snapshot()`, `assert()` | -| `agentcrumbs/sessions-and-tags` | `session()`, tags, grouping and filtering | -| `agentcrumbs/cli` | `collect`, `tail`, `query`, `strip`, `session` | Skills travel with the package version. The agent always has docs matching the installed code. diff --git a/docs/content/docs/skills.mdx b/docs/content/docs/skills.mdx index dd121b7..13ccd59 100644 --- a/docs/content/docs/skills.mdx +++ b/docs/content/docs/skills.mdx @@ -30,43 +30,34 @@ Each skill is a Markdown file with YAML frontmatter: ```yaml --- -name: agentcrumbs/core +name: agentcrumbs description: > - Core debug tracing with agentcrumbs: trail(), crumb(), - @crumbs markers, env var config, noop strategy... + Debug mode for AI coding agents. Drop structured traces inline + while writing code, query them when something breaks, strip + before merge. type: core library: agentcrumbs -library_version: "0.1.0" +library_version: "0.2.0" sources: + - "triggerdotdev/agentcrumbs:README.md" - "triggerdotdev/agentcrumbs:src/trail.ts" - - "triggerdotdev/agentcrumbs:src/env.ts" --- ``` -The content includes correct usage patterns, explicitly flags common mistakes, and defines constraints the agent must follow. +The content includes correct usage patterns, explicitly flags common mistakes, and points agents to CLI help and docs for deeper discovery. ## Available skills | Skill | What it teaches | | --- | --- | +| `agentcrumbs` | Core workflow, API, markers, CLI quick reference, critical mistakes, and pointers to further discovery | | `agentcrumbs/init` | Scans repo structure, discovers namespaces, writes config to CLAUDE.md or .cursorrules | -| `agentcrumbs/core` | `trail()`, `crumb()`, `// @crumbs` markers, `#region @crumbs` blocks, env var, noop guarantee | -| `agentcrumbs/scopes-and-context` | `scope()`, `wrap()`, `child()`, `snapshot()`, `assert()`, context propagation | -| `agentcrumbs/sessions-and-tags` | `session()`, tags, grouping crumbs for replay and filtering | -| `agentcrumbs/cli` | `collect`, `tail`, `query`, `strip`, `session`, and other CLI commands | - -## What each skill contains - -**Patterns.** Correct usage examples the agent can copy. These show the right way to use each API, with proper markers, at module scope, with structured data. - -**Common mistakes.** Explicitly marked with severity levels (CRITICAL, HIGH, MEDIUM). Things like: checking `process.env.AGENTCRUMBS` on every call instead of using the noop, creating `trail()` inside request handlers, forgetting `// @crumbs` markers. The agent learns what to avoid, not just what to do. - -**Constraints.** Hard rules: every crumb line must have a marker, don't invent namespaces without checking the catalog, create trails at module scope. +The top-level `agentcrumbs` skill covers the essentials an agent needs to use crumbs correctly: the write-collect-query-strip workflow, core API (`trail`, `crumb`, `child`, `scope`), marker syntax, and the most common mistakes. For deeper functionality like sessions, tags, scopes, and testing patterns, it points agents to CLI help (`agentcrumbs --help`), type definitions, and the docs. ## The init skill -The `agentcrumbs/init` skill deserves special mention. It's the entry point for setting up agentcrumbs in any project. +The `agentcrumbs/init` skill is the entry point for setting up agentcrumbs in any project. When the agent runs init, it: @@ -81,9 +72,8 @@ After init, every agent working in the repo uses the same consistent namespaces. If you don't use @tanstack/intent, you can point agents to skills directly: ``` -skills/agentcrumbs/core/SKILL.md -skills/agentcrumbs/cli/SKILL.md -skills/agentcrumbs/init/SKILL.md +node_modules/agentcrumbs/skills/agentcrumbs/SKILL.md +node_modules/agentcrumbs/skills/agentcrumbs/init/SKILL.md ``` Or add a reference in your agent config file manually. But `npx @tanstack/intent install` handles all of this automatically. diff --git a/docs/src/app/page.tsx b/docs/src/app/page.tsx index ebb33ac..013bcd5 100644 --- a/docs/src/app/page.tsx +++ b/docs/src/app/page.tsx @@ -248,7 +248,7 @@ export default function HomePage() {
-

agentcrumbs ships 5 skills via @tanstack/intent, covering the full API, CLI, and common mistakes. Skills travel with the package version, so the agent always has docs matching the installed code.

+

agentcrumbs ships 2 skills via @tanstack/intent: one covering the core workflow, API, and common mistakes, and an init skill that sets up your repo. Skills travel with the package version, so the agent always has docs matching the installed code.

Compatible with Claude Code, Cursor, GitHub Copilot, and any agent that supports the Agent Skills spec.

diff --git a/packages/agentcrumbs/README.md b/packages/agentcrumbs/README.md index 6d314a3..623cde0 100644 --- a/packages/agentcrumbs/README.md +++ b/packages/agentcrumbs/README.md @@ -29,11 +29,8 @@ agentcrumbs ships with [@tanstack/intent](https://tanstack.com/blog/from-docs-to | Skill | What it teaches | | --- | --- | +| `agentcrumbs` | Core workflow, API, markers, CLI reference, common mistakes | | `agentcrumbs/init` | Scans repo, discovers namespaces, writes config | -| `agentcrumbs/core` | `trail()`, `crumb()`, markers, env var, noop guarantee | -| `agentcrumbs/scopes-and-context` | `scope()`, `wrap()`, `child()`, `snapshot()`, `assert()` | -| `agentcrumbs/sessions-and-tags` | `session()`, tags, grouping and filtering | -| `agentcrumbs/cli` | `collect`, `tail`, `query`, `strip`, `session` | Skills travel with the package version. The agent always has docs matching the installed code. From de3cc91bb1c42e9692167b48e5c69dd37aec3cca Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Tue, 10 Mar 2026 13:56:55 +0000 Subject: [PATCH 3/6] docs: rewrite skills section headline and copy --- docs/src/app/page.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/src/app/page.tsx b/docs/src/app/page.tsx index 013bcd5..b8a6bba 100644 --- a/docs/src/app/page.tsx +++ b/docs/src/app/page.tsx @@ -225,9 +225,8 @@ export default function HomePage() { {/* SKILLS */}
-

The init skill is the real setup

-

After installing, tell your agent to run agentcrumbs/init. It scans your repo, discovers your services and modules, and builds a namespace catalog that gets written to your agent config (CLAUDE.md, .cursorrules, etc.).

-

This is the critical step. Without the catalog, every agent invents its own namespace names: auth, auth-service, authService, authentication, all pointing at the same thing. The catalog locks it down. Every agent, every session, same names.

+

Set up with agentcrumbs/init

+

The init skill scans your repo, discovers services and modules, and writes a namespace table to your agent config (CLAUDE.md, .cursorrules, etc.). Agents use the table to pick consistent namespace names across sessions.

From ca097946c9c9a8827381797496f2c0700eeea251 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Tue, 10 Mar 2026 14:02:15 +0000 Subject: [PATCH 4/6] fix: render namespace table as HTML instead of raw markdown in pre block --- docs/src/app/home.css | 6 ++++++ docs/src/app/page.tsx | 28 ++++++++++++++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/src/app/home.css b/docs/src/app/home.css index 8ac677b..67e4170 100644 --- a/docs/src/app/home.css +++ b/docs/src/app/home.css @@ -120,6 +120,12 @@ .hp-skills h2 { font-family: var(--hp-title); font-size: 28px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 12px; } .hp-skills-install { background: var(--hp-bg-code); border: 1px solid var(--hp-border); border-radius: 8px; overflow: hidden; margin-bottom: 24px; } .hp-skills-pre { padding: 20px; overflow-x: auto; font-family: var(--hp-mono); font-size: 12.5px; line-height: 1.7; color: var(--hp-text-dim); margin: 0; background: transparent !important; } +.hp-skills-config { padding: 20px; font-family: var(--hp-mono); font-size: 13px; } +.hp-skills-config-heading { color: var(--hp-text); font-weight: 600; margin-bottom: 12px; } +.hp-skills-table { width: 100%; border-collapse: collapse; margin-bottom: 16px; } +.hp-skills-table th { text-align: left; color: var(--hp-text-dim); font-weight: 500; padding: 6px 16px 6px 0; border-bottom: 1px solid var(--hp-border); } +.hp-skills-table td { color: var(--hp-text-dim); padding: 6px 16px 6px 0; border-bottom: 1px solid var(--hp-border); } +.hp-skills-config-note { color: var(--hp-text-muted); font-size: 12px; } .hp-skills-detail { display: flex; gap: 32px; } .hp-skills-detail p { color: var(--hp-text-dim); font-size: 14px; line-height: 1.6; flex: 1; } .hp-skills-detail a { color: var(--hp-accent); } diff --git a/docs/src/app/page.tsx b/docs/src/app/page.tsx index b8a6bba..d070bfc 100644 --- a/docs/src/app/page.tsx +++ b/docs/src/app/page.tsx @@ -232,18 +232,22 @@ export default function HomePage() {
what init writes to your agent config
-
## agentcrumbs
-
-### Namespaces
-
-| Namespace        | Description                      | Path              |
-| ---              | ---                              | ---               |
-| api-gateway    | HTTP API and routing             | apps/gateway      |
-| auth-service   | Authentication and token handling | apps/auth         |
-| billing        | Stripe integration and charges   | apps/billing      |
-| task-runner    | Background job execution         | apps/worker       |
-
-Do not invent new namespaces. Pick from this table or ask first.` }} />
+
+
## agentcrumbs
+
### Namespaces
+ + + + + + + + + + +
NamespaceDescriptionPath
api-gatewayHTTP API and routingapps/gateway
auth-serviceAuthentication and token handlingapps/auth
billingStripe integration and chargesapps/billing
task-runnerBackground job executionapps/worker
+
Do not invent new namespaces. Pick from this table or ask first.
+
From f9278e3919884225d19265ab3d96e27e87f66133 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Tue, 10 Mar 2026 14:02:57 +0000 Subject: [PATCH 5/6] chore: add Trigger.dev favicon --- docs/src/app/icon.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/src/app/icon.svg diff --git a/docs/src/app/icon.svg b/docs/src/app/icon.svg new file mode 100644 index 0000000..67e15c9 --- /dev/null +++ b/docs/src/app/icon.svg @@ -0,0 +1 @@ + From bb1eb1fa471e482e1479d6bc0fd8407a2f909366 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Tue, 10 Mar 2026 14:03:54 +0000 Subject: [PATCH 6/6] chore: use Trigger.dev favicon.ico --- docs/public/favicon.ico | Bin 0 -> 15086 bytes docs/src/app/icon.svg | 1 - 2 files changed, 1 deletion(-) create mode 100644 docs/public/favicon.ico delete mode 100644 docs/src/app/icon.svg diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..da7d88c13bad2b23fc7cfb53dd773cd664acbc0c GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/docs/src/app/icon.svg b/docs/src/app/icon.svg deleted file mode 100644 index 67e15c9..0000000 --- a/docs/src/app/icon.svg +++ /dev/null @@ -1 +0,0 @@ -