@tankpkg/sdk 0.11.0 → 0.13.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.
Files changed (2) hide show
  1. package/dist/index.mjs +316 -1
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1694,6 +1694,61 @@ const $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
1694
1694
  });
1695
1695
  };
1696
1696
  });
1697
+ const $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnion", (inst, def) => {
1698
+ def.inclusive = false;
1699
+ $ZodUnion.init(inst, def);
1700
+ const _super = inst._zod.parse;
1701
+ defineLazy(inst._zod, "propValues", () => {
1702
+ const propValues = {};
1703
+ for (const option of def.options) {
1704
+ const pv = option._zod.propValues;
1705
+ if (!pv || Object.keys(pv).length === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
1706
+ for (const [k, v] of Object.entries(pv)) {
1707
+ if (!propValues[k]) propValues[k] = /* @__PURE__ */ new Set();
1708
+ for (const val of v) propValues[k].add(val);
1709
+ }
1710
+ }
1711
+ return propValues;
1712
+ });
1713
+ const disc = cached(() => {
1714
+ const opts = def.options;
1715
+ const map = /* @__PURE__ */ new Map();
1716
+ for (const o of opts) {
1717
+ const values = o._zod.propValues?.[def.discriminator];
1718
+ if (!values || values.size === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
1719
+ for (const v of values) {
1720
+ if (map.has(v)) throw new Error(`Duplicate discriminator value "${String(v)}"`);
1721
+ map.set(v, o);
1722
+ }
1723
+ }
1724
+ return map;
1725
+ });
1726
+ inst._zod.parse = (payload, ctx) => {
1727
+ const input = payload.value;
1728
+ if (!isObject(input)) {
1729
+ payload.issues.push({
1730
+ code: "invalid_type",
1731
+ expected: "object",
1732
+ input,
1733
+ inst
1734
+ });
1735
+ return payload;
1736
+ }
1737
+ const opt = disc.value.get(input?.[def.discriminator]);
1738
+ if (opt) return opt._zod.run(payload, ctx);
1739
+ if (def.unionFallback) return _super(payload, ctx);
1740
+ payload.issues.push({
1741
+ code: "invalid_union",
1742
+ errors: [],
1743
+ note: "No matching discriminator",
1744
+ discriminator: def.discriminator,
1745
+ input,
1746
+ path: [def.discriminator],
1747
+ inst
1748
+ });
1749
+ return payload;
1750
+ };
1751
+ });
1697
1752
  const $ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
1698
1753
  $ZodType.init(inst, def);
1699
1754
  inst._zod.parse = (payload, ctx) => {
@@ -3658,6 +3713,18 @@ function union(options, params) {
3658
3713
  ...normalizeParams(params)
3659
3714
  });
3660
3715
  }
