@workerkit/core 0.3.18 → 0.3.20

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/CHANGELOG.md CHANGED
@@ -6,6 +6,35 @@ and the package adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.3.20] - 2026-10-21
10
+
11
+ ### Added
12
+
13
+ - `activity_feed` reads the runs, app calls and configuration changes of the workers a key reaches as one newest-first, cursor-paged feed with one flat row shape; `kind`, `outcome`, `workerId`, `since` and `until` narrow it. App calls go back as far as the plan's log window, reported as `callsSinceUtc`. `activity_summary` counts the same activity over a window, with the busiest apps and tools. Both require `readRuns`.
14
+ - `account_spend` reads this UTC day's and month's run spend with its split by worker, day and model, on the basis the budget gates use. The wallet's own charges for the month are included when the key reaches the whole account. Requires `manageBudgets`.
15
+
16
+ ### Changed
17
+
18
+ - Public kit publishing is temporarily paused. `kit_validate`, `kit_publish`, `kit_replace` and `kit_relist` say so, and the `visibility` parameter tells agents to send `private` explicitly, because an omitted visibility means public and is refused. The manager and directory instructions carry the same rule.
19
+ - `kits_search` and `publisher_get` explain that public publisher identity is hidden: `publisherName` is empty, `publisherSlug` is null and `isOfficialPublisher` is false, public publisher profiles return 404 and the `publisher` filter matches nothing. Owners still manage their own publisher profile.
20
+
21
+ ## [0.3.19] - 2026-10-21
22
+
23
+ ### Added
24
+
25
+ - Nine API-app authoring tools list, read, validate, preview, create and update account-private definitions, and publish, inspect and revoke immutable versions. Authoring requires a live account Admin and the explicit `managePrivateApiApps` scope. Draft edits preserve optimistic revisions; publication never upgrades worker bindings or creates a public listing.
26
+ - `worker_bindings_get` and `worker_bindings_set` read and set a worker's grants to call other workers after install. One atomic alias map fills, re-points or clears grants; a declared kit slot supplies its own operations and Action tools; an unchanged live grant keeps its revision. Reads ride `readWorkers`; the write requires the new `manageAppsAndWorkers` scope.
27
+ - `worker_permissions_set` replaces an existing worker's app set in the vocabulary `worker_permissions_get` returns, plus the contact stance, blocked sender categories, timeframes and child budget. A stance changes only when the call sends `allowAll`. Requires `manageAppsAndWorkers` and a live account Admin; rules, identities and MCP tool bindings remain dashboard-only.
28
+ - `managePrivateApiApps` and `manageAppsAndWorkers` join `managerScopes`. Existing keys gain `managePrivateApiApps` only through explicit re-scoping. Keys that held every earlier scope when `manageAppsAndWorkers` was introduced carry it; other existing keys need an account admin to add it.
29
+ - The backend contract's guidance coverage gains `APIAPP-01`, which pins the API-app safety guidance: Admin authority, no credentials in definitions, offline validation and preview, reviewed revisions and irreversible revocation.
30
+
31
+ ### Changed
32
+
33
+ - `worker_permissions_get`, `worker_get`, `run_get`, `kit_install_preview` and `kit_install` point to the new tools for binding slots and changing access.
34
+ - `worker_permissions_get` reports messaging `providers` and the Firecrawl and Nimble `capabilities` a worker holds, so its output writes back unchanged.
35
+ - `kit_install` returns no worker API key. Trigger signing secrets are still returned once.
36
+ - Quality receipt guidance separates code-computed `executionChecks` from model `systemReview` diagnostics and notes that runtime and app failure counts can overlap.
37
+
9
38
  ## [0.3.18] - 2026-10-17
10
39
 
