@yaklabs-ai/plugin-sdk 0.15.2 → 0.26.3

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/kay-agent.js CHANGED
@@ -18,57 +18,111 @@ function compileUriClaim(claim) {
18
18
  };
19
19
  }
20
20
  const pattern = compileRoutePattern(claim.pattern);
21
+ const normalizeTo = claim.normalizeTo === void 0 ? void 0 : compileTemplate(claim.normalizeTo);
22
+ const sourceUrl = claim.kind === "uriPattern" && claim.sourceUrl !== void 0 ? compileTemplate(claim.sourceUrl) : void 0;
23
+ const matchAt = (target, selector) => {
24
+ const parsed = parsePatternInput(target);
25
+ if (parsed === void 0)
26
+ return void 0;
27
+ const captures = matchRoute(pattern, parsed);
28
+ if (captures === void 0)
29
+ return void 0;
30
+ const restCaptures = pattern.restCaptures ?? [];
31
+ const normalized = normalizeTo === void 0 ? void 0 : fillTemplate(normalizeTo, captures, restCaptures);
32
+ if (normalizeTo !== void 0 && normalized === void 0)
33
+ return void 0;
34
+ const filledSourceUrl = sourceUrl === void 0 ? void 0 : fillTemplate(sourceUrl, captures, restCaptures);
35
+ return {
36
+ claimKind: claim.kind,
37
+ ...Object.keys(captures).length > 0 ? { captures } : {},
38
+ ...normalized !== void 0 ? {
39
+ normalizedUri: withSelector(withInputSearch(claim, pattern, parsed, normalized), parsed.protocol, selector)
40
+ } : {},
41
+ ...claim.route !== void 0 ? { route: claim.route } : {},
42
+ ...filledSourceUrl !== void 0 ? { sourceUrl: filledSourceUrl } : {},
43
+ ...claim.kind === "uriPattern" && claim.title !== void 0 ? { title: fillTitle(claim.title, captures) } : {}
44
+ };
45
+ };
21
46
  return {
22
47
  claim,
23
48
  match(input) {
24
- const parsed = parsePatternInput(input);
25
- if (parsed === void 0)
26
- return void 0;
27
- const captures = matchRoute(pattern, parsed);
28
- if (captures === void 0)
29
- return void 0;
30
- return {
31
- claimKind: claim.kind,
32
- ...Object.keys(captures).length > 0 ? { captures } : {},
33
- ...claim.normalizeTo !== void 0 ? {
34
- normalizedUri: withInputSearch(claim, pattern, parsed, interpolateNormalizeTo(claim.normalizeTo, captures, pattern.restCaptures ?? []))
35
- } : {}
36
- };
49
+ if (claim.kind === "uriPattern") {
50
+ const { selector, rest } = parseUriConnectionSelector(input);
51
+ if (selector !== void 0) {
52
+ const match = matchAt(rest, selector);
53
+ if (match !== void 0)
54
+ return match;
55
+ }
56
+ }
57
+ return matchAt(input, void 0);
37
58
  }
38
59
  };
39
60
  }
61
+ function fillTitle(template, captures) {
62
+ return template.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, (written, name) => captures[name] ?? written);
63
+ }
64
+ var CONNECTION_SELECTOR_RE = /^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)@([^/]+)(?:\/(.*))?$/;
65
+ function parseUriConnectionSelector(input) {
66
+ const match = CONNECTION_SELECTOR_RE.exec(input.trim());
67
+ if (match?.[1] === void 0 || match[2] === void 0) {
68
+ return { rest: input };
69
+ }
70
+ return { selector: match[2], rest: `${match[1]}${match[3] ?? ""}` };
71
+ }
72
+ function withSelector(normalized, inputProtocol, selector) {
73
+ if (selector === void 0)
74
+ return normalized;
75
+ if (templateProtocol(normalized) !== inputProtocol)
76
+ return normalized;
77
+ const schemeEnd = normalized.indexOf("://") + 3;
78
+ return `${normalized.slice(0, schemeEnd)}@${selector}/${normalized.slice(schemeEnd)}`;
79
+ }
40
80
  function normalizeProtocol(value) {
41
81
  return value.replace(/:$/, "").toLowerCase();
42
82
  }
43
83
  function parsePatternInput(input) {
84
+ const trimmed = input.trim();
85
+ let url;
44
86
  try {
45
- const url = new URL(input.trim());
46
- return {
47
- protocol: normalizeProtocol(url.protocol),
48
- hostname: url.hostname.toLowerCase(),
49
- pathname: url.pathname,
50
- search: url.search.startsWith("?") ? url.search.slice(1) : url.search
51
- };
87
+ url = new URL(trimmed);
52
88
  } catch {
53
- return void 0;
89
+ if (!trimmed.includes(" "))
90
+ return void 0;
91
+ try {
92
+ url = new URL(trimmed.replaceAll(" ", "%20"));
93
+ } catch {
94
+ return void 0;
95
+ }
54
96
  }
97
+ return {
98
+ protocol: normalizeProtocol(url.protocol),
99
+ // A web host arrives lowercased; a custom scheme's keeps its case, so a capture of it
100
+ // (`projects://Acme`) names it as written. Literal host parts match either case.
101
+ hostname: url.hostname,
102
+ pathname: url.pathname,
103
+ search: url.search.startsWith("?") ? url.search.slice(1) : url.search
104
+ };
55
105
  }
