@kuznai/inception-engine 0.6.2 → 0.8.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.
@@ -1,12 +1,24 @@
1
- import { type RegistryEntry } from "../schemas/registry.ts";
1
+ import { type ConfigPatchRegistryEntry, type FileWriteRegistryEntry, type RegistryEntry, type SkillDirRegistryEntry } from "../schemas/registry.ts";
2
2
  import type { AgentId } from "../types.ts";
3
3
  export type { RegistryEntry } from "../schemas/registry.ts";
4
- export declare function registryPath(home: string): string;
5
- export declare function registerDeployment(home: string, targetPath: string, entry: Omit<RegistryEntry, "deployed">): Promise<void>;
6
- export declare function unregisterDeployment(home: string, targetPath: string): Promise<void>;
7
- export declare function lookupDeployment(home: string, targetPath: string): Promise<RegistryEntry | null>;
8
- export declare function verifyDeployment(home: string, targetPath: string, expected: {
4
+ export type VerifyExpected = {
5
+ kind: "skill-dir";
6
+ source: string;
7
+ skill: string;
8
+ agent: AgentId;
9
+ } | {
10
+ kind: "file-write";
9
11
  source: string;
10
12
  skill: string;
11
13
  agent: AgentId;
12
- }): Promise<RegistryEntry | null>;
14
+ } | {
15
+ kind: "config-patch";
16
+ skill: string;
17
+ agent: AgentId;
18
+ };
19
+ export declare function registryPath(home: string): string;
20
+ export type RegisterEntry = Omit<SkillDirRegistryEntry, "deployed"> | Omit<FileWriteRegistryEntry, "deployed"> | Omit<ConfigPatchRegistryEntry, "deployed">;
21
+ export declare function registerDeployment(home: string, targetPath: string, entry: RegisterEntry): Promise<void>;
22
+ export declare function unregisterDeployment(home: string, targetPath: string): Promise<void>;
23
+ export declare function lookupDeployment(home: string, targetPath: string): Promise<RegistryEntry | null>;
24
+ export declare function verifyDeployment(home: string, targetPath: string, expected: VerifyExpected): Promise<RegistryEntry | null>;
@@ -59,9 +59,15 @@ export async function verifyDeployment(home, targetPath, expected) {
59
59
  const entry = await lookupDeployment(home, targetPath);
60
60
  if (!entry)
61
61
  return null;
62
- if (entry.source !== expected.source ||
63
- entry.skill !== expected.skill ||
64
- entry.agent !== expected.agent) {
62
+ if (entry.kind !== expected.kind)
63
+ return null;
64
+ if (entry.skill !== expected.skill)
65
+ return null;
66
+ if (entry.agent !== expected.agent)
67
+ return null;
68
+ if ((expected.kind === "skill-dir" || expected.kind === "file-write") &&
69
+ (entry.kind === "skill-dir" || entry.kind === "file-write") &&
70
+ entry.source !== expected.source) {
65
71
  return null;
66
72
  }
67
73
  return entry;
@@ -1,6 +1,6 @@
1
- import type { CliOptions, Manifest } from "../types.ts";
1
+ import type { AgentId, CliOptions, Manifest } from "../types.ts";
2
2
  export interface PreflightWarning {
3
3
  kind: "policy" | "config-authority" | "info";
4
4
  message: string;
5
5
  }
6
- export declare function runPreflight(_options: CliOptions, _manifest: Manifest, _home: string): Promise<PreflightWarning[]>;
6
+ export declare function runPreflight(_options: CliOptions, _manifest: Manifest, _home: string, detectedAgents: AgentId[]): Promise<PreflightWarning[]>;
@@ -1,6 +1,28 @@
1
- export async function runPreflight(_options, _manifest, _home) {
2
- // Extension point for future enterprise policy checks.
3
- // Future additions: check for local-config overrides, policy files,
4
- // agent version constraints, etc.
5
- return [];
1
+ import { AGENT_REGISTRY_BY_ID } from "../config/agents.js";
2
+ export async function runPreflight(_options, _manifest, _home, detectedAgents) {
3
+ const warnings = [];
4
+ for (const agentId of detectedAgents) {
5
+ const agent = AGENT_REGISTRY_BY_ID[agentId];
6
+ if (!agent)
7
+ continue;
8
+ if (agent.provenance.skills === "implementation-only") {
9
+ warnings.push({
10
+ kind: "config-authority",
11
+ message: `Agent "${agentId}" skill support is implementation-only: paths are derived from source inspection, not published documentation.`,
12
+ });
13
+ }
14
+ else if (agent.provenance.skills === "provisional") {
15
+ warnings.push({
16
+ kind: "config-authority",
17
+ message: `Agent "${agentId}" skill support is provisional: behavior has not been independently verified.`,
18
+ });
19
+ }
20
+ if (agent.policyNote) {
21
+ warnings.push({
22
+ kind: "policy",
23
+ message: `Agent "${agentId}": ${agent.policyNote}`,
24
+ });
25
+ }
26
+ }
27
+ return warnings;
6
28
  }
@@ -1,4 +1,4 @@
1
- import type { AgentId, Manifest, RevertAction } from "../types.ts";
1
+ import type { AgentId, Manifest, PlannedChange, RevertAction } from "../types.ts";
2
2
  export declare function planRevert(manifest: Manifest, detectedAgents: AgentId[], home: string): RevertAction[];
3
3
  export declare function planRevertAll(manifest: Manifest, home: string): RevertAction[];
4
4
  export declare function executeRevert(actions: RevertAction[], dryRun: boolean, verbose: boolean, home: string): Promise<{
@@ -8,4 +8,5 @@ export declare function executeRevert(actions: RevertAction[], dryRun: boolean,
8
8
  action: RevertAction;
9
9
  error: string;
10
10
  }>;
11
+ planned: PlannedChange[];
11
12
  }>;
@@ -1,46 +1,126 @@
1
- import { lstat, rm, unlink } from "node:fs/promises";
1
+ import { lstat, readFile, rm, unlink, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
2
3
  import { AGENT_REGISTRY_BY_ID } from "../config/agents.js";
3
4
  import { logger } from "../logger.js";
4
5
  import { lookupDeployment, unregisterDeployment } from "./ownership.js";
5
6
  import { resolveAgentSkillPath } from "./resolve.js";
6
- export function planRevert(manifest, detectedAgents, home) {
7
+ function resolveTargetTemplate(template, home) {
8
+ const appdata = process.env.APPDATA ?? path.join(home, "AppData", "Roaming");
9
+ const xdgRaw = process.env.XDG_CONFIG_HOME;
10
+ const xdgConfig = xdgRaw && path.isAbsolute(xdgRaw) ? xdgRaw : path.join(home, ".config");
11
+ return template
12
+ .replace("{home}", home)
13
+ .replace("{appdata}", appdata)
14
+ .replace("{xdg_config}", xdgConfig);
15
+ }
16
+ function buildSkillDirReverts(manifest, home, agentFilter) {
7
17
  const actions = [];
8
18
  for (const skill of manifest.skills) {
9
19
  for (const agentId of skill.agents) {
10
- if (!detectedAgents.includes(agentId))
20
+ if (agentFilter && !agentFilter.includes(agentId))
11
21
  continue;
12
22
  const agent = AGENT_REGISTRY_BY_ID[agentId];
13
23
  if (!agent)
14
24
  continue;
15
- const target = resolveAgentSkillPath(agent, skill.name, home);
16
25
  actions.push({
17
26
  kind: "skill-dir",
18
27
  skill: skill.name,
19
28
  agent: agentId,
20
- target,
29
+ target: resolveAgentSkillPath(agent, skill.name, home),
21
30
  });
22
31
  }
23
32
  }
24
33
  return actions;
25
34
  }
26
- export function planRevertAll(manifest, home) {
35
+ function buildFileWriteReverts(manifest, home, agentFilter) {
27
36
  const actions = [];
28
- for (const skill of manifest.skills) {
29
- for (const agentId of skill.agents) {
37
+ for (const fileEntry of manifest.files ?? []) {
38
+ for (const agentId of fileEntry.agents) {
39
+ if (agentFilter && !agentFilter.includes(agentId))
40
+ continue;
30
41
  const agent = AGENT_REGISTRY_BY_ID[agentId];
31
42
  if (!agent)
32
43
  continue;
33
- const target = resolveAgentSkillPath(agent, skill.name, home);
34
44
  actions.push({
35
- kind: "skill-dir",
36
- skill: skill.name,
45
+ kind: "file-write",
46
+ skill: fileEntry.name,
47
+ agent: agentId,
48
+ target: resolveTargetTemplate(fileEntry.target, home),
49
+ });
50
+ }
51
+ }
52
+ return actions;
53
+ }
54
+ function buildConfigPatchReverts(manifest, home, agentFilter) {
55
+ const actions = [];
56
+ for (const configEntry of manifest.configs ?? []) {
57
+ for (const agentId of configEntry.agents) {
58
+ if (agentFilter && !agentFilter.includes(agentId))
59
+ continue;
60
+ const agent = AGENT_REGISTRY_BY_ID[agentId];
61
+ if (!agent)
62
+ continue;
63
+ actions.push({
64
+ kind: "config-patch",
65
+ skill: configEntry.name,
37
66
  agent: agentId,
38
- target,
67
+ target: resolveTargetTemplate(configEntry.target, home),
39
68
  });
40
69
  }
41
70
  }
42
71
  return actions;
43
72
  }
73
+ export function planRevert(manifest, detectedAgents, home) {
74
+ return [
75
+ ...buildSkillDirReverts(manifest, home, detectedAgents),
76
+ ...buildFileWriteReverts(manifest, home, detectedAgents),
77
+ ...buildConfigPatchReverts(manifest, home, detectedAgents),
78
+ ];
79
+ }
80
+ export function planRevertAll(manifest, home) {
81
+ return [
82
+ ...buildSkillDirReverts(manifest, home, null),
83
+ ...buildFileWriteReverts(manifest, home, null),
84
+ ...buildConfigPatchReverts(manifest, home, null),
85
+ ];
86
+ }
87
+ function recordOutcome(result, action, counts, failed) {
88
+ if (result.outcome === "fail") {
89
+ failed.push({ action, error: result.error });
90
+ }
91
+ else if (result.outcome === "skip") {
92
+ counts.skipped++;
93
+ }
94
+ else {
95
+ counts.succeeded++;
96
+ }
97
+ }
98
+ async function readJsonConfig(filePath) {
99
+ const rawContent = await readFile(filePath, "utf-8");
100
+ let parsed;
101
+ try {
102
+ parsed = JSON.parse(rawContent);
103
+ }
104
+ catch {
105
+ throw new Error(`Config file is not valid JSON: ${filePath}`);
106
+ }
107
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
108
+ throw new Error(`Config file is not a JSON object: ${filePath}`);
109
+ }
110
+ return parsed;
111
+ }
112
+ function applyUndoPatch(current, undoPatch) {
113
+ const restored = { ...current };
114
+ for (const [key, originalValue] of Object.entries(undoPatch)) {
115
+ if (originalValue === null) {
116
+ delete restored[key];
117
+ }
118
+ else {
119
+ restored[key] = originalValue;
120
+ }
121
+ }
122
+ return restored;
123
+ }
44
124
  function lstatOutcome(err) {
45
125
  if (err.code === "ENOENT") {
46
126
  return { outcome: "skip" };
@@ -52,34 +132,33 @@ export async function executeRevert(actions, dryRun, verbose, home) {
52
132
  let succeeded = 0;
53
133
  let skipped = 0;
54
134
  const failed = [];
135
+ const planned = [];
136
+ const counts = { succeeded, skipped };
55
137
  for (const action of actions) {
138
+ let result;
56
139
  switch (action.kind) {
57
- case "skill-dir": {
58
- const result = await executeRevertAction(action, dryRun, verbose, home);
59
- if (result.outcome === "fail") {
60
- failed.push({ action, error: result.error });
61
- }
62
- else if (result.outcome === "skip") {
63
- skipped++;
64
- }
65
- else {
66
- succeeded++;
67
- }
140
+ case "skill-dir":
141
+ result = await executeRevertAction(action, dryRun, verbose, home, planned);
142
+ break;
143
+ case "file-write":
144
+ result = await revertFileWrite(action, dryRun, verbose, home, planned);
68
145
  break;
69
- }
70
- default: {
71
- const _ = action.kind;
72
- throw new Error(`Unhandled revert action kind: ${_}`);
73
- }
146
+ case "config-patch":
147
+ result = await revertConfigPatch(action, dryRun, verbose, home, planned);
148
+ break;
149
+ default:
150
+ throw new Error(`Unhandled revert action kind: ${action}`);
74
151
  }
152
+ recordOutcome(result, action, counts, failed);
75
153
  }
76
- return { succeeded, skipped, failed };
154
+ succeeded = counts.succeeded;
155
+ skipped = counts.skipped;
156
+ return { succeeded, skipped, failed, planned };
77
157
  }
78
- async function executeRevertAction(action, dryRun, verbose, home) {
158
+ async function executeRevertAction(action, dryRun, verbose, home, planned) {
79
159
  const label = `${action.skill} -> ${action.agent}`;
80
- let stat;
81
160
  try {
82
- stat = await lstat(action.target);
161
+ await lstat(action.target);
83
162
  }
84
163
  catch (err) {
85
164
  const result = lstatOutcome(err);
@@ -96,14 +175,20 @@ async function executeRevertAction(action, dryRun, verbose, home) {
96
175
  return { outcome: "skip" };
97
176
  }
98
177
  if (dryRun) {
99
- logger.plan(label);
100
- if (verbose) {
101
- logger.detail(`would remove: ${action.target}`);
102
- }
178
+ planned.push({
179
+ verb: "remove",
180
+ kind: "skill-dir",
181
+ skill: action.skill,
182
+ agent: action.agent,
183
+ target: action.target,
184
+ });
103
185
  return { outcome: "ok" };
104
186
  }
105
187
  try {
106
- if (stat.isSymbolicLink()) {
188
+ // Re-stat immediately before deletion to minimise the window between the
189
+ // type-check and the removal syscall.
190
+ const currentStat = await lstat(action.target);
191
+ if (currentStat.isSymbolicLink()) {
107
192
  await unlink(action.target);
108
193
  }
109
194
  else {
@@ -116,6 +201,113 @@ async function executeRevertAction(action, dryRun, verbose, home) {
116
201
  }
117
202
  return { outcome: "ok" };
118
203
  }
204
+ catch (err) {
205
+ if (err.code === "ENOENT") {
206
+ // Target disappeared between ownership check and removal — treat as skip.
207
+ logger.skip(label, "(disappeared before removal, skipping)");
208
+ return { outcome: "skip" };
209
+ }
210
+ const msg = err instanceof Error ? err.message : String(err);
211
+ logger.fail(label, msg);
212
+ return { outcome: "fail", error: msg };
213
+ }
214
+ }
215
+ async function revertFileWrite(action, dryRun, verbose, home, planned) {
216
+ const label = `${action.skill} -> ${action.agent}`;
217
+ try {
218
+ await lstat(action.target);
219
+ }
220
+ catch (err) {
221
+ const result = lstatOutcome(err);
222
+ if (result.outcome === "skip") {
223
+ logger.skip(label, "(not found, skipping)");
224
+ return result;
225
+ }
226
+ logger.fail(label, result.error);
227
+ return result;
228
+ }
229
+ const entry = await lookupDeployment(home, action.target);
230
+ if (!entry || entry.skill !== action.skill || entry.agent !== action.agent) {
231
+ logger.warn(label, `skipping: ${action.target} is not in the deployment registry — not managed by inception-engine`);
232
+ return { outcome: "skip" };
233
+ }
234
+ if (dryRun) {
235
+ planned.push({
236
+ verb: "remove",
237
+ kind: "file-write",
238
+ skill: action.skill,
239
+ agent: action.agent,
240
+ target: action.target,
241
+ });
242
+ return { outcome: "ok" };
243
+ }
244
+ try {
245
+ // Re-stat immediately before deletion to minimise the type-check to
246
+ // removal window; handle the case where the file has since disappeared.
247
+ await lstat(action.target);
248
+ await unlink(action.target);
249
+ await unregisterDeployment(home, action.target);
250
+ logger.ok(label);
251
+ if (verbose) {
252
+ logger.detail(`removed: ${action.target}`);
253
+ }
254
+ return { outcome: "ok" };
255
+ }
256
+ catch (err) {
257
+ if (err.code === "ENOENT") {
258
+ logger.skip(label, "(disappeared before removal, skipping)");
259
+ return { outcome: "skip" };
260
+ }
261
+ const msg = err instanceof Error ? err.message : String(err);
262
+ logger.fail(label, msg);
263
+ return { outcome: "fail", error: msg };
264
+ }
265
+ }
266
+ async function revertConfigPatch(action, dryRun, verbose, home, planned) {
267
+ const label = `${action.skill} -> ${action.agent}`;
268
+ try {
269
+ await lstat(action.target);
270
+ }
271
+ catch (err) {
272
+ const result = lstatOutcome(err);
273
+ if (result.outcome === "skip") {
274
+ logger.skip(label, "(not found, skipping)");
275
+ return result;
276
+ }
277
+ logger.fail(label, result.error);
278
+ return result;
279
+ }
280
+ const entry = await lookupDeployment(home, action.target);
281
+ if (!entry ||
282
+ entry.kind !== "config-patch" ||
283
+ entry.skill !== action.skill ||
284
+ entry.agent !== action.agent) {
285
+ logger.warn(label, `skipping: ${action.target} is not in the deployment registry — not managed by inception-engine`);
286
+ return { outcome: "skip" };
287
+ }
288
+ const configPatchEntry = entry;
289
+ if (dryRun) {
290
+ planned.push({
291
+ verb: "unapply-patch",
292
+ kind: "config-patch",
293
+ skill: action.skill,
294
+ agent: action.agent,
295
+ target: action.target,
296
+ patch: configPatchEntry.undoPatch,
297
+ });
298
+ return { outcome: "ok" };
299
+ }
300
+ try {
301
+ const current = await readJsonConfig(action.target);
302
+ const restored = applyUndoPatch(current, configPatchEntry.undoPatch);
303
+ await writeFile(action.target, `${JSON.stringify(restored, null, 2)}\n`, "utf-8");
304
+ await unregisterDeployment(home, action.target);
305
+ logger.ok(label);
306
+ if (verbose) {
307
+ logger.detail(`unapplied patch from: ${action.target}`);
308
+ }
309
+ return { outcome: "ok" };
310
+ }
119
311
  catch (err) {
120
312
  const msg = err instanceof Error ? err.message : String(err);
121
313
  logger.fail(label, msg);
package/dist/index.js CHANGED
@@ -5,8 +5,8 @@ import { AGENT_REGISTRY } from "./config/agents.js";
5
5
  import { loadManifest } from "./config/manifest.js";
6
6
  import { executeDeploy, planDeploy } from "./core/deploy.js";
7
7
  import { detectInstalledAgents } from "./core/detect.js";
8
- import { resolveHome } from "./core/resolve.js";
9
8
  import { runPreflight } from "./core/preflight.js";
9
+ import { resolveHome } from "./core/resolve.js";
10
10
  import { executeRevert, planRevert, planRevertAll } from "./core/revert.js";
11
11
  import { UserError } from "./errors.js";
12
12
  import { dryRunPrefix, logger } from "./logger.js";
@@ -106,15 +106,26 @@ async function main() {
106
106
  }
107
107
  const manifest = await loadManifest(options.directory);
108
108
  const home = resolveHome();
109
- const preflightWarnings = await runPreflight(options, manifest, home);
110
- for (const w of preflightWarnings) {
111
- logger.warn("preflight", w.message);
112
- }
113
109
  if (options.command === "deploy") {
114
110
  return runDeploy(options, manifest, home);
115
111
  }
116
112
  return runRevert(options, manifest, home);
117
113
  }
114
+ function renderDryRunPlan(planned) {
115
+ for (const change of planned) {
116
+ logger.plan(`[${change.agent}] ${change.verb} ${change.skill}`);
117
+ if (change.source !== undefined) {
118
+ logger.detail(`source: ${change.source}`);
119
+ }
120
+ logger.detail(`target: ${change.target}`);
121
+ if (change.verb === "patch-config" && change.patch !== undefined) {
122
+ logger.detail(`patch: ${JSON.stringify(change.patch)}`);
123
+ }
124
+ else if (change.verb === "unapply-patch" && change.patch !== undefined) {
125
+ logger.detail(`undo: ${JSON.stringify(change.patch)}`);
126
+ }
127
+ }
128
+ }
118
129
  async function runDeploy(options, manifest, home) {
119
130
  let detectedAgents;
120
131
  if (options.agents) {
@@ -134,19 +145,34 @@ async function runDeploy(options, manifest, home) {
134
145
  logger.info(`Detected agents: ${detectedAgents.join(", ")}`);
135
146
  }
136
147
  }
137
- const actions = await planDeploy(manifest, options.directory, detectedAgents, home);
148
+ const preflightWarnings = await runPreflight(options, manifest, home, detectedAgents);
149
+ for (const w of preflightWarnings) {
150
+ const label = w.kind === "policy" ? "policy" : "preflight";
151
+ logger.warn(label, w.message);
152
+ }
153
+ const { actions, warnings: planWarnings } = await planDeploy(manifest, options.directory, detectedAgents, home);
154
+ for (const w of planWarnings) {
155
+ logger.warn("plan", w.message);
156
+ }
138
157
  if (actions.length === 0) {
139
158
  logger.info("No skills to deploy for detected agents.");
140
159
  return 0;
141
160
  }
142
- logger.info(`${dryRunPrefix(options.dryRun)}Deploying ${actions.length} skill(s):`);
143
- const { succeeded, failed } = await executeDeploy(actions, options.dryRun, options.verbose, home);
161
+ logger.info(`${dryRunPrefix(options.dryRun)}Deploying ${actions.length} action(s):`);
162
+ const { succeeded, failed, planned } = await executeDeploy(actions, options.dryRun, options.verbose, home);
163
+ if (options.dryRun) {
164
+ logger.info("");
165
+ renderDryRunPlan(planned);
166
+ logger.info("");
167
+ logger.info(`${planned.length} action(s) would be applied (dry-run)`);
168
+ return 0;
169
+ }
144
170
  logger.info("");
145
171
  if (failed.length > 0) {
146
172
  logger.info(`${succeeded} succeeded, ${failed.length} failed`);
147
173
  return 1;
148
174
  }
149
- logger.info(`${succeeded} skill(s) deployed${options.dryRun ? " (dry-run)" : ""}`);
175
+ logger.info(`${succeeded} action(s) deployed`);
150
176
  return 0;
151
177
  }
152
178
  async function runRevert(options, manifest, home) {
@@ -157,21 +183,28 @@ async function runRevert(options, manifest, home) {
157
183
  logger.info("No skills to revert.");
158
184
  return 0;
159
185
  }
160
- logger.info(`${dryRunPrefix(options.dryRun)}Reverting ${actions.length} skill(s):`);
161
- const { succeeded, skipped, failed } = await executeRevert(actions, options.dryRun, options.verbose, home);
186
+ logger.info(`${dryRunPrefix(options.dryRun)}Reverting ${actions.length} action(s):`);
187
+ const { succeeded, skipped, failed, planned } = await executeRevert(actions, options.dryRun, options.verbose, home);
188
+ if (options.dryRun) {
189
+ logger.info("");
190
+ renderDryRunPlan(planned);
191
+ logger.info("");
192
+ logger.info(`${planned.length} action(s) would be removed (dry-run)`);
193
+ return 0;
194
+ }
162
195
  logger.info("");
163
196
  if (failed.length > 0) {
164
197
  const parts = [`${succeeded} removed`];
165
198
  if (skipped > 0)
166
199
  parts.push(`${skipped} skipped`);
167
200
  parts.push(`${failed.length} failed`);
168
- logger.info(`${parts.join(", ")}${options.dryRun ? " (dry-run)" : ""}`);
201
+ logger.info(parts.join(", "));
169
202
  return 1;
170
203
  }
171
204
  const parts = [`${succeeded} removed`];
172
205
  if (skipped > 0)
173
206
  parts.push(`${skipped} skipped`);
174
- logger.info(`${parts.join(", ")}${options.dryRun ? " (dry-run)" : ""}`);
207
+ logger.info(parts.join(", "));
175
208
  return 0;
176
209
  }
177
210
  const USER_ERROR_EXIT = {
@@ -22,6 +22,38 @@ export declare const SkillEntrySchema: z.ZodObject<{
22
22
  "github-copilot": "github-copilot";
23
23
  }>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
24
24
  }, z.core.$strip>;
25
+ export declare const FileEntrySchema: z.ZodObject<{
26
+ name: z.ZodString;
27
+ path: z.ZodString;
28
+ target: z.ZodString;
29
+ agents: z.ZodPipe<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
30
+ "claude-code": "claude-code";
31
+ codex: "codex";
32
+ "gemini-cli": "gemini-cli";
33
+ antigravity: "antigravity";
34
+ opencode: "opencode";
35
+ "github-copilot": "github-copilot";
36
+ }>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
37
+ }, z.core.$strip>;
38
+ export declare const ConfigEntrySchema: z.ZodObject<{
39
+ name: z.ZodString;
40
+ target: z.ZodString;
41
+ patch: z.ZodRecord<z.ZodString, z.ZodUnknown>;
42
+ agents: z.ZodPipe<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
43
+ "claude-code": "claude-code";
44
+ codex: "codex";
45
+ "gemini-cli": "gemini-cli";
46
+ antigravity: "antigravity";
47
+ opencode: "opencode";
48
+ "github-copilot": "github-copilot";
49
+ }>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
50
+ }, z.core.$strip>;
51
+ export declare const McpServerEntrySchema: z.ZodObject<{
52
+ name: z.ZodString;
53
+ }, z.core.$loose>;
54
+ export declare const AgentRuleEntrySchema: z.ZodObject<{
55
+ name: z.ZodString;
56
+ }, z.core.$loose>;
25
57
  export declare const ManifestSchema: z.ZodObject<{
26
58
  skills: z.ZodArray<z.ZodObject<{
27
59
  name: z.ZodString;
@@ -35,10 +67,44 @@ export declare const ManifestSchema: z.ZodObject<{
35
67
  "github-copilot": "github-copilot";
36
68
  }>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
37
69
  }, z.core.$strip>>;
38
- mcpServers: z.ZodDefault<z.ZodArray<z.ZodUnknown>>;
39
- agentRules: z.ZodDefault<z.ZodArray<z.ZodUnknown>>;
70
+ files: z.ZodDefault<z.ZodArray<z.ZodObject<{
71
+ name: z.ZodString;
72
+ path: z.ZodString;
73
+ target: z.ZodString;
74
+ agents: z.ZodPipe<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
75
+ "claude-code": "claude-code";
76
+ codex: "codex";
77
+ "gemini-cli": "gemini-cli";
78
+ antigravity: "antigravity";
79
+ opencode: "opencode";
80
+ "github-copilot": "github-copilot";
81
+ }>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
82
+ }, z.core.$strip>>>;
83
+ configs: z.ZodDefault<z.ZodArray<z.ZodObject<{
84
+ name: z.ZodString;
85
+ target: z.ZodString;
86
+ patch: z.ZodRecord<z.ZodString, z.ZodUnknown>;
87
+ agents: z.ZodPipe<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
88
+ "claude-code": "claude-code";
89
+ codex: "codex";
90
+ "gemini-cli": "gemini-cli";
91
+ antigravity: "antigravity";
92
+ opencode: "opencode";
93
+ "github-copilot": "github-copilot";
94
+ }>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
95
+ }, z.core.$strip>>>;
96
+ mcpServers: z.ZodDefault<z.ZodArray<z.ZodObject<{
97
+ name: z.ZodString;
98
+ }, z.core.$loose>>>;
99
+ agentRules: z.ZodDefault<z.ZodArray<z.ZodObject<{
100
+ name: z.ZodString;
101
+ }, z.core.$loose>>>;
40
102
  }, z.core.$strip>;
41
103
  export type SkillEntry = z.infer<typeof SkillEntrySchema>;
104
+ export type FileEntry = z.infer<typeof FileEntrySchema>;
105
+ export type ConfigEntry = z.infer<typeof ConfigEntrySchema>;
106
+ export type McpServerEntry = z.infer<typeof McpServerEntrySchema>;
107
+ export type AgentRuleEntry = z.infer<typeof AgentRuleEntrySchema>;
42
108
  export type Manifest = z.infer<typeof ManifestSchema>;
43
109
  export declare const AgentListSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>, z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
44
110
  "claude-code": "claude-code";