11
40
  ### Added
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![license](https://img.shields.io/npm/l/%40workerkit%2Fcore.svg)](LICENSE)
7
7
 
8
8
  The [WorkerKit](https://workerkit.ai) API client and tool registry for Node.js.
9
- It provides 100 authenticated management tools, 8 anonymous directory tools,
9
+ It provides 115 authenticated management tools, 8 anonymous directory tools,
10
10
  and a shared execution engine for their HTTP requests.
11
11
 
12
12
  Descriptors include agent guidance, annotations and Zod input schemas. MCP
@@ -68,6 +68,32 @@ whole-call deadline, bounded retries for idempotent methods only, a streamed
68
68
  response-size cap, and quota/rate-limit header extraction. `scrubSecrets` helps
69
69
  keep credentials out of logs.
70
70
 
71
+ ## Kit publishing
72
+
73
+ Public kit publishing is temporarily paused, including promotion of a private
74
+ kit, public replacement and relisting. Send `visibility: "private"` explicitly
75
+ to `kit_validate`, `kit_publish` and `kit_replace`; an omitted visibility
76
+ means public and is refused. Private kits publish and install as before.
77
+ Public publisher identity is also hidden: catalog entries carry no publisher
78
+ attribution and public publisher profiles return 404. Owners still manage
79
+ their own publisher profile.
80
+
81
+ ## Author API apps
82
+
83
+ `api_app_validate` checks a `{ definition }` offline, and `api_app_create`
84
+ saves it as an account-private draft from `{ name, definition, enabled: false }`.
85
+ Use `api_apps_list` / `api_app_get` to inspect saved state, `api_app_update`
86
+ with its reviewed revision to edit it, and `api_app_publish` with
87
+ `{ appId, revision }` to publish an immutable version. Version reads and
88
+ revocation use `api_app_version_get` and `api_app_version_revoke`.
89
+
90
+ Authoring requires a live account Admin and the `managePrivateApiApps` scope,
91
+ which existing keys gain only through explicit re-scoping. Publishing does not
92
+ create a public listing or upgrade worker bindings. Definitions declare named
93
+ authentication slots, never credentials; credentials and worker bindings are
94
+ configured separately on the dashboard. A revision conflict requires re-reading
95
+ the app.
96
+
71
97
  ## Discover GitHub targets before installing
72
98
 
73
99
  `app_github_accounts`, `app_github_repos` and `app_github_branches` look up
@@ -185,8 +211,15 @@ installed worker, to `kit_install`. The target must be in the same account and
185
211
  within the installer's authority and fleet-key selection, and its kind,
186
212
  operations and pinned contracts must match the slot. An install without
187
213
  bindings succeeds, but an unbound required slot reports the readiness issue
188
- `worker_slots_pending` and runs are skipped until it is bound under Apps and
189
- workers on the dashboard.
214
+ `worker_slots_pending` and runs are skipped until it is bound.
215
+
216
+ After install, `worker_bindings_get` lists a worker's grants, the slots its
217
+ kit declares, the required slots still missing and the workers that could
218
+ fill them. `worker_bindings_set` fills, re-points or clears aliases in one
219
+ atomic map (`manageAppsAndWorkers`): a declared slot takes the slot's
220
+ operations and Action tools when they are omitted, a free alias names its
221
+ operations, and an unchanged live grant is left alone. Both follow the
222
+ caller's authority and fleet-key selection.
190
223
 
191
224
  A binding shares the target's bounded result with the caller, not its full
192
225
  receipt or transcript. The target keeps its own permissions, budget, model and
@@ -197,6 +230,19 @@ returns the metadata and `contentReferences` without copying reports. A fleet
197
230
  key appears as an id, name and prefix snapshot, never a credential. Core only
198
231
  describes these fields; the server owns execution, waiting and billing.
199
232
 
233
+ ## Change an existing worker's apps
234
+
235
+ `worker_permissions_set` (account Admin, `manageAppsAndWorkers`) replaces an
236
+ existing worker's app set in the vocabulary `worker_permissions_get` returns.
237
+ An app left out is switched off, and a stance changes only when the call sends
238
+ `allowAll`: a deny-by-default app switched on reads nothing until the owner
239
+ writes rules or the call sends `allowAll: true`. Rules, identities and MCP tool
240
+ bindings stay on the dashboard.
241
+
242
+ `manageAppsAndWorkers` also covers `worker_bindings_set`. Keys that held every
243
+ earlier scope when it was introduced carry it; other existing keys need an
244
+ account admin to add it.
245
+
200
246
  ## Worker quality
201
247
 
202
248
  `worker_quality_get` reads a worker's acceptance criteria, settings revision,
@@ -1,6 +1,6 @@
1
1
  export declare const backendContractProvenance: {
2
2
  readonly sourceRepository: "workerkit-backend";
3
3
  readonly contractVersion: "1.0.0";
4
- readonly sourceRevision: "e50d14f21fc9d14186127fb5c0721ce16fecc9cb";
5
- readonly contentHash: "3291157abc1d967ea9fd9ccd048e17b279b3156398ac79b0e3b57b100e6ab4a6";
4
+ readonly sourceRevision: "1953496c8dff09fab24d19661457faa600f2af64";
5
+ readonly contentHash: "c6a74062d1063233f9040971ddaea5e2fdb38248b929257eaaa008c3800b9b4a";
6
6
  };
@@ -2,7 +2,7 @@
2
2
  export const backendContractProvenance = {
3
3
  "sourceRepository": "workerkit-backend",
4
4
  "contractVersion": "1.0.0",
5
- "sourceRevision": "e50d14f21fc9d14186127fb5c0721ce16fecc9cb",
6
- "contentHash": "3291157abc1d967ea9fd9ccd048e17b279b3156398ac79b0e3b57b100e6ab4a6"
5
+ "sourceRevision": "1953496c8dff09fab24d19661457faa600f2af64",
6
+ "contentHash": "c6a74062d1063233f9040971ddaea5e2fdb38248b929257eaaa008c3800b9b4a"
7
7
  };
8
8
  //# sourceMappingURL=contract-provenance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract-provenance.js","sourceRoot":"","sources":["../src/contract-provenance.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,kBAAkB,EAAE,mBAAmB;IACvC,iBAAiB,EAAE,OAAO;IAC1B,gBAAgB,EAAE,0CAA0C;IAC5D,aAAa,EAAE,kEAAkE;CACzE,CAAC","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\nexport const backendContractProvenance = {\n \"sourceRepository\": \"workerkit-backend\",\n \"contractVersion\": \"1.0.0\",\n \"sourceRevision\": \"e50d14f21fc9d14186127fb5c0721ce16fecc9cb\",\n \"contentHash\": \"3291157abc1d967ea9fd9ccd048e17b279b3156398ac79b0e3b57b100e6ab4a6\"\n} as const;\n"]}
1
+ {"version":3,"file":"contract-provenance.js","sourceRoot":"","sources":["../src/contract-provenance.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,kBAAkB,EAAE,mBAAmB;IACvC,iBAAiB,EAAE,OAAO;IAC1B,gBAAgB,EAAE,0CAA0C;IAC5D,aAAa,EAAE,kEAAkE;CACzE,CAAC","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\nexport const backendContractProvenance = {\n \"sourceRepository\": \"workerkit-backend\",\n \"contractVersion\": \"1.0.0\",\n \"sourceRevision\": \"1953496c8dff09fab24d19661457faa600f2af64\",\n \"contentHash\": \"c6a74062d1063233f9040971ddaea5e2fdb38248b929257eaaa008c3800b9b4a\"\n} as const;\n"]}
@@ -0,0 +1,3 @@
1
+ import { type ToolDescriptor } from "./types.js";
2
+ export declare const apiAppOperationsText = "Named operations. Each declares key, description, effect, method (GET/HEAD/POST/PUT/PATCH/DELETE), fixed path, inputs, and responseFields (output name to JSON Pointer), or emptyResponse:true. inputs is a closed object schema with properties, additionalProperties:false and optional required; supported types: object/array/string/integer/number/boolean, bounded enum/const and type-appropriate bounds. pathInputs/query/headers map names to {input:field} or {literal:value}; each declared top-level input maps once. body uses those leaves in a JSON object. Path placeholders occupy whole segments. authentication is {kind:none}, {kind:bearer,secretSlot}, {kind:basic,usernameSlot,passwordSlot}, or {kind:apiKey,headers:{name:slot},query:{name:slot}}. Store slot names only, never credentials. successStatuses contains declared 2xx codes. The backend rejects unknown fields, unsafe mappings and unsupported schema features; api_app_validate reports errors before saving.";
3
+ export declare const apiAppDescriptors: readonly ToolDescriptor[];
@@ -0,0 +1,79 @@
1
+ // Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.
2
+ import { z } from "../zod.js";
3
+ import { CREATE, DELETE, READ_ONLY, UPDATE, defineTool } from "./types.js";
4
+ const API = "/api/manage/custom-api";
5
+ const appId = z.string().uuid().describe("Account-owned app UUID from api_apps_list or api_app_create. Another account's app is indistinguishable from a missing app.");
6
+ const versionId = z.string().uuid().describe("Immutable version UUID from api_app_get or api_app_publish.");
7
+ const revision = z.string().uuid().describe("Current revision from api_app_get, api_app_create or api_app_update. After publishing use appRevision from that response. A 409 requires re-reading and reviewing the draft; never overwrite using a newer revision automatically.");
8
+ const operations = "Named operations. Each declares key, description, effect, method (GET/HEAD/POST/PUT/PATCH/DELETE), fixed path, inputs, and responseFields (output name to JSON Pointer), or emptyResponse:true. inputs is a closed object schema with properties, additionalProperties:false and optional required; supported types: object/array/string/integer/number/boolean, bounded enum/const and type-appropriate bounds. pathInputs/query/headers map names to {input:field} or {literal:value}; each declared top-level input maps once. body uses those leaves in a JSON object. Path placeholders occupy whole segments. authentication is {kind:none}, {kind:bearer,secretSlot}, {kind:basic,usernameSlot,passwordSlot}, or {kind:apiKey,headers:{name:slot},query:{name:slot}}. Store slot names only, never credentials. successStatuses contains declared 2xx codes. The backend rejects unknown fields, unsafe mappings and unsupported schema features; api_app_validate reports errors before saving.";
9
+ export const apiAppOperationsText = operations;
10
+ const definition = z.object({
11
+ schemaVersion: z.literal(1).describe("Definition format version; must be 1."),
12
+ origin: z.string().url().max(2048).describe("One public HTTPS origin on port 443 without a path, query, credentials or fragment. Private networks and WorkerKit control-plane hosts are denied."),
13
+ operations: z.array(z.record(z.unknown())).min(1).max(40).describe(operations),
14
+ }).strict().describe("Structured API definition, at most 128 KiB. No scripts, OpenAPI imports, executable templates or credentials. Validate before saving; preview only constructs a request shape and sends nothing.");
15
+ const path = (params) => `${API}/apps/${encodeURIComponent(String(params.appId))}`;
16
+ const versionPath = (params) => `${path(params)}/versions/${encodeURIComponent(String(params.versionId))}`;
17
+ export const apiAppDescriptors = [
18
+ defineTool({
19
+ name: "api_apps_list", title: "List API Apps", auth: "manager", method: "get", schema: {}, path: `${API}/apps`,
20
+ description: "List this account's API apps: id, name, enabled, optimistic revision and liveVersionNumber (the newest unrevoked version; null if none). connectionCount, usableConnectionCount (enabled and authorized for the live version) and stoppedWorkerCount (enabled worker bindings stopped by a revoked version or a disabled or unauthorized connection) require an account Admin credential with managePrivateApiApps; otherwise null means withheld, not zero. {{scope}} Admins see all apps; members see only enabled apps explicitly granted to their current membership. Apps stay account-private. Use api_app_get for a saved draft and published version IDs.",
21
+ annotations: READ_ONLY,
22
+ }),
23
+ defineTool({
24
+ name: "api_app_get", title: "Get API App", auth: "manager", method: "get", schema: { appId }, path,
25
+ paramFilter: () => ({}), strictInput: true,
26
+ description: "Read app metadata, current revision and published version IDs/hashes/revocation state. {{scope}} The draft additionally requires an account Admin credential with managePrivateApiApps; otherwise draft:null means withheld. No credentials are returned. Existing workers keep their pinned versions when the draft changes. Use api_app_version_get for an immutable definition.",
27
+ annotations: READ_ONLY,
28
+ }),
29
+ defineTool({
30
+ name: "api_app_validate", title: "Validate API App", auth: "manager", method: "post", schema: { definition }, path: `${API}/validate`,
31
+ strictInput: true,
32
+ description: "Validate an API app definition offline and return its normalized definition and content hash. {{scope}} Requires a live account Admin. Saves nothing and sends no upstream request. Correct validation errors before api_app_create or api_app_update. A definition grants no worker access by itself; connections and exact worker bindings are configured separately on the dashboard.",
33
+ annotations: READ_ONLY,
34
+ }),
35
+ defineTool({
36
+ name: "api_app_preview", title: "Preview API Request", auth: "manager", method: "post",
37
+ schema: { definition, operation: z.string().min(1).max(48).describe("Operation key declared in definition.operations."),
38
+ arguments: z.record(z.unknown()).describe("Example arguments matching the operation's closed input schema. Use non-sensitive examples; this is shape validation, not a live test.") },
39
+ path: `${API}/preview`, strictInput: true,
40
+ description: "Construct an API request shape offline. {{scope}} Requires a live account Admin. Returns origin, method, path template, query/header names, body byte count and authentication slot names; argument values and credentials are omitted. Saves nothing, resolves no DNS and sends no upstream request. This does not prove credentials or the destination work.",
41
+ annotations: READ_ONLY,
42
+ }),
43
+ defineTool({
44
+ name: "api_app_create", title: "Create API App", auth: "manager", method: "post",
45
+ schema: { name: z.string().trim().min(1).max(100).describe("App's display name within this account."), definition,
46
+ enabled: z.boolean().optional().describe("Defaults false. Enabling allows existing authorized bindings to execute; it does not publish a version or grant user/worker access.") },
47
+ path: `${API}/apps`, strictInput: true,
48
+ description: "Create an account-private API app draft; returns its app UUID and revision. {{scope}} Requires a live account Admin. Validate first with api_app_validate. No upstream request, connection or worker grant is created. Publish the saved draft with api_app_publish before configuring a connection and binding in the dashboard. Limited to 25 apps/account. After a lost response inspect api_apps_list before creating again; creation is not idempotent.",
49
+ annotations: CREATE,
50
+ }),
51
+ defineTool({
52
+ name: "api_app_update", title: "Update API App", auth: "manager", method: "put",
53
+ schema: { appId, revision, name: z.string().trim().min(1).max(100).describe("Replacement display name."), definition,
54
+ enabled: z.boolean().describe("Explicit app state. false immediately blocks new dispatches for every version; true still requires current grants, bindings, connections and policy.") },
55
+ path, strictInput: true,
56
+ bodyBuilder: ({ appId: _appId, ...body }) => body,
57
+ description: "Replace an app's saved draft, name and enabled state using its current revision. {{scope}} Requires a live account Admin. Returns a new revision. Published definitions remain immutable and workers keep their pinned versions; use api_app_publish for a new version. A 409 revision_conflict requires reviewing the latest draft. Do not blindly retry a lost update with a newer revision.",
58
+ annotations: UPDATE,
59
+ }),
60
+ defineTool({
61
+ name: "api_app_publish", title: "Publish API App Version", auth: "manager", method: "post", schema: { appId, revision },
62
+ path: params => `${path(params)}/versions`, bodyBuilder: ({ revision }) => ({ revision }), strictInput: true,
63
+ description: "Publish the saved API app draft as an immutable version in this account; returns id, number, contentHash and appRevision. {{scope}} Requires a live account Admin. Uses the reviewed draft revision, creates no public listing and never upgrades worker bindings. Publication does not enable the app. A 409 means re-read the app; after a lost response inspect its versions before publishing again. Use appRevision for the next app edit or publication.",
64
+ annotations: CREATE,
65
+ }),
66
+ defineTool({
67
+ name: "api_app_version_get", title: "Get API App Version", auth: "manager", method: "get", schema: { appId, versionId },
68
+ path: versionPath, paramFilter: () => ({}), strictInput: true,
69
+ description: "Read one immutable API app definition, content hash, authentication-profile fingerprint and revoked state. {{scope}} Requires a live account Admin. No credential values are returned. Connections must match the version's origin and authentication profile; the worker's binding separately selects a finite operation list and fixed inputs. Revoked versions cannot execute.",
70
+ annotations: READ_ONLY,
71
+ }),
72
+ defineTool({
73
+ name: "api_app_version_revoke", title: "Revoke API App Version", auth: "manager", method: "delete", schema: { appId, versionId },
74
+ path: versionPath, strictInput: true,
75
+ description: "Permanently revoke a published API app version. {{scope}} Requires a live account Admin. Immediately prevents new dispatches by all workers pinned to that version; already dispatched effects cannot be undone. It does not delete the definition, app or credentials. Publish a new version and review bindings to resume use; revocation cannot be reversed.",
76
+ annotations: DELETE,
77
+ }),
78
+ ];
79
+ //# sourceMappingURL=api-apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-apps.js","sourceRoot":"","sources":["../../src/descriptors/api-apps.ts"],"names":[],"mappings":"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","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\nimport { z } from \"../zod.js\";\nimport { CREATE, DELETE, READ_ONLY, UPDATE, defineTool, type ToolDescriptor } from \"./types.js\";\n\nconst API = \"/api/manage/custom-api\";\nconst appId = z.string().uuid().describe(\"Account-owned app UUID from api_apps_list or api_app_create. Another account's app is indistinguishable from a missing app.\");\nconst versionId = z.string().uuid().describe(\"Immutable version UUID from api_app_get or api_app_publish.\");\nconst revision = z.string().uuid().describe(\"Current revision from api_app_get, api_app_create or api_app_update. After publishing use appRevision from that response. A 409 requires re-reading and reviewing the draft; never overwrite using a newer revision automatically.\");\nconst operations = \"Named operations. Each declares key, description, effect, method (GET/HEAD/POST/PUT/PATCH/DELETE), fixed path, inputs, and responseFields (output name to JSON Pointer), or emptyResponse:true. inputs is a closed object schema with properties, additionalProperties:false and optional required; supported types: object/array/string/integer/number/boolean, bounded enum/const and type-appropriate bounds. pathInputs/query/headers map names to {input:field} or {literal:value}; each declared top-level input maps once. body uses those leaves in a JSON object. Path placeholders occupy whole segments. authentication is {kind:none}, {kind:bearer,secretSlot}, {kind:basic,usernameSlot,passwordSlot}, or {kind:apiKey,headers:{name:slot},query:{name:slot}}. Store slot names only, never credentials. successStatuses contains declared 2xx codes. The backend rejects unknown fields, unsafe mappings and unsupported schema features; api_app_validate reports errors before saving.\";\nexport const apiAppOperationsText = operations;\nconst definition = z.object({\n schemaVersion: z.literal(1).describe(\"Definition format version; must be 1.\"),\n origin: z.string().url().max(2048).describe(\"One public HTTPS origin on port 443 without a path, query, credentials or fragment. Private networks and WorkerKit control-plane hosts are denied.\"),\n operations: z.array(z.record(z.unknown())).min(1).max(40).describe(operations),\n}).strict().describe(\"Structured API definition, at most 128 KiB. No scripts, OpenAPI imports, executable templates or credentials. Validate before saving; preview only constructs a request shape and sends nothing.\");\nconst path = (params: Record<string, unknown>) => `${API}/apps/${encodeURIComponent(String(params.appId))}`;\nconst versionPath = (params: Record<string, unknown>) => `${path(params)}/versions/${encodeURIComponent(String(params.versionId))}`;\n\nexport const apiAppDescriptors: readonly ToolDescriptor[] = [\n defineTool({\n name: \"api_apps_list\", title: \"List API Apps\", auth: \"manager\", method: \"get\", schema: {}, path: `${API}/apps`,\n description: \"List this account's API apps: id, name, enabled, optimistic revision and liveVersionNumber (the newest unrevoked version; null if none). connectionCount, usableConnectionCount (enabled and authorized for the live version) and stoppedWorkerCount (enabled worker bindings stopped by a revoked version or a disabled or unauthorized connection) require an account Admin credential with managePrivateApiApps; otherwise null means withheld, not zero. {{scope}} Admins see all apps; members see only enabled apps explicitly granted to their current membership. Apps stay account-private. Use api_app_get for a saved draft and published version IDs.\",\n annotations: READ_ONLY,\n }),\n defineTool({\n name: \"api_app_get\", title: \"Get API App\", auth: \"manager\", method: \"get\", schema: { appId }, path,\n paramFilter: () => ({}), strictInput: true,\n description: \"Read app metadata, current revision and published version IDs/hashes/revocation state. {{scope}} The draft additionally requires an account Admin credential with managePrivateApiApps; otherwise draft:null means withheld. No credentials are returned. Existing workers keep their pinned versions when the draft changes. Use api_app_version_get for an immutable definition.\",\n annotations: READ_ONLY,\n }),\n defineTool({\n name: \"api_app_validate\", title: \"Validate API App\", auth: \"manager\", method: \"post\", schema: { definition }, path: `${API}/validate`,\n strictInput: true,\n description: \"Validate an API app definition offline and return its normalized definition and content hash. {{scope}} Requires a live account Admin. Saves nothing and sends no upstream request. Correct validation errors before api_app_create or api_app_update. A definition grants no worker access by itself; connections and exact worker bindings are configured separately on the dashboard.\",\n annotations: READ_ONLY,\n }),\n defineTool({\n name: \"api_app_preview\", title: \"Preview API Request\", auth: \"manager\", method: \"post\",\n schema: { definition, operation: z.string().min(1).max(48).describe(\"Operation key declared in definition.operations.\"),\n arguments: z.record(z.unknown()).describe(\"Example arguments matching the operation's closed input schema. Use non-sensitive examples; this is shape validation, not a live test.\") },\n path: `${API}/preview`, strictInput: true,\n description: \"Construct an API request shape offline. {{scope}} Requires a live account Admin. Returns origin, method, path template, query/header names, body byte count and authentication slot names; argument values and credentials are omitted. Saves nothing, resolves no DNS and sends no upstream request. This does not prove credentials or the destination work.\",\n annotations: READ_ONLY,\n }),\n defineTool({\n name: \"api_app_create\", title: \"Create API App\", auth: \"manager\", method: \"post\",\n schema: { name: z.string().trim().min(1).max(100).describe(\"App's display name within this account.\"), definition,\n enabled: z.boolean().optional().describe(\"Defaults false. Enabling allows existing authorized bindings to execute; it does not publish a version or grant user/worker access.\") },\n path: `${API}/apps`, strictInput: true,\n description: \"Create an account-private API app draft; returns its app UUID and revision. {{scope}} Requires a live account Admin. Validate first with api_app_validate. No upstream request, connection or worker grant is created. Publish the saved draft with api_app_publish before configuring a connection and binding in the dashboard. Limited to 25 apps/account. After a lost response inspect api_apps_list before creating again; creation is not idempotent.\",\n annotations: CREATE,\n }),\n defineTool({\n name: \"api_app_update\", title: \"Update API App\", auth: \"manager\", method: \"put\",\n schema: { appId, revision, name: z.string().trim().min(1).max(100).describe(\"Replacement display name.\"), definition,\n enabled: z.boolean().describe(\"Explicit app state. false immediately blocks new dispatches for every version; true still requires current grants, bindings, connections and policy.\") },\n path, strictInput: true,\n bodyBuilder: ({ appId: _appId, ...body }) => body,\n description: \"Replace an app's saved draft, name and enabled state using its current revision. {{scope}} Requires a live account Admin. Returns a new revision. Published definitions remain immutable and workers keep their pinned versions; use api_app_publish for a new version. A 409 revision_conflict requires reviewing the latest draft. Do not blindly retry a lost update with a newer revision.\",\n annotations: UPDATE,\n }),\n defineTool({\n name: \"api_app_publish\", title: \"Publish API App Version\", auth: \"manager\", method: \"post\", schema: { appId, revision },\n path: params => `${path(params)}/versions`, bodyBuilder: ({ revision }) => ({ revision }), strictInput: true,\n description: \"Publish the saved API app draft as an immutable version in this account; returns id, number, contentHash and appRevision. {{scope}} Requires a live account Admin. Uses the reviewed draft revision, creates no public listing and never upgrades worker bindings. Publication does not enable the app. A 409 means re-read the app; after a lost response inspect its versions before publishing again. Use appRevision for the next app edit or publication.\",\n annotations: CREATE,\n }),\n defineTool({\n name: \"api_app_version_get\", title: \"Get API App Version\", auth: \"manager\", method: \"get\", schema: { appId, versionId },\n path: versionPath, paramFilter: () => ({}), strictInput: true,\n description: \"Read one immutable API app definition, content hash, authentication-profile fingerprint and revoked state. {{scope}} Requires a live account Admin. No credential values are returned. Connections must match the version's origin and authentication profile; the worker's binding separately selects a finite operation list and fixed inputs. Revoked versions cannot execute.\",\n annotations: READ_ONLY,\n }),\n defineTool({\n name: \"api_app_version_revoke\", title: \"Revoke API App Version\", auth: \"manager\", method: \"delete\", schema: { appId, versionId },\n path: versionPath, strictInput: true,\n description: \"Permanently revoke a published API app version. {{scope}} Requires a live account Admin. Immediately prevents new dispatches by all workers pinned to that version; already dispatched effects cannot be undone. It does not delete the definition, app or credentials. Publish a new version and review bindings to resume use; revocation cannot be reversed.\",\n annotations: DELETE,\n }),\n];\n"]}
@@ -18,6 +18,7 @@
18
18
  // / kit_install on the authenticated WorkerKit Manager server.
19
19
  import { z } from "../zod.js";
20
20
  import { READ_ONLY } from "./types.js";
21
+ import { publicPublisherIdentityPause } from "../guidance.js";
21
22
  const API = "/api/directory/mcp";
22
23
  const SITE = "https://workerkit.ai";
23
24
  // ─── Shared phrasing ────────────────────────────────────────────────────────
@@ -125,7 +126,8 @@ const directoryOverview = {
125
126
  const searchKits = {
126
127
  name: "kits_search",
127
128
  title: "Search Kits",
128
- description: "Search public worker templates: instructions, decision routing or Action tools, with pre-scoped app permissions and often schedules. All optional filters AND; omit to browse. Returns {items,totalCount,page,pageSize}. Cards: slug(kit_get key), name/jobSentence, publisherName/publisherSlug/isOfficialPublisher/verificationTier, apps/categorySlots(installer chooses member), categories/triggerModes, starCount, modelScores(publisher-declared 0-100 fit, best first)/recommendedModel, modelType(language|decision|hybrid|none), isProtected,isFeatured,publishedAt. Protected instruction TEXT is intentionally withheld; kit still works, not a red flag. Empty is not an error; read its footer and directory_overview for valid filters. Human page: https://workerkit.ai/kit/{slug}." + DIRECTORY_NOTE,
129
+ description: publicPublisherIdentityPause +
130
+ "Search public worker templates: instructions, decision routing or Action tools, with pre-scoped app permissions and often schedules. All optional filters AND; omit to browse. Returns {items,totalCount,page,pageSize}. Cards: slug(kit_get key), name/jobSentence, publisherName/publisherSlug/isOfficialPublisher/verificationTier, apps/categorySlots(installer chooses member), categories/triggerModes, starCount, modelScores(publisher-declared 0-100 fit, best first)/recommendedModel, modelType(language|decision|hybrid|none), isProtected,isFeatured,publishedAt. Protected instruction TEXT is intentionally withheld; kit still works, not a red flag. Empty is not an error; read its footer and directory_overview for valid filters. Human page: https://workerkit.ai/kit/{slug}." + DIRECTORY_NOTE,
129
131
  auth: "anonymous",
130
132
  method: "get",
131
133
  schema: {
@@ -137,7 +139,7 @@ const searchKits = {
137
139
  model: z.string().max(80).optional().describe("Substring match on a scored model name, e.g. 'sonnet' or 'gpt'. Valid names: directory_overview → models."),
138
140
  trigger: z.enum(["onDemand", "scheduled", "event"]).optional().describe("How the kit's worker runs: onDemand (a human or agent triggers it), scheduled (ships recurring schedules), event (webhook-triggered)."),
139
141
  modelType: z.enum(["none", "language", "decision", "hybrid"]).optional().describe("Worker type: none=direct Action tools; language=prose with installer-chosen model; decision=per-item routing without prose/model choice; hybrid=bounded classification then one language agent. Omit for all."),
140
- publisher: z.string().optional().describe("Publisher slug (publisherSlug on any card) — that publisher's kits only."),
142
+ publisher: z.string().optional().describe("Temporarily unavailable: publisher identity is hidden, so every publisher filter returns an empty page. Omit to browse kits."),
141
143
  sort: z.enum(["downloads", "new", "name", "stars"]).default("downloads").describe("downloads = most installed (the popularity signal), new = latest published, name = A-Z, stars = most starred."),
142
144
  page: z.number().int().min(1).default(1).describe("1-based page number."),
143
145
  pageSize: z.number().int().min(1).max(200).default(20).describe("Cards per page (max 200). 20 keeps responses lean; totalCount always reports the full match count."),
@@ -174,7 +176,8 @@ const getKit = {
174
176
  const getPublisher = {
175
177
  name: "publisher_get",
176
178
  title: "Get Publisher",
177
- description: "Inspect a publisher and its published kits for the 'who is behind this?' check. Returns {publisher,kits,pageUrl}. publisher: name,isOfficial(WorkerKit), xHandle(x.com),gitHubHandle(github.com),linkedInUrl,description,createDate(member since),kitCount(published only). kits uses the paginated kits_search card shape, scoped to this publisher. 404:unknown publisher or none currently published." + DIRECTORY_NOTE,
179
+ description: publicPublisherIdentityPause +
180
+ "Inspect a publisher and its published kits for the 'who is behind this?' check. Returns {publisher,kits,pageUrl}. publisher: name,isOfficial(WorkerKit), xHandle(x.com),gitHubHandle(github.com),linkedInUrl,description,createDate(member since),kitCount(published only). kits uses the paginated kits_search card shape, scoped to this publisher. 404:unknown publisher or none currently published." + DIRECTORY_NOTE,
178
181
  auth: "anonymous",
179
182
  method: "get",
180
183
  schema: {
@@ -1 +1 @@
1
- {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/descriptors/directory.ts"],"names":[],"mappings":"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","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\n// The public kits-directory tools: anonymous, read-only catalog tools over the\n// public directory API. Eight tools rather than one per REST endpoint — the about read\n// (what WorkerKit is and when an agent should reach for it), one vocabulary\n// call, one search, one dossier, one publisher profile, and the three authoring\n// reads (the guide, the permission vocabulary an author needs, and the explorer\n// of what each app lets a worker do).\n//\n// The upstream surface is already agent-shaped (always-anonymous, no\n// viewer-scoped fields, opt-in skill-resource bodies, composed overview), so\n// these tools stay thin passthroughs. What lives HERE is the pure half of the\n// presentation an MCP server (or CLI) should not each reinvent:\n// - Empty search results append a broaden-this hint; truncated results append\n// the next page number — the two places agents reliably mis-step.\n// - kit_get / publisher_get carry a computed pageUrl: nothing on an anonymous\n// surface can install, so the agent hands over the link — or, when it holds\n// a manager key with the installKits scope, installs via kit_install_preview\n// / kit_install on the authenticated WorkerKit Manager server.\n\nimport { z } from \"../zod.js\";\nimport { READ_ONLY, type ToolDescriptor } from \"./types.js\";\n\nconst API = \"/api/directory/mcp\";\nconst SITE = \"https://workerkit.ai\";\n\n// ─── Shared phrasing ────────────────────────────────────────────────────────\n\nconst SLUG_HINT = \"The kit's URL slug, as returned by kits_search (slug).\";\n\n// Appended to every tool: the two facts an agent must never get wrong on a\n// public mount — no auth exists, and installing is out of its reach.\nconst DIRECTORY_NOTE =\n \" Public and anonymous, identical for everyone; reads only. Install: signed-in human at pageUrl, or kit_install_preview/kit_install on Manager /workers (installKits).\";\n\n// The two authoring reads share one framing: they are what an agent reads BEFORE\n// writing a kit for the manager surface, and they are anonymous so it can draft\n// before it holds any credential.\nconst AUTHORING_NOTE =\n \" Public and anonymous. On Manager /workers: kit_validate checks all sections, then kit_publish (publishKits). Publish PRIVATE first: only this account can install it via a signed-in human at pageUrl or kit_install, also the create-from-scratch path. Workers need apps connected on their operator (apps_list/app_connect). Add unsupported apps via mcp_server_create (credential), mcp_server_set_tools, then content.mcpServers.\";\n\n// ─── Pure data mappers + footers (presentation data, not ToolResult assembly) ─\n\ntype Json = Record<string, unknown>;\n\nconst SEARCH_EMPTY_HINT =\n \"No kits matched. Filters AND together — drop some. query is a plain case-insensitive substring over name + job sentence (one short word beats a phrase), and unknown category/app/publisher values match nothing rather than erroring. directory_overview lists every valid filter value. If nothing fits after broadening, author a kit for the exact job rather than installing a near miss: kit_authoring_guide (index, then schema and rules) and kit_app_tools here, then kit_validate and kit_publish (private) on the /workers mount, then kit_install.\";\n\n// publisher_get accepts no search filters, so the search hint above would tell an\n// agent to broaden filters it never set. Reachable: the profile 404s only when the\n// publisher has no PUBLISHED kits, while the catalog list additionally excludes\n// taken-down ones — so a publisher whose only published kit was moderated out\n// returns 200 with an empty items array.\nconst PUBLISHER_EMPTY_HINT =\n \"This publisher currently lists no kits (publisher.kitCount can still be non-zero — a published kit can be withheld from the catalog). publisher_get takes no search filters, so there is nothing to broaden; report the profile as-is.\";\n\n/**\n * The one footer a {items, totalCount, page, pageSize} list needs: how to\n * broaden when nothing matched, or which page comes next when truncated.\n */\nexport function listFooter(body: Json, emptyHint: string = SEARCH_EMPTY_HINT): string | undefined {\n const items = Array.isArray(body.items) ? body.items : [];\n const totalCount = typeof body.totalCount === \"number\" ? body.totalCount : items.length;\n const page = typeof body.page === \"number\" ? body.page : 1;\n const pageSize = typeof body.pageSize === \"number\" && body.pageSize > 0 ? body.pageSize : Math.max(items.length, 1);\n if (totalCount === 0) {\n return emptyHint;\n }\n if (page * pageSize < totalCount) {\n return `Showing page ${page} of ${Math.ceil(totalCount / pageSize)} (${totalCount} kits total) — call again with page: ${page + 1} for more`;\n }\n return undefined;\n}\n\n/** kits_search data: the validated list body, or undefined = serve verbatim. */\nexport function kitListData(data: unknown): Json | undefined {\n const body = data as Json | null;\n if (!body || typeof body !== \"object\" || !Array.isArray((body as Json).items)) {\n return undefined; // unexpected shape — serve verbatim rather than guess\n }\n return body;\n}\n\n/** kit_get data: the dossier with the computed pageUrl, or undefined = verbatim. */\nexport function kitDetailData(data: unknown, params: Record<string, unknown>): Json | undefined {\n const body = data as Json | null;\n if (!body || typeof body !== \"object\" || Array.isArray(body)) return undefined;\n\n const detail = { ...body };\n const slug = typeof detail.slug === \"string\" && detail.slug.length > 0 ? detail.slug : String(params.slug ?? \"\");\n detail.pageUrl = `${SITE}/kit/${encodeURIComponent(slug)}`;\n return detail;\n}\n\n/**\n * kit_get footer. Bodies exist upstream but were not requested: each such\n * resource reports a contentLength with no content. A protected kit's resources\n * carry neither (identity-only), so this stays silent there — re-calling would\n * not help.\n */\nexport function kitDetailFooter(data: unknown, params: Record<string, unknown>): string | undefined {\n const detail = data as Json;\n if (params.includeResourceBodies !== true && Array.isArray(detail.skillResources)) {\n const omitted = detail.skillResources.filter(\n (r) =>\n r !== null && typeof r === \"object\" && !Array.isArray(r) &&\n typeof (r as Json).contentLength === \"number\" && ((r as Json).contentLength as number) > 0 &&\n typeof (r as Json).content !== \"string\"\n ).length;\n if (omitted > 0) {\n return `${omitted} skillResources ${omitted === 1 ? \"body\" : \"bodies\"} omitted — call again with includeResourceBodies: true to read them`;\n }\n }\n return undefined;\n}\n\n/** publisher_get data: the profile with the computed pageUrl, or undefined = verbatim. */\nexport function publisherPageData(data: unknown, params: Record<string, unknown>): Json | undefined {\n const body = data as Json | null;\n if (!body || typeof body !== \"object\" || Array.isArray(body)) return undefined;\n\n const page = { ...body };\n const publisher = page.publisher as Json | undefined;\n const slug =\n publisher && typeof publisher.slug === \"string\" && publisher.slug.length > 0\n ? publisher.slug\n : String(params.slug ?? \"\");\n page.pageUrl = `${SITE}/publishers/${encodeURIComponent(slug)}`;\n return page;\n}\n\n/** publisher_get footer: pages the embedded kit list with the publisher-shaped empty hint. */\nexport function publisherPageFooter(data: unknown): string | undefined {\n const page = data as Json;\n const kits = page.kits;\n if (kits && typeof kits === \"object\" && !Array.isArray(kits) && Array.isArray((kits as Json).items)) {\n return listFooter(kits as Json, PUBLISHER_EMPTY_HINT);\n }\n return undefined;\n}\n\n// ─── Tools ──────────────────────────────────────────────────────────────────\n\nconst directoryOverview: ToolDescriptor = {\n name: \"directory_overview\",\n title: \"Directory Overview\",\n description:\n \"Read directory vocabulary before choosing kits_search filters. kitCount counts published kits; categories.jobFamilies/roles/industries supplies slug/name for category/industry. apps code/name/categoryCode/installable supplies app (installable:false can appear in kits but cannot be installed). appCategories code/name/members[{code,name,appCode}] supplies appCategory and installer choices (e.g. Slack/Teams). models model/normalized/kitCount supplies model (normalized or substring). modelTypes code/name/summary supplies none(Action)|language|decision|hybrid. Also sortOptions/triggerModes. No kits here: for popularity use kits_search's default downloads sort. Human pages: https://workerkit.ai/kit/{slug}.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {},\n path: `${API}/overview`,\n annotations: READ_ONLY,\n};\n\nconst searchKits: ToolDescriptor = {\n name: \"kits_search\",\n title: \"Search Kits\",\n description:\n \"Search public worker templates: instructions, decision routing or Action tools, with pre-scoped app permissions and often schedules. All optional filters AND; omit to browse. Returns {items,totalCount,page,pageSize}. Cards: slug(kit_get key), name/jobSentence, publisherName/publisherSlug/isOfficialPublisher/verificationTier, apps/categorySlots(installer chooses member), categories/triggerModes, starCount, modelScores(publisher-declared 0-100 fit, best first)/recommendedModel, modelType(language|decision|hybrid|none), isProtected,isFeatured,publishedAt. Protected instruction TEXT is intentionally withheld; kit still works, not a red flag. Empty is not an error; read its footer and directory_overview for valid filters. Human page: https://workerkit.ai/kit/{slug}.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n query: z.string().max(200).optional().describe(\n \"Free-text search: case-insensitive SUBSTRING match over kit name + job sentence — not keyword or semantic search, so one short stem ('invoice') beats a phrase ('help with my invoices'). Omit to browse by filters alone.\"\n ),\n category: z.string().optional().describe(\n \"Job-category slug (any kind — job family, role, or industry). Valid slugs: directory_overview → categories. Unknown slugs match nothing.\"\n ),\n industry: z.string().optional().describe(\n \"Industry-kind category slug ONLY (a role/job-family slug here matches nothing). ANDs with category.\"\n ),\n app: z.string().optional().describe(\n \"Exact app code the kit must use, e.g. 'email', 'slack', 'crm'. Valid codes: directory_overview → apps.\"\n ),\n appCategory: z.string().optional().describe(\n \"Capability category from directory_overview.appCategories: matches an install slot OR a pinned member app, broader than app. Unknown code errors with the fix.\"\n ),\n model: z.string().max(80).optional().describe(\n \"Substring match on a scored model name, e.g. 'sonnet' or 'gpt'. Valid names: directory_overview → models.\"\n ),\n trigger: z.enum([\"onDemand\", \"scheduled\", \"event\"]).optional().describe(\n \"How the kit's worker runs: onDemand (a human or agent triggers it), scheduled (ships recurring schedules), event (webhook-triggered).\"\n ),\n modelType: z.enum([\"none\", \"language\", \"decision\", \"hybrid\"]).optional().describe(\n \"Worker type: none=direct Action tools; language=prose with installer-chosen model; decision=per-item routing without prose/model choice; hybrid=bounded classification then one language agent. Omit for all.\"\n ),\n publisher: z.string().optional().describe(\"Publisher slug (publisherSlug on any card) — that publisher's kits only.\"),\n sort: z.enum([\"downloads\", \"new\", \"name\", \"stars\"]).default(\"downloads\").describe(\n \"downloads = most installed (the popularity signal), new = latest published, name = A-Z, stars = most starred.\"\n ),\n page: z.number().int().min(1).default(1).describe(\"1-based page number.\"),\n pageSize: z.number().int().min(1).max(200).default(20).describe(\n \"Cards per page (max 200). 20 keeps responses lean; totalCount always reports the full match count.\"\n ),\n },\n path: `${API}/kits`,\n paramFilter: (params) => {\n // The wire param is `q`; `query` is the agent-facing name.\n const { query, ...rest } = params;\n return { ...rest, q: query };\n },\n annotations: READ_ONLY,\n mapData: (data) => kitListData(data),\n footer: (data) => listFooter(data as Json),\n};\n\nconst getKit: ToolDescriptor = {\n name: \"kit_get\",\n title: \"Get Kit\",\n description:\n \"Inspect a kit before installation: description/appDescriptions (author app/tool notes), modelType, exact permissions, content and setup. none exposes actionSpec without a model; hybrid combines prose/classification; language is default. instructionContent is verbatim prose, empty if isProtected while instructionLength remains real; protected startCommand/endCommand/whenToUse are null, indistinguishable from absent. For decision, evaluate decisionNarration (sources/questions/routes/confidence fallback, also served when protected) and decisionSetup. permissionsManifest is EXACT installed access: operations/fields/scopes; numeric values are authoritative, names display-only; its workerSlots name other workers the kit calls, bound explicitly at install. Summarize this for access questions. requiredInputs/memorySetup is the install form. memoryProfile stateless omits recent-run summaries, contextual includes bounded summaries; owner rules/injected facts apply to both. selfFactsEnabled permits unreviewed recall-only saves that later runs must search to use. Also schedules/triggers/usageWindows, modelScores with notes/starCount/pageUrl. skillResources always has key/kind/name; description/contentLength withheld when protected; includeResourceBodies fetches bodies. Surface hasExternalMcpShells when recommending: install creates account gateways to publisher URLs in permissionsManifest.mcpServers.shells. scan.outcome cleared|underReview are BOTH live/installable; underReview is an unsettled raised check, not unsafe. scannedAtUtc:null means pre-scanner publication. checks lists families run; static-only cleared is weaker than all three. Attribute recommendation safe|caution|doNotInstall to SkillSpector; independent of outcome and may disagree. caution means worth reviewing, including incomplete analysis. scan is absent with nothing to report, never includes findings. 404:no published kit for slug.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n slug: z.string().min(1).describe(SLUG_HINT),\n includeResourceBodies: z.boolean().default(false).describe(\n \"true = include each skill resource's full text (can be up to 20k chars each). Default false returns key/kind/name/description/contentLength — enough to describe the kit; fetch bodies only when their content is the question.\"\n ),\n },\n path: (params) => `${API}/kits/${encodeURIComponent(String(params.slug))}`,\n paramFilter: (params) => {\n const { slug: _slug, ...queryParams } = params;\n return queryParams;\n },\n annotations: READ_ONLY,\n mapData: kitDetailData,\n footer: kitDetailFooter,\n};\n\nconst getPublisher: ToolDescriptor = {\n name: \"publisher_get\",\n title: \"Get Publisher\",\n description:\n \"Inspect a publisher and its published kits for the 'who is behind this?' check. Returns {publisher,kits,pageUrl}. publisher: name,isOfficial(WorkerKit), xHandle(x.com),gitHubHandle(github.com),linkedInUrl,description,createDate(member since),kitCount(published only). kits uses the paginated kits_search card shape, scoped to this publisher. 404:unknown publisher or none currently published.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n slug: z.string().min(1).describe(\"The publisher's slug, as returned on any kit card (publisherSlug).\"),\n sort: z.enum([\"downloads\", \"new\", \"name\", \"stars\"]).default(\"downloads\").describe(\"Sort for the publisher's kit list.\"),\n page: z.number().int().min(1).default(1).describe(\"1-based page of the publisher's kit list.\"),\n pageSize: z.number().int().min(1).max(200).default(20).describe(\"Kits per page (max 200).\"),\n },\n path: (params) => `${API}/publishers/${encodeURIComponent(String(params.slug))}`,\n paramFilter: (params) => {\n const { slug: _slug, ...queryParams } = params;\n return queryParams;\n },\n annotations: READ_ONLY,\n mapData: publisherPageData,\n footer: (data) => publisherPageFooter(data),\n};\n\n// ─── Authoring reads ────────────────────────────────────────────────────────\n\nconst GUIDE_SECTIONS = [\"index\", \"decision\", \"schema\", \"rules\", \"skill\", \"state\", \"slots\", \"workers\", \"instruction\", \"example\", \"selfcheck\"] as const;\n\nconst kitAuthoringGuide: ToolDescriptor = {\n name: \"kit_authoring_guide\",\n title: \"Kit Authoring Guide\",\n description:\n \"Read kit authoring guidance one Markdown section at a time, with table of contents. Classification/scoring/filtering/triage: decision has recipes, typed questions, creation examples/results. Action(modelType none): index/schema; quickest create path is action_worker_options then action_worker_create on Manager. Full kit authoring: index, then schema/rules; state covers Records, memory and context hygiene; workers covers kits that call other workers (workerSlots, bindings, waiting, receipts); fetch other sections as needed. Unknown section:400 with valid names. Live sources:kit_app_tools; exact permission keys:kit_vocabulary. On Manager /workers, kit_validate the exact body then kit_publish (publishKits). Publish private, install and prove a run (Action:tool call) before public promotion with kit_replace.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n section: z.enum(GUIDE_SECTIONS).default(\"index\").describe(\n \"Which section to read. index (default) is the table of contents plus how to use the guide; schema and rules are the two an author cannot skip; workers is required before declaring workerSlots.\"\n ),\n },\n path: `${API}/authoring/guide`,\n annotations: READ_ONLY,\n};\n\nconst kitVocabulary: ToolDescriptor = {\n name: \"kit_vocabulary\",\n title: \"Kit Authoring Vocabulary\",\n description:\n \"Read the exact live keys before writing content.apps/categorySlots/categorySlugs; strict validation, no 'all' shorthand. Without app: apps[] code/name/summary, operations(tool KEYS), fields, supported axes(readOperations,masterAccessLevels,writableFields,providers,channels,objectTypes,scopePolicies,contentTypeScopes,capabilities,supportsAllowAll,supportsWriteEnabled,subApps,installable); concreteApps[] vendor tiles with standalone|provider|slotMember|subApp kind and content mapping; appCategories[] members/labelAlias/genericName; categories.jobFamilies/roles/industries(the valid categorySlugs); models; mcpApps(id=gatewayId,tools[].toolId=toolIds); note. Own MCP servers: mcp_servers_list on Manager. With app: {app,vendors,tools,note}; tools describes installed-worker tools: name(use in prose),description,readOnly,argsSchema,decisionSource result mapping where known,requires(grant one listed operations key). toolsNote replaces an unavailable catalog. Full response is large: read once/task, then per-app; kit_app_tools explores all app capabilities in one call. Unknown app:400 with valid codes.\" + AUTHORING_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n app: z.string().max(40).optional().describe(\n \"One app code (from apps[].code) to read just that surface with its vendors and tools. Omit for the whole vocabulary.\"\n ),\n },\n path: `${API}/authoring/vocabulary`,\n annotations: READ_ONLY,\n};\n\nconst kitAppTools: ToolDescriptor = {\n name: \"kit_app_tools\",\n title: \"Kit App Tools\",\n description:\n \"Discover app tool capabilities. purpose:decision returns convenience source recipes, evidence fields, argument schemas, read permissions, limits and editable decision_worker_create examples; app narrows email/calendar/drive recipes. Public capability data only; apps_list checks account connections. Without purpose: apps[] in catalog order with operations and tools[{name,title,description,readOnly,argsSchema,decisionSource,requires,provider,scope,hosted}]. requires grants one listed operations key; absent means the tool comes with the app. provider pins a vendor, scope a Drive content family; hosted:false excludes hosted runs. toolsNote replaces unavailable catalogs. Platform MCP tools:kit_vocabulary.mcpApps; unsupported apps:mcp_server_create. Unknown app:400 with valid codes. Responses are cacheable public capability data; connectionStatus:not_checked is not live authorization. Recipes are not an allowlist: arbitrary sources/routed actions use the general catalog, argsSchema/result mapping, then kit_validate -> kit_publish(private) -> kit_install. Validation checks structure/grants, not live access. Action tool selection: action_worker_options. Detailed permission axes:kit_vocabulary.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n purpose: z.enum([\"decision\"]).optional().describe(\"Supported classification source recipes, with schemas and creation examples.\"),\n app: z.string().max(40).optional().describe(\n \"One app code to read just that app's tools. Omit for every app.\"\n ),\n },\n path: `${API}/authoring/tools`,\n annotations: READ_ONLY,\n};\n\n// ─── About ──────────────────────────────────────────────────────────────────\n//\n// The one read that is not about kits: what WorkerKit is and when an agent\n// should reach for it, written for the agent. First in the registry on purpose:\n// a model reads tools/list top-down, and this is the tool that tells it whether\n// the rest of the list applies to the request in front of it.\n\nconst ABOUT_SECTIONS = [\"index\", \"why\", \"operate\", \"access\", \"cost\", \"start\"] as const;\n\nconst workerkitAbout: ToolDescriptor = {\n name: \"workerkit_about\",\n title: \"About WorkerKit\",\n description:\n \"Read what WorkerKit does and when to use it: index/why/operate/access/cost/start. Workers classify, score, triage, monitor and run jobs with app grants, budgets and receipts. Action(modelType none) exposes tools without a model: action_worker_options/create then worker_tool_call. For custom classification: kit_app_tools(purpose:decision), kit_authoring_guide(section:decision), decision_worker_create. Reuse templates via kits_search(modelType:decision); key_info shows account scopes.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n section: z.enum(ABOUT_SECTIONS).default(\"index\").describe(\n \"Which section to read. index (default) is the one-read summary plus the table of contents; why and start are the two to read before recommending WorkerKit to a user.\"\n ),\n },\n path: `${API}/about`,\n annotations: READ_ONLY,\n};\n\n// ─── Registry ───────────────────────────────────────────────────────────────\n\nexport const directoryDescriptors: readonly ToolDescriptor[] = [\n workerkitAbout,\n directoryOverview,\n searchKits,\n getKit,\n getPublisher,\n kitAuthoringGuide,\n kitVocabulary,\n kitAppTools,\n];\n"]}
1
+ {"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/descriptors/directory.ts"],"names":[],"mappings":"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","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\n// The public kits-directory tools: anonymous, read-only catalog tools over the\n// public directory API. Eight tools rather than one per REST endpoint — the about read\n// (what WorkerKit is and when an agent should reach for it), one vocabulary\n// call, one search, one dossier, one publisher profile, and the three authoring\n// reads (the guide, the permission vocabulary an author needs, and the explorer\n// of what each app lets a worker do).\n//\n// The upstream surface is already agent-shaped (always-anonymous, no\n// viewer-scoped fields, opt-in skill-resource bodies, composed overview), so\n// these tools stay thin passthroughs. What lives HERE is the pure half of the\n// presentation an MCP server (or CLI) should not each reinvent:\n// - Empty search results append a broaden-this hint; truncated results append\n// the next page number — the two places agents reliably mis-step.\n// - kit_get / publisher_get carry a computed pageUrl: nothing on an anonymous\n// surface can install, so the agent hands over the link — or, when it holds\n// a manager key with the installKits scope, installs via kit_install_preview\n// / kit_install on the authenticated WorkerKit Manager server.\n\nimport { z } from \"../zod.js\";\nimport { READ_ONLY, type ToolDescriptor } from \"./types.js\";\nimport { publicPublisherIdentityPause } from \"../guidance.js\";\n\nconst API = \"/api/directory/mcp\";\nconst SITE = \"https://workerkit.ai\";\n\n// ─── Shared phrasing ────────────────────────────────────────────────────────\n\nconst SLUG_HINT = \"The kit's URL slug, as returned by kits_search (slug).\";\n\n// Appended to every tool: the two facts an agent must never get wrong on a\n// public mount — no auth exists, and installing is out of its reach.\nconst DIRECTORY_NOTE =\n \" Public and anonymous, identical for everyone; reads only. Install: signed-in human at pageUrl, or kit_install_preview/kit_install on Manager /workers (installKits).\";\n\n// The two authoring reads share one framing: they are what an agent reads BEFORE\n// writing a kit for the manager surface, and they are anonymous so it can draft\n// before it holds any credential.\nconst AUTHORING_NOTE =\n \" Public and anonymous. On Manager /workers: kit_validate checks all sections, then kit_publish (publishKits). Publish PRIVATE first: only this account can install it via a signed-in human at pageUrl or kit_install, also the create-from-scratch path. Workers need apps connected on their operator (apps_list/app_connect). Add unsupported apps via mcp_server_create (credential), mcp_server_set_tools, then content.mcpServers.\";\n\n// ─── Pure data mappers + footers (presentation data, not ToolResult assembly) ─\n\ntype Json = Record<string, unknown>;\n\nconst SEARCH_EMPTY_HINT =\n \"No kits matched. Filters AND together — drop some. query is a plain case-insensitive substring over name + job sentence (one short word beats a phrase), and unknown category/app/publisher values match nothing rather than erroring. directory_overview lists every valid filter value. If nothing fits after broadening, author a kit for the exact job rather than installing a near miss: kit_authoring_guide (index, then schema and rules) and kit_app_tools here, then kit_validate and kit_publish (private) on the /workers mount, then kit_install.\";\n\n// publisher_get accepts no search filters, so the search hint above would tell an\n// agent to broaden filters it never set. Reachable: the profile 404s only when the\n// publisher has no PUBLISHED kits, while the catalog list additionally excludes\n// taken-down ones — so a publisher whose only published kit was moderated out\n// returns 200 with an empty items array.\nconst PUBLISHER_EMPTY_HINT =\n \"This publisher currently lists no kits (publisher.kitCount can still be non-zero — a published kit can be withheld from the catalog). publisher_get takes no search filters, so there is nothing to broaden; report the profile as-is.\";\n\n/**\n * The one footer a {items, totalCount, page, pageSize} list needs: how to\n * broaden when nothing matched, or which page comes next when truncated.\n */\nexport function listFooter(body: Json, emptyHint: string = SEARCH_EMPTY_HINT): string | undefined {\n const items = Array.isArray(body.items) ? body.items : [];\n const totalCount = typeof body.totalCount === \"number\" ? body.totalCount : items.length;\n const page = typeof body.page === \"number\" ? body.page : 1;\n const pageSize = typeof body.pageSize === \"number\" && body.pageSize > 0 ? body.pageSize : Math.max(items.length, 1);\n if (totalCount === 0) {\n return emptyHint;\n }\n if (page * pageSize < totalCount) {\n return `Showing page ${page} of ${Math.ceil(totalCount / pageSize)} (${totalCount} kits total) — call again with page: ${page + 1} for more`;\n }\n return undefined;\n}\n\n/** kits_search data: the validated list body, or undefined = serve verbatim. */\nexport function kitListData(data: unknown): Json | undefined {\n const body = data as Json | null;\n if (!body || typeof body !== \"object\" || !Array.isArray((body as Json).items)) {\n return undefined; // unexpected shape — serve verbatim rather than guess\n }\n return body;\n}\n\n/** kit_get data: the dossier with the computed pageUrl, or undefined = verbatim. */\nexport function kitDetailData(data: unknown, params: Record<string, unknown>): Json | undefined {\n const body = data as Json | null;\n if (!body || typeof body !== \"object\" || Array.isArray(body)) return undefined;\n\n const detail = { ...body };\n const slug = typeof detail.slug === \"string\" && detail.slug.length > 0 ? detail.slug : String(params.slug ?? \"\");\n detail.pageUrl = `${SITE}/kit/${encodeURIComponent(slug)}`;\n return detail;\n}\n\n/**\n * kit_get footer. Bodies exist upstream but were not requested: each such\n * resource reports a contentLength with no content. A protected kit's resources\n * carry neither (identity-only), so this stays silent there — re-calling would\n * not help.\n */\nexport function kitDetailFooter(data: unknown, params: Record<string, unknown>): string | undefined {\n const detail = data as Json;\n if (params.includeResourceBodies !== true && Array.isArray(detail.skillResources)) {\n const omitted = detail.skillResources.filter(\n (r) =>\n r !== null && typeof r === \"object\" && !Array.isArray(r) &&\n typeof (r as Json).contentLength === \"number\" && ((r as Json).contentLength as number) > 0 &&\n typeof (r as Json).content !== \"string\"\n ).length;\n if (omitted > 0) {\n return `${omitted} skillResources ${omitted === 1 ? \"body\" : \"bodies\"} omitted — call again with includeResourceBodies: true to read them`;\n }\n }\n return undefined;\n}\n\n/** publisher_get data: the profile with the computed pageUrl, or undefined = verbatim. */\nexport function publisherPageData(data: unknown, params: Record<string, unknown>): Json | undefined {\n const body = data as Json | null;\n if (!body || typeof body !== \"object\" || Array.isArray(body)) return undefined;\n\n const page = { ...body };\n const publisher = page.publisher as Json | undefined;\n const slug =\n publisher && typeof publisher.slug === \"string\" && publisher.slug.length > 0\n ? publisher.slug\n : String(params.slug ?? \"\");\n page.pageUrl = `${SITE}/publishers/${encodeURIComponent(slug)}`;\n return page;\n}\n\n/** publisher_get footer: pages the embedded kit list with the publisher-shaped empty hint. */\nexport function publisherPageFooter(data: unknown): string | undefined {\n const page = data as Json;\n const kits = page.kits;\n if (kits && typeof kits === \"object\" && !Array.isArray(kits) && Array.isArray((kits as Json).items)) {\n return listFooter(kits as Json, PUBLISHER_EMPTY_HINT);\n }\n return undefined;\n}\n\n// ─── Tools ──────────────────────────────────────────────────────────────────\n\nconst directoryOverview: ToolDescriptor = {\n name: \"directory_overview\",\n title: \"Directory Overview\",\n description:\n \"Read directory vocabulary before choosing kits_search filters. kitCount counts published kits; categories.jobFamilies/roles/industries supplies slug/name for category/industry. apps code/name/categoryCode/installable supplies app (installable:false can appear in kits but cannot be installed). appCategories code/name/members[{code,name,appCode}] supplies appCategory and installer choices (e.g. Slack/Teams). models model/normalized/kitCount supplies model (normalized or substring). modelTypes code/name/summary supplies none(Action)|language|decision|hybrid. Also sortOptions/triggerModes. No kits here: for popularity use kits_search's default downloads sort. Human pages: https://workerkit.ai/kit/{slug}.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {},\n path: `${API}/overview`,\n annotations: READ_ONLY,\n};\n\nconst searchKits: ToolDescriptor = {\n name: \"kits_search\",\n title: \"Search Kits\",\n description:\n publicPublisherIdentityPause +\n \"Search public worker templates: instructions, decision routing or Action tools, with pre-scoped app permissions and often schedules. All optional filters AND; omit to browse. Returns {items,totalCount,page,pageSize}. Cards: slug(kit_get key), name/jobSentence, publisherName/publisherSlug/isOfficialPublisher/verificationTier, apps/categorySlots(installer chooses member), categories/triggerModes, starCount, modelScores(publisher-declared 0-100 fit, best first)/recommendedModel, modelType(language|decision|hybrid|none), isProtected,isFeatured,publishedAt. Protected instruction TEXT is intentionally withheld; kit still works, not a red flag. Empty is not an error; read its footer and directory_overview for valid filters. Human page: https://workerkit.ai/kit/{slug}.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n query: z.string().max(200).optional().describe(\n \"Free-text search: case-insensitive SUBSTRING match over kit name + job sentence — not keyword or semantic search, so one short stem ('invoice') beats a phrase ('help with my invoices'). Omit to browse by filters alone.\"\n ),\n category: z.string().optional().describe(\n \"Job-category slug (any kind — job family, role, or industry). Valid slugs: directory_overview → categories. Unknown slugs match nothing.\"\n ),\n industry: z.string().optional().describe(\n \"Industry-kind category slug ONLY (a role/job-family slug here matches nothing). ANDs with category.\"\n ),\n app: z.string().optional().describe(\n \"Exact app code the kit must use, e.g. 'email', 'slack', 'crm'. Valid codes: directory_overview → apps.\"\n ),\n appCategory: z.string().optional().describe(\n \"Capability category from directory_overview.appCategories: matches an install slot OR a pinned member app, broader than app. Unknown code errors with the fix.\"\n ),\n model: z.string().max(80).optional().describe(\n \"Substring match on a scored model name, e.g. 'sonnet' or 'gpt'. Valid names: directory_overview → models.\"\n ),\n trigger: z.enum([\"onDemand\", \"scheduled\", \"event\"]).optional().describe(\n \"How the kit's worker runs: onDemand (a human or agent triggers it), scheduled (ships recurring schedules), event (webhook-triggered).\"\n ),\n modelType: z.enum([\"none\", \"language\", \"decision\", \"hybrid\"]).optional().describe(\n \"Worker type: none=direct Action tools; language=prose with installer-chosen model; decision=per-item routing without prose/model choice; hybrid=bounded classification then one language agent. Omit for all.\"\n ),\n publisher: z.string().optional().describe(\"Temporarily unavailable: publisher identity is hidden, so every publisher filter returns an empty page. Omit to browse kits.\"),\n sort: z.enum([\"downloads\", \"new\", \"name\", \"stars\"]).default(\"downloads\").describe(\n \"downloads = most installed (the popularity signal), new = latest published, name = A-Z, stars = most starred.\"\n ),\n page: z.number().int().min(1).default(1).describe(\"1-based page number.\"),\n pageSize: z.number().int().min(1).max(200).default(20).describe(\n \"Cards per page (max 200). 20 keeps responses lean; totalCount always reports the full match count.\"\n ),\n },\n path: `${API}/kits`,\n paramFilter: (params) => {\n // The wire param is `q`; `query` is the agent-facing name.\n const { query, ...rest } = params;\n return { ...rest, q: query };\n },\n annotations: READ_ONLY,\n mapData: (data) => kitListData(data),\n footer: (data) => listFooter(data as Json),\n};\n\nconst getKit: ToolDescriptor = {\n name: \"kit_get\",\n title: \"Get Kit\",\n description:\n \"Inspect a kit before installation: description/appDescriptions (author app/tool notes), modelType, exact permissions, content and setup. none exposes actionSpec without a model; hybrid combines prose/classification; language is default. instructionContent is verbatim prose, empty if isProtected while instructionLength remains real; protected startCommand/endCommand/whenToUse are null, indistinguishable from absent. For decision, evaluate decisionNarration (sources/questions/routes/confidence fallback, also served when protected) and decisionSetup. permissionsManifest is EXACT installed access: operations/fields/scopes; numeric values are authoritative, names display-only; its workerSlots name other workers the kit calls, bound explicitly at install. Summarize this for access questions. requiredInputs/memorySetup is the install form. memoryProfile stateless omits recent-run summaries, contextual includes bounded summaries; owner rules/injected facts apply to both. selfFactsEnabled permits unreviewed recall-only saves that later runs must search to use. Also schedules/triggers/usageWindows, modelScores with notes/starCount/pageUrl. skillResources always has key/kind/name; description/contentLength withheld when protected; includeResourceBodies fetches bodies. Surface hasExternalMcpShells when recommending: install creates account gateways to publisher URLs in permissionsManifest.mcpServers.shells. scan.outcome cleared|underReview are BOTH live/installable; underReview is an unsettled raised check, not unsafe. scannedAtUtc:null means pre-scanner publication. checks lists families run; static-only cleared is weaker than all three. Attribute recommendation safe|caution|doNotInstall to SkillSpector; independent of outcome and may disagree. caution means worth reviewing, including incomplete analysis. scan is absent with nothing to report, never includes findings. 404:no published kit for slug.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n slug: z.string().min(1).describe(SLUG_HINT),\n includeResourceBodies: z.boolean().default(false).describe(\n \"true = include each skill resource's full text (can be up to 20k chars each). Default false returns key/kind/name/description/contentLength — enough to describe the kit; fetch bodies only when their content is the question.\"\n ),\n },\n path: (params) => `${API}/kits/${encodeURIComponent(String(params.slug))}`,\n paramFilter: (params) => {\n const { slug: _slug, ...queryParams } = params;\n return queryParams;\n },\n annotations: READ_ONLY,\n mapData: kitDetailData,\n footer: kitDetailFooter,\n};\n\nconst getPublisher: ToolDescriptor = {\n name: \"publisher_get\",\n title: \"Get Publisher\",\n description:\n publicPublisherIdentityPause +\n \"Inspect a publisher and its published kits for the 'who is behind this?' check. Returns {publisher,kits,pageUrl}. publisher: name,isOfficial(WorkerKit), xHandle(x.com),gitHubHandle(github.com),linkedInUrl,description,createDate(member since),kitCount(published only). kits uses the paginated kits_search card shape, scoped to this publisher. 404:unknown publisher or none currently published.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n slug: z.string().min(1).describe(\"The publisher's slug, as returned on any kit card (publisherSlug).\"),\n sort: z.enum([\"downloads\", \"new\", \"name\", \"stars\"]).default(\"downloads\").describe(\"Sort for the publisher's kit list.\"),\n page: z.number().int().min(1).default(1).describe(\"1-based page of the publisher's kit list.\"),\n pageSize: z.number().int().min(1).max(200).default(20).describe(\"Kits per page (max 200).\"),\n },\n path: (params) => `${API}/publishers/${encodeURIComponent(String(params.slug))}`,\n paramFilter: (params) => {\n const { slug: _slug, ...queryParams } = params;\n return queryParams;\n },\n annotations: READ_ONLY,\n mapData: publisherPageData,\n footer: (data) => publisherPageFooter(data),\n};\n\n// ─── Authoring reads ────────────────────────────────────────────────────────\n\nconst GUIDE_SECTIONS = [\"index\", \"decision\", \"schema\", \"rules\", \"skill\", \"state\", \"slots\", \"workers\", \"instruction\", \"example\", \"selfcheck\"] as const;\n\nconst kitAuthoringGuide: ToolDescriptor = {\n name: \"kit_authoring_guide\",\n title: \"Kit Authoring Guide\",\n description:\n \"Read kit authoring guidance one Markdown section at a time, with table of contents. Classification/scoring/filtering/triage: decision has recipes, typed questions, creation examples/results. Action(modelType none): index/schema; quickest create path is action_worker_options then action_worker_create on Manager. Full kit authoring: index, then schema/rules; state covers Records, memory and context hygiene; workers covers kits that call other workers (workerSlots, bindings, waiting, receipts); fetch other sections as needed. Unknown section:400 with valid names. Live sources:kit_app_tools; exact permission keys:kit_vocabulary. On Manager /workers, kit_validate the exact body then kit_publish (publishKits). Publish private, install and prove a run (Action:tool call) before public promotion with kit_replace.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n section: z.enum(GUIDE_SECTIONS).default(\"index\").describe(\n \"Which section to read. index (default) is the table of contents plus how to use the guide; schema and rules are the two an author cannot skip; workers is required before declaring workerSlots.\"\n ),\n },\n path: `${API}/authoring/guide`,\n annotations: READ_ONLY,\n};\n\nconst kitVocabulary: ToolDescriptor = {\n name: \"kit_vocabulary\",\n title: \"Kit Authoring Vocabulary\",\n description:\n \"Read the exact live keys before writing content.apps/categorySlots/categorySlugs; strict validation, no 'all' shorthand. Without app: apps[] code/name/summary, operations(tool KEYS), fields, supported axes(readOperations,masterAccessLevels,writableFields,providers,channels,objectTypes,scopePolicies,contentTypeScopes,capabilities,supportsAllowAll,supportsWriteEnabled,subApps,installable); concreteApps[] vendor tiles with standalone|provider|slotMember|subApp kind and content mapping; appCategories[] members/labelAlias/genericName; categories.jobFamilies/roles/industries(the valid categorySlugs); models; mcpApps(id=gatewayId,tools[].toolId=toolIds); note. Own MCP servers: mcp_servers_list on Manager. With app: {app,vendors,tools,note}; tools describes installed-worker tools: name(use in prose),description,readOnly,argsSchema,decisionSource result mapping where known,requires(grant one listed operations key). toolsNote replaces an unavailable catalog. Full response is large: read once/task, then per-app; kit_app_tools explores all app capabilities in one call. Unknown app:400 with valid codes.\" + AUTHORING_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n app: z.string().max(40).optional().describe(\n \"One app code (from apps[].code) to read just that surface with its vendors and tools. Omit for the whole vocabulary.\"\n ),\n },\n path: `${API}/authoring/vocabulary`,\n annotations: READ_ONLY,\n};\n\nconst kitAppTools: ToolDescriptor = {\n name: \"kit_app_tools\",\n title: \"Kit App Tools\",\n description:\n \"Discover app tool capabilities. purpose:decision returns convenience source recipes, evidence fields, argument schemas, read permissions, limits and editable decision_worker_create examples; app narrows email/calendar/drive recipes. Public capability data only; apps_list checks account connections. Without purpose: apps[] in catalog order with operations and tools[{name,title,description,readOnly,argsSchema,decisionSource,requires,provider,scope,hosted}]. requires grants one listed operations key; absent means the tool comes with the app. provider pins a vendor, scope a Drive content family; hosted:false excludes hosted runs. toolsNote replaces unavailable catalogs. Platform MCP tools:kit_vocabulary.mcpApps; unsupported apps:mcp_server_create. Unknown app:400 with valid codes. Responses are cacheable public capability data; connectionStatus:not_checked is not live authorization. Recipes are not an allowlist: arbitrary sources/routed actions use the general catalog, argsSchema/result mapping, then kit_validate -> kit_publish(private) -> kit_install. Validation checks structure/grants, not live access. Action tool selection: action_worker_options. Detailed permission axes:kit_vocabulary.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n purpose: z.enum([\"decision\"]).optional().describe(\"Supported classification source recipes, with schemas and creation examples.\"),\n app: z.string().max(40).optional().describe(\n \"One app code to read just that app's tools. Omit for every app.\"\n ),\n },\n path: `${API}/authoring/tools`,\n annotations: READ_ONLY,\n};\n\n// ─── About ──────────────────────────────────────────────────────────────────\n//\n// The one read that is not about kits: what WorkerKit is and when an agent\n// should reach for it, written for the agent. First in the registry on purpose:\n// a model reads tools/list top-down, and this is the tool that tells it whether\n// the rest of the list applies to the request in front of it.\n\nconst ABOUT_SECTIONS = [\"index\", \"why\", \"operate\", \"access\", \"cost\", \"start\"] as const;\n\nconst workerkitAbout: ToolDescriptor = {\n name: \"workerkit_about\",\n title: \"About WorkerKit\",\n description:\n \"Read what WorkerKit does and when to use it: index/why/operate/access/cost/start. Workers classify, score, triage, monitor and run jobs with app grants, budgets and receipts. Action(modelType none) exposes tools without a model: action_worker_options/create then worker_tool_call. For custom classification: kit_app_tools(purpose:decision), kit_authoring_guide(section:decision), decision_worker_create. Reuse templates via kits_search(modelType:decision); key_info shows account scopes.\" + DIRECTORY_NOTE,\n auth: \"anonymous\",\n method: \"get\",\n schema: {\n section: z.enum(ABOUT_SECTIONS).default(\"index\").describe(\n \"Which section to read. index (default) is the one-read summary plus the table of contents; why and start are the two to read before recommending WorkerKit to a user.\"\n ),\n },\n path: `${API}/about`,\n annotations: READ_ONLY,\n};\n\n// ─── Registry ───────────────────────────────────────────────────────────────\n\nexport const directoryDescriptors: readonly ToolDescriptor[] = [\n workerkitAbout,\n directoryOverview,\n searchKits,\n getKit,\n getPublisher,\n kitAuthoringGuide,\n kitVocabulary,\n kitAppTools,\n];\n"]}
@@ -3,7 +3,7 @@ export type { HttpMethod, ToolAnnotations, ToolDescriptor } from "./types.js";
3
3
  export { manageDescriptors } from "./manage.js";
4
4
  export { directoryDescriptors, kitDetailData, kitDetailFooter, kitListData, listFooter, publisherPageData, publisherPageFooter, } from "./directory.js";
5
5
  import type { ToolDescriptor } from "./types.js";
6
- /** Every descriptor this package ships — 100 manager + 8 anonymous. */
6
+ /** Every descriptor this package ships: the manager tools, then the anonymous directory tools. */
7
7
  export declare const allDescriptors: readonly ToolDescriptor[];
8
8
  /** Look a descriptor up by its tool name. */
9
9
  export declare function byName(name: string): ToolDescriptor | undefined;
@@ -4,7 +4,7 @@ export { manageDescriptors } from "./manage.js";
4
4
  export { directoryDescriptors, kitDetailData, kitDetailFooter, kitListData, listFooter, publisherPageData, publisherPageFooter, } from "./directory.js";
5
5
  import { manageDescriptors } from "./manage.js";
6
6
  import { directoryDescriptors } from "./directory.js";
7
- /** Every descriptor this package ships — 100 manager + 8 anonymous. */
7
+ /** Every descriptor this package ships: the manager tools, then the anonymous directory tools. */
8
8
  export const allDescriptors = [
9
9
  ...manageDescriptors,
10
10
  ...directoryDescriptors,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,OAAO,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,uEAAuE;AACvE,MAAM,CAAC,MAAM,cAAc,GAA8B;IACvD,GAAG,iBAAiB;IACpB,GAAG,oBAAoB;CACxB,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\nexport {\n CREATE,\n DELETE,\n READ_ONLY,\n TRIGGER,\n UPDATE,\n} from \"./types.js\";\nexport type { HttpMethod, ToolAnnotations, ToolDescriptor } from \"./types.js\";\n\nexport { manageDescriptors } from \"./manage.js\";\nexport {\n directoryDescriptors,\n kitDetailData,\n kitDetailFooter,\n kitListData,\n listFooter,\n publisherPageData,\n publisherPageFooter,\n} from \"./directory.js\";\n\nimport type { ToolDescriptor } from \"./types.js\";\nimport { manageDescriptors } from \"./manage.js\";\nimport { directoryDescriptors } from \"./directory.js\";\n\n/** Every descriptor this package ships — 100 manager + 8 anonymous. */\nexport const allDescriptors: readonly ToolDescriptor[] = [\n ...manageDescriptors,\n ...directoryDescriptors,\n];\n\nconst byNameIndex = new Map(allDescriptors.map((d) => [d.name, d]));\n\n/** Look a descriptor up by its tool name. */\nexport function byName(name: string): ToolDescriptor | undefined {\n return byNameIndex.get(name);\n}\n\nexport { toolDocumentation } from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/descriptors/index.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,OAAO,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,kGAAkG;AAClG,MAAM,CAAC,MAAM,cAAc,GAA8B;IACvD,GAAG,iBAAiB;IACpB,GAAG,oBAAoB;CACxB,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,6CAA6C;AAC7C,MAAM,UAAU,MAAM,CAAC,IAAY;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Generated from the backend agent contract. Edit the backend source and re-import; do not edit here.\nexport {\n CREATE,\n DELETE,\n READ_ONLY,\n TRIGGER,\n UPDATE,\n} from \"./types.js\";\nexport type { HttpMethod, ToolAnnotations, ToolDescriptor } from \"./types.js\";\n\nexport { manageDescriptors } from \"./manage.js\";\nexport {\n directoryDescriptors,\n kitDetailData,\n kitDetailFooter,\n kitListData,\n listFooter,\n publisherPageData,\n publisherPageFooter,\n} from \"./directory.js\";\n\nimport type { ToolDescriptor } from \"./types.js\";\nimport { manageDescriptors } from \"./manage.js\";\nimport { directoryDescriptors } from \"./directory.js\";\n\n/** Every descriptor this package ships: the manager tools, then the anonymous directory tools. */\nexport const allDescriptors: readonly ToolDescriptor[] = [\n ...manageDescriptors,\n ...directoryDescriptors,\n];\n\nconst byNameIndex = new Map(allDescriptors.map((d) => [d.name, d]));\n\n/** Look a descriptor up by its tool name. */\nexport function byName(name: string): ToolDescriptor | undefined {\n return byNameIndex.get(name);\n}\n\nexport { toolDocumentation } from \"./types.js\";\n"]}