@ai-plugin-marketplace/core 0.1.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/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/core.d.ts +291 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/build.d.ts +90 -0
- package/dist/pipeline/build.d.ts.map +1 -0
- package/dist/pipeline/build.js +224 -0
- package/dist/pipeline/build.js.map +1 -0
- package/dist/pipeline/discover.d.ts +37 -0
- package/dist/pipeline/discover.d.ts.map +1 -0
- package/dist/pipeline/discover.js +71 -0
- package/dist/pipeline/discover.js.map +1 -0
- package/dist/pipeline/init-template.d.ts +33 -0
- package/dist/pipeline/init-template.d.ts.map +1 -0
- package/dist/pipeline/init-template.js +142 -0
- package/dist/pipeline/init-template.js.map +1 -0
- package/dist/pipeline/init.d.ts +39 -0
- package/dist/pipeline/init.d.ts.map +1 -0
- package/dist/pipeline/init.js +84 -0
- package/dist/pipeline/init.js.map +1 -0
- package/dist/pipeline/load-config.d.ts +47 -0
- package/dist/pipeline/load-config.d.ts.map +1 -0
- package/dist/pipeline/load-config.js +106 -0
- package/dist/pipeline/load-config.js.map +1 -0
- package/dist/pipeline/operations.d.ts +70 -0
- package/dist/pipeline/operations.d.ts.map +1 -0
- package/dist/pipeline/operations.js +100 -0
- package/dist/pipeline/operations.js.map +1 -0
- package/dist/pipeline/scaffold.d.ts +105 -0
- package/dist/pipeline/scaffold.d.ts.map +1 -0
- package/dist/pipeline/scaffold.js +422 -0
- package/dist/pipeline/scaffold.js.map +1 -0
- package/dist/pipeline/sentinel.d.ts +127 -0
- package/dist/pipeline/sentinel.d.ts.map +1 -0
- package/dist/pipeline/sentinel.js +263 -0
- package/dist/pipeline/sentinel.js.map +1 -0
- package/dist/pipeline/types.d.ts +178 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +26 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/pipeline/validate.d.ts +90 -0
- package/dist/pipeline/validate.d.ts.map +1 -0
- package/dist/pipeline/validate.js +617 -0
- package/dist/pipeline/validate.js.map +1 -0
- package/dist/targets/claude/scaffold.d.ts +32 -0
- package/dist/targets/claude/scaffold.d.ts.map +1 -0
- package/dist/targets/claude/scaffold.js +48 -0
- package/dist/targets/claude/scaffold.js.map +1 -0
- package/dist/targets/claude/schemas.d.ts +119 -0
- package/dist/targets/claude/schemas.d.ts.map +1 -0
- package/dist/targets/claude/schemas.js +204 -0
- package/dist/targets/claude/schemas.js.map +1 -0
- package/dist/targets/claude/transform.d.ts +40 -0
- package/dist/targets/claude/transform.d.ts.map +1 -0
- package/dist/targets/claude/transform.js +48 -0
- package/dist/targets/claude/transform.js.map +1 -0
- package/dist/targets/claude/validate.d.ts +25 -0
- package/dist/targets/claude/validate.d.ts.map +1 -0
- package/dist/targets/claude/validate.js +263 -0
- package/dist/targets/claude/validate.js.map +1 -0
- package/dist/targets/cursor/scaffold.d.ts +29 -0
- package/dist/targets/cursor/scaffold.d.ts.map +1 -0
- package/dist/targets/cursor/scaffold.js +45 -0
- package/dist/targets/cursor/scaffold.js.map +1 -0
- package/dist/targets/cursor/schemas.d.ts +49 -0
- package/dist/targets/cursor/schemas.d.ts.map +1 -0
- package/dist/targets/cursor/schemas.js +125 -0
- package/dist/targets/cursor/schemas.js.map +1 -0
- package/dist/targets/cursor/validate.d.ts +28 -0
- package/dist/targets/cursor/validate.d.ts.map +1 -0
- package/dist/targets/cursor/validate.js +181 -0
- package/dist/targets/cursor/validate.js.map +1 -0
- package/dist/targets/gemini/bundle.d.ts +25 -0
- package/dist/targets/gemini/bundle.d.ts.map +1 -0
- package/dist/targets/gemini/bundle.js +149 -0
- package/dist/targets/gemini/bundle.js.map +1 -0
- package/dist/targets/gemini/scaffold.d.ts +28 -0
- package/dist/targets/gemini/scaffold.d.ts.map +1 -0
- package/dist/targets/gemini/scaffold.js +57 -0
- package/dist/targets/gemini/scaffold.js.map +1 -0
- package/dist/targets/gemini/schemas.d.ts +53 -0
- package/dist/targets/gemini/schemas.d.ts.map +1 -0
- package/dist/targets/gemini/schemas.js +72 -0
- package/dist/targets/gemini/schemas.js.map +1 -0
- package/dist/targets/gemini/transform.d.ts +106 -0
- package/dist/targets/gemini/transform.d.ts.map +1 -0
- package/dist/targets/gemini/transform.js +137 -0
- package/dist/targets/gemini/transform.js.map +1 -0
- package/dist/targets/gemini/validate.d.ts +26 -0
- package/dist/targets/gemini/validate.d.ts.map +1 -0
- package/dist/targets/gemini/validate.js +146 -0
- package/dist/targets/gemini/validate.js.map +1 -0
- package/dist/targets/kiro/bundle.d.ts +32 -0
- package/dist/targets/kiro/bundle.d.ts.map +1 -0
- package/dist/targets/kiro/bundle.js +106 -0
- package/dist/targets/kiro/bundle.js.map +1 -0
- package/dist/targets/kiro/scaffold.d.ts +28 -0
- package/dist/targets/kiro/scaffold.d.ts.map +1 -0
- package/dist/targets/kiro/scaffold.js +55 -0
- package/dist/targets/kiro/scaffold.js.map +1 -0
- package/dist/targets/kiro/schemas.d.ts +100 -0
- package/dist/targets/kiro/schemas.d.ts.map +1 -0
- package/dist/targets/kiro/schemas.js +147 -0
- package/dist/targets/kiro/schemas.js.map +1 -0
- package/dist/targets/kiro/transform.d.ts +53 -0
- package/dist/targets/kiro/transform.d.ts.map +1 -0
- package/dist/targets/kiro/transform.js +113 -0
- package/dist/targets/kiro/transform.js.map +1 -0
- package/dist/targets/kiro/validate.d.ts +36 -0
- package/dist/targets/kiro/validate.d.ts.map +1 -0
- package/dist/targets/kiro/validate.js +232 -0
- package/dist/targets/kiro/validate.js.map +1 -0
- package/dist/targets/scaffold-kit.d.ts +56 -0
- package/dist/targets/scaffold-kit.d.ts.map +1 -0
- package/dist/targets/scaffold-kit.js +33 -0
- package/dist/targets/scaffold-kit.js.map +1 -0
- package/dist/targets/vercel/scaffold.d.ts +34 -0
- package/dist/targets/vercel/scaffold.d.ts.map +1 -0
- package/dist/targets/vercel/scaffold.js +58 -0
- package/dist/targets/vercel/scaffold.js.map +1 -0
- package/dist/targets/vercel/schemas.d.ts +42 -0
- package/dist/targets/vercel/schemas.d.ts.map +1 -0
- package/dist/targets/vercel/schemas.js +69 -0
- package/dist/targets/vercel/schemas.js.map +1 -0
- package/dist/targets/vercel/validate.d.ts +28 -0
- package/dist/targets/vercel/validate.d.ts.map +1 -0
- package/dist/targets/vercel/validate.js +180 -0
- package/dist/targets/vercel/validate.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-target validators for the Kiro target.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities (v0.1.0):
|
|
5
|
+
* 1. POWER.md frontmatter — parse YAML and validate against
|
|
6
|
+
* `kiroPowerMdFrontmatterSchema`. Missing block or missing required fields
|
|
7
|
+
* → hard `schema-invalid`.
|
|
8
|
+
* 2. POWER.md name-consistency — frontmatter `name` must match
|
|
9
|
+
* `path.basename(pluginDir)` → hard `name-consistency`.
|
|
10
|
+
* 3. mcp.json schema — parse JSON and validate against `kiroMcpConfigSchema`
|
|
11
|
+
* → hard `schema-invalid`.
|
|
12
|
+
* 4. Agent tool-name warnings — for each `.md` under `agents/` (one level),
|
|
13
|
+
* each tool not in `CLAUDE_TO_KIRO_TOOLS` → soft `schema-invalid`.
|
|
14
|
+
*
|
|
15
|
+
* What NOT validated here:
|
|
16
|
+
* - `.kiro/agents/<name>.json` (generated output — validated at bundle time)
|
|
17
|
+
* - Envelope adherence, marketplace registration, cross-target consistency
|
|
18
|
+
* - Shared agent .md shape beyond tool names (Claude validator owns frontmatter)
|
|
19
|
+
*
|
|
20
|
+
* Cross-target imports are forbidden per §3.4 of the architecture spec.
|
|
21
|
+
*
|
|
22
|
+
* @see docs/specs/architecture.md §10 (validation contract), §8.1 (Finding types)
|
|
23
|
+
* @see docs/specs/architecture.md §12.5 (internal module shape), §3.4 (target isolation)
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from 'node:fs';
|
|
26
|
+
import * as path from 'node:path';
|
|
27
|
+
import { parse as parseYaml } from 'yaml';
|
|
28
|
+
import { CLAUDE_TO_KIRO_TOOLS } from './transform.js';
|
|
29
|
+
import { kiroMcpConfigSchema, kiroPowerMdFrontmatterSchema } from './schemas.js';
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Internal helpers
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
/** Build a hard `schema-invalid` Finding scoped to `pluginName`. */
|
|
34
|
+
function hardSchemaFinding(pluginName, message, hint) {
|
|
35
|
+
const finding = {
|
|
36
|
+
severity: 'hard',
|
|
37
|
+
code: 'schema-invalid',
|
|
38
|
+
plugin: pluginName,
|
|
39
|
+
message,
|
|
40
|
+
};
|
|
41
|
+
if (hint !== undefined) {
|
|
42
|
+
finding.hint = hint;
|
|
43
|
+
}
|
|
44
|
+
return finding;
|
|
45
|
+
}
|
|
46
|
+
/** Build a hard `name-consistency` Finding scoped to `pluginName`. */
|
|
47
|
+
function hardNameFinding(pluginName, message, hint) {
|
|
48
|
+
const finding = {
|
|
49
|
+
severity: 'hard',
|
|
50
|
+
code: 'name-consistency',
|
|
51
|
+
plugin: pluginName,
|
|
52
|
+
message,
|
|
53
|
+
};
|
|
54
|
+
if (hint !== undefined) {
|
|
55
|
+
finding.hint = hint;
|
|
56
|
+
}
|
|
57
|
+
return finding;
|
|
58
|
+
}
|
|
59
|
+
/** Build a soft `schema-invalid` Finding scoped to `pluginName`. */
|
|
60
|
+
function softSchemaFinding(pluginName, message, hint) {
|
|
61
|
+
const finding = {
|
|
62
|
+
severity: 'soft',
|
|
63
|
+
code: 'schema-invalid',
|
|
64
|
+
plugin: pluginName,
|
|
65
|
+
message,
|
|
66
|
+
};
|
|
67
|
+
if (hint !== undefined) {
|
|
68
|
+
finding.hint = hint;
|
|
69
|
+
}
|
|
70
|
+
return finding;
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// POWER.md validation
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
/**
|
|
76
|
+
* Validate POWER.md frontmatter:
|
|
77
|
+
* - Parse YAML between `---` markers.
|
|
78
|
+
* - Validate against `kiroPowerMdFrontmatterSchema`.
|
|
79
|
+
* - Verify `name` matches `path.basename(pluginDir)`.
|
|
80
|
+
*
|
|
81
|
+
* Returns zero findings when POWER.md is absent (envelope-adherence owns that check).
|
|
82
|
+
*/
|
|
83
|
+
function validatePowerMd(pluginDir, pluginName) {
|
|
84
|
+
const powerMdPath = path.join(pluginDir, 'POWER.md');
|
|
85
|
+
if (!fs.existsSync(powerMdPath))
|
|
86
|
+
return [];
|
|
87
|
+
const content = fs.readFileSync(powerMdPath, 'utf-8');
|
|
88
|
+
// Extract frontmatter block between leading `---` markers.
|
|
89
|
+
const fmMatch = /^---\r?\n([\s\S]*?)\r?\n---/m.exec(content);
|
|
90
|
+
if (fmMatch === null) {
|
|
91
|
+
return [
|
|
92
|
+
hardSchemaFinding(pluginName, `POWER.md has no frontmatter block`, `add a YAML frontmatter block between --- markers at the top of POWER.md with required fields: name, description, version`),
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
const frontmatterYaml = fmMatch[1] ?? '';
|
|
96
|
+
let parsed;
|
|
97
|
+
try {
|
|
98
|
+
parsed = parseYaml(frontmatterYaml);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
102
|
+
return [
|
|
103
|
+
hardSchemaFinding(pluginName, `POWER.md frontmatter YAML parse error: ${msg}`, `fix the YAML syntax in the POWER.md frontmatter`),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
const result = kiroPowerMdFrontmatterSchema.safeParse(parsed);
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
const issues = result.error.issues
|
|
109
|
+
.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)
|
|
110
|
+
.join('; ');
|
|
111
|
+
return [
|
|
112
|
+
hardSchemaFinding(pluginName, `POWER.md frontmatter does not match schema — ${issues}`, `ensure POWER.md frontmatter includes required fields: name, description, version`),
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
// Name-consistency check: frontmatter name must match the plugin directory name.
|
|
116
|
+
const frontmatterName = result.data.name;
|
|
117
|
+
if (frontmatterName !== pluginName) {
|
|
118
|
+
return [
|
|
119
|
+
hardNameFinding(pluginName, `POWER.md frontmatter name '${frontmatterName}' does not match plugin directory '${pluginName}'`, `set the name field in POWER.md frontmatter to '${pluginName}'`),
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// mcp.json validation
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
/**
|
|
128
|
+
* If `mcp.json` exists, parse JSON and validate against `kiroMcpConfigSchema`.
|
|
129
|
+
* Missing file → no finding (envelope-adherence owns that check).
|
|
130
|
+
*/
|
|
131
|
+
function validateMcpJson(pluginDir, pluginName) {
|
|
132
|
+
const mcpPath = path.join(pluginDir, 'mcp.json');
|
|
133
|
+
if (!fs.existsSync(mcpPath))
|
|
134
|
+
return [];
|
|
135
|
+
let raw;
|
|
136
|
+
try {
|
|
137
|
+
raw = JSON.parse(fs.readFileSync(mcpPath, 'utf-8'));
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return [
|
|
141
|
+
hardSchemaFinding(pluginName, `mcp.json is not valid JSON`, `fix the JSON syntax in mcp.json`),
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
const result = kiroMcpConfigSchema.safeParse(raw);
|
|
145
|
+
if (!result.success) {
|
|
146
|
+
const issues = result.error.issues
|
|
147
|
+
.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)
|
|
148
|
+
.join('; ');
|
|
149
|
+
return [
|
|
150
|
+
hardSchemaFinding(pluginName, `mcp.json does not match the Kiro MCP config schema — ${issues}`, `ensure mcp.json has the shape { mcpServers: Record<string, { command: string, args?: string[], env?: Record<string, string> }> }`),
|
|
151
|
+
];
|
|
152
|
+
}
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Agent tool-name translation warnings
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
/**
|
|
159
|
+
* Extract the `tools` array from YAML frontmatter of a `.md` file.
|
|
160
|
+
* Returns an empty array if the file has no frontmatter or no `tools` field.
|
|
161
|
+
* Parse errors are silently ignored (the Claude validator owns frontmatter shape).
|
|
162
|
+
*/
|
|
163
|
+
function extractAgentTools(content) {
|
|
164
|
+
const fmMatch = /^---\r?\n([\s\S]*?)\r?\n---/m.exec(content);
|
|
165
|
+
if (fmMatch === null)
|
|
166
|
+
return [];
|
|
167
|
+
const frontmatterYaml = fmMatch[1] ?? '';
|
|
168
|
+
let parsed;
|
|
169
|
+
try {
|
|
170
|
+
parsed = parseYaml(frontmatterYaml);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
if (typeof parsed !== 'object' ||
|
|
176
|
+
parsed === null ||
|
|
177
|
+
!('tools' in parsed) ||
|
|
178
|
+
!Array.isArray(parsed['tools'])) {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
const tools = parsed['tools'];
|
|
182
|
+
return tools.filter((t) => typeof t === 'string');
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* For each `.md` file directly under `agents/` (one level deep), emit a soft
|
|
186
|
+
* `schema-invalid` finding for each tool name not present in `CLAUDE_TO_KIRO_TOOLS`.
|
|
187
|
+
*
|
|
188
|
+
* Severity is soft — unmapped tools are dropped from the Kiro bundle but do not
|
|
189
|
+
* block the build.
|
|
190
|
+
*/
|
|
191
|
+
function validateAgentToolNames(pluginDir, pluginName) {
|
|
192
|
+
const agentsDir = path.join(pluginDir, 'agents');
|
|
193
|
+
if (!fs.existsSync(agentsDir))
|
|
194
|
+
return [];
|
|
195
|
+
const entries = fs.readdirSync(agentsDir, { withFileTypes: true });
|
|
196
|
+
const findings = [];
|
|
197
|
+
for (const entry of entries) {
|
|
198
|
+
if (!entry.isFile() || !entry.name.endsWith('.md'))
|
|
199
|
+
continue;
|
|
200
|
+
const agentName = entry.name.replace(/\.md$/, '');
|
|
201
|
+
const agentPath = path.join(agentsDir, entry.name);
|
|
202
|
+
const content = fs.readFileSync(agentPath, 'utf-8');
|
|
203
|
+
const tools = extractAgentTools(content);
|
|
204
|
+
for (const tool of tools) {
|
|
205
|
+
if (!(tool in CLAUDE_TO_KIRO_TOOLS)) {
|
|
206
|
+
findings.push(softSchemaFinding(pluginName, `agent '${agentName}' uses Claude tool '${tool}' which has no Kiro equivalent — it will be dropped from the Kiro bundle`, `remove '${tool}' from the tools list in agents/${entry.name}, or check the CLAUDE_TO_KIRO_TOOLS table for the correct Claude tool name`));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return findings;
|
|
211
|
+
}
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// Public entry point
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
/**
|
|
216
|
+
* Run Kiro-specific validators against a plugin directory.
|
|
217
|
+
*
|
|
218
|
+
* `pluginDir` is the absolute path to a `plugins/<name>/` directory.
|
|
219
|
+
* All findings use `plugin: path.basename(pluginDir)`.
|
|
220
|
+
*
|
|
221
|
+
* Returns zero or more Findings. Callers combine these with other targets'
|
|
222
|
+
* findings and the cross-target findings in the pipeline validator.
|
|
223
|
+
*/
|
|
224
|
+
export function validateKiroPlugin(pluginDir) {
|
|
225
|
+
const pluginName = path.basename(pluginDir);
|
|
226
|
+
return [
|
|
227
|
+
...validatePowerMd(pluginDir, pluginName),
|
|
228
|
+
...validateMcpJson(pluginDir, pluginName),
|
|
229
|
+
...validateAgentToolNames(pluginDir, pluginName),
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/targets/kiro/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared scaffold primitives for per-target scaffold modules.
|
|
3
|
+
*
|
|
4
|
+
* This module lives at `targets/` (not inside any single target folder), so importing it from a
|
|
5
|
+
* `targets/<target>/scaffold.ts` file does NOT violate the cross-target-import rule (§3.4) — that
|
|
6
|
+
* rule forbids importing from a *sibling target* folder, not from shared infrastructure.
|
|
7
|
+
*
|
|
8
|
+
* It carries no target-specific logic: only the common file-descriptor shape, the canonical
|
|
9
|
+
* `schemaVersion` literal (§12.2), and the per-target scaffold option bag.
|
|
10
|
+
*
|
|
11
|
+
* @see docs/specs/architecture.md §12.2 (schemaVersion on every manifest)
|
|
12
|
+
* @see docs/specs/architecture.md §12.5 (per-target scaffold.ts)
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Canonical `schemaVersion` literal emitted by every scaffolded manifest in this toolkit version.
|
|
16
|
+
* Pinned per §9.4 / §12.2 — a single value in v0.1.0.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SCHEMA_VERSION = "0.1.0";
|
|
19
|
+
/**
|
|
20
|
+
* A single file a target contributes to a scaffolded plugin.
|
|
21
|
+
*
|
|
22
|
+
* `path` is RELATIVE to the plugin directory (e.g. `.claude-plugin/plugin.json`). Content is the
|
|
23
|
+
* complete file body. Scaffold functions are pure — they never touch the filesystem.
|
|
24
|
+
*/
|
|
25
|
+
export interface ScaffoldedFile {
|
|
26
|
+
/** Path relative to the plugin directory. POSIX-style forward slashes. */
|
|
27
|
+
path: string;
|
|
28
|
+
/** Complete file content. */
|
|
29
|
+
content: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Options accepted by a per-target scaffold function.
|
|
33
|
+
*
|
|
34
|
+
* When `placeholder` is true (the `aipm add-target` path, §6.4), descriptive fields are emitted
|
|
35
|
+
* as empty/placeholder values for the author to fill in rather than auto-generated text.
|
|
36
|
+
*/
|
|
37
|
+
export interface TargetScaffoldOptions {
|
|
38
|
+
/** Human-readable plugin description. Omitted → a deterministic default per target. */
|
|
39
|
+
description?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Emit blank manifest fields for the author to complete, per §6.4 "leaving manifest fields
|
|
42
|
+
* blank for the author". Used by `aipm add-target`. Default: false.
|
|
43
|
+
*/
|
|
44
|
+
placeholder?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the description to embed in a scaffolded manifest.
|
|
48
|
+
*
|
|
49
|
+
* - `placeholder` mode → empty string (author fills it in).
|
|
50
|
+
* - explicit `description` → used verbatim.
|
|
51
|
+
* - otherwise → a deterministic default derived from the plugin name.
|
|
52
|
+
*
|
|
53
|
+
* Deterministic: never reads the clock or environment (scaffold output must be reproducible).
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveDescription(pluginName: string, opts: TargetScaffoldOptions): string;
|
|
56
|
+
//# sourceMappingURL=scaffold-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-kit.d.ts","sourceRoot":"","sources":["../../src/targets/scaffold-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;GAGG;AACH,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAG1F"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared scaffold primitives for per-target scaffold modules.
|
|
3
|
+
*
|
|
4
|
+
* This module lives at `targets/` (not inside any single target folder), so importing it from a
|
|
5
|
+
* `targets/<target>/scaffold.ts` file does NOT violate the cross-target-import rule (§3.4) — that
|
|
6
|
+
* rule forbids importing from a *sibling target* folder, not from shared infrastructure.
|
|
7
|
+
*
|
|
8
|
+
* It carries no target-specific logic: only the common file-descriptor shape, the canonical
|
|
9
|
+
* `schemaVersion` literal (§12.2), and the per-target scaffold option bag.
|
|
10
|
+
*
|
|
11
|
+
* @see docs/specs/architecture.md §12.2 (schemaVersion on every manifest)
|
|
12
|
+
* @see docs/specs/architecture.md §12.5 (per-target scaffold.ts)
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Canonical `schemaVersion` literal emitted by every scaffolded manifest in this toolkit version.
|
|
16
|
+
* Pinned per §9.4 / §12.2 — a single value in v0.1.0.
|
|
17
|
+
*/
|
|
18
|
+
export const SCHEMA_VERSION = '0.1.0';
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the description to embed in a scaffolded manifest.
|
|
21
|
+
*
|
|
22
|
+
* - `placeholder` mode → empty string (author fills it in).
|
|
23
|
+
* - explicit `description` → used verbatim.
|
|
24
|
+
* - otherwise → a deterministic default derived from the plugin name.
|
|
25
|
+
*
|
|
26
|
+
* Deterministic: never reads the clock or environment (scaffold output must be reproducible).
|
|
27
|
+
*/
|
|
28
|
+
export function resolveDescription(pluginName, opts) {
|
|
29
|
+
if (opts.placeholder)
|
|
30
|
+
return '';
|
|
31
|
+
return opts.description ?? `A plugin for ${pluginName}`;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=scaffold-kit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-kit.js","sourceRoot":"","sources":["../../src/targets/scaffold-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AA+BtC;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,IAA2B;IAChF,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,IAAI,CAAC,WAAW,IAAI,gBAAgB,UAAU,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffold templates for the Vercel Skills CLI target.
|
|
3
|
+
*
|
|
4
|
+
* `scaffoldVercelFiles` is a pure function returning the skeleton files this target contributes
|
|
5
|
+
* to a new plugin: a `skills/<name>/SKILL.md` whose YAML frontmatter is the complete Vercel
|
|
6
|
+
* surface (there is no separate plugin.json-like manifest). The frontmatter carries
|
|
7
|
+
* `schemaVersion: "0.1.0"` (§12.2). No generated-file sentinels — this is an author-authored
|
|
8
|
+
* skeleton file (§4.3).
|
|
9
|
+
*
|
|
10
|
+
* This module must not import from any sibling targets/<other>/ folder (§3.4).
|
|
11
|
+
*
|
|
12
|
+
* @see https://agentskills.io (SKILL.md frontmatter constraints)
|
|
13
|
+
* @see docs/specs/architecture.md §4 (plugin source layout)
|
|
14
|
+
* @see docs/specs/architecture.md §6.4 (compatibility-assist)
|
|
15
|
+
* @see docs/specs/architecture.md §12.2 (schemaVersion on every manifest)
|
|
16
|
+
* @see docs/specs/architecture.md §12.5 (per-target scaffold.ts)
|
|
17
|
+
*/
|
|
18
|
+
import { type ScaffoldedFile, type TargetScaffoldOptions } from '../scaffold-kit.js';
|
|
19
|
+
/**
|
|
20
|
+
* Produce the Vercel skeleton files for a plugin.
|
|
21
|
+
*
|
|
22
|
+
* The minimum required artifact (validated specially in `validateEnvelopeAdherence`) is at least
|
|
23
|
+
* one `skills/<skill>/SKILL.md`. The scaffold seeds a single skill named after the plugin; the
|
|
24
|
+
* frontmatter satisfies `vercelSkillFrontmatterSchema` (`name` slug + non-empty `description`).
|
|
25
|
+
*
|
|
26
|
+
* The skill directory name MUST equal the frontmatter `name` (Stage 4 cross-validator); both are
|
|
27
|
+
* the plugin name here.
|
|
28
|
+
*
|
|
29
|
+
* @param pluginName - Plugin identity; used as the skill directory name and frontmatter `name`.
|
|
30
|
+
* @param opts - Optional description and add-target placeholder behaviour.
|
|
31
|
+
* @returns Files contributed by this target, with paths relative to the plugin directory.
|
|
32
|
+
*/
|
|
33
|
+
export declare function scaffoldVercelFiles(pluginName: string, opts?: TargetScaffoldOptions): ScaffoldedFile[];
|
|
34
|
+
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../src/targets/vercel/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,oBAAoB,CAAC;AAK5B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,qBAA0B,GAC/B,cAAc,EAAE,CAwBlB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffold templates for the Vercel Skills CLI target.
|
|
3
|
+
*
|
|
4
|
+
* `scaffoldVercelFiles` is a pure function returning the skeleton files this target contributes
|
|
5
|
+
* to a new plugin: a `skills/<name>/SKILL.md` whose YAML frontmatter is the complete Vercel
|
|
6
|
+
* surface (there is no separate plugin.json-like manifest). The frontmatter carries
|
|
7
|
+
* `schemaVersion: "0.1.0"` (§12.2). No generated-file sentinels — this is an author-authored
|
|
8
|
+
* skeleton file (§4.3).
|
|
9
|
+
*
|
|
10
|
+
* This module must not import from any sibling targets/<other>/ folder (§3.4).
|
|
11
|
+
*
|
|
12
|
+
* @see https://agentskills.io (SKILL.md frontmatter constraints)
|
|
13
|
+
* @see docs/specs/architecture.md §4 (plugin source layout)
|
|
14
|
+
* @see docs/specs/architecture.md §6.4 (compatibility-assist)
|
|
15
|
+
* @see docs/specs/architecture.md §12.2 (schemaVersion on every manifest)
|
|
16
|
+
* @see docs/specs/architecture.md §12.5 (per-target scaffold.ts)
|
|
17
|
+
*/
|
|
18
|
+
import { resolveDescription, SCHEMA_VERSION, } from '../scaffold-kit.js';
|
|
19
|
+
/** Identity tag enabling editor highlighting of the embedded Markdown body. */
|
|
20
|
+
const md = String.raw;
|
|
21
|
+
/**
|
|
22
|
+
* Produce the Vercel skeleton files for a plugin.
|
|
23
|
+
*
|
|
24
|
+
* The minimum required artifact (validated specially in `validateEnvelopeAdherence`) is at least
|
|
25
|
+
* one `skills/<skill>/SKILL.md`. The scaffold seeds a single skill named after the plugin; the
|
|
26
|
+
* frontmatter satisfies `vercelSkillFrontmatterSchema` (`name` slug + non-empty `description`).
|
|
27
|
+
*
|
|
28
|
+
* The skill directory name MUST equal the frontmatter `name` (Stage 4 cross-validator); both are
|
|
29
|
+
* the plugin name here.
|
|
30
|
+
*
|
|
31
|
+
* @param pluginName - Plugin identity; used as the skill directory name and frontmatter `name`.
|
|
32
|
+
* @param opts - Optional description and add-target placeholder behaviour.
|
|
33
|
+
* @returns Files contributed by this target, with paths relative to the plugin directory.
|
|
34
|
+
*/
|
|
35
|
+
export function scaffoldVercelFiles(pluginName, opts = {}) {
|
|
36
|
+
const description = resolveDescription(pluginName, opts);
|
|
37
|
+
// `description` is constrained to min length 1. In placeholder mode (add-target) we emit an
|
|
38
|
+
// empty value, intentionally leaving an incomplete-but-fillable skeleton per §6.4; the author
|
|
39
|
+
// completes it before the plugin validates.
|
|
40
|
+
const content = md `---
|
|
41
|
+
schemaVersion: ${SCHEMA_VERSION}
|
|
42
|
+
name: ${pluginName}
|
|
43
|
+
description: ${JSON.stringify(description)}
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
# ${pluginName}
|
|
47
|
+
|
|
48
|
+
${description}
|
|
49
|
+
|
|
50
|
+
## Procedure
|
|
51
|
+
|
|
52
|
+
1. [Step 1]
|
|
53
|
+
2. [Step 2]
|
|
54
|
+
3. [Step 3]
|
|
55
|
+
`;
|
|
56
|
+
return [{ path: `skills/${pluginName}/SKILL.md`, content }];
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../../src/targets/vercel/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,kBAAkB,EAClB,cAAc,GAGf,MAAM,oBAAoB,CAAC;AAE5B,+EAA+E;AAC/E,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;AAEtB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,OAA8B,EAAE;IAEhC,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAEzD,4FAA4F;IAC5F,8FAA8F;IAC9F,4CAA4C;IAC5C,MAAM,OAAO,GAAG,EAAE,CAAA;iBACH,cAAc;QACvB,UAAU;eACH,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;;IAGtC,UAAU;;EAEZ,WAAW;;;;;;;CAOZ,CAAC;IAEA,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,UAAU,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for the Vercel Skills CLI target.
|
|
3
|
+
*
|
|
4
|
+
* The primary artifact for the Vercel target is `SKILL.md` — a markdown file with YAML
|
|
5
|
+
* frontmatter consumed by the Vercel Skills CLI per the agentskills.io spec. There is no
|
|
6
|
+
* `plugin.json`-like manifest; `SKILL.md` is the complete surface.
|
|
7
|
+
*
|
|
8
|
+
* This module must not import from any sibling targets/<other>/ folder (§3.4).
|
|
9
|
+
*
|
|
10
|
+
* Note on ownership: `SKILL.md` is also consumed by Claude, Cursor, Gemini, and Kiro
|
|
11
|
+
* (via steering), but the schema lives here because Vercel's primary surface is SKILL.md.
|
|
12
|
+
* A future refactor may move it to a shared module (see §16 open questions).
|
|
13
|
+
*
|
|
14
|
+
* schemaVersion: accepted but not validated in v0.1.0 per §9.4 and §12.2.
|
|
15
|
+
*
|
|
16
|
+
* @see https://agentskills.io (agentskills.io spec — source of name/description constraints)
|
|
17
|
+
*/
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
/** Maximum byte length for a skill `name` field per agentskills.io spec. */
|
|
20
|
+
export declare const SKILL_NAME_MAX_LENGTH = 64;
|
|
21
|
+
/** Maximum byte length for a skill `description` field per agentskills.io spec. */
|
|
22
|
+
export declare const SKILL_DESCRIPTION_MAX_LENGTH = 1024;
|
|
23
|
+
/**
|
|
24
|
+
* Schema for the YAML frontmatter of `SKILL.md` files per the agentskills.io spec.
|
|
25
|
+
*
|
|
26
|
+
* Constraints faithfully ported from `validateSkillFrontmatter` in the template repo:
|
|
27
|
+
* - `name`: lowercase-alphanumeric-with-hyphens slug, max 64 chars, must start with a
|
|
28
|
+
* letter, no consecutive hyphens (`--`), no trailing hyphen.
|
|
29
|
+
* - `description`: non-empty string, max 1024 chars.
|
|
30
|
+
*
|
|
31
|
+
* `.loose()` (passthrough) is used at the top level because authors may add
|
|
32
|
+
* platform-specific keys (e.g., Claude's `model`, `tools`, `color`).
|
|
33
|
+
*
|
|
34
|
+
* Parent-directory-name matching is a Stage 4 cross-validator concern — not enforced here.
|
|
35
|
+
* Body line-count (soft 500-line recommendation) is informational — not enforced here.
|
|
36
|
+
*/
|
|
37
|
+
export declare const vercelSkillFrontmatterSchema: z.ZodObject<{
|
|
38
|
+
schemaVersion: z.ZodOptional<z.ZodString>;
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
description: z.ZodString;
|
|
41
|
+
}, z.core.$loose>;
|
|
42
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/targets/vercel/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,mFAAmF;AACnF,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAMjD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B;;;;iBA8B/B,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for the Vercel Skills CLI target.
|
|
3
|
+
*
|
|
4
|
+
* The primary artifact for the Vercel target is `SKILL.md` — a markdown file with YAML
|
|
5
|
+
* frontmatter consumed by the Vercel Skills CLI per the agentskills.io spec. There is no
|
|
6
|
+
* `plugin.json`-like manifest; `SKILL.md` is the complete surface.
|
|
7
|
+
*
|
|
8
|
+
* This module must not import from any sibling targets/<other>/ folder (§3.4).
|
|
9
|
+
*
|
|
10
|
+
* Note on ownership: `SKILL.md` is also consumed by Claude, Cursor, Gemini, and Kiro
|
|
11
|
+
* (via steering), but the schema lives here because Vercel's primary surface is SKILL.md.
|
|
12
|
+
* A future refactor may move it to a shared module (see §16 open questions).
|
|
13
|
+
*
|
|
14
|
+
* schemaVersion: accepted but not validated in v0.1.0 per §9.4 and §12.2.
|
|
15
|
+
*
|
|
16
|
+
* @see https://agentskills.io (agentskills.io spec — source of name/description constraints)
|
|
17
|
+
*/
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Constants (exported so Stage 4 validators can reference without re-deriving)
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/** Maximum byte length for a skill `name` field per agentskills.io spec. */
|
|
23
|
+
export const SKILL_NAME_MAX_LENGTH = 64;
|
|
24
|
+
/** Maximum byte length for a skill `description` field per agentskills.io spec. */
|
|
25
|
+
export const SKILL_DESCRIPTION_MAX_LENGTH = 1024;
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// vercelSkillFrontmatterSchema
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Schema for the YAML frontmatter of `SKILL.md` files per the agentskills.io spec.
|
|
31
|
+
*
|
|
32
|
+
* Constraints faithfully ported from `validateSkillFrontmatter` in the template repo:
|
|
33
|
+
* - `name`: lowercase-alphanumeric-with-hyphens slug, max 64 chars, must start with a
|
|
34
|
+
* letter, no consecutive hyphens (`--`), no trailing hyphen.
|
|
35
|
+
* - `description`: non-empty string, max 1024 chars.
|
|
36
|
+
*
|
|
37
|
+
* `.loose()` (passthrough) is used at the top level because authors may add
|
|
38
|
+
* platform-specific keys (e.g., Claude's `model`, `tools`, `color`).
|
|
39
|
+
*
|
|
40
|
+
* Parent-directory-name matching is a Stage 4 cross-validator concern — not enforced here.
|
|
41
|
+
* Body line-count (soft 500-line recommendation) is informational — not enforced here.
|
|
42
|
+
*/
|
|
43
|
+
export const vercelSkillFrontmatterSchema = z
|
|
44
|
+
.object({
|
|
45
|
+
/** Reserved for future migrex adoption. Accepted but not validated in v0.1.0. */
|
|
46
|
+
schemaVersion: z.string().optional(),
|
|
47
|
+
/**
|
|
48
|
+
* Skill identifier. Must be a lowercase alphanumeric slug:
|
|
49
|
+
* - Starts with `[a-z]`
|
|
50
|
+
* - Contains only `[a-z0-9-]`
|
|
51
|
+
* - Maximum 64 characters
|
|
52
|
+
* - No consecutive hyphens (`--`)
|
|
53
|
+
* - Does not end with a hyphen
|
|
54
|
+
*/
|
|
55
|
+
name: z
|
|
56
|
+
.string()
|
|
57
|
+
.regex(/^[a-z][a-z0-9-]*$/, 'name must be lowercase alphanumeric with hyphens, starting with a letter')
|
|
58
|
+
.max(SKILL_NAME_MAX_LENGTH)
|
|
59
|
+
.refine((v) => !v.includes('--'), {
|
|
60
|
+
message: 'name must not contain consecutive hyphens',
|
|
61
|
+
})
|
|
62
|
+
.refine((v) => !v.endsWith('-'), {
|
|
63
|
+
message: 'name must not end with a hyphen',
|
|
64
|
+
}),
|
|
65
|
+
/** What this skill does. Non-empty, maximum 1024 characters. */
|
|
66
|
+
description: z.string().min(1).max(SKILL_DESCRIPTION_MAX_LENGTH),
|
|
67
|
+
})
|
|
68
|
+
.loose();
|
|
69
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/targets/vercel/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAE9E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC,mFAAmF;AACnF,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAEjD,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAE9E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC;KAC1C,MAAM,CAAC;IACN,iFAAiF;IACjF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAEpC;;;;;;;OAOG;IACH,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,KAAK,CACJ,mBAAmB,EACnB,0EAA0E,CAC3E;SACA,GAAG,CAAC,qBAAqB,CAAC;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;QAChC,OAAO,EAAE,2CAA2C;KACrD,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QAC/B,OAAO,EAAE,iCAAiC;KAC3C,CAAC;IAEJ,gEAAgE;IAChE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC;CACjE,CAAC;KACD,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-target validators for the Vercel Skills CLI target.
|
|
3
|
+
*
|
|
4
|
+
* The Vercel target's primary authored artifact is `SKILL.md` — one file per
|
|
5
|
+
* skill directory under `plugins/<name>/skills/<skill-name>/SKILL.md`. This
|
|
6
|
+
* module validates:
|
|
7
|
+
* 1. YAML frontmatter presence and schema conformance.
|
|
8
|
+
* 2. Name/parent-directory consistency (the agentskills.io spec requires that
|
|
9
|
+
* a skill's frontmatter `name` matches the name of its immediate parent
|
|
10
|
+
* directory).
|
|
11
|
+
* 3. Body line-count recommendation (soft finding when body exceeds 500 lines).
|
|
12
|
+
*
|
|
13
|
+
* Cross-target concerns (envelope-adherence, name-consistency, mcp-key-sync,
|
|
14
|
+
* marketplace-registration, freshness) are out of scope for this module.
|
|
15
|
+
*
|
|
16
|
+
* @see docs/specs/architecture.md §10 (validation contract), §8.1 (Finding types)
|
|
17
|
+
* @see https://agentskills.io (agentskills.io spec — source of name/description constraints)
|
|
18
|
+
*/
|
|
19
|
+
import type { Finding } from '../../pipeline/types.js';
|
|
20
|
+
/**
|
|
21
|
+
* Run Vercel-specific validators (SKILL.md shape and name consistency)
|
|
22
|
+
* against a plugin directory.
|
|
23
|
+
*
|
|
24
|
+
* `pluginDir` is the absolute path to a `plugins/<name>/` directory.
|
|
25
|
+
* All findings use `plugin: path.basename(pluginDir)`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateVercelPlugin(pluginDir: string): Finding[];
|
|
28
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/targets/vercel/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAuLvD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAUjE"}
|