@yaklabs-ai/plugin-sdk 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 YakLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # @yaklabs-ai/plugin-sdk
2
+
3
+ The SDK for authoring a **Kay directory plugin** — a plugin you write in a
4
+ repository and add to Kay through an approved plugin repository source.
5
+
6
+ Published to the public npm registry under the MIT licence.
7
+
8
+ ## Install
9
+
10
+ There is no registry configuration, no `.npmrc`, and no access token. Depend on
11
+ it under the name your plugin code actually imports:
12
+
13
+ ```json
14
+ {
15
+ "dependencies": {
16
+ "@kay/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.8.4"
17
+ }
18
+ }
19
+ ```
20
+
21
+ **The alias is not cosmetic.** The package is published as
22
+ `@yaklabs-ai/plugin-sdk`, but Kay's daemon resolves the specifier
23
+ `@kay/plugin-sdk` when it loads your entrypoint, so that is the name your source
24
+ must import. The alias installs the published package at
25
+ `node_modules/@kay/plugin-sdk`, satisfying both.
26
+
27
+ <details>
28
+ <summary>Installing a release older than 0.8.0</summary>
29
+
30
+ Releases before 0.8.0 shipped only to GitHub Packages, where access is Yak Labs
31
+ organization membership. To install one, point the `@yaklabs-ai` scope at that
32
+ registry in an `.npmrc` beside your `package.json`:
33
+
34
+ ```
35
+ @yaklabs-ai:registry=https://npm.pkg.github.com
36
+ //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
37
+ ```
38
+
39
+ `GITHUB_TOKEN` must be a **classic** personal access token with the
40
+ `read:packages` scope — GitHub Packages' npm registry does not accept
41
+ fine-grained tokens. Prefer upgrading instead; the public releases need none of
42
+ this.
43
+
44
+ </details>
45
+
46
+ ## Use
47
+
48
+ Working with an agent? This package ships the skill that teaches one the whole
49
+ authoring flow — scaffold, the SDK resolution contract, the reload loop, and
50
+ the diagnostics to read when a plugin does not load. Point your agent at
51
+ `node_modules/@kay/plugin-sdk/skills/directory-plugin-authoring/SKILL.md`
52
+ before it writes any plugin code.
53
+
54
+ ```ts
55
+ import {
56
+ defineTool,
57
+ textResult,
58
+ toolParameters,
59
+ z,
60
+ type KayAgentActivate,
61
+ } from "@kay/plugin-sdk/kay-agent";
62
+
63
+ const greet = defineTool({
64
+ name: "widgets_greet",
65
+ label: "Greet",
66
+ description: "Greet someone by name.",
67
+ parameters: toolParameters(z.object({ name: z.string() })),
68
+ async execute(_toolCallId, params) {
69
+ return textResult(`Hello, ${params.name}!`, undefined);
70
+ },
71
+ });
72
+
73
+ const activate: KayAgentActivate = (api) => {
74
+ api.registerTool(greet);
75
+ };
76
+
77
+ export default activate;
78
+ ```
79
+
80
+ ## Entrypoints
81
+
82
+ | Import | What it gives you |
83
+ | ----------------------------------- | -------------------------------------------------------------------------- |
84
+ | `@kay/plugin-sdk/kay-agent` | Tools, URI modules, search providers, auth — the per-session agent surface |
85
+ | `@kay/plugin-sdk/kay-app` | App-lifetime surface: storage, endpoints, app-scoped URI modules |
86
+ | `@kay/plugin-sdk/kay-agent/testing` | `invokeToolForTest`, `fauxAuthContext` — for your own `node --test` runs |
87
+ | `@kay/plugin-sdk/disclosure` | The conformance audit Kay gates your plugin with — run it before you ship |
88
+
89
+ `kay-agent/host` is intentionally not published; it is Kay's own loading
90
+ machinery, not an authoring API.
91
+
92
+ ## Check yourself against the gate that can reject you
93
+
94
+ Kay runs `auditPluginDisclosure` against your `kay.agent` target **at load,
95
+ fail-closed**: one violation and the whole target fails — no tools, no URI
96
+ modules, no skills. It is the same function this entrypoint exports, so the
97
+ run below is the run Kay does.
98
+
99
+ ```ts
100
+ import {
101
+ auditPluginDisclosure,
102
+ collectUriModulesFromKayAgentActivate,
103
+ } from "@kay/plugin-sdk/disclosure";
104
+
105
+ import activate from "../src/kay-agent.ts";
106
+ import manifest from "../kay-plugin.json" with { type: "json" };
107
+
108
+ const violations = await auditPluginDisclosure({
109
+ // Recover what activate() ACTUALLY registers — the same input the loader audits.
110
+ modules: collectUriModulesFromKayAgentActivate(activate),
111
+ declaredSkills: manifest.targets?.kay?.agent?.contributes?.skills ?? [],
112
+ });
113
+ if (violations.length > 0) throw new Error(JSON.stringify(violations, null, 2));
114
+ ```
115
+
116
+ (Reading the manifest needs `"resolveJsonModule": true` in your `tsconfig.json`
117
+ — `pnpm create-plugin` sets it. Restating your skills inline instead is the
118
+ thing that drifts.)
119
+
120
+ Pass the loader's inputs, not a subset — the audit judges what it is given:
121
+
122
+ - `modules` — from the probe, not a hand-assembled list. A module your
123
+ `activate` registers conditionally is exactly the one a hand-written list
124
+ forgets.
125
+ - `declaredSkills` — your manifest's
126
+ `targets.kay.agent.contributes.skills` (`{ localId, description }`). Omit
127
+ them and the module ↔ skill cross-link rules cannot fire.
128
+ - `commandBoundSkillIds` — the `localId` of every skill bound to a declared
129
+ command (`contributes.commands[].handler.kind === "skill"`). Omit it when
130
+ you have such commands and you will see `skill-link-missing-scheme`
131
+ violations Kay itself would not report.
132
+
133
+ `auditSkillCodegenPairs({ declaredSkills, exportedSkills, packageDir })` is the
134
+ companion check for a bundled-skill plugin. Both are pure — they return
135
+ violations rather than asserting — so any runner works. Both read from disk
136
+ and call your own `help()`, so run them in Node, and keep `activate` free of
137
+ side effects: the probe calls it.
138
+
139
+ `PLUGIN_DISCLOSURE_CONTRACT` names the floor this SDK enforces. Kay's load
140
+ failure names the floor **it** enforces. Different numbers mean the rules
141
+ moved, not your code — update this package and re-run.
142
+
143
+ A newer floor always has a release: every change to the rule set publishes a
144
+ version of this package as it lands, so "update and re-run" is never blocked on
145
+ someone remembering to cut one. If the numbers differ, a newer version exists.
146
+
147
+ ## What this package is, and is not, at runtime
148
+
149
+ Installing this SDK gives you **types, editor completion, and a runtime you can
150
+ execute in your own tests**. It is not what runs inside Kay.
151
+
152
+ When the daemon loads your plugin, chord bundles its declared target and keeps
153
+ `@kay/plugin-sdk/*` as a host external. Those imports resolve to the SDK
154
+ **bundled with the Kay app**. The host's copy always wins. That is deliberate —
155
+ one implementation, the one the daemon is built against — but it has a
156
+ consequence worth stating plainly:
157
+
158
+ > If your installed SDK is newer than your Kay app, code that typechecks against
159
+ > a newly-added API can still fail at load time, because the running host does
160
+ > not have it.
161
+
162
+ Importing an entire subpath the host does not know about fails loudly and
163
+ specifically (a `target-load` diagnostic naming the subpath, shown on the
164
+ Plugins page). A _symbol_ that exists here but not in the host's older copy is
165
+ not caught that way. Keep the SDK version in step with the Kay app you run.
166
+
167
+ The same skew applies to the conformance floor, and in the direction that
168
+ bites: if your Kay app is **newer** than this package, it can enforce a rule
169
+ your copy of the audit does not know about, so a green local run is not a
170
+ promise the host will load you. That is why the load failure names its
171
+ contract number — compare it against `PLUGIN_DISCLOSURE_CONTRACT` here, and if
172
+ they differ, update before you debug your code.
173
+
174
+ ## Install the plugin in Kay
175
+
176
+ The fastest route is the local plugin root. Put the plugin directory in
177
+ `~/.kay/plugins/<your-plugin>/` and turn it on in **Settings → Plugins**. That
178
+ root is already consented, so there is no repository to stage and no Trust step,
179
+ and your edits load without restarting Kay.
180
+
181
+ To share a plugin with someone who does not have your files, commit it to a Git
182
+ repository and have them add it under **Settings → Plugins → Plugin sources →
183
+ Add repository source**. They stage the source, Trust it, and enable the plugin;
184
+ Trust and activation are separate gates.
185
+
186
+ A plugin executes as a trusted in-process Node module with the daemon's own
187
+ authority. **The SDK does not provide a sandbox.** Putting code in the local
188
+ plugin root is itself the decision to run it, with no prompt in between — so
189
+ treat that directory exactly as carefully as you would Trust an unfamiliar
190
+ repository.
191
+
192
+ ## Requirements
193
+
194
+ Use Node.js 24 with an ESM package (`"type": "module"`) and ordinary
195
+ TypeScript. For standalone authoring and typechecking, install `typescript`
196
+ and `@types/node@^24`, and run `tsc --noEmit`; the scaffold's machine-local
197
+ checkout script is not the standalone path. The SDK's `kay-app` declarations
198
+ use `node:sqlite`, which TypeScript cannot resolve without the Node 24
199
+ typings.
200
+
201
+ When Kay loads your plugin, chord bundles the declared entrypoint and its
202
+ relative imports. Multi-file entrypoints are supported, and TypeScript syntax
203
+ that native stripping cannot execute, such as enums, namespaces, constructor
204
+ parameter properties, and decorators, is compiled into the bundle. The host
205
+ SDK remains external and is supplied by the running Kay app.
@@ -0,0 +1,65 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "package": "@yaklabs-ai/plugin-sdk",
4
+ "version": "0.8.4",
5
+ "target": "npm",
6
+ "firstPartyLicense": "MIT",
7
+ "bundled": [
8
+ {
9
+ "name": "@earendil-works/pi-agent-core",
10
+ "version": "0.87.0",
11
+ "license": "MIT",
12
+ "copyright": "Copyright (c) 2025 Mario Zechner",
13
+ "source": "https://github.com/earendil-works/pi/tree/v0.87.0/packages/agent",
14
+ "licenseSource": "https://github.com/earendil-works/pi/blob/v0.87.0/LICENSE",
15
+ "upstreamCommit": "16787ad5b2dc748047f314ca1bfe7708f30f54f3",
16
+ "noticeFile": "THIRD-PARTY-NOTICES.md"
17
+ },
18
+ {
19
+ "name": "@earendil-works/pi-ai",
20
+ "version": "0.87.1",
21
+ "license": "MIT",
22
+ "copyright": "Copyright (c) 2025 Mario Zechner",
23
+ "source": "https://github.com/earendil-works/pi/tree/v0.87.1/packages/ai",
24
+ "licenseSource": "https://github.com/earendil-works/pi/blob/v0.87.1/LICENSE",
25
+ "upstreamCommit": "f07218c4d4bbc12bef056a7058c3dd49dfe41abe",
26
+ "noticeFile": "THIRD-PARTY-NOTICES.md"
27
+ },
28
+ {
29
+ "name": "@earendil-works/chord",
30
+ "version": "0.87.0",
31
+ "license": "MIT",
32
+ "copyright": "Copyright (c) 2025 Mario Zechner",
33
+ "source": "https://github.com/earendil-works/pi/tree/v0.87.0/packages/chord",
34
+ "licenseSource": "https://github.com/earendil-works/pi/blob/v0.87.0/LICENSE",
35
+ "upstreamCommit": "16787ad5b2dc748047f314ca1bfe7708f30f54f3",
36
+ "noticeFile": "THIRD-PARTY-NOTICES.md"
37
+ },
38
+ {
39
+ "name": "typebox",
40
+ "version": "1.3.27",
41
+ "license": "MIT",
42
+ "copyright": "Copyright (c) 2017-2026 Haydn Paterson",
43
+ "source": "https://github.com/sinclairzx81/typebox/tree/1.3.27",
44
+ "licenseSource": "https://github.com/sinclairzx81/typebox/blob/1.3.27/license",
45
+ "upstreamCommit": "ffe23ba614322bf0dcb846ceaf7c1bbc7ef0bba6",
46
+ "noticeFile": "THIRD-PARTY-NOTICES.md"
47
+ }
48
+ ],
49
+ "external": [
50
+ {
51
+ "name": "zod",
52
+ "license": "MIT",
53
+ "source": "https://github.com/colinhacks/zod",
54
+ "note": "Installed as a consumer dependency; it is not bundled into the staged artifacts.",
55
+ "versionRange": "^4.0.0"
56
+ },
57
+ {
58
+ "name": "@typesafe-ai/sdk",
59
+ "license": "MIT",
60
+ "source": "https://github.com/typesafe-ai/typesafe-sdk-js",
61
+ "note": "Types-only: the SDK re-exports the vendor's Jev client types, and the vendor's nominal class must stay a single declaration across entrypoints. Installed as a consumer dependency; a plugin never declares it itself.",
62
+ "versionRange": "0.6.0"
63
+ }
64
+ ]
65
+ }
@@ -0,0 +1,103 @@
1
+ # Third-party notices
2
+
3
+ This package bundles 4 first-party-selected component(s). The notices below are reproduced verbatim from each component's upstream MIT license source.
4
+
5
+ ## @earendil-works/pi-agent-core@0.87.0
6
+
7
+ - Source: https://github.com/earendil-works/pi/tree/v0.87.0/packages/agent
8
+ - License source: https://github.com/earendil-works/pi/blob/v0.87.0/LICENSE
9
+ - Upstream commit: 16787ad5b2dc748047f314ca1bfe7708f30f54f3
10
+
11
+ ## @earendil-works/chord@0.87.0
12
+
13
+ - Source: https://github.com/earendil-works/pi/tree/v0.87.0/packages/chord
14
+ - License source: https://github.com/earendil-works/pi/blob/v0.87.0/LICENSE
15
+ - Upstream commit: 16787ad5b2dc748047f314ca1bfe7708f30f54f3
16
+
17
+ License text for the component(s) above, verbatim from the license source:
18
+
19
+ MIT License
20
+
21
+ Copyright (c) 2025 Mario Zechner
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ of this software and associated documentation files (the "Software"), to deal
25
+ in the Software without restriction, including without limitation the rights
26
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ copies of the Software, and to permit persons to whom the Software is
28
+ furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in all
31
+ copies or substantial portions of the Software.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
+ SOFTWARE.
40
+
41
+ ## @earendil-works/pi-ai@0.87.1
42
+
43
+ - Source: https://github.com/earendil-works/pi/tree/v0.87.1/packages/ai
44
+ - License source: https://github.com/earendil-works/pi/blob/v0.87.1/LICENSE
45
+ - Upstream commit: f07218c4d4bbc12bef056a7058c3dd49dfe41abe
46
+
47
+ License text for the component(s) above, verbatim from the license source:
48
+
49
+ MIT License
50
+
51
+ Copyright (c) 2025 Mario Zechner
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining a copy
54
+ of this software and associated documentation files (the "Software"), to deal
55
+ in the Software without restriction, including without limitation the rights
56
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57
+ copies of the Software, and to permit persons to whom the Software is
58
+ furnished to do so, subject to the following conditions:
59
+
60
+ The above copyright notice and this permission notice shall be included in all
61
+ copies or substantial portions of the Software.
62
+
63
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
68
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
69
+ SOFTWARE.
70
+
71
+ ## typebox@1.3.27
72
+
73
+ - Source: https://github.com/sinclairzx81/typebox/tree/1.3.27
74
+ - License source: https://github.com/sinclairzx81/typebox/blob/1.3.27/license
75
+ - Upstream commit: ffe23ba614322bf0dcb846ceaf7c1bbc7ef0bba6
76
+
77
+ License text for the component(s) above, verbatim from the license source:
78
+
79
+ TypeBox
80
+
81
+ The MIT License (MIT)
82
+
83
+ Copyright (c) 2017-2026 Haydn Paterson
84
+
85
+ Permission is hereby granted, free of charge, to any person obtaining a copy
86
+ of this software and associated documentation files (the "Software"), to deal
87
+ in the Software without restriction, including without limitation the rights
88
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
89
+ copies of the Software, and to permit persons to whom the Software is
90
+ furnished to do so, subject to the following conditions:
91
+
92
+ The above copyright notice and this permission notice shall be included in
93
+ all copies or substantial portions of the Software.
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
96
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
97
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
98
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
99
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
100
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
101
+ THE SOFTWARE.
102
+
103
+ The package's own code is licensed under the MIT License in `LICENSE`.