@kuznai/inception-engine 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -3
- package/dist/config/agents.js +97 -8
- package/dist/config/manifest.js +2 -0
- package/dist/core/adapters/agent-definitions.d.ts +20 -0
- package/dist/core/adapters/agent-definitions.js +90 -0
- package/dist/core/adapters/index.d.ts +5 -3
- package/dist/core/adapters/index.js +14 -2
- package/dist/core/adapters/mcp.js +10 -1
- package/dist/core/adapters/permissions.d.ts +8 -0
- package/dist/core/adapters/permissions.js +90 -0
- package/dist/core/adapters/rules.js +10 -1
- package/dist/core/deploy.js +5 -3
- package/dist/core/init.js +282 -20
- package/dist/core/resolve.js +4 -0
- package/dist/core/revert.js +7 -1
- package/dist/core/validation.d.ts +1 -0
- package/dist/core/validation.js +45 -0
- package/dist/schemas/manifest.d.ts +50 -0
- package/dist/schemas/manifest.js +18 -0
- package/dist/types.d.ts +28 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,9 @@ Managed skills overwrite their previous version. If a target exists but was not
|
|
|
50
50
|
| Config patch (JSON merge) | All agents via manifest and CLI | All agents |
|
|
51
51
|
| MCP Servers | claude-code, gemini-cli, codex, antigravity, opencode; github-copilot repo-scoped surfaces are warned and skipped | claude-code, gemini-cli, codex, antigravity, opencode |
|
|
52
52
|
| Global/Repo Rules Files | All agents (antigravity uses repo-local `.agents/rules/`); github-copilot reads CLAUDE.md natively (deploy via claude-code) | All agents |
|
|
53
|
-
|
|
|
53
|
+
| Permissions / Approval Config | claude-code (`~/.claude/settings.json`), codex (`~/.codex/config.toml`); other agents are warned and skipped | claude-code, codex |
|
|
54
|
+
| Agent Definitions | claude-code (`{repo}/.claude/agents/{name}.md`), gemini-cli (`{repo}/.gemini/agents/{name}.md`), antigravity (`{repo}/.agents/rules/{name}.md`), opencode (`{repo}/.opencode/agents/{name}.md`), github-copilot (`{repo}/.github/agents/{name}.agent.md`); codex is warned and skipped | All supported agents |
|
|
55
|
+
| `init` manifest generation | Scans `SKILL.md` directories (`skills`), `.md` files with Claude-first agent mapping (`agentRules`), `mcp-servers.json` (`mcpServers`), and agent-definition Markdown files (`agentDefinitions`); emits hints for `files/` and `configs/` directories | N/A |
|
|
54
56
|
|
|
55
57
|
Features that depend on agent-specific config surfaces are intentionally conservative: if a target path or schema is not implemented with enough confidence, inception-engine warns and skips it rather than guessing.
|
|
56
58
|
|
|
@@ -98,6 +100,25 @@ Create an `inception.json` file at the root of your skills directory:
|
|
|
98
100
|
"path": "rules/CLAUDE.md",
|
|
99
101
|
"agents": ["claude-code"]
|
|
100
102
|
}
|
|
103
|
+
],
|
|
104
|
+
"permissions": [
|
|
105
|
+
{
|
|
106
|
+
"name": "safety-defaults",
|
|
107
|
+
"agents": ["claude-code"],
|
|
108
|
+
"config": {
|
|
109
|
+
"permissions": {
|
|
110
|
+
"allow": ["Read", "Glob"],
|
|
111
|
+
"deny": ["Bash(rm:*)"]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
"agentDefinitions": [
|
|
117
|
+
{
|
|
118
|
+
"name": "code-reviewer",
|
|
119
|
+
"path": "agents/code-reviewer.md",
|
|
120
|
+
"agents": ["claude-code", "opencode", "github-copilot"]
|
|
121
|
+
}
|
|
101
122
|
]
|
|
102
123
|
}
|
|
103
124
|
```
|
|
@@ -145,6 +166,64 @@ Each **agentRules** entry deploys a Markdown instruction file to an agent's supp
|
|
|
145
166
|
|
|
146
167
|
Instruction rule deployment is supported for all agents. For most agents, this targets a single global rules file (e.g., `~/.claude/CLAUDE.md` for `claude-code`, `~/.codex/AGENTS.md` for `codex`, `~/.gemini/GEMINI.md` for `gemini-cli`, and `~/.config/opencode/AGENTS.md` for `opencode`). For `antigravity`, inception-engine deploys to repo-local instruction surfaces at `{repo}/.agents/rules/{name}.md`. For `github-copilot`, no separate deployment is needed because Copilot reads `CLAUDE.md` natively — target it via the `claude-code` agentRules entry and it reaches Copilot automatically. Revert removes the deployed rules file.
|
|
147
168
|
|
|
169
|
+
Each **permissions** entry deploys execution and safety-oriented configuration to an agent's permission or approval surface:
|
|
170
|
+
|
|
171
|
+
- **name** - Unique identifier (same format as skill names)
|
|
172
|
+
- **agents** - Array of agent IDs to deploy this entry to
|
|
173
|
+
- **config** - Permission config payload; shape is validated per agent (see below)
|
|
174
|
+
|
|
175
|
+
Permission deployment is currently supported for `claude-code` and `codex`. Other agents emit a warning and are skipped.
|
|
176
|
+
|
|
177
|
+
For `claude-code`, the config is merged into `~/.claude/settings.json`. Only the `permissions` key is accepted:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"name": "safety-defaults",
|
|
182
|
+
"agents": ["claude-code"],
|
|
183
|
+
"config": {
|
|
184
|
+
"permissions": {
|
|
185
|
+
"allow": ["Read", "Glob", "Bash(git:*)"],
|
|
186
|
+
"deny": ["Bash(rm:*)"]
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Both `allow` and `deny` are optional string arrays. Tool patterns follow Claude Code's permission glob syntax (e.g., `Bash(git:*)` to allow all git commands).
|
|
193
|
+
|
|
194
|
+
For `codex`, the config is merged into `~/.codex/config.toml`. Only the `approval_policy` key is accepted:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"name": "codex-approval",
|
|
199
|
+
"agents": ["codex"],
|
|
200
|
+
"config": {
|
|
201
|
+
"approval_policy": "suggest"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Valid `approval_policy` values are `"auto"`, `"manual"`, `"suggest"`, and `"on-failure"`.
|
|
207
|
+
|
|
208
|
+
Revert restores the previous config values using the undo patch recorded at deploy time.
|
|
209
|
+
|
|
210
|
+
Each **agentDefinitions** entry deploys a Markdown agent-definition file to the repo-local agent-definitions directory of each targeted agent:
|
|
211
|
+
|
|
212
|
+
- **name** - Unique identifier (same format as skill names); used as the definition filename
|
|
213
|
+
- **path** - Relative path to the source Markdown file within the repo; must be a `.md` or `.markdown` file
|
|
214
|
+
- **agents** - Array of agent IDs to deploy this definition to
|
|
215
|
+
|
|
216
|
+
Agent-definition deployment is supported for `claude-code`, `gemini-cli`, `antigravity`, `opencode`, and `github-copilot`. For `codex`, inception-engine emits a warning and skips the entry — use `agentRules` to deploy persona instructions to Codex instead.
|
|
217
|
+
|
|
218
|
+
All targets are repo-local (they land inside the repository being deployed, not the user's home directory):
|
|
219
|
+
- **claude-code**: `{repo}/.claude/agents/{name}.md`
|
|
220
|
+
- **gemini-cli**: `{repo}/.gemini/agents/{name}.md`
|
|
221
|
+
- **antigravity**: `{repo}/.agents/rules/{name}.md`
|
|
222
|
+
- **opencode**: `{repo}/.opencode/agents/{name}.md`
|
|
223
|
+
- **github-copilot**: `{repo}/.github/agents/{name}.agent.md` (note the `.agent.md` suffix)
|
|
224
|
+
|
|
225
|
+
Revert removes the deployed agent-definition file.
|
|
226
|
+
|
|
148
227
|
## Creating Skills
|
|
149
228
|
|
|
150
229
|
Each skill is a directory containing at minimum a `SKILL.md` file with YAML frontmatter:
|
|
@@ -175,12 +254,15 @@ Current `init` behavior:
|
|
|
175
254
|
- Supports `--dry-run` so you can inspect the generated manifest before writing it
|
|
176
255
|
- Discovers agent-rules Markdown files in the root and conventional subdirectories (`rules/`, `instructions/`, `.github/`, `.agents/rules/`), mapping them to agents using Claude-first portability conventions: `copilot-instructions.md` maps to `claude-code` (Copilot reads `CLAUDE.md` natively), and the fallback for unrecognized files excludes agents whose agentRules surface is unsupported
|
|
177
256
|
- Reads `mcp-servers.json` from the repo root (if present) and generates `mcpServers` entries; invalid entries are warned and skipped
|
|
178
|
-
-
|
|
257
|
+
- Reads `files-manifest.json` from the repo root (if present) and generates `files` entries; invalid entries are warned and skipped
|
|
258
|
+
- Reads `configs-manifest.json` from the repo root (if present) and generates `configs` entries; invalid entries are warned and skipped
|
|
259
|
+
- Reads `agent-definitions-manifest.json` from the repo root (if present) and generates `agentDefinitions` entries; if absent, auto-discovers agent-definition Markdown files from `.claude/agents/`, `.gemini/agents/`, `.agents/rules/`, `.opencode/agents/`, and `.github/agents/`; invalid entries are warned and skipped
|
|
260
|
+
- Emits guidance to create a sidecar manifest when a `files/` or `configs/` directory is detected but the corresponding sidecar file is absent
|
|
179
261
|
|
|
180
262
|
Current `init` limitations:
|
|
181
263
|
|
|
182
264
|
- It does not reconcile generated manifest entries against `SKILL.md` frontmatter values
|
|
183
|
-
- `files` and `configs`
|
|
265
|
+
- `files` and `configs` target paths are deployment-system-specific and cannot be inferred; they must be provided explicitly in `files-manifest.json` and `configs-manifest.json`
|
|
184
266
|
|
|
185
267
|
### Repo Conventions Recognized by `init`
|
|
186
268
|
|
|
@@ -196,6 +278,48 @@ Place a `mcp-servers.json` file at the repo root to have `init` populate the `mc
|
|
|
196
278
|
]
|
|
197
279
|
```
|
|
198
280
|
|
|
281
|
+
Place a `files-manifest.json` file at the repo root to have `init` populate the `files` section automatically. The file must be a JSON array of file entries using the same schema as the `files` field in `inception.json`:
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
[
|
|
285
|
+
{
|
|
286
|
+
"name": "my-settings",
|
|
287
|
+
"path": "files/settings.json",
|
|
288
|
+
"target": "{home}/.claude/settings.json",
|
|
289
|
+
"agents": ["claude-code"]
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Place a `configs-manifest.json` file at the repo root to have `init` populate the `configs` section automatically. The file must be a JSON array of config entries using the same schema as the `configs` field in `inception.json`:
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
[
|
|
298
|
+
{
|
|
299
|
+
"name": "enable-feature",
|
|
300
|
+
"target": "{home}/.claude/settings.json",
|
|
301
|
+
"patch": { "someFeature": true },
|
|
302
|
+
"agents": ["claude-code"]
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Invalid entries are warned and skipped; the rest are written into the generated manifest verbatim.
|
|
308
|
+
|
|
309
|
+
Place an `agent-definitions-manifest.json` file at the repo root to have `init` populate the `agentDefinitions` section automatically. The file must be a JSON array of agent-definition entries using the same schema as the `agentDefinitions` field in `inception.json`:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
[
|
|
313
|
+
{
|
|
314
|
+
"name": "code-reviewer",
|
|
315
|
+
"path": "agents/code-reviewer.md",
|
|
316
|
+
"agents": ["claude-code", "opencode", "github-copilot"]
|
|
317
|
+
}
|
|
318
|
+
]
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
If no `agent-definitions-manifest.json` is present, `init` auto-discovers agent-definition Markdown files from five conventional subdirectories: `.claude/agents/`, `.gemini/agents/`, `.agents/rules/`, `.opencode/agents/`, and `.github/agents/`. Each discovered file is mapped to the owning agent(s). GitHub Copilot files named `{name}.agent.md` have the `.agent` infix stripped to derive the manifest name (e.g., `foo.agent.md` → name `foo`).
|
|
322
|
+
|
|
199
323
|
Invalid entries are warned and skipped; the rest are written into the generated manifest verbatim.
|
|
200
324
|
|
|
201
325
|
## CLI Reference
|
package/dist/config/agents.js
CHANGED
|
@@ -17,6 +17,8 @@ export const AGENT_REGISTRY = [
|
|
|
17
17
|
detectBinary: "documented",
|
|
18
18
|
mcpConfig: "documented",
|
|
19
19
|
agentRules: "documented",
|
|
20
|
+
permissions: "documented",
|
|
21
|
+
agentDefinitions: "documented",
|
|
20
22
|
},
|
|
21
23
|
mcpSupport: {
|
|
22
24
|
status: "supported",
|
|
@@ -34,6 +36,22 @@ export const AGENT_REGISTRY = [
|
|
|
34
36
|
windows: ["{home}", ".claude", "CLAUDE.md"],
|
|
35
37
|
},
|
|
36
38
|
},
|
|
39
|
+
permissionsSupport: {
|
|
40
|
+
status: "supported",
|
|
41
|
+
schemaLabel: "JSON permissions config",
|
|
42
|
+
path: {
|
|
43
|
+
posix: ["{home}", ".claude", "settings.json"],
|
|
44
|
+
windows: ["{home}", ".claude", "settings.json"],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
agentDefinitionsSupport: {
|
|
48
|
+
status: "supported",
|
|
49
|
+
schemaLabel: "repo-local agent definition Markdown file",
|
|
50
|
+
path: {
|
|
51
|
+
posix: ["{repo}", ".claude", "agents", "{name}.md"],
|
|
52
|
+
windows: ["{repo}", ".claude", "agents", "{name}.md"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
37
55
|
},
|
|
38
56
|
{
|
|
39
57
|
id: "codex",
|
|
@@ -52,6 +70,7 @@ export const AGENT_REGISTRY = [
|
|
|
52
70
|
detectPaths: "documented",
|
|
53
71
|
detectBinary: "documented",
|
|
54
72
|
agentRules: "documented",
|
|
73
|
+
permissions: "documented",
|
|
55
74
|
},
|
|
56
75
|
mcpSupport: {
|
|
57
76
|
status: "supported",
|
|
@@ -69,6 +88,19 @@ export const AGENT_REGISTRY = [
|
|
|
69
88
|
windows: ["{home}", ".codex", "AGENTS.md"],
|
|
70
89
|
},
|
|
71
90
|
},
|
|
91
|
+
permissionsSupport: {
|
|
92
|
+
status: "supported",
|
|
93
|
+
schemaLabel: "TOML approval policy config",
|
|
94
|
+
path: {
|
|
95
|
+
posix: ["{home}", ".codex", "config.toml"],
|
|
96
|
+
windows: ["{home}", ".codex", "config.toml"],
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
agentDefinitionsSupport: {
|
|
100
|
+
status: "unsupported",
|
|
101
|
+
schemaLabel: "dedicated agent definition directory",
|
|
102
|
+
reason: "OpenAI Codex does not expose a documented dedicated per-agent definition directory surface separate from AGENTS.md and config.toml — use agentRules to deploy persona instructions instead",
|
|
103
|
+
},
|
|
72
104
|
},
|
|
73
105
|
{
|
|
74
106
|
id: "gemini-cli",
|
|
@@ -88,6 +120,7 @@ export const AGENT_REGISTRY = [
|
|
|
88
120
|
detectBinary: "documented",
|
|
89
121
|
mcpConfig: "documented",
|
|
90
122
|
agentRules: "documented",
|
|
123
|
+
agentDefinitions: "implementation-only",
|
|
91
124
|
},
|
|
92
125
|
mcpSupport: {
|
|
93
126
|
status: "supported",
|
|
@@ -105,6 +138,19 @@ export const AGENT_REGISTRY = [
|
|
|
105
138
|
windows: ["{home}", ".gemini", "GEMINI.md"],
|
|
106
139
|
},
|
|
107
140
|
},
|
|
141
|
+
permissionsSupport: {
|
|
142
|
+
status: "unsupported",
|
|
143
|
+
schemaLabel: "global permissions surface",
|
|
144
|
+
reason: "Gemini CLI does not expose a documented global per-user permission or approval config surface",
|
|
145
|
+
},
|
|
146
|
+
agentDefinitionsSupport: {
|
|
147
|
+
status: "supported",
|
|
148
|
+
schemaLabel: "repo-local agent definition Markdown file",
|
|
149
|
+
path: {
|
|
150
|
+
posix: ["{repo}", ".gemini", "agents", "{name}.md"],
|
|
151
|
+
windows: ["{repo}", ".gemini", "agents", "{name}.md"],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
108
154
|
},
|
|
109
155
|
{
|
|
110
156
|
id: "antigravity",
|
|
@@ -122,6 +168,8 @@ export const AGENT_REGISTRY = [
|
|
|
122
168
|
skills: "implementation-only",
|
|
123
169
|
detectPaths: "implementation-only",
|
|
124
170
|
detectBinary: "provisional",
|
|
171
|
+
agentRules: "documented",
|
|
172
|
+
agentDefinitions: "documented",
|
|
125
173
|
},
|
|
126
174
|
mcpSupport: {
|
|
127
175
|
status: "supported",
|
|
@@ -139,6 +187,19 @@ export const AGENT_REGISTRY = [
|
|
|
139
187
|
windows: ["{repo}", ".agents", "rules", "{name}.md"],
|
|
140
188
|
},
|
|
141
189
|
},
|
|
190
|
+
permissionsSupport: {
|
|
191
|
+
status: "unsupported",
|
|
192
|
+
schemaLabel: "global permissions surface",
|
|
193
|
+
reason: "Antigravity does not expose a documented global per-user permission or approval config surface",
|
|
194
|
+
},
|
|
195
|
+
agentDefinitionsSupport: {
|
|
196
|
+
status: "supported",
|
|
197
|
+
schemaLabel: "repo-local agent definition Markdown file",
|
|
198
|
+
path: {
|
|
199
|
+
posix: ["{repo}", ".agents", "rules", "{name}.md"],
|
|
200
|
+
windows: ["{repo}", ".agents", "rules", "{name}.md"],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
142
203
|
},
|
|
143
204
|
{
|
|
144
205
|
id: "opencode",
|
|
@@ -157,6 +218,7 @@ export const AGENT_REGISTRY = [
|
|
|
157
218
|
detectPaths: "documented",
|
|
158
219
|
detectBinary: "documented",
|
|
159
220
|
agentRules: "documented",
|
|
221
|
+
agentDefinitions: "documented",
|
|
160
222
|
},
|
|
161
223
|
mcpSupport: {
|
|
162
224
|
status: "supported",
|
|
@@ -175,35 +237,62 @@ export const AGENT_REGISTRY = [
|
|
|
175
237
|
windows: ["{appdata}", "opencode", "AGENTS.md"],
|
|
176
238
|
},
|
|
177
239
|
},
|
|
240
|
+
permissionsSupport: {
|
|
241
|
+
status: "unsupported",
|
|
242
|
+
schemaLabel: "global permissions surface",
|
|
243
|
+
reason: "OpenCode does not expose a documented global per-user permission or approval config surface",
|
|
244
|
+
},
|
|
245
|
+
agentDefinitionsSupport: {
|
|
246
|
+
status: "supported",
|
|
247
|
+
schemaLabel: "repo-local agent definition Markdown file",
|
|
248
|
+
path: {
|
|
249
|
+
posix: ["{repo}", ".opencode", "agents", "{name}.md"],
|
|
250
|
+
windows: ["{repo}", ".opencode", "agents", "{name}.md"],
|
|
251
|
+
},
|
|
252
|
+
},
|
|
178
253
|
},
|
|
179
254
|
{
|
|
180
255
|
id: "github-copilot",
|
|
181
256
|
displayName: "GitHub Copilot",
|
|
182
|
-
skills:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
257
|
+
// No `skills` field: GitHub Copilot natively executes Claude-style skills
|
|
258
|
+
// from `.claude/skills/` (the same path used by claude-code). Deploying
|
|
259
|
+
// via the `claude-code` skills target automatically covers Copilot — no
|
|
260
|
+
// separate `~/.copilot/skills/` path is needed or maintained.
|
|
186
261
|
detectPaths: {
|
|
187
262
|
posix: ["{home}", ".copilot"],
|
|
188
263
|
windows: ["{home}", ".copilot"],
|
|
189
264
|
},
|
|
190
265
|
detectBinary: "github-copilot",
|
|
191
266
|
provenance: {
|
|
192
|
-
skills: "documented",
|
|
193
267
|
detectPaths: "documented",
|
|
194
268
|
detectBinary: "documented",
|
|
269
|
+
agentDefinitions: "documented",
|
|
195
270
|
},
|
|
196
271
|
mcpSupport: {
|
|
197
|
-
status: "
|
|
272
|
+
status: "planned",
|
|
198
273
|
schemaLabel: "repo-scoped MCP surfaces",
|
|
199
|
-
|
|
274
|
+
plannedSurface: "devcontainer (.devcontainer/devcontainer.json) and agent-frontmatter (.github/agents/*.agent.md)",
|
|
275
|
+
reason: "GitHub Copilot MCP support will be implemented via repo-scoped devcontainer features and agent-frontmatter mappings — surfaces that are genuinely Copilot-specific and not covered by other agent targets",
|
|
200
276
|
},
|
|
201
277
|
agentRulesSupport: {
|
|
202
278
|
status: "unsupported",
|
|
203
279
|
schemaLabel: "Claude-native shared instructions",
|
|
204
280
|
reason: 'GitHub Copilot reads CLAUDE.md natively, so deploy via the "claude-code" agentRules target instead of a separate rules surface',
|
|
205
281
|
},
|
|
206
|
-
|
|
282
|
+
permissionsSupport: {
|
|
283
|
+
status: "unsupported",
|
|
284
|
+
schemaLabel: "global permissions surface",
|
|
285
|
+
reason: "GitHub Copilot permissions are managed via organization policy, not a deployable per-user config surface",
|
|
286
|
+
},
|
|
287
|
+
agentDefinitionsSupport: {
|
|
288
|
+
status: "supported",
|
|
289
|
+
schemaLabel: "repo-local agent definition Markdown file",
|
|
290
|
+
path: {
|
|
291
|
+
posix: ["{repo}", ".github", "agents", "{name}.agent.md"],
|
|
292
|
+
windows: ["{repo}", ".github", "agents", "{name}.agent.md"],
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
policyNote: "Organization policies may override locally deployed configuration. Verify with your GitHub org admin if deployed skills or rules are not active.",
|
|
207
296
|
},
|
|
208
297
|
];
|
|
209
298
|
export const AGENT_REGISTRY_BY_ID = Object.fromEntries(AGENT_REGISTRY.map((a) => [a.id, a]));
|
package/dist/config/manifest.js
CHANGED
|
@@ -42,6 +42,8 @@ function validateManifest(data, filePath) {
|
|
|
42
42
|
if (issuePath.length === 1 &&
|
|
43
43
|
(issuePath[0] === "mcpServers" ||
|
|
44
44
|
issuePath[0] === "agentRules" ||
|
|
45
|
+
issuePath[0] === "agentDefinitions" ||
|
|
46
|
+
issuePath[0] === "permissions" ||
|
|
45
47
|
issuePath[0] === "files" ||
|
|
46
48
|
issuePath[0] === "configs")) {
|
|
47
49
|
throw new UserError("MANIFEST_INVALID", `${filePath}: "${issuePath[0]}" must be an array`);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentDefinitionEntry } from "../../schemas/manifest.ts";
|
|
2
|
+
import type { AgentId, FileWriteDeployAction, FileWriteRevertAction, PlanWarning } from "../../types.ts";
|
|
3
|
+
export interface AgentDefinitionsAdapterResult {
|
|
4
|
+
actions: FileWriteDeployAction[];
|
|
5
|
+
warnings: PlanWarning[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Compiles deploy actions for agentDefinitions manifest entries.
|
|
9
|
+
*
|
|
10
|
+
* Agent definition files are Markdown files (typically with YAML frontmatter)
|
|
11
|
+
* that define custom agents or subagents for a given platform. Unlike
|
|
12
|
+
* agentRules (which target a single shared global file per agent), each
|
|
13
|
+
* definition entry produces a separate file named after the entry in the
|
|
14
|
+
* agent's dedicated agent-definitions directory (repo-local).
|
|
15
|
+
*
|
|
16
|
+
* Target paths use the `{repo}` placeholder so definitions land in the
|
|
17
|
+
* repository being deployed, not the user's home directory.
|
|
18
|
+
*/
|
|
19
|
+
export declare function compileAgentDefinitionActions(entry: AgentDefinitionEntry, sourceDir: string, resolvedSourceDir: string, realRoot: string, detectedAgents: AgentId[], home: string, repo?: string): Promise<AgentDefinitionsAdapterResult>;
|
|
20
|
+
export declare function compileAgentDefinitionReverts(entry: AgentDefinitionEntry, agentFilter: AgentId[] | null, home: string, repo?: string): FileWriteRevertAction[];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { AGENT_REGISTRY_BY_ID } from "../../config/agents.js";
|
|
3
|
+
import { getPlatformKey, resolvePlaceholders } from "../resolve.js";
|
|
4
|
+
import { validateAgentRuleMarkdownPath, validateSourceFile, validateSourcePath, } from "../validation.js";
|
|
5
|
+
/**
|
|
6
|
+
* Compiles deploy actions for agentDefinitions manifest entries.
|
|
7
|
+
*
|
|
8
|
+
* Agent definition files are Markdown files (typically with YAML frontmatter)
|
|
9
|
+
* that define custom agents or subagents for a given platform. Unlike
|
|
10
|
+
* agentRules (which target a single shared global file per agent), each
|
|
11
|
+
* definition entry produces a separate file named after the entry in the
|
|
12
|
+
* agent's dedicated agent-definitions directory (repo-local).
|
|
13
|
+
*
|
|
14
|
+
* Target paths use the `{repo}` placeholder so definitions land in the
|
|
15
|
+
* repository being deployed, not the user's home directory.
|
|
16
|
+
*/
|
|
17
|
+
export async function compileAgentDefinitionActions(entry, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home, repo) {
|
|
18
|
+
const actions = [];
|
|
19
|
+
const warnings = [];
|
|
20
|
+
const platform = getPlatformKey();
|
|
21
|
+
const targetAgents = entry.agents.filter((agentId) => detectedAgents.includes(agentId));
|
|
22
|
+
const supportedTargets = [];
|
|
23
|
+
if (targetAgents.length === 0) {
|
|
24
|
+
return { actions, warnings };
|
|
25
|
+
}
|
|
26
|
+
for (const agentId of targetAgents) {
|
|
27
|
+
const agent = AGENT_REGISTRY_BY_ID[agentId];
|
|
28
|
+
const support = agent?.agentDefinitionsSupport;
|
|
29
|
+
if (!support || support.status === "unsupported") {
|
|
30
|
+
warnings.push({
|
|
31
|
+
kind: "confidence",
|
|
32
|
+
message: `agentDefinitions: agent "${agentId}" uses ${support?.schemaLabel ?? "an unsupported agent-definition schema"} and ${support?.status === "unsupported" ? support.reason : "does not expose a supported agent-definitions adapter"} — skipping "${entry.name}"`,
|
|
33
|
+
});
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (support.status === "planned") {
|
|
37
|
+
warnings.push({
|
|
38
|
+
kind: "confidence",
|
|
39
|
+
message: `agentDefinitions: agent "${agentId}" agent-definitions support is planned via ${support.plannedSurface} — skipping "${entry.name}" until that surface is implemented`,
|
|
40
|
+
});
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
supportedTargets.push({
|
|
44
|
+
agentId,
|
|
45
|
+
confidence: agent.provenance.agentDefinitions ?? "provisional",
|
|
46
|
+
target: resolvePlaceholders(support.path[platform], entry.name, home, repo),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (supportedTargets.length === 0) {
|
|
50
|
+
return { actions, warnings };
|
|
51
|
+
}
|
|
52
|
+
// Validate the shared source file only when at least one target is active.
|
|
53
|
+
const source = path.resolve(sourceDir, entry.path);
|
|
54
|
+
await validateSourcePath(source, entry.path, resolvedSourceDir, realRoot);
|
|
55
|
+
await validateSourceFile(source, entry.path);
|
|
56
|
+
for (const target of supportedTargets) {
|
|
57
|
+
validateAgentRuleMarkdownPath(entry.path, target.agentId);
|
|
58
|
+
actions.push({
|
|
59
|
+
kind: "file-write",
|
|
60
|
+
skill: entry.name,
|
|
61
|
+
agent: target.agentId,
|
|
62
|
+
source,
|
|
63
|
+
target: target.target,
|
|
64
|
+
confidence: target.confidence,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return { actions, warnings };
|
|
68
|
+
}
|
|
69
|
+
export function compileAgentDefinitionReverts(entry, agentFilter, home, repo) {
|
|
70
|
+
const actions = [];
|
|
71
|
+
const platform = getPlatformKey();
|
|
72
|
+
for (const agentId of entry.agents) {
|
|
73
|
+
if (agentFilter && !agentFilter.includes(agentId))
|
|
74
|
+
continue;
|
|
75
|
+
const agent = AGENT_REGISTRY_BY_ID[agentId];
|
|
76
|
+
const support = agent?.agentDefinitionsSupport;
|
|
77
|
+
if (!support ||
|
|
78
|
+
support.status === "unsupported" ||
|
|
79
|
+
support.status === "planned")
|
|
80
|
+
continue;
|
|
81
|
+
const target = resolvePlaceholders(support.path[platform], entry.name, home, repo);
|
|
82
|
+
actions.push({
|
|
83
|
+
kind: "file-write",
|
|
84
|
+
skill: entry.name,
|
|
85
|
+
agent: agentId,
|
|
86
|
+
target,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return actions;
|
|
90
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import type { AgentRuleEntry, McpServerEntry } from "../../schemas/manifest.ts";
|
|
1
|
+
import type { AgentDefinitionEntry, AgentRuleEntry, McpServerEntry, PermissionsEntry } from "../../schemas/manifest.ts";
|
|
2
2
|
import type { AgentId, ConfigPatchDeployAction, FileWriteDeployAction, FrontmatterEmitDeployAction, PlanWarning, TomlPatchDeployAction } from "../../types.ts";
|
|
3
|
+
import { compileAgentDefinitionReverts } from "./agent-definitions.ts";
|
|
3
4
|
import { compileMcpServerReverts } from "./mcp.ts";
|
|
5
|
+
import { compilePermissionsReverts } from "./permissions.ts";
|
|
4
6
|
import { compileAgentRuleReverts } from "./rules.ts";
|
|
5
|
-
export { compileAgentRuleReverts, compileMcpServerReverts };
|
|
7
|
+
export { compileAgentDefinitionReverts, compileAgentRuleReverts, compileMcpServerReverts, compilePermissionsReverts, };
|
|
6
8
|
export type AdapterAction = ConfigPatchDeployAction | FileWriteDeployAction | TomlPatchDeployAction | FrontmatterEmitDeployAction;
|
|
7
9
|
export interface AdapterResult {
|
|
8
10
|
actions: AdapterAction[];
|
|
9
11
|
warnings: PlanWarning[];
|
|
10
12
|
}
|
|
11
|
-
export declare function compileAdapterActions(mcpServers: McpServerEntry[], agentRules: AgentRuleEntry[], sourceDir: string, resolvedSourceDir: string, realRoot: string, detectedAgents: AgentId[], home: string, repo?: string): Promise<AdapterResult>;
|
|
13
|
+
export declare function compileAdapterActions(mcpServers: McpServerEntry[], agentRules: AgentRuleEntry[], permissions: PermissionsEntry[], sourceDir: string, resolvedSourceDir: string, realRoot: string, detectedAgents: AgentId[], home: string, repo?: string, agentDefinitions?: AgentDefinitionEntry[]): Promise<AdapterResult>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { compileAgentDefinitionActions, compileAgentDefinitionReverts, } from "./agent-definitions.js";
|
|
1
2
|
import { compileMcpServerActions, compileMcpServerReverts } from "./mcp.js";
|
|
3
|
+
import { compilePermissionsActions, compilePermissionsReverts, } from "./permissions.js";
|
|
2
4
|
import { compileAgentRuleActions, compileAgentRuleReverts } from "./rules.js";
|
|
3
|
-
export { compileAgentRuleReverts, compileMcpServerReverts };
|
|
4
|
-
export async function compileAdapterActions(mcpServers, agentRules, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home, repo) {
|
|
5
|
+
export { compileAgentDefinitionReverts, compileAgentRuleReverts, compileMcpServerReverts, compilePermissionsReverts, };
|
|
6
|
+
export async function compileAdapterActions(mcpServers, agentRules, permissions, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home, repo, agentDefinitions) {
|
|
5
7
|
const actions = [];
|
|
6
8
|
const warnings = [];
|
|
7
9
|
for (const entry of mcpServers) {
|
|
@@ -14,5 +16,15 @@ export async function compileAdapterActions(mcpServers, agentRules, sourceDir, r
|
|
|
14
16
|
actions.push(...r.actions);
|
|
15
17
|
warnings.push(...r.warnings);
|
|
16
18
|
}
|
|
19
|
+
for (const entry of permissions) {
|
|
20
|
+
const r = compilePermissionsActions(entry, detectedAgents, home);
|
|
21
|
+
actions.push(...r.actions);
|
|
22
|
+
warnings.push(...r.warnings);
|
|
23
|
+
}
|
|
24
|
+
for (const entry of agentDefinitions ?? []) {
|
|
25
|
+
const r = await compileAgentDefinitionActions(entry, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home, repo);
|
|
26
|
+
actions.push(...r.actions);
|
|
27
|
+
warnings.push(...r.warnings);
|
|
28
|
+
}
|
|
17
29
|
return { actions, warnings };
|
|
18
30
|
}
|
|
@@ -62,6 +62,13 @@ export function compileMcpServerActions(entry, detectedAgents, home, repo) {
|
|
|
62
62
|
});
|
|
63
63
|
continue;
|
|
64
64
|
}
|
|
65
|
+
if (support.status === "planned") {
|
|
66
|
+
warnings.push({
|
|
67
|
+
kind: "confidence",
|
|
68
|
+
message: `mcpServers: agent "${agentId}" MCP support is planned via ${support.plannedSurface} — skipping "${entry.name}" until that surface is implemented`,
|
|
69
|
+
});
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
65
72
|
validateMcpServerConfigShape(entry.config, entry.name, agentId);
|
|
66
73
|
const rawTarget = resolvePlaceholders(support.path[platform], entry.name, home, repo);
|
|
67
74
|
const resolvedTarget = path.resolve(rawTarget);
|
|
@@ -79,7 +86,9 @@ export function compileMcpServerReverts(entry, agentFilter, home, repo) {
|
|
|
79
86
|
continue;
|
|
80
87
|
const agent = AGENT_REGISTRY_BY_ID[agentId];
|
|
81
88
|
const support = agent?.mcpSupport;
|
|
82
|
-
if (!support ||
|
|
89
|
+
if (!support ||
|
|
90
|
+
support.status === "unsupported" ||
|
|
91
|
+
support.status === "planned")
|
|
83
92
|
continue;
|
|
84
93
|
const rawTarget = resolvePlaceholders(support.path[platform], entry.name, home, repo);
|
|
85
94
|
const target = path.resolve(rawTarget);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PermissionsEntry } from "../../schemas/manifest.ts";
|
|
2
|
+
import type { AgentId, ConfigPatchDeployAction, ConfigPatchRevertAction, PlanWarning, TomlPatchDeployAction, TomlPatchRevertAction } from "../../types.ts";
|
|
3
|
+
export interface PermissionsAdapterResult {
|
|
4
|
+
actions: Array<ConfigPatchDeployAction | TomlPatchDeployAction>;
|
|
5
|
+
warnings: PlanWarning[];
|
|
6
|
+
}
|
|
7
|
+
export declare function compilePermissionsActions(entry: PermissionsEntry, detectedAgents: AgentId[], home: string): PermissionsAdapterResult;
|
|
8
|
+
export declare function compilePermissionsReverts(entry: PermissionsEntry, agentFilter: AgentId[] | null, home: string): Array<ConfigPatchRevertAction | TomlPatchRevertAction>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { AGENT_REGISTRY_BY_ID } from "../../config/agents.js";
|
|
3
|
+
import { getPlatformKey, resolvePlaceholders } from "../resolve.js";
|
|
4
|
+
import { validatePermissionsConfigShape } from "../validation.js";
|
|
5
|
+
function isTomlTarget(targetPath) {
|
|
6
|
+
return path.extname(targetPath).toLowerCase() === ".toml";
|
|
7
|
+
}
|
|
8
|
+
export function compilePermissionsActions(entry, detectedAgents, home) {
|
|
9
|
+
const actions = [];
|
|
10
|
+
const warnings = [];
|
|
11
|
+
const platform = getPlatformKey();
|
|
12
|
+
for (const agentId of entry.agents) {
|
|
13
|
+
if (!detectedAgents.includes(agentId))
|
|
14
|
+
continue;
|
|
15
|
+
const agent = AGENT_REGISTRY_BY_ID[agentId];
|
|
16
|
+
const support = agent?.permissionsSupport;
|
|
17
|
+
if (!support || support.status === "unsupported") {
|
|
18
|
+
warnings.push({
|
|
19
|
+
kind: "confidence",
|
|
20
|
+
message: `permissions: agent "${agentId}" ${support?.status === "unsupported" ? support.reason : "does not expose a supported permissions adapter"} — skipping "${entry.name}"`,
|
|
21
|
+
});
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (support.status === "planned") {
|
|
25
|
+
warnings.push({
|
|
26
|
+
kind: "confidence",
|
|
27
|
+
message: `permissions: agent "${agentId}" permissions support is planned via ${support.plannedSurface} — skipping "${entry.name}" until that surface is implemented`,
|
|
28
|
+
});
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
validatePermissionsConfigShape(entry.config, entry.name, agentId);
|
|
32
|
+
const rawTarget = resolvePlaceholders(support.path[platform], entry.name, home);
|
|
33
|
+
const resolvedTarget = path.resolve(rawTarget);
|
|
34
|
+
const confidence = agent.provenance.permissions ?? "provisional";
|
|
35
|
+
if (isTomlTarget(resolvedTarget)) {
|
|
36
|
+
actions.push({
|
|
37
|
+
kind: "toml-patch",
|
|
38
|
+
skill: entry.name,
|
|
39
|
+
agent: agentId,
|
|
40
|
+
target: resolvedTarget,
|
|
41
|
+
config: entry.config,
|
|
42
|
+
confidence,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
actions.push({
|
|
47
|
+
kind: "config-patch",
|
|
48
|
+
skill: entry.name,
|
|
49
|
+
agent: agentId,
|
|
50
|
+
target: resolvedTarget,
|
|
51
|
+
patch: entry.config,
|
|
52
|
+
confidence,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { actions, warnings };
|
|
57
|
+
}
|
|
58
|
+
export function compilePermissionsReverts(entry, agentFilter, home) {
|
|
59
|
+
const actions = [];
|
|
60
|
+
const platform = getPlatformKey();
|
|
61
|
+
for (const agentId of entry.agents) {
|
|
62
|
+
if (agentFilter && !agentFilter.includes(agentId))
|
|
63
|
+
continue;
|
|
64
|
+
const agent = AGENT_REGISTRY_BY_ID[agentId];
|
|
65
|
+
const support = agent?.permissionsSupport;
|
|
66
|
+
if (!support ||
|
|
67
|
+
support.status === "unsupported" ||
|
|
68
|
+
support.status === "planned")
|
|
69
|
+
continue;
|
|
70
|
+
const rawTarget = resolvePlaceholders(support.path[platform], entry.name, home);
|
|
71
|
+
const target = path.resolve(rawTarget);
|
|
72
|
+
if (isTomlTarget(target)) {
|
|
73
|
+
actions.push({
|
|
74
|
+
kind: "toml-patch",
|
|
75
|
+
skill: entry.name,
|
|
76
|
+
agent: agentId,
|
|
77
|
+
target,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
actions.push({
|
|
82
|
+
kind: "config-patch",
|
|
83
|
+
skill: entry.name,
|
|
84
|
+
agent: agentId,
|
|
85
|
+
target,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return actions;
|
|
90
|
+
}
|