@kuznai/inception-engine 0.16.0 → 0.18.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 +72 -6
- package/dist/config/agents.js +104 -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/frontmatter.d.ts +17 -5
- package/dist/core/adapters/frontmatter.js +36 -57
- package/dist/core/adapters/index.d.ts +4 -3
- package/dist/core/adapters/index.js +8 -2
- package/dist/core/adapters/mcp.js +10 -1
- package/dist/core/adapters/permissions.js +10 -1
- package/dist/core/adapters/rules.js +49 -16
- package/dist/core/deploy.js +5 -3
- package/dist/core/init.js +181 -11
- package/dist/core/preflight.d.ts +2 -2
- package/dist/core/preflight.js +71 -1
- package/dist/core/resolve.js +4 -0
- package/dist/core/revert.js +5 -1
- package/dist/core/validation.js +21 -38
- package/dist/schemas/manifest.d.ts +33 -0
- package/dist/schemas/manifest.js +13 -0
- package/dist/types.d.ts +27 -4
- package/package.json +2 -2
package/dist/core/validation.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { lstat, readFile, realpath, stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { UserError } from "../errors.js";
|
|
4
|
+
import { parseFrontmatterDocument } from "./adapters/frontmatter.js";
|
|
4
5
|
export function sourceAccessError(err, sourcePath) {
|
|
5
6
|
const code = err.code;
|
|
6
7
|
if (code === "ENOENT")
|
|
@@ -147,23 +148,6 @@ export function validateAgentRuleMarkdownPath(manifestPath, agentId) {
|
|
|
147
148
|
throw new UserError("DEPLOY_FAILED", `agentRules entry "${manifestPath}" for agent "${agentId}" must point to a Markdown source file`);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
|
-
function trimMatchingQuotes(value) {
|
|
151
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
152
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
153
|
-
return value.slice(1, -1).trim();
|
|
154
|
-
}
|
|
155
|
-
return value;
|
|
156
|
-
}
|
|
157
|
-
function parseSimpleFrontmatterValue(field, rawValue, manifestPath) {
|
|
158
|
-
const value = trimMatchingQuotes(rawValue.trim());
|
|
159
|
-
if (value.length === 0) {
|
|
160
|
-
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter field "${field}" must be a non-empty string`);
|
|
161
|
-
}
|
|
162
|
-
if (rawValue.trim() === "|" || rawValue.trim() === ">") {
|
|
163
|
-
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter field "${field}" must be a single-line string`);
|
|
164
|
-
}
|
|
165
|
-
return value;
|
|
166
|
-
}
|
|
167
151
|
export async function validateSkillDefinitionFile(sourcePath, manifestPath) {
|
|
168
152
|
await validateSourceFile(sourcePath, `${manifestPath}/SKILL.md`);
|
|
169
153
|
let raw;
|
|
@@ -181,27 +165,26 @@ export async function validateSkillDefinitionFile(sourcePath, manifestPath) {
|
|
|
181
165
|
if (closingIndex === -1) {
|
|
182
166
|
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md is missing the closing --- frontmatter delimiter`);
|
|
183
167
|
}
|
|
184
|
-
let
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (trimmed.length === 0 || trimmed.startsWith("#"))
|
|
189
|
-
continue;
|
|
190
|
-
const match = /^([A-Za-z0-9_-]+)\s*:\s*(.*)$/.exec(line);
|
|
191
|
-
if (!match)
|
|
192
|
-
continue;
|
|
193
|
-
const [, key, rawValue] = match;
|
|
194
|
-
if (key === "name") {
|
|
195
|
-
name = parseSimpleFrontmatterValue("name", rawValue, manifestPath);
|
|
196
|
-
}
|
|
197
|
-
else if (key === "description") {
|
|
198
|
-
description = parseSimpleFrontmatterValue("description", rawValue, manifestPath);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
if (name === null) {
|
|
202
|
-
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter must include a non-empty "name" field`);
|
|
168
|
+
let attributes;
|
|
169
|
+
try {
|
|
170
|
+
const parsed = parseFrontmatterDocument(raw);
|
|
171
|
+
attributes = parsed.attributes;
|
|
203
172
|
}
|
|
204
|
-
|
|
205
|
-
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter
|
|
173
|
+
catch (err) {
|
|
174
|
+
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md has malformed YAML frontmatter: ${err instanceof Error ? err.message : String(err)}`);
|
|
206
175
|
}
|
|
176
|
+
const validateField = (field) => {
|
|
177
|
+
const value = attributes[field];
|
|
178
|
+
if (value === undefined || value === null) {
|
|
179
|
+
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter must include a non-empty "${field}" field`);
|
|
180
|
+
}
|
|
181
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
182
|
+
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter field "${field}" must be a non-empty string`);
|
|
183
|
+
}
|
|
184
|
+
if (value.includes("\n") || value.includes("\r")) {
|
|
185
|
+
throw new UserError("DEPLOY_FAILED", `Skill "${manifestPath}" SKILL.md frontmatter field "${field}" must be a single-line string`);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
validateField("name");
|
|
189
|
+
validateField("description");
|
|
207
190
|
}
|
|
@@ -71,6 +71,10 @@ export declare const AgentRuleEntrySchema: z.ZodObject<{
|
|
|
71
71
|
"github-copilot": "github-copilot";
|
|
72
72
|
}>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
|
|
73
73
|
path: z.ZodString;
|
|
74
|
+
scope: z.ZodDefault<z.ZodEnum<{
|
|
75
|
+
global: "global";
|
|
76
|
+
repo: "repo";
|
|
77
|
+
}>>;
|
|
74
78
|
}, z.core.$strip>;
|
|
75
79
|
export declare const PermissionsEntrySchema: z.ZodObject<{
|
|
76
80
|
name: z.ZodString;
|
|
@@ -84,6 +88,18 @@ export declare const PermissionsEntrySchema: z.ZodObject<{
|
|
|
84
88
|
}>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
|
|
85
89
|
config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
86
90
|
}, z.core.$strip>;
|
|
91
|
+
export declare const AgentDefinitionEntrySchema: z.ZodObject<{
|
|
92
|
+
name: z.ZodString;
|
|
93
|
+
agents: z.ZodPipe<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
94
|
+
"claude-code": "claude-code";
|
|
95
|
+
codex: "codex";
|
|
96
|
+
"gemini-cli": "gemini-cli";
|
|
97
|
+
antigravity: "antigravity";
|
|
98
|
+
opencode: "opencode";
|
|
99
|
+
"github-copilot": "github-copilot";
|
|
100
|
+
}>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
|
|
101
|
+
path: z.ZodString;
|
|
102
|
+
}, z.core.$strip>;
|
|
87
103
|
export declare const ManifestSchema: z.ZodObject<{
|
|
88
104
|
skills: z.ZodArray<z.ZodObject<{
|
|
89
105
|
name: z.ZodString;
|
|
@@ -146,6 +162,10 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
146
162
|
"github-copilot": "github-copilot";
|
|
147
163
|
}>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
|
|
148
164
|
path: z.ZodString;
|
|
165
|
+
scope: z.ZodDefault<z.ZodEnum<{
|
|
166
|
+
global: "global";
|
|
167
|
+
repo: "repo";
|
|
168
|
+
}>>;
|
|
149
169
|
}, z.core.$strip>>>;
|
|
150
170
|
permissions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
151
171
|
name: z.ZodString;
|
|
@@ -159,6 +179,18 @@ export declare const ManifestSchema: z.ZodObject<{
|
|
|
159
179
|
}>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
|
|
160
180
|
config: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
161
181
|
}, z.core.$strip>>>;
|
|
182
|
+
agentDefinitions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
183
|
+
name: z.ZodString;
|
|
184
|
+
agents: z.ZodPipe<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
185
|
+
"claude-code": "claude-code";
|
|
186
|
+
codex: "codex";
|
|
187
|
+
"gemini-cli": "gemini-cli";
|
|
188
|
+
antigravity: "antigravity";
|
|
189
|
+
opencode: "opencode";
|
|
190
|
+
"github-copilot": "github-copilot";
|
|
191
|
+
}>>>, z.ZodTransform<("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[], ("claude-code" | "codex" | "gemini-cli" | "antigravity" | "opencode" | "github-copilot")[]>>;
|
|
192
|
+
path: z.ZodString;
|
|
193
|
+
}, z.core.$strip>>>;
|
|
162
194
|
}, z.core.$strip>;
|
|
163
195
|
export type SkillEntry = z.infer<typeof SkillEntrySchema>;
|
|
164
196
|
export type FileEntry = z.infer<typeof FileEntrySchema>;
|
|
@@ -166,6 +198,7 @@ export type ConfigEntry = z.infer<typeof ConfigEntrySchema>;
|
|
|
166
198
|
export type McpServerEntry = z.infer<typeof McpServerEntrySchema>;
|
|
167
199
|
export type AgentRuleEntry = z.infer<typeof AgentRuleEntrySchema>;
|
|
168
200
|
export type PermissionsEntry = z.infer<typeof PermissionsEntrySchema>;
|
|
201
|
+
export type AgentDefinitionEntry = z.infer<typeof AgentDefinitionEntrySchema>;
|
|
169
202
|
export type Manifest = z.infer<typeof ManifestSchema>;
|
|
170
203
|
export declare const AgentListSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>, z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
171
204
|
"claude-code": "claude-code";
|
package/dist/schemas/manifest.js
CHANGED
|
@@ -89,6 +89,10 @@ export const AgentRuleEntrySchema = z.object({
|
|
|
89
89
|
agents: agentsField,
|
|
90
90
|
// Relative path to the rules/instruction file within the source bundle.
|
|
91
91
|
path: sourcePathField,
|
|
92
|
+
// Deployment scope: "global" targets the agent's home-directory instruction
|
|
93
|
+
// file (default), "repo" targets the project-root instruction file within the
|
|
94
|
+
// deployed repository (e.g. {repo}/CLAUDE.md for claude-code).
|
|
95
|
+
scope: z.enum(["global", "repo"]).default("global"),
|
|
92
96
|
});
|
|
93
97
|
export const PermissionsEntrySchema = z.object({
|
|
94
98
|
name: nameField,
|
|
@@ -98,6 +102,14 @@ export const PermissionsEntrySchema = z.object({
|
|
|
98
102
|
// For codex: { approval_policy?: "auto" | "manual" | "suggest" | "on-failure" }
|
|
99
103
|
config: z.record(z.string(), z.unknown()),
|
|
100
104
|
});
|
|
105
|
+
export const AgentDefinitionEntrySchema = z.object({
|
|
106
|
+
name: nameField,
|
|
107
|
+
agents: agentsField,
|
|
108
|
+
// Relative path to the agent definition Markdown file within the source bundle.
|
|
109
|
+
// Must be a .md or .markdown file. Content and frontmatter structure are not
|
|
110
|
+
// validated by inception-engine — format requirements are agent-specific.
|
|
111
|
+
path: sourcePathField,
|
|
112
|
+
});
|
|
101
113
|
export const ManifestSchema = z.object({
|
|
102
114
|
skills: z.array(SkillEntrySchema).superRefine((skills, ctx) => {
|
|
103
115
|
const seen = new Set();
|
|
@@ -117,6 +129,7 @@ export const ManifestSchema = z.object({
|
|
|
117
129
|
mcpServers: z.array(McpServerEntrySchema).default([]),
|
|
118
130
|
agentRules: z.array(AgentRuleEntrySchema).default([]),
|
|
119
131
|
permissions: z.array(PermissionsEntrySchema).default([]),
|
|
132
|
+
agentDefinitions: z.array(AgentDefinitionEntrySchema).default([]),
|
|
120
133
|
});
|
|
121
134
|
// Parses the --agents CLI flag: comma-separated agent IDs → AgentId[]
|
|
122
135
|
export const AgentListSchema = z
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentId } from "./schemas/manifest.ts";
|
|
2
|
-
export type { AgentId, ConfigEntry, FileEntry, Manifest, SkillEntry, } from "./schemas/manifest.ts";
|
|
2
|
+
export type { AgentDefinitionEntry, AgentId, ConfigEntry, FileEntry, Manifest, SkillEntry, } from "./schemas/manifest.ts";
|
|
3
3
|
export interface AgentPaths {
|
|
4
4
|
posix: string[];
|
|
5
5
|
windows: string[];
|
|
@@ -16,25 +16,48 @@ export interface UnsupportedAgentSurface {
|
|
|
16
16
|
schemaLabel: string;
|
|
17
17
|
reason: string;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* A surface that is confirmed as Copilot-specific and genuinely justified for
|
|
21
|
+
* future dedicated implementation, but not yet supported. Distinct from
|
|
22
|
+
* "unsupported" (which means the surface is either covered by another target or
|
|
23
|
+
* will never be added) so adapters can emit a forward-looking "planned" notice
|
|
24
|
+
* rather than a blocking skip warning.
|
|
25
|
+
*/
|
|
26
|
+
export interface PlannedAgentSurface {
|
|
27
|
+
status: "planned";
|
|
28
|
+
schemaLabel: string;
|
|
29
|
+
/** Short description of the concrete file / config surface to be implemented. */
|
|
30
|
+
plannedSurface: string;
|
|
31
|
+
reason: string;
|
|
32
|
+
}
|
|
33
|
+
export type AgentSurfaceSupport = SupportedAgentSurface | UnsupportedAgentSurface | PlannedAgentSurface;
|
|
20
34
|
export interface AgentProvenance {
|
|
21
|
-
|
|
35
|
+
/** Omit when the agent has no separate skill deployment path. */
|
|
36
|
+
skills?: Confidence;
|
|
22
37
|
detectPaths: Confidence;
|
|
23
38
|
detectBinary: Confidence;
|
|
24
39
|
mcpConfig?: Confidence;
|
|
25
40
|
agentRules?: Confidence;
|
|
26
41
|
permissions?: Confidence;
|
|
42
|
+
agentDefinitions?: Confidence;
|
|
27
43
|
}
|
|
28
44
|
export interface AgentConfig {
|
|
29
45
|
id: AgentId;
|
|
30
46
|
displayName: string;
|
|
31
|
-
|
|
47
|
+
/**
|
|
48
|
+
* The on-disk path template for deploying skills to this agent.
|
|
49
|
+
* Omit for agents that consume skills from another agent's path natively
|
|
50
|
+
* (e.g. GitHub Copilot reads `.claude/skills/` directly).
|
|
51
|
+
*/
|
|
52
|
+
skills?: AgentPaths;
|
|
32
53
|
detectPaths: AgentPaths;
|
|
33
54
|
detectBinary: string | null;
|
|
34
55
|
provenance: AgentProvenance;
|
|
35
56
|
mcpSupport?: AgentSurfaceSupport;
|
|
36
57
|
agentRulesSupport?: AgentSurfaceSupport;
|
|
58
|
+
agentRulesRepoSupport?: AgentSurfaceSupport;
|
|
37
59
|
permissionsSupport?: AgentSurfaceSupport;
|
|
60
|
+
agentDefinitionsSupport?: AgentSurfaceSupport;
|
|
38
61
|
policyNote?: string;
|
|
39
62
|
}
|
|
40
63
|
export interface PlanWarning {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kuznai/inception-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Deploy AI agent skills from a git repo to user home directories",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Damian Piątkowski",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"test:posix": "node --test --test-isolation=none test/unit/*.test.ts test/os/cross-platform/*.test.ts test/os/posix/*.test.ts"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"front-matter": "^4.0.2",
|
|
51
50
|
"smol-toml": "^1.6.1",
|
|
51
|
+
"yaml": "^2.8.3",
|
|
52
52
|
"zod": "^4.0.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|