@yaklabs-ai/plugin-sdk 0.55.1 → 0.55.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ it under the name your plugin code actually imports:
13
13
  ```json
14
14
  {
15
15
  "dependencies": {
16
- "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.55.1"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.55.2"
17
17
  }
18
18
  }
19
19
  ```
@@ -62,7 +62,7 @@ Every tool the entrypoint registers is declared in the manifest too:
62
62
  "description": "Greets people by name.",
63
63
  "version": "0.1.0",
64
64
  "namespace": "widgets",
65
- "compatibility": { "sdk": "^0.55.1" },
65
+ "compatibility": { "sdk": "^0.55.2" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -153,7 +153,7 @@ naming both versions, instead of loading it and finding no `activate`.
153
153
  | `@bonsai/plugin-sdk/system-one` | The types and error class for `api.systemOne` / `app.systemOne`, from 0.13.8 |
154
154
  | `@bonsai/plugin-sdk/zod` | `z` (the host's in the daemon), on an entry with no other import, from 0.13.9 |
155
155
 
156
- A plugin that imports these subpaths declares the current supported SDK range (`^0.55.1`).
156
+ A plugin that imports these subpaths declares the current supported SDK range (`^0.55.2`).
157
157
  The rows record when each subpath appeared, not retained runtime compatibility. `vendored-mcp` builds the plugin's URI module (its link cards and help); hosting the
158
158
  vendor's MCP server itself is a separate host decision: Bonsai hosts it once a person approves
159
159
  the plugin's `mcp.host-server` grant for that server's name and URL. A server that needs an OAuth
@@ -161,7 +161,7 @@ sign-in names one of the plugin's auth services in `authService`; that service m
161
161
  one `delegated` scheme, which Bonsai uses to sign the person in to the server. Bonsai declares that
162
162
  scheme at runtime; the plugin's code must not declare it again. From 0.16.2 a plugin's code can also
163
163
  call the server's tools through `api.vendoredMcp.port(<server>)`, typed by this subpath's
164
- `VendoredMcpPort` and `VendoredMcpOutcome` (declare `^0.55.1`).
164
+ `VendoredMcpPort` and `VendoredMcpOutcome` (declare `^0.55.2`).
165
165
 
166
166
  From 0.13.10 the manifest schema carries two facts Bonsai reads for its own plugins only; another
167
167
  plugin's are ignored, with a load diagnostic. An `external-cli` auth scheme's `cli` says how Bonsai
@@ -243,7 +243,7 @@ Provider schemas remain authoritative; declaring a dependency grants no authorit
243
243
  through `app.uri`, parse returned Markdown in the consuming plugin, and retain the read's
244
244
  revision (or `contentDigest` from `/uri`) for edits. The old `memory.read` and `memory.write`
245
245
  grants do not authorize the replacement scheme-and-verb calls. Contracts before 0.49.0 are
246
- refused; migrate and declare `^0.55.1`. The current host also serves the 0.49.0 resource contract.
246
+ refused; migrate and declare `^0.55.2`. The current host also serves the 0.49.0 resource contract.
247
247
 
248
248
  ## What this package is, and is not, at runtime
249
249
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.55.1",
4
+ "version": "0.55.2",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -1723,7 +1723,7 @@ declare type InteractionSurface = Pick<InteractionDriver, "isAvailable" | "targe
1723
1723
 
1724
1724
  /**
1725
1725
  * One thing a driver can be pointed at: a browser page, a running app. `id` is the driver-owned
1726
- * address the agent passes back as `target` (`kay://tabs/.../items/<item>`, `app://<bundle id>`).
1726
+ * address the agent passes back as `target` (`bonsai://tabs/.../items/<item>`, `app://<bundle id>`).
1727
1727
  * `active` marks the default target (the page the user is looking at, the front app).
1728
1728
  */
1729
1729
  declare const InteractionTarget: z.ZodObject<{
@@ -2680,8 +2680,10 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2680
2680
  * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
2681
2681
  * tool previews with cancellation, app-scoped availability snapshots and app-target output
2682
2682
  * artifact usage declarations. A plugin using these declares ^0.55.1.
2683
+ *
2684
+ * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
2683
2685
  */
2684
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
2686
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
2685
2687
 
2686
2688
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2687
2689
 
@@ -10225,7 +10227,7 @@ declare interface UriParameter {
10225
10227
  /**
10226
10228
  * A claim on a module's own custom-scheme addresses. The pattern matches with or without an
10227
10229
  * account prefix: `gcal://@work/events/x` is matched as `gcal://events/x`, and the prefix is put
10228
- * back on the official spelling, so one claim covers both spellings.
10230
+ * back on the same-scheme official spelling, so one claim covers both spellings.
10229
10231
  */
10230
10232
  declare interface UriPatternClaim {
10231
10233
  readonly kind: "uriPattern";
@@ -10236,9 +10238,13 @@ declare interface UriPatternClaim {
10236
10238
  * carried over verbatim so a route flag such as `?permanent=true` survives
10237
10239
  * canonicalization (kay#7859); a template that re-targets to another scheme
10238
10240
  * (a projection to a web link) drops it, as does a pattern that consumed the
10239
- * query itself or a template that spells its own.
10241
+ * query itself or a template that spells its own. `preserveQuery` opts out of those defaults.
10240
10242
  */
10241
10243
  readonly normalizeTo?: UriClaimTemplate;
10244
+ /** Carry the matched query verbatim across normalization; incompatible with a target query. */
10245
+ readonly preserveQuery?: true;
10246
+ /** Carry the input's account selector even when normalization changes scheme. */
10247
+ readonly preserveConnection?: true;
10242
10248
  /**
10243
10249
  * Names the route this claim matches, so data keyed by route (a module's sign-in action rules)
10244
10250
  * can say which addresses it means. Several claims may name the same route.
@@ -1759,7 +1759,7 @@ declare type InteractionSurface = Pick<InteractionDriver, "isAvailable" | "targe
1759
1759
 
1760
1760
  /**
1761
1761
  * One thing a driver can be pointed at: a browser page, a running app. `id` is the driver-owned
1762
- * address the agent passes back as `target` (`kay://tabs/.../items/<item>`, `app://<bundle id>`).
1762
+ * address the agent passes back as `target` (`bonsai://tabs/.../items/<item>`, `app://<bundle id>`).
1763
1763
  * `active` marks the default target (the page the user is looking at, the front app).
1764
1764
  */
1765
1765
  declare const InteractionTarget: z.ZodObject<{
@@ -2734,8 +2734,10 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2734
2734
  * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
2735
2735
  * tool previews with cancellation, app-scoped availability snapshots and app-target output
2736
2736
  * artifact usage declarations. A plugin using these declares ^0.55.1.
2737
+ *
2738
+ * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
2737
2739
  */
2738
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
2740
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
2739
2741
 
2740
2742
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2741
2743
 
@@ -5763,6 +5765,8 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5763
5765
  search: z.ZodExactOptional<z.ZodString>;
5764
5766
  }, z.core.$strict>;
5765
5767
  normalizeTo: z.ZodExactOptional<z.ZodString>;
5768
+ preserveQuery: z.ZodExactOptional<z.ZodLiteral<true>>;
5769
+ preserveConnection: z.ZodExactOptional<z.ZodLiteral<true>>;
5766
5770
  route: z.ZodExactOptional<z.ZodString>;
5767
5771
  sourceUrl: z.ZodExactOptional<z.ZodString>;
5768
5772
  title: z.ZodExactOptional<z.ZodString>;
@@ -6049,6 +6053,8 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
6049
6053
  search: z.ZodExactOptional<z.ZodString>;
6050
6054
  }, z.core.$strict>;
6051
6055
  normalizeTo: z.ZodExactOptional<z.ZodString>;
6056
+ preserveQuery: z.ZodExactOptional<z.ZodLiteral<true>>;
6057
+ preserveConnection: z.ZodExactOptional<z.ZodLiteral<true>>;
6052
6058
  route: z.ZodExactOptional<z.ZodString>;
6053
6059
  sourceUrl: z.ZodExactOptional<z.ZodString>;
6054
6060
  title: z.ZodExactOptional<z.ZodString>;
@@ -11849,7 +11855,7 @@ declare interface UriParameter {
11849
11855
  /**
11850
11856
  * A claim on a module's own custom-scheme addresses. The pattern matches with or without an
11851
11857
  * account prefix: `gcal://@work/events/x` is matched as `gcal://events/x`, and the prefix is put
11852
- * back on the official spelling, so one claim covers both spellings.
11858
+ * back on the same-scheme official spelling, so one claim covers both spellings.
11853
11859
  */
11854
11860
  declare interface UriPatternClaim {
11855
11861
  readonly kind: "uriPattern";
@@ -11860,9 +11866,13 @@ declare interface UriPatternClaim {
11860
11866
  * carried over verbatim so a route flag such as `?permanent=true` survives
11861
11867
  * canonicalization (kay#7859); a template that re-targets to another scheme
11862
11868
  * (a projection to a web link) drops it, as does a pattern that consumed the
11863
- * query itself or a template that spells its own.
11869
+ * query itself or a template that spells its own. `preserveQuery` opts out of those defaults.
11864
11870
  */
11865
11871
  readonly normalizeTo?: UriClaimTemplate;
11872
+ /** Carry the matched query verbatim across normalization; incompatible with a target query. */
11873
+ readonly preserveQuery?: true;
11874
+ /** Carry the input's account selector even when normalization changes scheme. */
11875
+ readonly preserveConnection?: true;
11866
11876
  /**
11867
11877
  * Names the route this claim matches, so data keyed by route (a module's sign-in action rules)
11868
11878
  * can say which addresses it means. Several claims may name the same route.
@@ -2107,7 +2107,7 @@ export declare type InteractionTarget = ReadonlyContract<InteractionTarget_2>;
2107
2107
 
2108
2108
  /**
2109
2109
  * One thing a driver can be pointed at: a browser page, a running app. `id` is the driver-owned
2110
- * address the agent passes back as `target` (`kay://tabs/.../items/<item>`, `app://<bundle id>`).
2110
+ * address the agent passes back as `target` (`bonsai://tabs/.../items/<item>`, `app://<bundle id>`).
2111
2111
  * `active` marks the default target (the page the user is looking at, the front app).
2112
2112
  */
2113
2113
  declare const InteractionTarget_2: z.ZodObject<{
@@ -3088,8 +3088,10 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
3088
3088
  * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
3089
3089
  * tool previews with cancellation, app-scoped availability snapshots and app-target output
3090
3090
  * artifact usage declarations. A plugin using these declares ^0.55.1.
3091
+ *
3092
+ * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
3091
3093
  */
3092
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
3094
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
3093
3095
 
3094
3096
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
3095
3097
 
@@ -11753,7 +11755,7 @@ export declare interface UriParameterOptions {
11753
11755
  /**
11754
11756
  * A claim on a module's own custom-scheme addresses. The pattern matches with or without an
11755
11757
  * account prefix: `gcal://@work/events/x` is matched as `gcal://events/x`, and the prefix is put
11756
- * back on the official spelling, so one claim covers both spellings.
11758
+ * back on the same-scheme official spelling, so one claim covers both spellings.
11757
11759
  */
11758
11760
  declare interface UriPatternClaim {
11759
11761
  readonly kind: "uriPattern";
@@ -11764,9 +11766,13 @@ declare interface UriPatternClaim {
11764
11766
  * carried over verbatim so a route flag such as `?permanent=true` survives
11765
11767
  * canonicalization (kay#7859); a template that re-targets to another scheme
11766
11768
  * (a projection to a web link) drops it, as does a pattern that consumed the
11767
- * query itself or a template that spells its own.
11769
+ * query itself or a template that spells its own. `preserveQuery` opts out of those defaults.
11768
11770
  */
11769
11771
  readonly normalizeTo?: UriClaimTemplate;
11772
+ /** Carry the matched query verbatim across normalization; incompatible with a target query. */
11773
+ readonly preserveQuery?: true;
11774
+ /** Carry the input's account selector even when normalization changes scheme. */
11775
+ readonly preserveConnection?: true;
11770
11776
  /**
11771
11777
  * Names the route this claim matches, so data keyed by route (a module's sign-in action rules)
11772
11778
  * can say which addresses it means. Several claims may name the same route.
package/dist/kay-agent.js CHANGED
@@ -37,6 +37,9 @@ function compileClaim(claim) {
37
37
  }
38
38
  };
39
39
  }
40
+ if (claim.kind === "uriPattern" && claim.preserveQuery === true && claim.normalizeTo?.split("#", 1)[0]?.includes("?") === true) {
41
+ throw new Error("URI claim preserveQuery cannot use normalizeTo with a query.");
42
+ }
40
43
  const pattern = compileRoutePattern(claim.pattern);
41
44
  const normalizeTo = claim.normalizeTo === void 0 ? void 0 : compileTemplate(claim.normalizeTo);
42
45
  const sourceUrl = claim.kind === "uriPattern" && claim.sourceUrl !== void 0 ? compileTemplate(claim.sourceUrl) : void 0;
@@ -55,7 +58,7 @@ function compileClaim(claim) {
55
58
  claimKind: claim.kind,
56
59
  ...Object.keys(captures).length > 0 ? { captures } : {},
57
60
  ...normalized !== void 0 ? {
58
- normalizedUri: withSelector(withInputSearch(claim, pattern, parsed, normalized), parsed.protocol, selector)
61
+ normalizedUri: withSelector(withInputSearch(claim, pattern, parsed, normalized), parsed.protocol, selector, claim.kind === "uriPattern" && claim.preserveConnection === true)
59
62
  } : {},
60
63
  ...claim.route !== void 0 ? { route: claim.route } : {},
61
64
  ...filledSourceUrl !== void 0 ? { sourceUrl: filledSourceUrl } : {},
@@ -88,11 +91,13 @@ function parseUriConnectionSelector(input) {
88
91
  }
89
92
  return { selector: match[2], rest: `${match[1]}${match[3] ?? ""}` };
90
93
  }
91
- function withSelector(normalized, inputProtocol, selector) {
94
+ function withSelector(normalized, inputProtocol, selector, preserveConnection) {
92
95
  if (selector === void 0)
93
96
  return normalized;
94
- if (templateProtocol(normalized) !== inputProtocol)
97
+ const targetProtocol = templateProtocol(normalized);
98
+ if (targetProtocol === void 0 || !preserveConnection && targetProtocol !== inputProtocol) {
95
99
  return normalized;
100
+ }
96
101
  const schemeEnd = normalized.indexOf("://") + 3;
97
102
  return `${normalized.slice(0, schemeEnd)}@${selector}/${normalized.slice(schemeEnd)}`;
98
103
  }
@@ -253,7 +258,14 @@ function safeDecode(value) {
253
258
  }
254
259
  }
255
260
  function withInputSearch(claim, pattern, input, normalized) {
256
- if (claim.kind !== "uriPattern" || claim.normalizeTo === void 0 || pattern.search !== void 0 || input.search.length === 0 || claim.normalizeTo.includes("?") || templateProtocol(claim.normalizeTo) !== input.protocol) {
261
+ if (claim.kind !== "uriPattern" || claim.normalizeTo === void 0 || input.search.length === 0) {
262
+ return normalized;
263
+ }
264
+ if (claim.preserveQuery === true) {
265
+ const fragment = normalized.indexOf("#");
266
+ return fragment === -1 ? `${normalized}?${input.search}` : `${normalized.slice(0, fragment)}?${input.search}${normalized.slice(fragment)}`;
267
+ }
268
+ if (pattern.search !== void 0 || claim.normalizeTo.includes("?") || templateProtocol(claim.normalizeTo) !== input.protocol) {
257
269
  return normalized;
258
270
  }
259
271
  return `${normalized}?${input.search}`;
package/dist/kay-app.d.ts CHANGED
@@ -4390,8 +4390,10 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
4390
4390
  * 0.55.1 adds canonical path resources on declared tool permissions, asynchronous display-only
4391
4391
  * tool previews with cancellation, app-scoped availability snapshots and app-target output
4392
4392
  * artifact usage declarations. A plugin using these declares ^0.55.1.
4393
+ *
4394
+ * 0.55.2 adds opt-in query and connection-selector preservation during URI claim normalization.
4393
4395
  */
4394
- declare const KAY_PLUGIN_SDK_VERSION: "0.55.1";
4396
+ declare const KAY_PLUGIN_SDK_VERSION: "0.55.2";
4395
4397
 
4396
4398
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
4397
4399
 
@@ -6142,6 +6144,8 @@ export declare interface KayAppKnowledgeSearchOptions {
6142
6144
  readonly limit?: number;
6143
6145
  /** Treat the last query term as a prefix, for search as the person types. */
6144
6146
  readonly prefixLastTerm?: boolean;
6147
+ /** Skip vector eligibility and query embedding; false or absent keeps hybrid search. */
6148
+ readonly lexicalOnly?: boolean;
6145
6149
  /** Drop vector-leg hits below this cosine similarity. */
6146
6150
  readonly minCosineSimilarity?: number;
6147
6151
  /** Relative weights of the lexical and vector legs in rank fusion. */
@@ -18261,7 +18265,7 @@ declare interface UriParameter {
18261
18265
  /**
18262
18266
  * A claim on a module's own custom-scheme addresses. The pattern matches with or without an
18263
18267
  * account prefix: `gcal://@work/events/x` is matched as `gcal://events/x`, and the prefix is put
18264
- * back on the official spelling, so one claim covers both spellings.
18268
+ * back on the same-scheme official spelling, so one claim covers both spellings.
18265
18269
  */
18266
18270
  declare interface UriPatternClaim {
18267
18271
  readonly kind: "uriPattern";
@@ -18272,9 +18276,13 @@ declare interface UriPatternClaim {
18272
18276
  * carried over verbatim so a route flag such as `?permanent=true` survives
18273
18277
  * canonicalization (kay#7859); a template that re-targets to another scheme
18274
18278
  * (a projection to a web link) drops it, as does a pattern that consumed the
18275
- * query itself or a template that spells its own.
18279
+ * query itself or a template that spells its own. `preserveQuery` opts out of those defaults.
18276
18280
  */
18277
18281
  readonly normalizeTo?: UriClaimTemplate;
18282
+ /** Carry the matched query verbatim across normalization; incompatible with a target query. */
18283
+ readonly preserveQuery?: true;
18284
+ /** Carry the input's account selector even when normalization changes scheme. */
18285
+ readonly preserveConnection?: true;
18278
18286
  /**
18279
18287
  * Names the route this claim matches, so data keyed by route (a module's sign-in action rules)
18280
18288
  * can say which addresses it means. Several claims may name the same route.
@@ -865,7 +865,7 @@ declare interface UriParameter {
865
865
  /**
866
866
  * A claim on a module's own custom-scheme addresses. The pattern matches with or without an
867
867
  * account prefix: `gcal://@work/events/x` is matched as `gcal://events/x`, and the prefix is put
868
- * back on the official spelling, so one claim covers both spellings.
868
+ * back on the same-scheme official spelling, so one claim covers both spellings.
869
869
  */
870
870
  declare interface UriPatternClaim {
871
871
  readonly kind: "uriPattern";
@@ -876,9 +876,13 @@ declare interface UriPatternClaim {
876
876
  * carried over verbatim so a route flag such as `?permanent=true` survives
877
877
  * canonicalization (kay#7859); a template that re-targets to another scheme
878
878
  * (a projection to a web link) drops it, as does a pattern that consumed the
879
- * query itself or a template that spells its own.
879
+ * query itself or a template that spells its own. `preserveQuery` opts out of those defaults.
880
880
  */
881
881
  readonly normalizeTo?: UriClaimTemplate;
882
+ /** Carry the matched query verbatim across normalization; incompatible with a target query. */
883
+ readonly preserveQuery?: true;
884
+ /** Carry the input's account selector even when normalization changes scheme. */
885
+ readonly preserveConnection?: true;
882
886
  /**
883
887
  * Names the route this claim matches, so data keyed by route (a module's sign-in action rules)
884
888
  * can say which addresses it means. Several claims may name the same route.
@@ -91,6 +91,9 @@ function compileClaim(claim) {
91
91
  }
92
92
  };
93
93
  }
94
+ if (claim.kind === "uriPattern" && claim.preserveQuery === true && claim.normalizeTo?.split("#", 1)[0]?.includes("?") === true) {
95
+ throw new Error("URI claim preserveQuery cannot use normalizeTo with a query.");
96
+ }
94
97
  const pattern = compileRoutePattern(claim.pattern);
95
98
  const normalizeTo = claim.normalizeTo === void 0 ? void 0 : compileTemplate(claim.normalizeTo);
96
99
  const sourceUrl = claim.kind === "uriPattern" && claim.sourceUrl !== void 0 ? compileTemplate(claim.sourceUrl) : void 0;
@@ -109,7 +112,7 @@ function compileClaim(claim) {
109
112
  claimKind: claim.kind,
110
113
  ...Object.keys(captures).length > 0 ? { captures } : {},
111
114
  ...normalized !== void 0 ? {
112
- normalizedUri: withSelector(withInputSearch(claim, pattern, parsed, normalized), parsed.protocol, selector)
115
+ normalizedUri: withSelector(withInputSearch(claim, pattern, parsed, normalized), parsed.protocol, selector, claim.kind === "uriPattern" && claim.preserveConnection === true)
113
116
  } : {},
114
117
  ...claim.route !== void 0 ? { route: claim.route } : {},
115
118
  ...filledSourceUrl !== void 0 ? { sourceUrl: filledSourceUrl } : {},
@@ -142,11 +145,13 @@ function parseUriConnectionSelector(input) {
142
145
  }
143
146
  return { selector: match[2], rest: `${match[1]}${match[3] ?? ""}` };
144
147
  }
145
- function withSelector(normalized, inputProtocol, selector) {
148
+ function withSelector(normalized, inputProtocol, selector, preserveConnection) {
146
149
  if (selector === void 0)
147
150
  return normalized;
148
- if (templateProtocol(normalized) !== inputProtocol)
151
+ const targetProtocol = templateProtocol(normalized);
152
+ if (targetProtocol === void 0 || !preserveConnection && targetProtocol !== inputProtocol) {
149
153
  return normalized;
154
+ }
150
155
  const schemeEnd = normalized.indexOf("://") + 3;
151
156
  return `${normalized.slice(0, schemeEnd)}@${selector}/${normalized.slice(schemeEnd)}`;
152
157
  }
@@ -307,7 +312,14 @@ function safeDecode(value) {
307
312
  }
308
313
  }
309
314
  function withInputSearch(claim, pattern, input, normalized) {
310
- if (claim.kind !== "uriPattern" || claim.normalizeTo === void 0 || pattern.search !== void 0 || input.search.length === 0 || claim.normalizeTo.includes("?") || templateProtocol(claim.normalizeTo) !== input.protocol) {
315
+ if (claim.kind !== "uriPattern" || claim.normalizeTo === void 0 || input.search.length === 0) {
316
+ return normalized;
317
+ }
318
+ if (claim.preserveQuery === true) {
319
+ const fragment = normalized.indexOf("#");
320
+ return fragment === -1 ? `${normalized}?${input.search}` : `${normalized.slice(0, fragment)}?${input.search}${normalized.slice(fragment)}`;
321
+ }
322
+ if (pattern.search !== void 0 || claim.normalizeTo.includes("?") || templateProtocol(claim.normalizeTo) !== input.protocol) {
311
323
  return normalized;
312
324
  }
313
325
  return `${normalized}?${input.search}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.55.1",
3
+ "version": "0.55.2",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",