3716
+ const ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("ZodDiscriminatedUnion", (inst, def) => {
3717
+ ZodUnion.init(inst, def);
3718
+ $ZodDiscriminatedUnion.init(inst, def);
3719
+ });
3720
+ function discriminatedUnion(discriminator, options, params) {
3721
+ return new ZodDiscriminatedUnion({
3722
+ type: "union",
3723
+ options,
3724
+ discriminator,
3725
+ ...normalizeParams(params)
3726
+ });
3727
+ }
3661
3728
  const ZodIntersection = /* @__PURE__ */ $constructor("ZodIntersection", (inst, def) => {
3662
3729
  $ZodIntersection.init(inst, def);
3663
3730
  ZodType.init(inst, def);
@@ -3908,6 +3975,159 @@ const REGISTRY_URL = process.env.TANK_REGISTRY_URL || "https://www.tankpkg.dev";
3908
3975
  const MANIFEST_FILENAME = "tank.json";
3909
3976
  const LEGACY_MANIFEST_FILENAME = "skills.json";
3910
3977
  const LOCKFILE_FILENAME = "tank.lock";
3978
+ const supportLevelSchema = _enum([
3979
+ "full",
3980
+ "degraded",
3981
+ "none"
3982
+ ]);
3983
+ const adapterCapabilitiesSchema = object({
3984
+ instruction: supportLevelSchema,
3985
+ hook: supportLevelSchema,
3986
+ tool: supportLevelSchema,
3987
+ agent: supportLevelSchema,
3988
+ rule: supportLevelSchema,
3989
+ resource: supportLevelSchema,
3990
+ prompt: supportLevelSchema
3991
+ }).strict();
3992
+ const compilationWarningSchema = object({
3993
+ level: _enum(["degraded", "skipped"]),
3994
+ atomKind: string(),
3995
+ message: string()
3996
+ }).strict();
3997
+ object({
3998
+ files: array(object({
3999
+ path: string().min(1),
4000
+ content: string()
4001
+ }).strict()),
4002
+ warnings: array(compilationWarningSchema)
4003
+ }).strict();
4004
+ object({
4005
+ name: string().min(1, "Adapter name must not be empty"),
4006
+ supportedRange: string().min(1, "Supported range must not be empty"),
4007
+ capabilities: adapterCapabilitiesSchema
4008
+ }).strict();
4009
+ _enum([
4010
+ "instruction",
4011
+ "hook",
4012
+ "tool",
4013
+ "agent",
4014
+ "rule",
4015
+ "resource",
4016
+ "prompt"
4017
+ ]);
4018
+ const extensionBagSchema = record(string(), unknown()).optional();
4019
+ const modelTierSchema = _enum([
4020
+ "fast",
4021
+ "balanced",
4022
+ "powerful",
4023
+ "custom"
4024
+ ]);
4025
+ modelTierSchema.options;
4026
+ const canonicalToolNameSchema = _enum([
4027
+ "bash",
4028
+ "read",
4029
+ "write",
4030
+ "edit",
4031
+ "grep",
4032
+ "glob",
4033
+ "lsp",
4034
+ "mcp",
4035
+ "browser",
4036
+ "fetch",
4037
+ "git",
4038
+ "task",
4039
+ "notebook"
4040
+ ]);
4041
+ canonicalToolNameSchema.options;
4042
+ const agentIRSchema = object({
4043
+ kind: literal("agent"),
4044
+ name: string().min(1, "Agent name must not be empty"),
4045
+ role: string().min(1, "Agent role must not be empty"),
4046
+ tools: array(canonicalToolNameSchema.or(string().min(1))).optional(),
4047
+ model: modelTierSchema.or(string().min(1)).optional(),
4048
+ readonly: boolean().optional(),
4049
+ extensions: extensionBagSchema
4050
+ }).strict();
4051
+ const hookEventSchema = _enum([
4052
+ "pre-tool-use",
4053
+ "post-tool-use",
4054
+ "pre-file-read",
4055
+ "post-file-read",
4056
+ "pre-file-write",
4057
+ "post-file-write",
4058
+ "file-edited",
4059
+ "file-watcher-updated",
4060
+ "pre-command",
4061
+ "post-command",
4062
+ "pre-mcp-tool-use",
4063
+ "post-mcp-tool-use",
4064
+ "session-created",
4065
+ "session-updated",
4066
+ "session-idle",
4067
+ "session-error",
4068
+ "session-deleted",
4069
+ "pre-stop",
4070
+ "task-start",
4071
+ "task-resume",
4072
+ "task-complete",
4073
+ "task-cancel",
4074
+ "pre-user-prompt",
4075
+ "post-response",
4076
+ "message-updated",
4077
+ "message-removed",
4078
+ "system-prompt-transform",
4079
+ "pre-context-compact",
4080
+ "post-context-compact",
4081
+ "permission-asked",
4082
+ "permission-replied",
4083
+ "lsp-diagnostics",
4084
+ "lsp-updated",
4085
+ "subagent-start",
4086
+ "subagent-complete",
4087
+ "subagent-tool-use",
4088
+ "shell-env",
4089
+ "todo-updated",
4090
+ "installation-updated"
4091
+ ]);
4092
+ hookEventSchema.options;
4093
+ const hookActionIRSchema = object({
4094
+ action: _enum([
4095
+ "block",
4096
+ "allow",
4097
+ "rewrite",
4098
+ "injectContext"
4099
+ ]),
4100
+ match: string().optional(),
4101
+ reason: string().optional(),
4102
+ value: string().optional()
4103
+ }).strict();
4104
+ const hookHandlerIRSchema = discriminatedUnion("type", [object({
4105
+ type: literal("dsl"),
4106
+ actions: array(hookActionIRSchema).min(1, "DSL handler must have at least one action")
4107
+ }).strict(), object({
4108
+ type: literal("js"),
4109
+ entry: string().min(1, "JS handler entry path must not be empty")
4110
+ }).strict()]);
4111
+ const hookIRSchema = object({
4112
+ kind: literal("hook"),
4113
+ name: string().optional(),
4114
+ event: hookEventSchema,
4115
+ match: canonicalToolNameSchema.or(string().min(1)).optional(),
4116
+ handler: hookHandlerIRSchema,
4117
+ scope: _enum(["project", "global"]).optional(),
4118
+ extensions: extensionBagSchema
4119
+ }).strict();
4120
+ const instructionIRSchema = object({
4121
+ kind: literal("instruction"),
4122
+ content: string().min(1, "Content path must not be empty"),
4123
+ scope: _enum([
4124
+ "project",
4125
+ "global",
4126
+ "directory"
4127
+ ]).optional(),
4128
+ globs: array(string()).optional(),
4129
+ extensions: extensionBagSchema
4130
+ }).strict();
3911
4131
  const networkPermissionsSchema = object({ outbound: array(string()).optional() }).strict();
3912
4132
  const filesystemPermissionsSchema = object({
3913
4133
  read: array(string()).optional(),
@@ -3946,7 +4166,77 @@ _enum([
3946
4166
  "org.member.remove",
3947
4167
  "org.delete"
3948
4168
  ]);
4169
+ const promptIRSchema = object({
4170
+ kind: literal("prompt"),
4171
+ name: string().min(1, "Prompt name must not be empty"),
4172
+ description: string().optional(),
4173
+ template: string().min(1, "Prompt template path must not be empty"),
4174
+ arguments: array(object({
4175
+ name: string(),
4176
+ description: string().optional(),
4177
+ required: boolean().optional()
4178
+ }).strict()).optional(),
4179
+ extensions: extensionBagSchema
4180
+ }).strict();
4181
+ const resourceIRSchema = object({
4182
+ kind: literal("resource"),
4183
+ name: string().optional(),
4184
+ uri: string().min(1, "Resource URI must not be empty"),
4185
+ description: string().optional(),
4186
+ mimeType: string().optional(),
4187
+ extensions: extensionBagSchema
4188
+ }).strict();
4189
+ const ruleIRSchema = object({
4190
+ kind: literal("rule"),
4191
+ name: string().optional(),
4192
+ event: hookEventSchema,
4193
+ match: canonicalToolNameSchema.or(string().min(1)).optional(),
4194
+ policy: _enum([
4195
+ "block",
4196
+ "allow",
4197
+ "warn"
4198
+ ]),
4199
+ reason: string().optional(),
4200
+ extensions: extensionBagSchema
4201
+ }).strict();
4202
+ const mcpServerConfigSchema = object({
4203
+ command: string().min(1).optional(),
4204
+ args: array(string()).optional(),
4205
+ env: record(string(), string()).optional(),
4206
+ runtime: string().min(1).optional(),
4207
+ entry: string().min(1).optional()
4208
+ }).strict().refine((data) => data.command || data.runtime && data.entry, "MCP config must have either \"command\" or both \"runtime\" and \"entry\"");
4209
+ const toolIRSchema = object({
4210
+ kind: literal("tool"),
4211
+ name: string().min(1, "Tool name must not be empty"),
4212
+ description: string().optional(),
4213
+ mcp: mcpServerConfigSchema.optional(),
4214
+ extensions: extensionBagSchema
4215
+ }).strict();
4216
+ const NAME_PATTERN = /^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/;
4217
+ const SEMVER_PATTERN = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
4218
+ const atomIRSchema = discriminatedUnion("kind", [
4219
+ instructionIRSchema,
4220
+ hookIRSchema,
4221
+ toolIRSchema,
4222
+ agentIRSchema,
4223
+ ruleIRSchema,
4224
+ resourceIRSchema,
4225
+ promptIRSchema
4226
+ ]);
3949
4227
  object({
4228
+ 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"),
4229
+ version: string().regex(SEMVER_PATTERN, "Version must be valid semver"),
4230
+ description: string().max(500).optional(),
4231
+ atoms: array(atomIRSchema),
4232
+ includes: array(string()).optional(),
4233
+ skills: record(string(), string()).optional(),
4234
+ permissions: permissionsSchema.optional(),
4235
+ repository: string().url("Repository must be a valid URL").optional(),
4236
+ visibility: _enum(["public", "private"]).optional(),
4237
+ audit: object({ min_score: number().min(0).max(10) }).strict().optional()
4238
+ }).strict();
4239
+ const baseManifestFields = {
3950
4240
  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"),
3951
4241
  version: string().regex(/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/, "Version must be valid semver"),
3952
4242
  description: string().max(500, `Description must be 500 characters or fewer`).optional(),
@@ -3955,7 +4245,29 @@ object({
3955
4245
  repository: string().url("Repository must be a valid URL").optional(),
3956
4246
  visibility: _enum(["public", "private"]).optional(),
3957
4247
  audit: object({ min_score: number().min(0).max(10) }).strict().optional()
4248
+ };
4249
+ object(baseManifestFields).strict();
4250
+ object({
4251
+ ...baseManifestFields,
4252
+ atoms: array(record(string(), unknown())).optional(),
4253
+ includes: array(string()).optional()
3958
4254
  }).strict();
4255
+ const SKILL_SOURCES = [
4256
+ "registry",
4257
+ "github",
4258
+ "clawhub",
4259
+ "skills_sh",
4260
+ "agentskills_il",
4261
+ "npm",
4262
+ "local"
4263
+ ];
4264
+ const SCAN_VERDICTS = [
4265
+ "pass",
4266
+ "pass_with_notes",
4267
+ "flagged",
4268
+ "fail",
4269
+ "error"
4270
+ ];
3959
4271
  const lockedSkillV1Schema = object({
3960
4272
  resolved: string().url(),
3961
4273
  integrity: string().regex(/^sha512-/, "Integrity must start with sha512-"),
@@ -3971,7 +4283,10 @@ const lockedSkillSchema = object({
3971
4283
  integrity: string().regex(/^sha512-/, "Integrity must start with sha512-"),
3972
4284
  permissions: permissionsSchema,
3973
4285
  audit_score: number().min(0).max(10).nullable(),
3974
- dependencies: record(string(), string()).optional()
4286
+ dependencies: record(string(), string()).optional(),
4287
+ source: _enum(SKILL_SOURCES).optional(),
4288
+ scan_verdict: _enum(SCAN_VERDICTS).optional(),
4289
+ scanned_at: string().optional()
3975
4290
  });
3976
4291
  object({
3977
4292
  lockfileVersion: union([literal(1), literal(2)]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tankpkg/sdk",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Official TypeScript SDK for the Tank registry — search, download, install, and audit AI agent skills programmatically",
5
5
  "type": "module",
6
6
  "exports": {