251 lines
7.2 KiB
Markdown
251 lines
7.2 KiB
Markdown
# Contributor Map (Agent-Oriented)
|
||
|
||
This is a fast navigation guide for contributors (human or AI). It answers:
|
||
|
||
- Where do I add a new tool?
|
||
- Where do I add a new skill?
|
||
- Where do I change routing/policy?
|
||
- What tests should I run?
|
||
|
||
For the execution-flow diagram, see `docs/architecture/AGENT_DIAGRAM.md`.
|
||
|
||
## 30-Second Repo Tour
|
||
|
||
```text
|
||
src/
|
||
daemon/ Start-up wiring, service init, message routing
|
||
backends/ Native agent + orchestrator (tool loop lives here)
|
||
tools/ Tool interfaces, policy, executor, builtins
|
||
skills/ Skill loader/registry + install/watch infra
|
||
hooks/ Confirm/log/silent policy + autonomy resolution
|
||
sandbox/ Docker sandbox manager + sandboxed tool wrappers
|
||
models/ Provider clients + model router + retry/cost/capabilities
|
||
channels/ Chat adapters + pairing gate
|
||
gateway/ WebSocket JSON-RPC server + web UI + handlers
|
||
memory/ Hybrid search + embeddings + persistence
|
||
session/ SQLite store + session mgmt
|
||
cli/ CLI entrypoints + setup wizard
|
||
automation/ Cron/webhooks/heartbeat/gmail watcher
|
||
docs/
|
||
api/ Tool and gateway protocol docs
|
||
security/ Capability model, sandboxing, injection resistance
|
||
architecture/ Diagrams + contributor maps
|
||
config/
|
||
default.yaml Example configuration
|
||
```
|
||
|
||
## Adding a New Tool
|
||
|
||
### Where code goes
|
||
|
||
- Builtins live in `src/tools/builtin/`.
|
||
- Core types live in `src/tools/types.ts`.
|
||
- Tools are registered through the daemon wiring (see existing patterns in `src/daemon/index.ts`).
|
||
|
||
### Minimal tool skeleton
|
||
|
||
```ts
|
||
import type { Tool, ToolResult } from '../types.js';
|
||
|
||
export const myTool: Tool = {
|
||
name: 'my.tool',
|
||
description: 'What it does (model-facing).',
|
||
// Optional: gate credentialed actions
|
||
requiredSecretScopes: ['my_scope'],
|
||
inputSchema: {
|
||
type: 'object',
|
||
properties: {
|
||
foo: { type: 'string', description: '...' },
|
||
},
|
||
required: ['foo'],
|
||
},
|
||
execute: async (rawArgs: unknown, _context?: { signal?: AbortSignal }): Promise<ToolResult> => {
|
||
// ...
|
||
return { success: true, output: 'ok' };
|
||
},
|
||
};
|
||
```
|
||
|
||
### Security checklist
|
||
|
||
- If the tool calls an external service or uses credentials:
|
||
- set `requiredSecretScopes` on the tool.
|
||
- ensure skill permissions can gate it (`manifest.json.permissions.secrets`).
|
||
- If it reads/writes files:
|
||
- use `file.*` tools rather than bespoke FS access.
|
||
- skills can restrict FS paths via `permissions.fs`.
|
||
|
||
### Tests to add
|
||
|
||
- Unit tests in `src/tools/builtin/<tool>.test.ts`.
|
||
- If you touch policy/executor logic: add tests in `src/tools/policy.test.ts` or `src/tools/executor.test.ts`.
|
||
|
||
## Adding a New Skill
|
||
|
||
### What a skill is
|
||
|
||
A skill is a package with:
|
||
|
||
- `SKILL.md`: instructions injected into the system prompt.
|
||
- `manifest.json`: metadata + capability declarations.
|
||
|
||
Where skills live:
|
||
|
||
- Bundled skills: `skills/`
|
||
- Managed skills (installed by Flynn): configured skill directory (see config)
|
||
|
||
Skill loading:
|
||
|
||
- Loader: `src/skills/loader.ts`
|
||
- Registry: `src/skills/registry.ts`
|
||
- Watcher (optional): `src/skills/watcher.ts`
|
||
|
||
### Capability permissions
|
||
|
||
If the skill is used via routing (intent target type `skill`), add `permissions` to `manifest.json`.
|
||
|
||
Without `permissions`, a skill is still loadable, but in skill context it has no tool access.
|
||
|
||
Reference: `docs/security/SAFE_PERSONAL_AGENT.md`.
|
||
|
||
## Routing: Agents vs Skills vs Default
|
||
|
||
Where routing decisions happen:
|
||
|
||
- Inbound routing: `src/daemon/routing.ts`
|
||
|
||
Inputs to routing:
|
||
|
||
- Channel + sender (agent router)
|
||
- Intent registry (regex rules) — can target `agent` or `skill`
|
||
- Metadata overrides (gateway / channel adapters)
|
||
|
||
If you need a new routing rule type:
|
||
|
||
- Intent targets live in the intent registry/types (see `src/intents/registry.ts`).
|
||
|
||
## Tool Policy + Execution
|
||
|
||
You will usually touch these files for capability/security work:
|
||
|
||
- Tool allowlisting: `src/tools/policy.ts`
|
||
- Tool runtime enforcement + audit: `src/tools/executor.ts`
|
||
- Confirmation/autonomy: `src/hooks/engine.ts`, `src/hooks/autonomy.ts`
|
||
|
||
In skill context:
|
||
|
||
- `ToolPolicyContext.skillName` and `.skillPermissions` are set in `src/daemon/routing.ts`.
|
||
- ToolPolicy filters available tools.
|
||
- ToolExecutor enforces fs/net/secret/injection restrictions even if a tool is somehow called.
|
||
|
||
## Sandbox
|
||
|
||
Sandbox components:
|
||
|
||
- Docker sandbox manager: `src/sandbox/manager.ts`
|
||
- Docker implementation: `src/sandbox/docker.ts`
|
||
- Sandboxed tool wrappers: `src/sandbox/tools.ts`
|
||
- Tool replacement wiring: `src/daemon/routing.ts`
|
||
|
||
Notes:
|
||
|
||
- Today the sandbox wiring replaces `shell.exec` and `process.start` when sandbox is enabled.
|
||
- In skill context, high-risk execution defaults to sandbox unless the skill opts into host execution.
|
||
|
||
## Gateway / API Surface
|
||
|
||
Gateway protocol docs:
|
||
|
||
- `docs/api/PROTOCOL.md`
|
||
|
||
Gateway handlers:
|
||
|
||
- `src/gateway/handlers/` (JSON-RPC methods)
|
||
|
||
Useful places to start:
|
||
|
||
- `src/gateway/server.ts` (server lifecycle)
|
||
- `src/gateway/protocol.ts` (types)
|
||
|
||
## Tests + Commands
|
||
|
||
Common checks:
|
||
|
||
```bash
|
||
pnpm typecheck
|
||
pnpm lint
|
||
pnpm test:run
|
||
```
|
||
|
||
Targeted tests for safety boundary changes:
|
||
|
||
- Tool policy: `pnpm test:run src/tools/policy.test.ts`
|
||
- Tool executor: `pnpm test:run src/tools/executor.test.ts`
|
||
- Skill loader: `pnpm test:run src/skills/loader.test.ts`
|
||
- Routing: `pnpm test:run src/daemon/routing.test.ts`
|
||
|
||
## First 3 PRs to Pick Up (Good Agent On-Ramps)
|
||
|
||
These are small, high-leverage changes that teach you the architecture quickly.
|
||
|
||
### PR 1: Add a new "narrow" skill + permissions
|
||
|
||
Goal: add a skill that can only do one bounded thing (example: summarize a URL).
|
||
|
||
Deliverables:
|
||
|
||
- `skills/url-summarizer/SKILL.md`
|
||
- `skills/url-summarizer/manifest.json` with permissions:
|
||
- `tool_groups: ["group:web"]`
|
||
- `net: [{"host":"*","ports":[443]}]` (or narrower if you prefer)
|
||
- `execution_environment: "sandbox"` (default)
|
||
|
||
Acceptance:
|
||
|
||
- Skill loads (`flynn doctor` / skills list)
|
||
- In skill context, `shell.exec` is not available
|
||
- `web.fetch` works for https URLs
|
||
|
||
### PR 2: Route into the skill via intents
|
||
|
||
Goal: make it easy to invoke the skill without special UI.
|
||
|
||
Deliverables:
|
||
|
||
- Add an `intents.rules[]` entry targeting `type: skill`
|
||
- Patterns like: `summarize *`, `tldr *`
|
||
|
||
Acceptance:
|
||
|
||
- A message like `summarize https://example.com` routes to the skill
|
||
- Tool list is capability-filtered for that skill context
|
||
|
||
### PR 3: Add an end-to-end safety test
|
||
|
||
Goal: lock in behavior so future refactors don’t weaken the boundary.
|
||
|
||
Deliverables:
|
||
|
||
- A test that asserts: when routed to a skill context with web-only permissions:
|
||
- `ToolPolicy` excludes `shell.exec` and `file.write`
|
||
- `ToolExecutor` denies a direct attempt to call `file.write` outside allowed fs globs
|
||
|
||
Suggested test locations:
|
||
|
||
- `src/tools/policy.test.ts`
|
||
- `src/tools/executor.test.ts`
|
||
|
||
## Where to Add What (Cheat Sheet)
|
||
|
||
```text
|
||
New tool .................. src/tools/builtin/ + register in daemon
|
||
Tool allow/deny logic ...... src/tools/policy.ts
|
||
Tool runtime enforcement .... src/tools/executor.ts
|
||
New skill .................. skills/<name>/{SKILL.md,manifest.json}
|
||
Skill loader/validation ..... src/skills/loader.ts
|
||
Skill routing (intents) ..... src/daemon/routing.ts + config intents
|
||
Sandbox behavior ........... src/sandbox/* + src/daemon/routing.ts
|
||
Confirmation UX ............ src/hooks/* + frontends/gateway
|
||
Web UI changes ............. src/gateway/ui/
|
||
```
|