Skip to main content

Data model

config.json (schema v1)

Stored at ~/.ide-agents/config.json:

{
"version": 1,
"adapter": "cursor",
"ides": {
"opencode": { "enabled": true, "configPath": "/Users/me/.config/opencode" },
"cursor": { "enabled": true, "configPath": "/Users/me/.cursor" },
"claude": { "enabled": true, "configPath": "/Users/me/.claude" },
"codex": { "enabled": false, "configPath": "/Users/me/.codex" }
},
"server": { "port": 3921 },
"repos": [
{
"id": "main",
"url": "https://github.com/org/skills.git",
"ref": "main",
"slug": "github-com-org-skills"
}
],
"installations": [
{
"id": "uuid",
"repoId": "main",
"kind": "skill",
"artifactId": "tech-debt",
"sourcePath": "skills/tech-debt",
"targetName": "tech-debt",
"global": false,
"project": true,
"projectPath": "/Users/me/code/my-app"
}
],
"recentProjects": ["/Users/me/code/my-app"]
}

ides

Per-tool settings — see Settings & IDEs.

FieldDescription
enabledIf true, apply creates symlinks for this tool
configPathGlobal config directory (default ~/.config/opencode, ~/.cursor, ~/.claude, or ~/.codex)

On first config creation, enabled is set only when the matching directory already exists under ~.

Installation fields

FieldDescription
kind"skill" or "agent"
globalSymlink under each enabled tool’s configPath
projectSymlink under <project>/<tool-subfolder>/...
projectPathActive installs use CLI launch cwd; when project is off, the previous path is kept so removal can run

Global and project are independent in the UI — both may be active for the same artifact (global symlink in IDE config dirs, project symlink under the launch directory). A single installation record is applied to all enabled IDEs when you toggle either scope.

recentProjects

FieldDescription
recentProjectsUp to 10 absolute paths, most recent first. Updated when a project install is saved via PUT /installations.

Repository scan: skillLayout

Each repo in GET /api/repos includes a detected layout (not stored in config.json):

ValueMeaning
nestedskills/<id>/SKILL.md
bucketedskills/<bucket>/<id>/SKILL.md
flat<id>/SKILL.md at repo root
emptyNo skills found

Detection order: nested → bucketed → flat. See Source repositories.

Legacy migration

  • scope: "global" | "project" | "off"global / project booleans
  • Configs without ides → defaults from home-folder detection
  • adapter kept for compatibility (first enabled IDE)

Artifact (scanned, not persisted)

Returned by GET /api/repos/:id/artifacts:

{
"id": "hello",
"kind": "skill",
"sourcePath": "skills/hello",
"name": "hello",
"description": "From SKILL.md frontmatter",
"allowedScope": "any",
"bucket": ".curated",
"codexMeta": {
"displayName": "Hello",
"shortDescription": "Demo skill from the starter template.",
"defaultPrompt": "Say hello using this skill."
},
"targets": {
"global": { "exists": false, "isSymlink": false, "blocked": false },
"project": { "exists": true, "isSymlink": true, "blocked": false }
}
}

For agents, optional dependsOnSkills lists skill ids from frontmatter; GET /artifacts also resolves skillDependencies with names and descriptions for the UI. Router agents may also declare dependsOnSubagents (other agent ids they delegate to); ide-agents resolves it into subagentDependencies and, on install, transitively enables the delegated agents and their own skills. A subagent cannot be turned off while a router agent that depends on it is installed in the same scope.

allowedScope comes from SKILL.md or agent frontmatter. If missing, it defaults to any (both toggles enabled).

bucket is set only for bucketed layouts. codexMeta is parsed from agents/openai.yaml when present (presentation only).

targets aggregates status across all enabled IDEs: blocked if any tool has a non-symlink at the target path.