@tankpkg/mcp-server 0.11.0 → 0.13.1
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/dist/index.js +570 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,6 +15,162 @@ const MANIFEST_FILENAME = "tank.json";
|
|
|
15
15
|
const LEGACY_MANIFEST_FILENAME = "skills.json";
|
|
16
16
|
const LOCKFILE_FILENAME = "tank.lock";
|
|
17
17
|
const LEGACY_LOCKFILE_FILENAME = "skills.lock";
|
|
18
|
+
const supportLevelSchema$1 = z.enum([
|
|
19
|
+
"full",
|
|
20
|
+
"degraded",
|
|
21
|
+
"none"
|
|
22
|
+
]);
|
|
23
|
+
const adapterCapabilitiesSchema$1 = z.object({
|
|
24
|
+
instruction: supportLevelSchema$1,
|
|
25
|
+
hook: supportLevelSchema$1,
|
|
26
|
+
tool: supportLevelSchema$1,
|
|
27
|
+
agent: supportLevelSchema$1,
|
|
28
|
+
rule: supportLevelSchema$1,
|
|
29
|
+
resource: supportLevelSchema$1,
|
|
30
|
+
prompt: supportLevelSchema$1
|
|
31
|
+
}).strict();
|
|
32
|
+
const compilationWarningSchema$1 = z.object({
|
|
33
|
+
level: z.enum(["degraded", "skipped"]),
|
|
34
|
+
atomKind: z.string(),
|
|
35
|
+
message: z.string()
|
|
36
|
+
}).strict();
|
|
37
|
+
const fileWriteSchema = z.object({
|
|
38
|
+
path: z.string().min(1),
|
|
39
|
+
content: z.string()
|
|
40
|
+
}).strict();
|
|
41
|
+
z.object({
|
|
42
|
+
files: z.array(fileWriteSchema),
|
|
43
|
+
warnings: z.array(compilationWarningSchema$1)
|
|
44
|
+
}).strict();
|
|
45
|
+
z.object({
|
|
46
|
+
name: z.string().min(1, "Adapter name must not be empty"),
|
|
47
|
+
supportedRange: z.string().min(1, "Supported range must not be empty"),
|
|
48
|
+
capabilities: adapterCapabilitiesSchema$1
|
|
49
|
+
}).strict();
|
|
50
|
+
z.enum([
|
|
51
|
+
"instruction",
|
|
52
|
+
"hook",
|
|
53
|
+
"tool",
|
|
54
|
+
"agent",
|
|
55
|
+
"rule",
|
|
56
|
+
"resource",
|
|
57
|
+
"prompt"
|
|
58
|
+
]);
|
|
59
|
+
const extensionBagSchema$1 = z.record(z.string(), z.unknown()).optional();
|
|
60
|
+
const modelTierSchema$1 = z.enum([
|
|
61
|
+
"fast",
|
|
62
|
+
"balanced",
|
|
63
|
+
"powerful",
|
|
64
|
+
"custom"
|
|
65
|
+
]);
|
|
66
|
+
modelTierSchema$1.options;
|
|
67
|
+
const canonicalToolNameSchema$1 = z.enum([
|
|
68
|
+
"bash",
|
|
69
|
+
"read",
|
|
70
|
+
"write",
|
|
71
|
+
"edit",
|
|
72
|
+
"grep",
|
|
73
|
+
"glob",
|
|
74
|
+
"lsp",
|
|
75
|
+
"mcp",
|
|
76
|
+
"browser",
|
|
77
|
+
"fetch",
|
|
78
|
+
"git",
|
|
79
|
+
"task",
|
|
80
|
+
"notebook"
|
|
81
|
+
]);
|
|
82
|
+
canonicalToolNameSchema$1.options;
|
|
83
|
+
const agentIRSchema$1 = z.object({
|
|
84
|
+
kind: z.literal("agent"),
|
|
85
|
+
name: z.string().min(1, "Agent name must not be empty"),
|
|
86
|
+
role: z.string().min(1, "Agent role must not be empty"),
|
|
87
|
+
tools: z.array(canonicalToolNameSchema$1.or(z.string().min(1))).optional(),
|
|
88
|
+
model: modelTierSchema$1.or(z.string().min(1)).optional(),
|
|
89
|
+
readonly: z.boolean().optional(),
|
|
90
|
+
extensions: extensionBagSchema$1
|
|
91
|
+
}).strict();
|
|
92
|
+
const hookEventSchema$1 = z.enum([
|
|
93
|
+
"pre-tool-use",
|
|
94
|
+
"post-tool-use",
|
|
95
|
+
"pre-file-read",
|
|
96
|
+
"post-file-read",
|
|
97
|
+
"pre-file-write",
|
|
98
|
+
"post-file-write",
|
|
99
|
+
"file-edited",
|
|
100
|
+
"file-watcher-updated",
|
|
101
|
+
"pre-command",
|
|
102
|
+
"post-command",
|
|
103
|
+
"pre-mcp-tool-use",
|
|
104
|
+
"post-mcp-tool-use",
|
|
105
|
+
"session-created",
|
|
106
|
+
"session-updated",
|
|
107
|
+
"session-idle",
|
|
108
|
+
"session-error",
|
|
109
|
+
"session-deleted",
|
|
110
|
+
"pre-stop",
|
|
111
|
+
"task-start",
|
|
112
|
+
"task-resume",
|
|
113
|
+
"task-complete",
|
|
114
|
+
"task-cancel",
|
|
115
|
+
"pre-user-prompt",
|
|
116
|
+
"post-response",
|
|
117
|
+
"message-updated",
|
|
118
|
+
"message-removed",
|
|
119
|
+
"system-prompt-transform",
|
|
120
|
+
"pre-context-compact",
|
|
121
|
+
"post-context-compact",
|
|
122
|
+
"permission-asked",
|
|
123
|
+
"permission-replied",
|
|
124
|
+
"lsp-diagnostics",
|
|
125
|
+
"lsp-updated",
|
|
126
|
+
"subagent-start",
|
|
127
|
+
"subagent-complete",
|
|
128
|
+
"subagent-tool-use",
|
|
129
|
+
"shell-env",
|
|
130
|
+
"todo-updated",
|
|
131
|
+
"installation-updated"
|
|
132
|
+
]);
|
|
133
|
+
hookEventSchema$1.options;
|
|
134
|
+
const hookActionIRSchema$1 = z.object({
|
|
135
|
+
action: z.enum([
|
|
136
|
+
"block",
|
|
137
|
+
"allow",
|
|
138
|
+
"rewrite",
|
|
139
|
+
"injectContext"
|
|
140
|
+
]),
|
|
141
|
+
match: z.string().optional(),
|
|
142
|
+
reason: z.string().optional(),
|
|
143
|
+
value: z.string().optional()
|
|
144
|
+
}).strict();
|
|
145
|
+
const hookDslHandlerSchema = z.object({
|
|
146
|
+
type: z.literal("dsl"),
|
|
147
|
+
actions: z.array(hookActionIRSchema$1).min(1, "DSL handler must have at least one action")
|
|
148
|
+
}).strict();
|
|
149
|
+
const hookJsHandlerSchema = z.object({
|
|
150
|
+
type: z.literal("js"),
|
|
151
|
+
entry: z.string().min(1, "JS handler entry path must not be empty")
|
|
152
|
+
}).strict();
|
|
153
|
+
const hookHandlerIRSchema$1 = z.discriminatedUnion("type", [hookDslHandlerSchema, hookJsHandlerSchema]);
|
|
154
|
+
const hookIRSchema$1 = z.object({
|
|
155
|
+
kind: z.literal("hook"),
|
|
156
|
+
name: z.string().optional(),
|
|
157
|
+
event: hookEventSchema$1,
|
|
158
|
+
match: canonicalToolNameSchema$1.or(z.string().min(1)).optional(),
|
|
159
|
+
handler: hookHandlerIRSchema$1,
|
|
160
|
+
scope: z.enum(["project", "global"]).optional(),
|
|
161
|
+
extensions: extensionBagSchema$1
|
|
162
|
+
}).strict();
|
|
163
|
+
const instructionIRSchema$1 = z.object({
|
|
164
|
+
kind: z.literal("instruction"),
|
|
165
|
+
content: z.string().min(1, "Content path must not be empty"),
|
|
166
|
+
scope: z.enum([
|
|
167
|
+
"project",
|
|
168
|
+
"global",
|
|
169
|
+
"directory"
|
|
170
|
+
]).optional(),
|
|
171
|
+
globs: z.array(z.string()).optional(),
|
|
172
|
+
extensions: extensionBagSchema$1
|
|
173
|
+
}).strict();
|
|
18
174
|
const networkPermissionsSchema$1 = z.object({ outbound: z.array(z.string()).optional() }).strict();
|
|
19
175
|
const filesystemPermissionsSchema$1 = z.object({
|
|
20
176
|
read: z.array(z.string()).optional(),
|
|
@@ -53,7 +209,77 @@ z.enum([
|
|
|
53
209
|
"org.member.remove",
|
|
54
210
|
"org.delete"
|
|
55
211
|
]);
|
|
56
|
-
const
|
|
212
|
+
const promptIRSchema$1 = z.object({
|
|
213
|
+
kind: z.literal("prompt"),
|
|
214
|
+
name: z.string().min(1, "Prompt name must not be empty"),
|
|
215
|
+
description: z.string().optional(),
|
|
216
|
+
template: z.string().min(1, "Prompt template path must not be empty"),
|
|
217
|
+
arguments: z.array(z.object({
|
|
218
|
+
name: z.string(),
|
|
219
|
+
description: z.string().optional(),
|
|
220
|
+
required: z.boolean().optional()
|
|
221
|
+
}).strict()).optional(),
|
|
222
|
+
extensions: extensionBagSchema$1
|
|
223
|
+
}).strict();
|
|
224
|
+
const resourceIRSchema$1 = z.object({
|
|
225
|
+
kind: z.literal("resource"),
|
|
226
|
+
name: z.string().optional(),
|
|
227
|
+
uri: z.string().min(1, "Resource URI must not be empty"),
|
|
228
|
+
description: z.string().optional(),
|
|
229
|
+
mimeType: z.string().optional(),
|
|
230
|
+
extensions: extensionBagSchema$1
|
|
231
|
+
}).strict();
|
|
232
|
+
const ruleIRSchema$1 = z.object({
|
|
233
|
+
kind: z.literal("rule"),
|
|
234
|
+
name: z.string().optional(),
|
|
235
|
+
event: hookEventSchema$1,
|
|
236
|
+
match: canonicalToolNameSchema$1.or(z.string().min(1)).optional(),
|
|
237
|
+
policy: z.enum([
|
|
238
|
+
"block",
|
|
239
|
+
"allow",
|
|
240
|
+
"warn"
|
|
241
|
+
]),
|
|
242
|
+
reason: z.string().optional(),
|
|
243
|
+
extensions: extensionBagSchema$1
|
|
244
|
+
}).strict();
|
|
245
|
+
const mcpServerConfigSchema$1 = z.object({
|
|
246
|
+
command: z.string().min(1).optional(),
|
|
247
|
+
args: z.array(z.string()).optional(),
|
|
248
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
249
|
+
runtime: z.string().min(1).optional(),
|
|
250
|
+
entry: z.string().min(1).optional()
|
|
251
|
+
}).strict().refine((data) => data.command || data.runtime && data.entry, "MCP config must have either \"command\" or both \"runtime\" and \"entry\"");
|
|
252
|
+
const toolIRSchema$1 = z.object({
|
|
253
|
+
kind: z.literal("tool"),
|
|
254
|
+
name: z.string().min(1, "Tool name must not be empty"),
|
|
255
|
+
description: z.string().optional(),
|
|
256
|
+
mcp: mcpServerConfigSchema$1.optional(),
|
|
257
|
+
extensions: extensionBagSchema$1
|
|
258
|
+
}).strict();
|
|
259
|
+
const NAME_PATTERN$1 = /^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/;
|
|
260
|
+
const SEMVER_PATTERN$2 = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
261
|
+
const atomIRSchema$1 = z.discriminatedUnion("kind", [
|
|
262
|
+
instructionIRSchema$1,
|
|
263
|
+
hookIRSchema$1,
|
|
264
|
+
toolIRSchema$1,
|
|
265
|
+
agentIRSchema$1,
|
|
266
|
+
ruleIRSchema$1,
|
|
267
|
+
resourceIRSchema$1,
|
|
268
|
+
promptIRSchema$1
|
|
269
|
+
]);
|
|
270
|
+
z.object({
|
|
271
|
+
name: z.string().min(1, "Name must not be empty").max(214, `Name must be 214 characters or fewer`).regex(NAME_PATTERN$1, "Name must be scoped (@org/name), lowercase alphanumeric and hyphens"),
|
|
272
|
+
version: z.string().regex(SEMVER_PATTERN$2, "Version must be valid semver"),
|
|
273
|
+
description: z.string().max(500).optional(),
|
|
274
|
+
atoms: z.array(atomIRSchema$1),
|
|
275
|
+
includes: z.array(z.string()).optional(),
|
|
276
|
+
skills: z.record(z.string(), z.string()).optional(),
|
|
277
|
+
permissions: permissionsSchema$1.optional(),
|
|
278
|
+
repository: z.string().url("Repository must be a valid URL").optional(),
|
|
279
|
+
visibility: z.enum(["public", "private"]).optional(),
|
|
280
|
+
audit: z.object({ min_score: z.number().min(0).max(10) }).strict().optional()
|
|
281
|
+
}).strict();
|
|
282
|
+
const baseManifestFields$1 = {
|
|
57
283
|
name: z.string().min(1, "Name must not be empty").max(214, `Name must be 214 characters or fewer`).regex(/^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/, "Name must be scoped (@org/name), lowercase alphanumeric and hyphens"),
|
|
58
284
|
version: z.string().regex(/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/, "Version must be valid semver"),
|
|
59
285
|
description: z.string().max(500, `Description must be 500 characters or fewer`).optional(),
|
|
@@ -62,7 +288,30 @@ const skillsJsonSchema = z.object({
|
|
|
62
288
|
repository: z.string().url("Repository must be a valid URL").optional(),
|
|
63
289
|
visibility: z.enum(["public", "private"]).optional(),
|
|
64
290
|
audit: z.object({ min_score: z.number().min(0).max(10) }).strict().optional()
|
|
291
|
+
};
|
|
292
|
+
/** Legacy skills.json schema — strict, no atoms. Used for backward-compatible consumers. */
|
|
293
|
+
const skillsJsonSchema = z.object(baseManifestFields$1).strict();
|
|
294
|
+
z.object({
|
|
295
|
+
...baseManifestFields$1,
|
|
296
|
+
atoms: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
297
|
+
includes: z.array(z.string()).optional()
|
|
65
298
|
}).strict();
|
|
299
|
+
const SKILL_SOURCES$1 = [
|
|
300
|
+
"registry",
|
|
301
|
+
"github",
|
|
302
|
+
"clawhub",
|
|
303
|
+
"skills_sh",
|
|
304
|
+
"agentskills_il",
|
|
305
|
+
"npm",
|
|
306
|
+
"local"
|
|
307
|
+
];
|
|
308
|
+
const SCAN_VERDICTS$1 = [
|
|
309
|
+
"pass",
|
|
310
|
+
"pass_with_notes",
|
|
311
|
+
"flagged",
|
|
312
|
+
"fail",
|
|
313
|
+
"error"
|
|
314
|
+
];
|
|
66
315
|
const lockedSkillV1Schema$1 = z.object({
|
|
67
316
|
resolved: z.string().url(),
|
|
68
317
|
integrity: z.string().regex(/^sha512-/, "Integrity must start with sha512-"),
|
|
@@ -78,7 +327,10 @@ const lockedSkillSchema$1 = z.object({
|
|
|
78
327
|
integrity: z.string().regex(/^sha512-/, "Integrity must start with sha512-"),
|
|
79
328
|
permissions: permissionsSchema$1,
|
|
80
329
|
audit_score: z.number().min(0).max(10).nullable(),
|
|
81
|
-
dependencies: z.record(z.string(), z.string()).optional()
|
|
330
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
331
|
+
source: z.enum(SKILL_SOURCES$1).optional(),
|
|
332
|
+
scan_verdict: z.enum(SCAN_VERDICTS$1).optional(),
|
|
333
|
+
scanned_at: z.string().optional()
|
|
82
334
|
});
|
|
83
335
|
z.object({
|
|
84
336
|
lockfileVersion: z.union([z.literal(1), z.literal(2)]),
|
|
@@ -1737,6 +1989,61 @@ const $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
|
|
|
1737
1989
|
});
|
|
1738
1990
|
};
|
|
1739
1991
|
});
|
|
1992
|
+
const $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnion", (inst, def) => {
|
|
1993
|
+
def.inclusive = false;
|
|
1994
|
+
$ZodUnion.init(inst, def);
|
|
1995
|
+
const _super = inst._zod.parse;
|
|
1996
|
+
defineLazy(inst._zod, "propValues", () => {
|
|
1997
|
+
const propValues = {};
|
|
1998
|
+
for (const option of def.options) {
|
|
1999
|
+
const pv = option._zod.propValues;
|
|
2000
|
+
if (!pv || Object.keys(pv).length === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
|
|
2001
|
+
for (const [k, v] of Object.entries(pv)) {
|
|
2002
|
+
if (!propValues[k]) propValues[k] = /* @__PURE__ */ new Set();
|
|
2003
|
+
for (const val of v) propValues[k].add(val);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
return propValues;
|
|
2007
|
+
});
|
|
2008
|
+
const disc = cached(() => {
|
|
2009
|
+
const opts = def.options;
|
|
2010
|
+
const map = /* @__PURE__ */ new Map();
|
|
2011
|
+
for (const o of opts) {
|
|
2012
|
+
const values = o._zod.propValues?.[def.discriminator];
|
|
2013
|
+
if (!values || values.size === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
|
|
2014
|
+
for (const v of values) {
|
|
2015
|
+
if (map.has(v)) throw new Error(`Duplicate discriminator value "${String(v)}"`);
|
|
2016
|
+
map.set(v, o);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
return map;
|
|
2020
|
+
});
|
|
2021
|
+
inst._zod.parse = (payload, ctx) => {
|
|
2022
|
+
const input = payload.value;
|
|
2023
|
+
if (!isObject(input)) {
|
|
2024
|
+
payload.issues.push({
|
|
2025
|
+
code: "invalid_type",
|
|
2026
|
+
expected: "object",
|
|
2027
|
+
input,
|
|
2028
|
+
inst
|
|
2029
|
+
});
|
|
2030
|
+
return payload;
|
|
2031
|
+
}
|
|
2032
|
+
const opt = disc.value.get(input?.[def.discriminator]);
|
|
2033
|
+
if (opt) return opt._zod.run(payload, ctx);
|
|
2034
|
+
if (def.unionFallback) return _super(payload, ctx);
|
|
2035
|
+
payload.issues.push({
|
|
2036
|
+
code: "invalid_union",
|
|
2037
|
+
errors: [],
|
|
2038
|
+
note: "No matching discriminator",
|
|
2039
|
+
discriminator: def.discriminator,
|
|
2040
|
+
input,
|
|
2041
|
+
path: [def.discriminator],
|
|
2042
|
+
inst
|
|
2043
|
+
});
|
|
2044
|
+
return payload;
|
|
2045
|
+
};
|
|
2046
|
+
});
|
|
1740
2047
|
const $ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
|
|
1741
2048
|
$ZodType.init(inst, def);
|
|
1742
2049
|
inst._zod.parse = (payload, ctx) => {
|
|
@@ -3685,6 +3992,18 @@ function union(options, params) {
|
|
|
3685
3992
|
...normalizeParams(params)
|
|
3686
3993
|
});
|
|
3687
3994
|
}
|
|
3995
|
+
const ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("ZodDiscriminatedUnion", (inst, def) => {
|
|
3996
|
+
ZodUnion.init(inst, def);
|
|
3997
|
+
$ZodDiscriminatedUnion.init(inst, def);
|
|
3998
|
+
});
|
|
3999
|
+
function discriminatedUnion(discriminator, options, params) {
|
|
4000
|
+
return new ZodDiscriminatedUnion({
|
|
4001
|
+
type: "union",
|
|
4002
|
+
options,
|
|
4003
|
+
discriminator,
|
|
4004
|
+
...normalizeParams(params)
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
3688
4007
|
const ZodIntersection = /* @__PURE__ */ $constructor("ZodIntersection", (inst, def) => {
|
|
3689
4008
|
$ZodIntersection.init(inst, def);
|
|
3690
4009
|
ZodType.init(inst, def);
|
|
@@ -3930,6 +4249,159 @@ function superRefine(fn) {
|
|
|
3930
4249
|
return /* @__PURE__ */ _superRefine(fn);
|
|
3931
4250
|
}
|
|
3932
4251
|
const REGISTRY_URL = process.env.TANK_REGISTRY_URL || "https://www.tankpkg.dev";
|
|
4252
|
+
const supportLevelSchema = _enum([
|
|
4253
|
+
"full",
|
|
4254
|
+
"degraded",
|
|
4255
|
+
"none"
|
|
4256
|
+
]);
|
|
4257
|
+
const adapterCapabilitiesSchema = object({
|
|
4258
|
+
instruction: supportLevelSchema,
|
|
4259
|
+
hook: supportLevelSchema,
|
|
4260
|
+
tool: supportLevelSchema,
|
|
4261
|
+
agent: supportLevelSchema,
|
|
4262
|
+
rule: supportLevelSchema,
|
|
4263
|
+
resource: supportLevelSchema,
|
|
4264
|
+
prompt: supportLevelSchema
|
|
4265
|
+
}).strict();
|
|
4266
|
+
const compilationWarningSchema = object({
|
|
4267
|
+
level: _enum(["degraded", "skipped"]),
|
|
4268
|
+
atomKind: string(),
|
|
4269
|
+
message: string()
|
|
4270
|
+
}).strict();
|
|
4271
|
+
object({
|
|
4272
|
+
files: array(object({
|
|
4273
|
+
path: string().min(1),
|
|
4274
|
+
content: string()
|
|
4275
|
+
}).strict()),
|
|
4276
|
+
warnings: array(compilationWarningSchema)
|
|
4277
|
+
}).strict();
|
|
4278
|
+
object({
|
|
4279
|
+
name: string().min(1, "Adapter name must not be empty"),
|
|
4280
|
+
supportedRange: string().min(1, "Supported range must not be empty"),
|
|
4281
|
+
capabilities: adapterCapabilitiesSchema
|
|
4282
|
+
}).strict();
|
|
4283
|
+
_enum([
|
|
4284
|
+
"instruction",
|
|
4285
|
+
"hook",
|
|
4286
|
+
"tool",
|
|
4287
|
+
"agent",
|
|
4288
|
+
"rule",
|
|
4289
|
+
"resource",
|
|
4290
|
+
"prompt"
|
|
4291
|
+
]);
|
|
4292
|
+
const extensionBagSchema = record(string(), unknown()).optional();
|
|
4293
|
+
const modelTierSchema = _enum([
|
|
4294
|
+
"fast",
|
|
4295
|
+
"balanced",
|
|
4296
|
+
"powerful",
|
|
4297
|
+
"custom"
|
|
4298
|
+
]);
|
|
4299
|
+
modelTierSchema.options;
|
|
4300
|
+
const canonicalToolNameSchema = _enum([
|
|
4301
|
+
"bash",
|
|
4302
|
+
"read",
|
|
4303
|
+
"write",
|
|
4304
|
+
"edit",
|
|
4305
|
+
"grep",
|
|
4306
|
+
"glob",
|
|
4307
|
+
"lsp",
|
|
4308
|
+
"mcp",
|
|
4309
|
+
"browser",
|
|
4310
|
+
"fetch",
|
|
4311
|
+
"git",
|
|
4312
|
+
"task",
|
|
4313
|
+
"notebook"
|
|
4314
|
+
]);
|
|
4315
|
+
canonicalToolNameSchema.options;
|
|
4316
|
+
const agentIRSchema = object({
|
|
4317
|
+
kind: literal("agent"),
|
|
4318
|
+
name: string().min(1, "Agent name must not be empty"),
|
|
4319
|
+
role: string().min(1, "Agent role must not be empty"),
|
|
4320
|
+
tools: array(canonicalToolNameSchema.or(string().min(1))).optional(),
|
|
4321
|
+
model: modelTierSchema.or(string().min(1)).optional(),
|
|
4322
|
+
readonly: boolean().optional(),
|
|
4323
|
+
extensions: extensionBagSchema
|
|
4324
|
+
}).strict();
|
|
4325
|
+
const hookEventSchema = _enum([
|
|
4326
|
+
"pre-tool-use",
|
|
4327
|
+
"post-tool-use",
|
|
4328
|
+
"pre-file-read",
|
|
4329
|
+
"post-file-read",
|
|
4330
|
+
"pre-file-write",
|
|
4331
|
+
"post-file-write",
|
|
4332
|
+
"file-edited",
|
|
4333
|
+
"file-watcher-updated",
|
|
4334
|
+
"pre-command",
|
|
4335
|
+
"post-command",
|
|
4336
|
+
"pre-mcp-tool-use",
|
|
4337
|
+
"post-mcp-tool-use",
|
|
4338
|
+
"session-created",
|
|
4339
|
+
"session-updated",
|
|
4340
|
+
"session-idle",
|
|
4341
|
+
"session-error",
|
|
4342
|
+
"session-deleted",
|
|
4343
|
+
"pre-stop",
|
|
4344
|
+
"task-start",
|
|
4345
|
+
"task-resume",
|
|
4346
|
+
"task-complete",
|
|
4347
|
+
"task-cancel",
|
|
4348
|
+
"pre-user-prompt",
|
|
4349
|
+
"post-response",
|
|
4350
|
+
"message-updated",
|
|
4351
|
+
"message-removed",
|
|
4352
|
+
"system-prompt-transform",
|
|
4353
|
+
"pre-context-compact",
|
|
4354
|
+
"post-context-compact",
|
|
4355
|
+
"permission-asked",
|
|
4356
|
+
"permission-replied",
|
|
4357
|
+
"lsp-diagnostics",
|
|
4358
|
+
"lsp-updated",
|
|
4359
|
+
"subagent-start",
|
|
4360
|
+
"subagent-complete",
|
|
4361
|
+
"subagent-tool-use",
|
|
4362
|
+
"shell-env",
|
|
4363
|
+
"todo-updated",
|
|
4364
|
+
"installation-updated"
|
|
4365
|
+
]);
|
|
4366
|
+
hookEventSchema.options;
|
|
4367
|
+
const hookActionIRSchema = object({
|
|
4368
|
+
action: _enum([
|
|
4369
|
+
"block",
|
|
4370
|
+
"allow",
|
|
4371
|
+
"rewrite",
|
|
4372
|
+
"injectContext"
|
|
4373
|
+
]),
|
|
4374
|
+
match: string().optional(),
|
|
4375
|
+
reason: string().optional(),
|
|
4376
|
+
value: string().optional()
|
|
4377
|
+
}).strict();
|
|
4378
|
+
const hookHandlerIRSchema = discriminatedUnion("type", [object({
|
|
4379
|
+
type: literal("dsl"),
|
|
4380
|
+
actions: array(hookActionIRSchema).min(1, "DSL handler must have at least one action")
|
|
4381
|
+
}).strict(), object({
|
|
4382
|
+
type: literal("js"),
|
|
4383
|
+
entry: string().min(1, "JS handler entry path must not be empty")
|
|
4384
|
+
}).strict()]);
|
|
4385
|
+
const hookIRSchema = object({
|
|
4386
|
+
kind: literal("hook"),
|
|
4387
|
+
name: string().optional(),
|
|
4388
|
+
event: hookEventSchema,
|
|
4389
|
+
match: canonicalToolNameSchema.or(string().min(1)).optional(),
|
|
4390
|
+
handler: hookHandlerIRSchema,
|
|
4391
|
+
scope: _enum(["project", "global"]).optional(),
|
|
4392
|
+
extensions: extensionBagSchema
|
|
4393
|
+
}).strict();
|
|
4394
|
+
const instructionIRSchema = object({
|
|
4395
|
+
kind: literal("instruction"),
|
|
4396
|
+
content: string().min(1, "Content path must not be empty"),
|
|
4397
|
+
scope: _enum([
|
|
4398
|
+
"project",
|
|
4399
|
+
"global",
|
|
4400
|
+
"directory"
|
|
4401
|
+
]).optional(),
|
|
4402
|
+
globs: array(string()).optional(),
|
|
4403
|
+
extensions: extensionBagSchema
|
|
4404
|
+
}).strict();
|
|
3933
4405
|
const networkPermissionsSchema = object({ outbound: array(string()).optional() }).strict();
|
|
3934
4406
|
const filesystemPermissionsSchema = object({
|
|
3935
4407
|
read: array(string()).optional(),
|
|
@@ -3968,7 +4440,77 @@ _enum([
|
|
|
3968
4440
|
"org.member.remove",
|
|
3969
4441
|
"org.delete"
|
|
3970
4442
|
]);
|
|
4443
|
+
const promptIRSchema = object({
|
|
4444
|
+
kind: literal("prompt"),
|
|
4445
|
+
name: string().min(1, "Prompt name must not be empty"),
|
|
4446
|
+
description: string().optional(),
|
|
4447
|
+
template: string().min(1, "Prompt template path must not be empty"),
|
|
4448
|
+
arguments: array(object({
|
|
4449
|
+
name: string(),
|
|
4450
|
+
description: string().optional(),
|
|
4451
|
+
required: boolean().optional()
|
|
4452
|
+
}).strict()).optional(),
|
|
4453
|
+
extensions: extensionBagSchema
|
|
4454
|
+
}).strict();
|
|
4455
|
+
const resourceIRSchema = object({
|
|
4456
|
+
kind: literal("resource"),
|
|
4457
|
+
name: string().optional(),
|
|
4458
|
+
uri: string().min(1, "Resource URI must not be empty"),
|
|
4459
|
+
description: string().optional(),
|
|
4460
|
+
mimeType: string().optional(),
|
|
4461
|
+
extensions: extensionBagSchema
|
|
4462
|
+
}).strict();
|
|
4463
|
+
const ruleIRSchema = object({
|
|
4464
|
+
kind: literal("rule"),
|
|
4465
|
+
name: string().optional(),
|
|
4466
|
+
event: hookEventSchema,
|
|
4467
|
+
match: canonicalToolNameSchema.or(string().min(1)).optional(),
|
|
4468
|
+
policy: _enum([
|
|
4469
|
+
"block",
|
|
4470
|
+
"allow",
|
|
4471
|
+
"warn"
|
|
4472
|
+
]),
|
|
4473
|
+
reason: string().optional(),
|
|
4474
|
+
extensions: extensionBagSchema
|
|
4475
|
+
}).strict();
|
|
4476
|
+
const mcpServerConfigSchema = object({
|
|
4477
|
+
command: string().min(1).optional(),
|
|
4478
|
+
args: array(string()).optional(),
|
|
4479
|
+
env: record(string(), string()).optional(),
|
|
4480
|
+
runtime: string().min(1).optional(),
|
|
4481
|
+
entry: string().min(1).optional()
|
|
4482
|
+
}).strict().refine((data) => data.command || data.runtime && data.entry, "MCP config must have either \"command\" or both \"runtime\" and \"entry\"");
|
|
4483
|
+
const toolIRSchema = object({
|
|
4484
|
+
kind: literal("tool"),
|
|
4485
|
+
name: string().min(1, "Tool name must not be empty"),
|
|
4486
|
+
description: string().optional(),
|
|
4487
|
+
mcp: mcpServerConfigSchema.optional(),
|
|
4488
|
+
extensions: extensionBagSchema
|
|
4489
|
+
}).strict();
|
|
4490
|
+
const NAME_PATTERN = /^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/;
|
|
4491
|
+
const SEMVER_PATTERN$1 = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
4492
|
+
const atomIRSchema = discriminatedUnion("kind", [
|
|
4493
|
+
instructionIRSchema,
|
|
4494
|
+
hookIRSchema,
|
|
4495
|
+
toolIRSchema,
|
|
4496
|
+
agentIRSchema,
|
|
4497
|
+
ruleIRSchema,
|
|
4498
|
+
resourceIRSchema,
|
|
4499
|
+
promptIRSchema
|
|
4500
|
+
]);
|
|
3971
4501
|
object({
|
|
4502
|
+
name: string().min(1, "Name must not be empty").max(214, `Name must be 214 characters or fewer`).regex(NAME_PATTERN, "Name must be scoped (@org/name), lowercase alphanumeric and hyphens"),
|
|
4503
|
+
version: string().regex(SEMVER_PATTERN$1, "Version must be valid semver"),
|
|
4504
|
+
description: string().max(500).optional(),
|
|
4505
|
+
atoms: array(atomIRSchema),
|
|
4506
|
+
includes: array(string()).optional(),
|
|
4507
|
+
skills: record(string(), string()).optional(),
|
|
4508
|
+
permissions: permissionsSchema.optional(),
|
|
4509
|
+
repository: string().url("Repository must be a valid URL").optional(),
|
|
4510
|
+
visibility: _enum(["public", "private"]).optional(),
|
|
4511
|
+
audit: object({ min_score: number().min(0).max(10) }).strict().optional()
|
|
4512
|
+
}).strict();
|
|
4513
|
+
const baseManifestFields = {
|
|
3972
4514
|
name: string().min(1, "Name must not be empty").max(214, `Name must be 214 characters or fewer`).regex(/^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/, "Name must be scoped (@org/name), lowercase alphanumeric and hyphens"),
|
|
3973
4515
|
version: string().regex(/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/, "Version must be valid semver"),
|
|
3974
4516
|
description: string().max(500, `Description must be 500 characters or fewer`).optional(),
|
|
@@ -3977,7 +4519,29 @@ object({
|
|
|
3977
4519
|
repository: string().url("Repository must be a valid URL").optional(),
|
|
3978
4520
|
visibility: _enum(["public", "private"]).optional(),
|
|
3979
4521
|
audit: object({ min_score: number().min(0).max(10) }).strict().optional()
|
|
4522
|
+
};
|
|
4523
|
+
object(baseManifestFields).strict();
|
|
4524
|
+
object({
|
|
4525
|
+
...baseManifestFields,
|
|
4526
|
+
atoms: array(record(string(), unknown())).optional(),
|
|
4527
|
+
includes: array(string()).optional()
|
|
3980
4528
|
}).strict();
|
|
4529
|
+
const SKILL_SOURCES = [
|
|
4530
|
+
"registry",
|
|
4531
|
+
"github",
|
|
4532
|
+
"clawhub",
|
|
4533
|
+
"skills_sh",
|
|
4534
|
+
"agentskills_il",
|
|
4535
|
+
"npm",
|
|
4536
|
+
"local"
|
|
4537
|
+
];
|
|
4538
|
+
const SCAN_VERDICTS = [
|
|
4539
|
+
"pass",
|
|
4540
|
+
"pass_with_notes",
|
|
4541
|
+
"flagged",
|
|
4542
|
+
"fail",
|
|
4543
|
+
"error"
|
|
4544
|
+
];
|
|
3981
4545
|
const lockedSkillV1Schema = object({
|
|
3982
4546
|
resolved: string().url(),
|
|
3983
4547
|
integrity: string().regex(/^sha512-/, "Integrity must start with sha512-"),
|
|
@@ -3993,7 +4557,10 @@ const lockedSkillSchema = object({
|
|
|
3993
4557
|
integrity: string().regex(/^sha512-/, "Integrity must start with sha512-"),
|
|
3994
4558
|
permissions: permissionsSchema,
|
|
3995
4559
|
audit_score: number().min(0).max(10).nullable(),
|
|
3996
|
-
dependencies: record(string(), string()).optional()
|
|
4560
|
+
dependencies: record(string(), string()).optional(),
|
|
4561
|
+
source: _enum(SKILL_SOURCES).optional(),
|
|
4562
|
+
scan_verdict: _enum(SCAN_VERDICTS).optional(),
|
|
4563
|
+
scanned_at: string().optional()
|
|
3997
4564
|
});
|
|
3998
4565
|
object({
|
|
3999
4566
|
lockfileVersion: union([literal(1), literal(2)]),
|