@hasna/skills 0.5.7 → 0.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -522,7 +522,10 @@ the same declaration, and an uncertain upload is never sent twice. If a process
522
522
  crashes while holding `operation.lock`, confirm it has stopped before removing
523
523
  that lock explicitly. Status and cancellation remain available when new
524
524
  publishing is disabled. Exit 2 means publication is still pending; `committed`
525
- means source was published. Private execution remains unavailable.
525
+ means source was published. Execution requires a separate server quote and approval.
526
+ Publication recovery results report `executionEnabled: null` because their durable
527
+ receipts contain no server capability observation. Use `getCapability()` for the
528
+ server's current boolean capability; it does not authorize an individual run.
526
529
 
527
530
  The SDK exports `RemotePrivatePublicationsClient` through both the root and
528
531
  `./sdk`; `RemoteSkillsAuthClient.openPrivatePublications` creates one from fresh
@@ -1193,3 +1196,46 @@ returned or saved by the tools.
1193
1196
 
1194
1197
  These clients still require deployed configuration and controlled real recipient
1195
1198
  email acceptance before recovery can be offered as a live product capability.
1199
+
1200
+ ### Injected operation transport
1201
+
1202
+ `@hasna/skills/sdk` exports `createSkillOperationClient` for an embedder-supplied
1203
+ `SkillOperationTransport`. It provides a bounded JSON envelope, immutable
1204
+ snapshots and explicit status lookup. It does not connect to a provider, discover
1205
+ an endpoint, read credentials, or provide guest IPC or authorization.
1206
+
1207
+ ```ts
1208
+ import { createSkillOperationClient, type SkillOperationTransport } from "@hasna/skills/sdk";
1209
+
1210
+ function operationsForCapturedRun(transport: SkillOperationTransport) {
1211
+ return createSkillOperationClient(transport, { timeoutMs: 30_000 });
1212
+ }
1213
+ // The embedder supplies invoke(request, { signal }) and get(requestId, { signal }).
1214
+ // invoke accepts { contractVersion: 1, requestId: UUID, operation: "text.generate",
1215
+ // input: { prompt: "..." } }.
1216
+ ```
1217
+
1218
+ Create one client per captured authority scope. The transport must enforce that
1219
+ scope, bind the request ID to the exact payload durably, and enforce approval,
1220
+ budget and execution policy. The client remembers up to 256 request identities
1221
+ and 1 MiB of canonical requests. It refuses capacity before transport and never
1222
+ evicts an old identity. An explicit repeat with the same payload makes one new
1223
+ transport call; a changed payload under a remembered ID is refused locally.
1224
+ This local check does not replace server deduplication.
1225
+
1226
+ Requests are limited to 64 KiB and responses to 1 MiB of serialized UTF-8 JSON,
1227
+ with depth and node limits exported in `SKILL_OPERATION_LIMITS`. Plain JSON data
1228
+ is copied and deeply frozen; cycles, accessors, `toJSON` functions, unsupported
1229
+ values and extra envelope fields are refused. Ordinary data inside `input` and
1230
+ `output` is preserved. Request IDs use canonical lowercase UUID strings;
1231
+ operation names use lowercase letters, digits and dot or hyphen separators.
1232
+
1233
+ Responses preserve `contractVersion` and `requestId`. A status of `succeeded`
1234
+ includes `output`; `refused` includes a fixed `SkillOperationRefusal` code.
1235
+ `pending`, `unknown` and authoritative `not-executed` have no additional fields.
1236
+ Transport failure, in-flight abort and timeout produce a safe
1237
+ `SkillOperationClientError` with an unknown outcome. They never prove that an
1238
+ operation did not execute. The client does not retry or issue a status read
1239
+ automatically: explicitly call `get` with the same request ID to reconcile.
1240
+ Aborting locally does not establish server cancellation. An already-aborted
1241
+ signal refuses before calling the transport.