Skip to content

Agent Manifest

Every agent repo must contain a jackin.agent.toml file at the repository root. This manifest tells jackin’ how to build, configure, and identify the agent.

jackin’ enforces strict parsing — unknown fields are rejected with an error. This catches typos and prevents silent misconfiguration.

jackin.agent.toml
dockerfile = "Dockerfile"
[identity]
name = "The Architect"
[claude]
plugins = ["code-review@claude-plugins-official"]
[hooks]
pre_launch = "hooks/pre-launch.sh"
[env.PROJECT]
interactive = true
options = ["project1", "project2"]
prompt = "Select a project:"
[env.BRANCH]
interactive = true
depends_on = ["env.PROJECT"]
prompt = "Branch name:"
default = "main"
FieldRequiredDescription
dockerfileYesRelative path to the Dockerfile within the repo

The Dockerfile path must:

  • Be relative (no absolute paths)
  • Stay inside the repository (no ../ escapes)
  • Point to a valid Dockerfile
  • Have a final stage that starts with FROM projectjackin/construct:trixie
FieldRequiredDescription
pluginsNoList of Claude plugin identifiers to install at runtime

Example values:

jackin.agent.toml
dockerfile = "Dockerfile"
[claude]
plugins = [
"code-review@claude-plugins-official",
"feature-dev@claude-plugins-official"
]
FieldRequiredDescription
nameNoHuman-readable display name for the agent

When omitted, jackin’ uses the class selector name.

FieldRequiredDescription
pre_launchNoRelative path to a bash script run before Claude starts

The pre-launch hook runs inside the container after plugin installation but before Claude Code launches. It has access to all resolved environment variables.

The script path must:

  • Be relative (no absolute paths)
  • Stay inside the repository (no ../ escapes)
  • Point to an existing, non-empty file
  • Not be a symlink

Example:

jackin.agent.toml
[hooks]
pre_launch = "hooks/pre-launch.sh"
hooks/pre-launch.sh
#!/bin/bash
set -euo pipefail
# Configure Context7 MCP if API key is available
if [ -n "${CONTEXT7_API_KEY:-}" ]; then
ctx7 setup --claude --mcp --api-key "$CONTEXT7_API_KEY" -y
fi

Declare environment variables that the agent needs at runtime. Each variable is a TOML table under [env].

FieldTypeDefaultDescription
defaultStringDefault value (used if no prompt or user accepts default)
interactiveboolfalseWhether to prompt the user at launch time
skippableboolfalseWhether the user can skip this prompt
promptStringVariable nameText shown when prompting
optionsString[][]Options for a select-style prompt
depends_onString[][]Variables that must be resolved first (use env. prefix)
  • A non-interactive variable must have a default value
  • options requires interactive = true
  • depends_on entries must use the env. prefix (e.g., "env.PROJECT")
  • depends_on must reference variables declared in the same manifest
  • CLAUDE_ENV is reserved for jackin and cannot be declared in [env]
  • Circular dependencies are rejected

jackin sets CLAUDE_ENV=jackin automatically inside the container to mark the isolated runtime. Do not declare CLAUDE_ENV in [env].

Prompt the user for a free-text value:

[env.GIT_BRANCH]
interactive = true
prompt = "Branch name:"
[env.BRANCH_WITH_DEFAULT]
interactive = true
prompt = "Branch name:"
default = "main"

Present a list of options:

[env.PROJECT]
interactive = true
options = ["frontend", "backend", "infra"]
prompt = "Select a project:"

Allow the user to skip a prompt. The variable won’t be set:

[env.API_KEY]
interactive = true
skippable = true
prompt = "API key (optional):"

Control prompt ordering and skip cascading:

[env.PROJECT]
interactive = true
skippable = true
options = ["frontend", "backend"]
prompt = "Select a project:"
[env.BRANCH]
interactive = true
depends_on = ["env.PROJECT"]
prompt = "Branch to work on:"
default = "main"

If a skippable variable is skipped, all variables that depend on it are also skipped — regardless of their own skippable setting.

The smallest valid manifest:

jackin.agent.toml
dockerfile = "Dockerfile"
[claude]
plugins = []
jackin.agent.toml
dockerfile = "docker/Dockerfile.agent"
[identity]
name = "The Architect"
[claude]
plugins = ["code-review@claude-plugins-official"]
[hooks]
pre_launch = "hooks/pre-launch.sh"
[env.CONTEXT7_API_KEY]
interactive = true
skippable = true
prompt = "Context7 API key:"
[env.PROJECT]
interactive = true
options = ["frontend", "backend", "infra"]
prompt = "Select a project to clone"
[env.BRANCH]
interactive = true
depends_on = ["env.PROJECT"]
prompt = "Branch name:"
default = "main"