56
106
  function compileRoutePattern(pattern) {
57
107
  const pathname = pattern.pathname !== void 0 ? compileParts(pattern.pathname, "/", { allowRest: true }) : void 0;
58
108
  return {
59
109
  ...pattern.protocol !== void 0 ? { protocol: normalizeProtocol(pattern.protocol) } : {},
60
- ...pattern.hostname !== void 0 ? { hostname: compileParts(pattern.hostname.toLowerCase(), ".") } : {},
110
+ ...pattern.hostname !== void 0 ? {
111
+ hostname: compileParts(pattern.hostname.toLowerCase(), LONE_CAPTURE_RE.test(pattern.hostname) ? void 0 : ".")
112
+ } : {},
61
113
  ...pathname !== void 0 ? { pathname } : {},
114
+ ...pattern.pathname?.endsWith("/") === true ? { pathnameEndsInSlash: true } : {},
62
115
  ...pathname !== void 0 ? {
63
116
  restCaptures: pathname.filter((part) => part.rest === true).map((part) => part.capture)
64
117
  } : {},
65
118
  ...pattern.search !== void 0 ? { search: compileParts(pattern.search.replace(/^\?/, ""), "&") } : {}
66
119
  };
67
120
  }
121
+ var LONE_CAPTURE_RE = /^:[A-Za-z_][A-Za-z0-9_]*(?:\([^()|]*\))?$/;
68
122
  function compileParts(value, separator, options = {}) {
69
123
  if (value === "")
70
124
  return [];
71
- const parts = value.split(separator);
125
+ const parts = separator === void 0 ? [value] : value.split(separator);
72
126
  return parts.map((part, index) => {
73
127
  const restMatch = REST_CAPTURE_RE.exec(part);
74
128
  if (restMatch !== null) {
@@ -108,19 +162,30 @@ function matchRoute(pattern, input) {
108
162
  return void 0;
109
163
  }
110
164
  const captures = {};
111
- if (pattern.hostname !== void 0 && !matchParts(pattern.hostname, input.hostname, ".", captures)) {
165
+ if (pattern.hostname !== void 0 && !matchParts(pattern.hostname, input.hostname, isLoneCapture(pattern.hostname) ? void 0 : ".", captures, true)) {
112
166
  return void 0;
113
167
  }
114
- if (pattern.pathname !== void 0 && !matchParts(pattern.pathname, input.pathname, "/", captures)) {
168
+ if (pattern.pathname !== void 0 && !matchParts(pattern.pathname, pattern.pathnameEndsInSlash === true ? input.pathname : withoutTrailingSlash(input), "/", captures)) {
115
169
  return void 0;
116
170
  }
117
- if (pattern.search !== void 0 && !matchParts(pattern.search, input.search, "&", captures)) {
171
+ if (pattern.search !== void 0 && (pattern.search.length === 0 ? input.search !== "" : !matchParts(pattern.search, input.search, "&", captures))) {
118
172
  return void 0;
119
173
  }
120
174
  return captures;
121
175
  }
122
- function matchParts(pattern, value, separator, captures) {
123
- const parts = value.split(separator);
176
+ function withoutTrailingSlash(input) {
177
+ const { hostname, pathname } = input;
178
+ if (!pathname.endsWith("/") || pathname.endsWith("//"))
179
+ return pathname;
180
+ if (pathname === "/" && hostname === "")
181
+ return pathname;
182
+ return pathname.slice(0, -1);
183
+ }
184
+ function isLoneCapture(pattern) {
185
+ return pattern.length === 1 && pattern[0].capture !== void 0 && pattern[0].rest !== true;
186
+ }
187
+ function matchParts(pattern, value, separator, captures, foldLiterals = false) {
188
+ const parts = separator === void 0 ? [value] : value.split(separator);
124
189
  let partIndex = 0;
125
190
  for (let i = 0; i < pattern.length; i += 1) {
126
191
  const expected = pattern[i];
@@ -128,7 +193,7 @@ function matchParts(pattern, value, separator, captures) {
128
193
  const remaining = parts.slice(partIndex);
129
194
  if (remaining.every((part) => part === ""))
130
195
  return false;
131
- captures[expected.capture] = remaining.join(separator);
196
+ captures[expected.capture] = remaining.join(separator ?? "");
132
197
  return true;
133
198
  }
134
199
  if (partIndex >= parts.length)
@@ -143,8 +208,9 @@ function matchParts(pattern, value, separator, captures) {
143
208
  partIndex += 1;
144
209
  continue;
145
210
  }
146
- if (expected.literal !== actual)
211
+ if (expected.literal !== (foldLiterals ? actual.toLowerCase() : actual)) {
147
212
  return false;
213
+ }
148
214
  partIndex += 1;
149
215
  }
150
216
  return partIndex === parts.length;
@@ -165,31 +231,116 @@ function withInputSearch(claim, pattern, input, normalized) {
165
231
  function templateProtocol(template) {
166
232
  return SCHEME_RE.exec(template)?.[1]?.toLowerCase();
167
233
  }
168
- function interpolateNormalizeTo(template, captures, restCaptures) {
169
- return template.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, (full, name, offset) => {
170
- const value = captures[name];
171
- if (value === void 0)
172
- return full;
173
- return encodeCaptureValue({
174
- template,
175
- offset,
176
- value,
177
- rest: restCaptures.includes(name)
178
- });
179
- });
180
- }
181
- function encodeCaptureValue({ template, offset, value, rest }) {
182
- const normalized = isAuthorityCapture(template, offset) ? value.toLowerCase() : value;
183
- if (!rest)
184
- return encodeURIComponent(normalized);
185
- return normalized.split("/").join("/");
234
+ var TEMPLATE_TOKEN_RE = /\{([A-Za-z][A-Za-z0-9]*)\(([^)]*)\)\}|:([A-Za-z_][A-Za-z0-9_]*)/g;
235
+ var TRANSFORMS = {
236
+ base64: (value) => {
237
+ const bytes = new TextEncoder().encode(value);
238
+ let binary = "";
239
+ for (const byte of bytes)
240
+ binary += String.fromCharCode(byte);
241
+ return btoa(binary).replace(/=+$/, "");
242
+ },
243
+ slackTimestamp: (value) => {
244
+ const match = /^p(\d+)(\d{6})$/.exec(value);
245
+ return match === null ? void 0 : `${match[1]}.${match[2]}`;
246
+ }
247
+ };
248
+ function isTransform(name) {
249
+ return Object.prototype.hasOwnProperty.call(TRANSFORMS, name);
250
+ }
251
+ function compileTemplate(template) {
252
+ const parts = [];
253
+ let last = 0;
254
+ for (const token of template.matchAll(TEMPLATE_TOKEN_RE)) {
255
+ const offset = token.index;
256
+ if (offset > last)
257
+ parts.push({ literal: template.slice(last, offset) });
258
+ const position = templatePosition(template, offset);
259
+ const [full, transform = "", inner = "", capture] = token;
260
+ if (capture !== void 0) {
261
+ parts.push({ capture, position });
262
+ } else {
263
+ if (!isTransform(transform)) {
264
+ throw new Error(`Unknown URI claim template transform '${transform}'.`);
265
+ }
266
+ parts.push({
267
+ transform,
268
+ inner: compileTransformInput(inner),
269
+ position
270
+ });
271
+ }
272
+ last = offset + full.length;
273
+ }
274
+ if (last < template.length)
275
+ parts.push({ literal: template.slice(last) });
276
+ return parts;
277
+ }
278
+ function compileTransformInput(text) {
279
+ const parts = [];
280
+ let last = 0;
281
+ for (const token of text.matchAll(/:([A-Za-z_][A-Za-z0-9_]*)/g)) {
282
+ if (token.index > last)
283
+ parts.push({ literal: text.slice(last, token.index) });
284
+ parts.push({ capture: token[1] });
285
+ last = token.index + token[0].length;
286
+ }
287
+ if (last < text.length)
288
+ parts.push({ literal: text.slice(last) });
289
+ return parts;
290
+ }
291
+ function fillTemplate(parts, captures, restCaptures) {
292
+ let out = "";
293
+ for (const part of parts) {
294
+ if ("literal" in part) {
295
+ out += part.literal;
296
+ continue;
297
+ }
298
+ if ("capture" in part) {
299
+ const value = captures[part.capture];
300
+ if (value === void 0) {
301
+ out += `:${part.capture}`;
302
+ continue;
303
+ }
304
+ const escaped = restCaptures.includes(part.capture) ? escapeRestCapture(value) : escapeForPosition(value, part.position);
305
+ if (escaped === void 0)
306
+ return void 0;
307
+ out += escaped;
308
+ continue;
309
+ }
310
+ let raw = "";
311
+ for (const inner of part.inner) {
312
+ raw += "literal" in inner ? inner.literal : captures[inner.capture] ?? `:${inner.capture}`;
313
+ }
314
+ const transformed = TRANSFORMS[part.transform](raw);
315
+ if (transformed === void 0)
316
+ return void 0;
317
+ out += escapeForPosition(transformed, part.position);
318
+ }
319
+ return out;
186
320
  }
187
- function isAuthorityCapture(template, offset) {
321
+ function templatePosition(template, offset) {
188
322
  const prefix = template.slice(0, offset);
323
+ if (prefix.includes("#"))
324
+ return "fragment";
325
+ if (prefix.includes("?"))
326
+ return "query";
189
327
  const schemeIndex = prefix.lastIndexOf("://");
190
- if (schemeIndex === -1)
191
- return false;
192
- return !/[/?#]/.test(prefix.slice(schemeIndex + 3));
328
+ if (schemeIndex !== -1 && !prefix.slice(schemeIndex + 3).includes("/")) {
329
+ return "host";
330
+ }
331
+ return "path";
332
+ }
333
+ function escapeForPosition(value, position) {
334
+ if (position === "host")
335
+ return encodeURIComponent(value.toLowerCase());
336
+ return encodeURIComponent(value).replace(/%(?:3A|40)/gi, (code) => decodeURIComponent(code));
337
+ }
338
+ function escapeRestCapture(value) {
339
+ const segments = value.split("/").map(safeDecode);
340
+ if (segments.some((segment) => segment === "." || segment === "..")) {
341
+ return void 0;
342
+ }
343
+ return segments.map(encodeURIComponent).join("/");
193
344
  }
194
345
 
195
346
  // packages/herd-uri/dist/errors.js
@@ -216,6 +367,15 @@ var UriValidationError = class extends UriError {
216
367
  this.name = "UriValidationError";
217
368
  }
218
369
  };
370
+ function requireWriteContent(payload2, uri) {
371
+ if (payload2 === void 0) {
372
+ throw new UriValidationError(`Writing ${uri} needs \`content\` (or a \`source\` to copy from): pass the payload this address takes, which its help names.`);
373
+ }
374
+ if (payload2 instanceof Uint8Array) {
375
+ throw new UriValidationError(`${uri} stores text only, so it cannot take raw bytes. Copy the file to an address that accepts bytes.`);
376
+ }
377
+ return payload2;
378
+ }
219
379
  var UriProviderError = class extends UriError {
220
380
  _tag = "UriProviderError";
221
381
  moduleId;
@@ -275,16 +435,6 @@ var UriUnsupportedOperationError = class extends UriError {
275
435
  }
276
436
  };
277
437
 
278
- // packages/herd-uri/dist/connection.js
279
- var CONNECTION_SELECTOR_RE = /^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)@([^/]+)(?:\/(.*))?$/;
280
- function parseUriConnectionSelector(input) {
281
- const match = CONNECTION_SELECTOR_RE.exec(input.trim());
282
- if (match?.[1] === void 0 || match[2] === void 0) {
283
- return { rest: input };
284
- }
285
- return { selector: match[2], rest: `${match[1]}${match[3] ?? ""}` };
286
- }
287
-
288
438
  // packages/herd-uri/dist/resource-witness.js
289
439
  import { createHash } from "node:crypto";
290
440
  function contentDigest(content) {
@@ -542,6 +692,13 @@ var UriPayloadContractSchema = z2.strictObject({
542
692
 
543
693
  // packages/herd-uri/dist/observation.js
544
694
  var OBSERVATION_MIME = "application/vnd.kay.observation+json";
695
+ var isOptionalString = (value) => value === void 0 || typeof value === "string";
696
+ function isObservationMaterial(value) {
697
+ if (typeof value !== "object" || value === null || Array.isArray(value))
698
+ return false;
699
+ const material = value;
700
+ return typeof material.uri === "string" && typeof material.kind === "string" && isOptionalString(material.title) && (material.text === void 0 || Array.isArray(material.text) && material.text.every((piece) => typeof piece === "string")) && isOptionalString(material.createdAt) && isOptionalString(material.updatedAt) && isOptionalString(material.version) && (material.retainForMs === void 0 || typeof material.retainForMs === "number" && Number.isFinite(material.retainForMs));
701
+ }
545
702
 
546
703
  // packages/herd-uri/dist/text-edit.js
547
704
  import { z as z3 } from "zod";
@@ -749,7 +906,7 @@ function toJsonSchema(schema) {
749
906
  // `io: "input"` describes what a caller may SEND, which is what a parameter and an
750
907
  // `accepts` payload advertise: a field with a Zod default is optional on the wire even
751
908
  // though the parsed value always carries it. Strictness still survives where the validator
752
- // really enforces it — `z.strictObject` emits `additionalProperties: false`, while a plain
909
+ // really enforces it - `z.strictObject` emits `additionalProperties: false`, while a plain
753
910
  // `z.object` correctly does not, because it TOLERATES unknown keys and silently strips
754
911
  // them. A `returns` payload derived from a Zod schema is described in the same input terms;
755
912
  // no module does that today, and a faithful output projection would need its own seam.
@@ -883,29 +1040,45 @@ function accountQualifiedUri(scheme, accountId, path) {
883
1040
  }
884
1041
  return `${scheme}://@${accountId}/${path}`;
885
1042
  }
886
- function isOptionalString(value) {
887
- return value === void 0 || typeof value === "string";
888
- }
889
- function isOptionalStringArray(value) {
890
- return value === void 0 || Array.isArray(value) && value.every((item) => typeof item === "string");
891
- }
892
1043
  function observationFromResource(resource) {
893
1044
  if (resource.mimeType !== OBSERVATION_MIME)
894
1045
  return void 0;
895
1046
  if (typeof resource.content !== "string")
896
1047
  return void 0;
897
1048
  const parsed = tryParseJson(resource.content);
898
- if (parsed === void 0 || typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
1049
+ return isObservationMaterial(parsed) ? parsed : void 0;
1050
+ }
1051
+
1052
+ // packages/herd-uri-extensions/dist/secure-transport.js
1053
+ var SecureTransportError = class extends Error {
1054
+ name = "SecureTransportError";
1055
+ };
1056
+ function isLoopbackHostname(hostname) {
1057
+ const host = hostname.toLowerCase();
1058
+ if (host === "localhost" || host === "[::1]")
1059
+ return true;
1060
+ const octets = host.split(".");
1061
+ return octets.length === 4 && octets[0] === "127" && octets.every((octet) => /^\d{1,3}$/.test(octet) && Number(octet) <= 255);
1062
+ }
1063
+ function secureTransportViolation(url) {
1064
+ let parsed;
1065
+ try {
1066
+ parsed = typeof url === "string" ? new URL(url) : url;
1067
+ } catch {
899
1068
  return void 0;
900
1069
  }
901
- const value = parsed;
902
- if (typeof value.uri !== "string" || typeof value.kind !== "string") {
1070
+ if (parsed.protocol !== "http:" && parsed.protocol !== "ws:")
903
1071
  return void 0;
904
- }
905
- if (!isOptionalString(value.title) || !isOptionalStringArray(value.text) || !isOptionalString(value.createdAt) || !isOptionalString(value.updatedAt) || !isOptionalString(value.version)) {
1072
+ if (isLoopbackHostname(parsed.hostname))
906
1073
  return void 0;
907
- }
908
- return value;
1074
+ const secure = parsed.protocol === "ws:" ? "wss://" : "https://";
1075
+ return `Plain HTTP is only allowed to this computer (localhost, 127.0.0.1 or ::1); use ${secure} for ${parsed.host}.`;
1076
+ }
1077
+ function assertSecureTransport(url, label) {
1078
+ const violation = secureTransportViolation(url);
1079
+ if (violation === void 0)
1080
+ return;
1081
+ throw new SecureTransportError(label === void 0 ? violation : `${label}: ${violation}`);
909
1082
  }
910
1083
 
911
1084
  // packages/plugin-primitives/dist/results.js
@@ -982,15 +1155,6 @@ function toToolParameters(schema) {
982
1155
 
983
1156
  // packages/plugin-primitives/dist/auth-scheme.js
984
1157
  var ACCOUNT_ID_PARAM = "accountId";
985
- function authContextOf(ctx) {
986
- return ctx.auth;
987
- }
988
- function authFailureResult(failure) {
989
- return {
990
- content: [{ type: "text", text: failure.message }],
991
- details: void 0
992
- };
993
- }
994
1158
  function withAccountIdParam(parameters) {
995
1159
  if (parameters === null || typeof parameters !== "object" || parameters.type !== "object") {
996
1160
  return parameters;
@@ -1016,27 +1180,18 @@ function withResolvedAuth(definition, binding, body) {
1016
1180
  requiresAuth: binding,
1017
1181
  parameters: withAccountIdParam(definition.parameters),
1018
1182
  async execute(toolCallId, params, signal, onUpdate, ctx) {
1019
- const auth = authContextOf(ctx);
1020
- if (auth === void 0) {
1021
- return authFailureResult({
1022
- ok: false,
1023
- reason: "no-connection",
1024
- message: `Auth is not available in this context for ${binding.serviceId}.`
1025
- });
1183
+ if (ctx.credential === void 0) {
1184
+ return {
1185
+ content: [
1186
+ {
1187
+ type: "text",
1188
+ text: `Auth is not available in this context for ${binding.serviceId}.`
1189
+ }
1190
+ ],
1191
+ details: void 0
1192
+ };
1026
1193
  }
1027
- const override = params?.[ACCOUNT_ID_PARAM];
1028
- const result = await auth.resolveToken({
1029
- serviceId: binding.serviceId,
1030
- ...binding.schemeId === void 0 ? {} : { schemeId: binding.schemeId },
1031
- ...typeof override === "string" && override.length > 0 ? { accountId: override } : {},
1032
- ...binding.requiredScopes === void 0 ? {} : { requiredScopes: binding.requiredScopes },
1033
- ...binding.scopeRequirement === void 0 ? {} : { scopeRequirement: binding.scopeRequirement },
1034
- ...binding.connectServiceId === void 0 ? {} : { connectServiceId: binding.connectServiceId }
1035
- });
1036
- if (!result.ok) {
1037
- return authFailureResult(result);
1038
- }
1039
- return body(toolCallId, params, signal, onUpdate, ctx, result.auth);
1194
+ return body(toolCallId, params, signal, onUpdate, ctx, ctx.credential);
1040
1195
  }
1041
1196
  };
1042
1197
  }
@@ -1058,23 +1213,14 @@ function withResolvedSearchProvider(definition, binding, body) {
1058
1213
  label: definition.label,
1059
1214
  providerId: definition.providerId ?? "",
1060
1215
  requiresAuth: binding,
1061
- async isAvailable(ctx) {
1062
- const auth = ctx?.auth;
1063
- if (auth === void 0)
1064
- return false;
1065
- const result = await auth.resolveToken(binding);
1066
- return result.ok;
1216
+ isAvailable(ctx) {
1217
+ return ctx?.credential !== void 0;
1067
1218
  },
1068
1219
  async search(params, signal, ctx) {
1069
- const auth = ctx?.auth;
1070
- if (auth === void 0) {
1220
+ if (ctx?.credential === void 0) {
1071
1221
  throw new SearchProviderError(definition.id, `Auth is not available in this context for ${binding.serviceId}.`);
1072
1222
  }
1073
- const result = await auth.resolveToken(binding);
1074
- if (!result.ok) {
1075
- throw new SearchProviderError(definition.id, result.message);
1076
- }
1077
- return body(params, signal, result.auth);
1223
+ return body(params, signal, ctx.credential);
1078
1224
  }
1079
1225
  };
1080
1226
  }
@@ -1286,6 +1432,27 @@ function bytesToBase64(bytes) {
1286
1432
  return output;
1287
1433
  }
1288
1434
 
1435
+ // packages/plugin-sdk/dist/kay-agent/known-resources-view.js
1436
+ function knownResourcesView(result) {
1437
+ return { ...result, knownResourcesView: true };
1438
+ }
1439
+
1440
+ // packages/plugin-sdk/dist/kay-agent/compiler.js
1441
+ function createUnavailableCompiler(message) {
1442
+ return {
1443
+ bundleBrowser: async () => {
1444
+ throw new Error(message);
1445
+ }
1446
+ };
1447
+ }
1448
+
1449
+ // packages/plugin-sdk/dist/kay-agent/endpoints.js
1450
+ function createUnavailableEndpoints(message) {
1451
+ return {
1452
+ invoke: async () => ({ ok: false, reason: "unavailable", message })
1453
+ };
1454
+ }
1455
+
1289
1456
  // packages/plugin-sdk/dist/kay-agent/osascript.js
1290
1457
  import { z as z6 } from "zod";
1291
1458
  var OSASCRIPT_TIMEOUT_MS = 3e4;
@@ -1443,204 +1610,21 @@ function fenced(text) {
1443
1610
  return [`${fence}text`, text, fence];
1444
1611
  }
1445
1612
 
1446
- // packages/plugin-sdk/dist/kay-agent/advertisement.js
1447
- function defineKayAgentAdvertisement(advertisement) {
1448
- return advertisement;
1449
- }
1450
- function rejectDuplicate(category, id, seen) {
1451
- if (seen.has(id)) {
1452
- throw new Error(`Duplicate advertised ${category} '${id}'.`);
1453
- }
1454
- seen.add(id);
1455
- }
1456
- function rejectImplementationFields(category, value, fields) {
1457
- for (const field of fields) {
1458
- if (field in value) {
1459
- throw new Error(`Advertised ${category} cannot include implementation field '${field}'.`);
1460
- }
1461
- }
1462
- }
1463
- function snapshotAdvertisementValue(value, seen = /* @__PURE__ */ new WeakMap()) {
1464
- if ((typeof value !== "object" || value === null) && typeof value !== "function") {
1465
- return value;
1466
- }
1467
- if (typeof value === "function") {
1468
- return value;
1469
- }
1470
- const existing = seen.get(value);
1471
- if (existing !== void 0)
1472
- return existing;
1473
- if (Array.isArray(value)) {
1474
- const copy2 = [];
1475
- seen.set(value, copy2);
1476
- for (const entry of value) {
1477
- copy2.push(snapshotAdvertisementValue(entry, seen));
1478
- }
1479
- return Object.freeze(copy2);
1480
- }
1481
- const copy = /* @__PURE__ */ Object.create(null);
1482
- seen.set(value, copy);
1483
- const copiedKeys = /* @__PURE__ */ new Set();
1484
- let source = value;
1485
- while (source !== null && source !== Object.prototype) {
1486
- for (const key of Reflect.ownKeys(source)) {
1487
- if (key === "constructor" || copiedKeys.has(key))
1488
- continue;
1489
- copiedKeys.add(key);
1490
- copy[key] = snapshotAdvertisementValue(Reflect.get(value, key), seen);
1491
- }
1492
- source = Object.getPrototypeOf(source);
1493
- }
1494
- return Object.freeze(copy);
1495
- }
1496
- function snapshotDelegatedServiceSource(source) {
1497
- return () => {
1498
- const entries = source();
1499
- if (!Array.isArray(entries)) {
1500
- throw new Error("An advertised delegated service source must return an array synchronously.");
1501
- }
1502
- return Object.freeze(entries.map((entry) => {
1503
- rejectImplementationFields("delegated service source scheme", entry.scheme, ["connect", "refresh"]);
1504
- return snapshotAdvertisementValue(entry);
1505
- }));
1506
- };
1507
- }
1508
- function collectKayAgentAdvertisement(advertisement) {
1509
- const tools = [];
1510
- const uriModules = [];
1511
- const searchProviders = [];
1512
- const converters = [];
1513
- const services = [];
1514
- const oauthPkceSchemes = [];
1515
- const apiKeySchemes = [];
1516
- const externalCliSchemes = [];
1517
- const delegatedSchemes = [];
1518
- const delegatedServiceSources = [];
1519
- const toolNames = /* @__PURE__ */ new Set();
1520
- const moduleIds = /* @__PURE__ */ new Set();
1521
- const providerIds = /* @__PURE__ */ new Set();
1522
- const converterIds = /* @__PURE__ */ new Set();
1523
- let collecting = true;
1524
- const assertCollecting = () => {
1525
- if (!collecting) {
1526
- throw new Error("The kay.agent advertisement API cannot be used after advertise() returns.");
1527
- }
1528
- };
1529
- const auth = {
1530
- advertiseService: (descriptor) => {
1531
- assertCollecting();
1532
- services.push(snapshotAdvertisementValue(descriptor));
1533
- },
1534
- declareOAuthPkceScheme: (serviceId, scheme) => {
1535
- assertCollecting();
1536
- rejectImplementationFields("OAuth PKCE scheme", scheme, [
1537
- "resolveAccountId",
1538
- "resolveAccounts"
1539
- ]);
1540
- oauthPkceSchemes.push(snapshotAdvertisementValue({ serviceId, scheme }));
1541
- },
1542
- declareApiKeyScheme: (serviceId, scheme) => {
1543
- assertCollecting();
1544
- rejectImplementationFields("API key scheme", scheme, ["validate"]);
1545
- apiKeySchemes.push(snapshotAdvertisementValue({ serviceId, scheme }));
1546
- },
1547
- declareExternalCliScheme: (serviceId, scheme) => {
1548
- assertCollecting();
1549
- externalCliSchemes.push(snapshotAdvertisementValue({ serviceId, scheme }));
1550
- },
1551
- declareDelegatedScheme: (serviceId, scheme) => {
1552
- assertCollecting();
1553
- rejectImplementationFields("delegated scheme", scheme, [
1554
- "connect",
1555
- "refresh"
1556
- ]);
1557
- delegatedSchemes.push(snapshotAdvertisementValue({ serviceId, scheme }));
1558
- },
1559
- registerDelegatedServiceSource: (source) => {
1560
- assertCollecting();
1561
- delegatedServiceSources.push(Object.freeze({ source: snapshotDelegatedServiceSource(source) }));
1562
- }
1563
- };
1564
- const api = {
1565
- uri: {
1566
- registerModule: (module) => {
1567
- assertCollecting();
1568
- rejectImplementationFields("URI module", module, [
1569
- "locate",
1570
- "read",
1571
- "help",
1572
- "write",
1573
- "edit",
1574
- "list",
1575
- "search",
1576
- "delete"
1577
- ]);
1578
- const snapshot = snapshotAdvertisementValue(module);
1579
- rejectDuplicate("URI module id", snapshot.id, moduleIds);
1580
- uriModules.push(snapshot);
1581
- }
1582
- },
1583
- registerTool: (definition) => {
1584
- assertCollecting();
1585
- rejectImplementationFields("tool", definition, ["execute"]);
1586
- const snapshot = snapshotAdvertisementValue(definition);
1587
- rejectDuplicate("tool name", snapshot.name, toolNames);
1588
- tools.push(snapshot);
1589
- },
1590
- registerSearchProvider: (provider) => {
1591
- assertCollecting();
1592
- rejectImplementationFields("search provider", provider, [
1593
- "isAvailable",
1594
- "search"
1595
- ]);
1596
- const snapshot = snapshotAdvertisementValue(provider);
1597
- rejectDuplicate("search provider id", snapshot.id, providerIds);
1598
- searchProviders.push(snapshot);
1599
- },
1600
- registerConverter: (converter) => {
1601
- assertCollecting();
1602
- rejectImplementationFields("converter", converter, ["convert"]);
1603
- const snapshot = snapshotAdvertisementValue(converter);
1604
- rejectDuplicate("converter id", snapshot.id, converterIds);
1605
- converters.push(snapshot);
1606
- },
1607
- auth
1608
- };
1609
- let result;
1610
- try {
1611
- result = advertisement.advertise(api);
1612
- } finally {
1613
- collecting = false;
1614
- }
1615
- if (result !== void 0) {
1616
- void Promise.resolve(result).catch(() => void 0);
1617
- throw new Error("A kay.agent advertisement must finish synchronously and return undefined.");
1618
- }
1619
- return Object.freeze({
1620
- tools: Object.freeze([...tools]),
1621
- uriModules: Object.freeze([...uriModules]),
1622
- searchProviders: Object.freeze([...searchProviders]),
1623
- converters: Object.freeze([...converters]),
1624
- auth: Object.freeze({
1625
- services: Object.freeze([...services]),
1626
- oauthPkceSchemes: Object.freeze([...oauthPkceSchemes]),
1627
- apiKeySchemes: Object.freeze([...apiKeySchemes]),
1628
- externalCliSchemes: Object.freeze([...externalCliSchemes]),
1629
- delegatedSchemes: Object.freeze([...delegatedSchemes]),
1630
- delegatedServiceSources: Object.freeze([...delegatedServiceSources])
1631
- })
1632
- });
1633
- }
1634
-
1635
1613
  // packages/plugin-sdk/dist/kay-agent/index.js
1636
1614
  function toolParameters(schema) {
1637
1615
  return toToolParameters(schema);
1638
1616
  }
1617
+ function manifestToolParameters(schema) {
1618
+ return toToolParameters(schema);
1619
+ }
1620
+ function toolExecute(schema, body) {
1621
+ return async (toolCallId, params, signal, onUpdate, ctx) => body(toolCallId, schema.parse(params), signal, onUpdate, ctx);
1622
+ }
1639
1623
  function defineTool(definition) {
1640
1624
  return definition;
1641
1625
  }
1642
1626
  function defineAuthedTool(definition, schema, binding, body) {
1643
- return withResolvedAuth({ ...definition, parameters: toolParameters(schema) }, binding, (toolCallId, rawParams, signal, onUpdate, ctx, resolvedAuth) => body(toolCallId, schema.parse(rawParams), signal, onUpdate, ctx, resolvedAuth));
1627
+ return withResolvedAuth({ ...definition, parameters: toolParameters(schema) }, binding, (toolCallId, rawParams, signal, onUpdate, ctx, credential) => body(toolCallId, schema.parse(rawParams), signal, onUpdate, ctx, credential));
1644
1628
  }
1645
1629
  var DELEGATED_REFRESH_REJECTED = Symbol.for("kay.plugin-sdk.delegated-refresh-rejected");
1646
1630
  var DelegatedRefreshRejectedError = class extends Error {
@@ -1681,6 +1665,7 @@ export {
1681
1665
  OSASCRIPT_TIMEOUT_MS,
1682
1666
  PluginApiError,
1683
1667
  SearchProviderError,
1668
+ SecureTransportError,
1684
1669
  URI_TEXT_EDIT_SHAPE_SUMMARY,
1685
1670
  UriConflictError,
1686
1671
  UriNotFoundError,
@@ -1692,18 +1677,19 @@ export {
1692
1677
  asArray,
1693
1678
  asRecord,
1694
1679
  assertResourceUnchanged,
1680
+ assertSecureTransport,
1695
1681
  basicUriHelp,
1696
1682
  bytesToBase64,
1697
1683
  capability,
1698
- collectKayAgentAdvertisement,
1699
1684
  compileUriClaim,
1700
1685
  contentDigest,
1701
1686
  contentResult,
1702
1687
  createJsonApiClient,
1703
1688
  createOsascriptRunner,
1689
+ createUnavailableCompiler,
1690
+ createUnavailableEndpoints,
1704
1691
  declareProducedResources,
1705
1692
  defineAuthedTool,
1706
- defineKayAgentAdvertisement,
1707
1693
  defineTool,
1708
1694
  describeUriTextEditTarget,
1709
1695
  fenced,
@@ -1711,11 +1697,14 @@ export {
1711
1697
  formatNumber,
1712
1698
  getBytes,
1713
1699
  isDelegatedRefreshRejected,
1700
+ isLoopbackHostname,
1714
1701
  jsonResource,
1702
+ knownResourcesView,
1715
1703
  labelOf,
1716
1704
  lineOf,
1717
1705
  lintUriHelpContracts,
1718
1706
  lintUriTemplate,
1707
+ manifestToolParameters,
1719
1708
  markdownResource,
1720
1709
  markdownText,
1721
1710
  num,
@@ -1730,9 +1719,12 @@ export {
1730
1719
  payload,
1731
1720
  readBodyWithByteCap,
1732
1721
  readOsascriptOutput,
1722
+ requireWriteContent,
1723
+ secureTransportViolation,
1733
1724
  str,
1734
1725
  textResult,
1735
1726
  toJsonSchema,
1727
+ toolExecute,
1736
1728
  toolParameters,
1737
1729
  unavailableInteractionSurface,
1738
1730
  unavailableInteractionSurfaces,