Project Layout
The agent/ directory convention — every slot, how it maps to the manifest, and the rules Zett validates.
A Zett agent is a directory of well-known slots. Zett discovers the slots
(static analysis, for arcie dev / arcie build) and loads them into an
agent manifest — the object the runtime executes.
agent/
├── agent.ts # required-ish — the agent config (model + Cencori)
├── instructions.md # the system prompt
├── tools/ # defineTool — what the agent can do
├── skills/ # defineSkill — what the agent knows
├── hooks/ # defineHook — lifecycle callbacks
├── channels/ # defineChannel — HTTP / Slack / custom ingress
├── schedules/ # defineSchedule — cron jobs
├── subagents/ # nested specialist agents (directories)
├── sessions/ # config.ts — durable-execution config
├── policies/ # index.ts — security + budget guardrails
├── connections/ # outbound service connections (discovered)
└── lib/ # shared helpers (discovered)Slot reference
Each file in a slot directory default-exports its config; the file name (without extension) becomes the slot's name. Subagents are the exception — they're directories, each a small agent of its own (see Subagents).
skills/ vs knowledge/. The loader and validator read skills from
skills/. The current starter template scaffolds a knowledge/ directory, and
the getSkill() helper reads markdown from knowledge/. If your skills live in
knowledge/, rename the directory to skills/ so they load into the manifest.
This naming drift is being reconciled upstream.
Defaults
- Missing
agent.ts→ the agent falls back to{ model: "gpt-4o" }. - Missing
instructions.md→ defaults to"You are a helpful AI agent." - Empty slot directory → simply contributes nothing.
Naming rules
Slot names are validated against slug patterns. A bad name is a warning
(INVALID_SLOT_NAME), not a hard failure.
Recognized module extensions: .ts, .mts, .cts, .js, .mjs, .cjs.
Files named .gitkeep are ignored.
Diagnostics
arcie dev and arcie build run discovery first and report diagnostics. Any
error-severity diagnostic stops the command (exit code 1); warnings are printed
and execution continues.
The manifest
loadAgent(agentDir) resolves every slot into an AgentManifest:
interface AgentManifest {
config: AgentConfig;
instructions: string;
tools: Record<string, ToolConfig>;
skills: Record<string, SkillConfig>;
hooks: Record<string, HookConfig>;
channels: Record<string, ChannelConfig>;
schedules: Record<string, ScheduleConfig>;
subagents: Record<string, SubagentManifest>;
session?: SessionConfig;
policy?: PolicyConfig;
}arcie build serializes a summary of this to .arcie/manifest.json. See the
CLI reference.