Skip to content

Latest commit

 

History

History
96 lines (74 loc) · 4.06 KB

claude-projects.md

File metadata and controls

96 lines (74 loc) · 4.06 KB

Claude Code projects

A repository that already carries Claude Code's conventional files — CLAUDE.md, .claude/skills/, .claude/agents/, .claude/rules/, .claude/scratchpad/ — loads them with claudeProject(): the result spreads into createAgent(), so the same directory drives both harnesses. Nothing is copied or renamed; Lousho reads the files where they already are.

import { createAgent, claudeProject } from '@lousho/build-ai-agent';
import { mockModel } from '@lousho/build-ai-agent/testing';

const provider = mockModel([{ text: 'ok' }]);

const project = await claudeProject('./my-repo', { provider });
const agent = createAgent({ provider, ...project });

What maps to what:

Claude convention Becomes
CLAUDE.md (and AGENTS.md) instructions (concatenated when both exist)
.claude/rules/*.md appended instruction sections, ## <file>, sorted by name
.claude/skills/<name>/SKILL.md skills — same layout loadSkills() already reads
.claude/agents/*.md subagents: frontmatter name/description/model, body = instructions
.claude/scratchpad/ a scratchpad tool — write/append/read/list named notes in that dir
.claude/commands/, settings*.json, mcp.json not loaded — listed on manifest.ignored

Sub-agents

.claude/agents/reviewer.md:

---
name: reviewer
description: Reviews diffs for correctness
model: openrouter/openai/gpt-4o-mini
---

You review code ruthlessly. Report findings, never rewrite.

The frontmatter name and description are required (Claude Code's own contract); the body becomes the sub-agent's instructions. model selects the sub-agent's model; without it the sub-agent runs on the provider / model passed to claudeProject() — a file with neither is an error naming it. A tools frontmatter list is recorded on the manifest but not enforced: Lousho sub-agents share the lead's tool registry (narrow them with permission rules instead).

Unlike agent directories, claudeProject() reads markdown as data and runs nothing: no file in .claude/ is imported or executed. Loading a project you don't trust is therefore safe — the tool surface stays whatever you pass to createAgent().

Scratchpad

.claude/scratchpad/ gets a scratchpad tool: the agent writes, appends, reads and lists *.md notes in that directory (names are a-z0-9-_, so paths can't escape it). It is the durable "working notes" surface — for secrets or structured facts prefer memory slots; for task-shaped notes, hooks can pause on scratchpad writes like any tool.

Options

import { claudeProject } from '@lousho/build-ai-agent';
import { mockModel } from '@lousho/build-ai-agent/testing';

const provider = mockModel([{ text: 'ok' }]);

await claudeProject('./repo', {
  provider,            // sub-agents without a frontmatter model run on this
  model: 'openai/gpt-4o', // ...or on this model id (frontmatter model wins)
  scratchpad: true,    // return the tool even if .claude/scratchpad is absent (created on first write)
  rules: false,        // skip .claude/rules
  agents: false,       // skip .claude/agents
});

manifest reports what was found: instructionFiles, rules, skills, subagents, scratchpad, ignored.

What's deliberately not loaded

.claude/commands/*.md are slash-command prompts for an interactive harness — the Lousho shape for "named repeatable workflows" is flows. .claude/settings*.json are Claude Code harness settings (they don't describe an agent), and .claude/mcp.json declares MCP servers — pass those to createAgent({ mcpServers }) yourself (MCP); parsing a third-party config format is deliberately out of scope.

For the other direction — projectInstructions: true on createAgent() — finds and appends the nearest AGENTS.md/CLAUDE.md up the tree, without touching .claude/. See the option in Configuration.