@yaklabs-ai/plugin-sdk 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ it under the name your plugin code actually imports:
13
13
  ```json
14
14
  {
15
15
  "dependencies": {
16
- "@kay/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.9.0"
16
+ "@kay/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.10.0"
17
17
  }
18
18
  }
19
19
  ```
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.9.0",
4
+ "version": "0.10.0",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
package/dist/kay-app.d.ts CHANGED
@@ -299,6 +299,93 @@ declare type ConstrainedSamplingConfig = {
299
299
  variants: GrammarVariants;
300
300
  };
301
301
 
302
+ export declare interface CorpusResourceInvocation {
303
+ readonly eventId: string;
304
+ /** Envelope recording time, never a run/message/incident identifier. */
305
+ readonly at: string;
306
+ readonly kind: CorpusResourceKind;
307
+ readonly sessionId: string;
308
+ /** Falls back to sessionId for legacy events without a recorded root. */
309
+ readonly rootSessionId: string;
310
+ readonly name: string;
311
+ readonly sourceId?: string;
312
+ /** Absent on unresolved legacy rows; names/aliases are not a substitute. */
313
+ readonly resourceId?: string;
314
+ readonly version?: string;
315
+ readonly variantId?: string;
316
+ readonly rootProvenance: SessionProvenanceRecord;
317
+ /** Current index hints, not the session's historical context at invocation. */
318
+ readonly currentContext: {
319
+ readonly cwd: string;
320
+ readonly projectId?: string;
321
+ };
322
+ }
323
+
324
+ /** Exclusive keyset position; preserve timestamp precision when returning it. */
325
+ export declare const CorpusResourceInvocationCursor: z.ZodObject<{
326
+ at: z.ZodISODateTime;
327
+ eventId: z.ZodString;
328
+ }, z.core.$strict>;
329
+
330
+ export declare type CorpusResourceInvocationCursor = z.infer<typeof CorpusResourceInvocationCursor>;
331
+
332
+ export declare interface CorpusResourceInvocationExclusion {
333
+ readonly eventId: string;
334
+ readonly sessionId: string;
335
+ readonly rootSessionId: string;
336
+ readonly reason: "session-missing" | "root-missing" | "root-provenance-unverified" | "root-creator-filtered";
337
+ }
338
+
339
+ export declare type CorpusResourceInvocationPage = {
340
+ readonly state: "available";
341
+ readonly items: readonly CorpusResourceInvocation[];
342
+ /** Absent only when this recording-time window is exhausted. */
343
+ readonly next?: CorpusResourceInvocationCursor;
344
+ /** Telemetry import succeeded; exclusions still describe missing or filtered index facts. */
345
+ readonly coverage: {
346
+ readonly scanned: number;
347
+ readonly exclusions: readonly CorpusResourceInvocationExclusion[];
348
+ };
349
+ } | {
350
+ readonly state: "unavailable";
351
+ readonly reason: "not-wired" | "telemetry-unavailable" | "telemetry-incomplete" | "index-unavailable" | "invalid-record";
352
+ readonly message: string;
353
+ };
354
+
355
+ /** Half-open recording-time window. Limits bound scanned rows, including exclusions. */
356
+ export declare const CorpusResourceInvocationQuery: z.ZodObject<{
357
+ kind: z.ZodEnum<{
358
+ skill: "skill";
359
+ "context-file": "context-file";
360
+ "prompt-command": "prompt-command";
361
+ }>;
362
+ since: z.ZodISODateTime;
363
+ until: z.ZodISODateTime;
364
+ after: z.ZodOptional<z.ZodObject<{
365
+ at: z.ZodISODateTime;
366
+ eventId: z.ZodString;
367
+ }, z.core.$strict>>;
368
+ limit: z.ZodOptional<z.ZodNumber>;
369
+ rootCreatedByKind: z.ZodOptional<z.ZodEnum<{
370
+ human: "human";
371
+ agent: "agent";
372
+ plugin: "plugin";
373
+ trigger: "trigger";
374
+ daemon: "daemon";
375
+ }>>;
376
+ }, z.core.$strict>;
377
+
378
+ export declare type CorpusResourceInvocationQuery = z.infer<typeof CorpusResourceInvocationQuery>;
379
+
380
+ /** Roster invocation facts, not evidence that a read completed successfully. */
381
+ export declare const CorpusResourceKind: z.ZodEnum<{
382
+ skill: "skill";
383
+ "context-file": "context-file";
384
+ "prompt-command": "prompt-command";
385
+ }>;
386
+
387
+ export declare type CorpusResourceKind = z.infer<typeof CorpusResourceKind>;
388
+
302
389
  /**
303
390
  * The `signals` a host with no Jev lane or no signals store binds: `observe` never touches the
304
391
  * network, answers `invalid` for an input that breaks the recorded-name grammar exactly as a
@@ -1189,9 +1276,20 @@ export declare interface KayAppAutomationContext {
1189
1276
  readonly sessionId: string;
1190
1277
  }
1191
1278
 
1192
- export declare type KayAppAutomationEffect = Extract<KayAppAutomationEffectInput, {
1279
+ export declare type KayAppAutomationEffect = {
1280
+ /**
1281
+ * STORED only: a binding created before the 2026-09-28 owner ruling (agents and plugins
1282
+ * may not create `spawn-session` automations) can still carry this effect, so a read must
1283
+ * still parse it. Absent from {@link KayAppAutomationEffectInput}, so no NEW binding can
1284
+ * be minted with it.
1285
+ */
1193
1286
  readonly kind: "spawn-session";
1194
- }> | {
1287
+ readonly prompt: string;
1288
+ readonly cwd?: string;
1289
+ readonly projectId?: string | null;
1290
+ /** Resolve the spawned session's model by tier instead of the caller's default. */
1291
+ readonly tier?: "small" | "medium" | "large" | "ultra";
1292
+ } | {
1195
1293
  /** As STORED: always a reference, never inline source. */
1196
1294
  readonly kind: "script";
1197
1295
  readonly ref: KayAppAutomationScriptRef;
@@ -1207,6 +1305,14 @@ export declare type KayAppAutomationEffect = Extract<KayAppAutomationEffectInput
1207
1305
  readonly prompt: string;
1208
1306
  };
1209
1307
 
1308
+ /**
1309
+ * What a plugin may CREATE an automation with. `spawn-session` is deliberately absent: owner
1310
+ * ruling (2026-09-28) forbids a plugin (or an agent) from minting a `spawn-session` binding —
1311
+ * durable recurring agent work belongs to a plugin workflow (`app.workflows.define` +
1312
+ * `ctx.runAgent`) or a direct `app.sessions.run`. A binding created before that ruling can still
1313
+ * carry the effect and still reads and runs; see {@link KayAppAutomationEffect}, the STORED type
1314
+ * this input narrows.
1315
+ */
1210
1316
  export declare type KayAppAutomationEffectInput = {
1211
1317
  readonly kind: "deliver-turn";
1212
1318
  readonly prompt: string;
@@ -1220,13 +1326,6 @@ export declare type KayAppAutomationEffectInput = {
1220
1326
  */
1221
1327
  readonly source?: string;
1222
1328
  readonly initialState?: JsonValue_4;
1223
- } | {
1224
- readonly kind: "spawn-session";
1225
- readonly prompt: string;
1226
- readonly cwd?: string;
1227
- readonly projectId?: string | null;
1228
- /** Resolve the spawned session's model by tier instead of the caller's default. */
1229
- readonly tier?: "small" | "medium" | "large" | "ultra";
1230
1329
  };
1231
1330
 
1232
1331
  /**
@@ -1495,6 +1594,8 @@ export declare type KayAppAutomationScriptRef = {
1495
1594
 
1496
1595
  /** A receipt-attributed skill candidate, with live status only for that exact revision. */
1497
1596
  export declare type KayAppAutomationSuggestionItem = {
1597
+ /** Only literal 1 proves physical addressing; other historical values remain uninterpreted. */
1598
+ readonly locatorVersion?: unknown;
1498
1599
  readonly sourceId: string;
1499
1600
  readonly skillName: string;
1500
1601
  readonly suggestionId: string;
@@ -1682,17 +1783,31 @@ export declare interface KayAppContextContributor {
1682
1783
  * Raw read access to every stored session's transcript. Always present on
1683
1784
  * {@link KayAppPluginApi}; each read is checked against the `corpus.read` claim, and refused
1684
1785
  * unless the user has granted it. Data is raw and un-redacted — the plugin filters to what it
1685
- * needs. Both reads are async iterables so a corpus pass never loads the whole corpus into memory
1686
- * at once (the bound is one session at a time).
1786
+ * needs. Invocation queries are bounded pages. Transcript reads materialize a whole session
1787
+ * before yielding; the iterable does not promise per-entry streaming or an allocation bound.
1687
1788
  */
1688
1789
  export declare interface KayAppCorpus {
1790
+ /** Page invocation leads under the live grant; inspect exclusions even on available empty pages. */
1791
+ listResourceInvocations(query: CorpusResourceInvocationQuery): Promise<CorpusResourceInvocationPage>;
1689
1792
  /** Enumerate every stored session, newest-first. */
1690
1793
  listSessions(): AsyncIterable<KayAppCorpusSession>;
1691
1794
  /**
1692
- * Stream one session's full entry log oldest→newest; an unknown id yields nothing. Treat the
1795
+ * Yield one session's full entry log oldest→newest; an unknown id yields nothing. Treat the
1693
1796
  * entries as read-only: for a session the daemon holds in memory they are its live objects.
1694
1797
  */
1695
1798
  readEntries(sessionId: string): AsyncIterable<SessionTreeEntry>;
1799
+ /**
1800
+ * Read one bounded physical JSONL page. The host resolves `sessionId` to its authoritative
1801
+ * indexed path and validates the opaque cursor before opening it. When `throughEntryId` is
1802
+ * supplied, the cursor stops at that entry's transaction line; a V4 line may carry later
1803
+ * entries, which are returned for the caller to filter and are replayed on the next page.
1804
+ */
1805
+ readEntryBatch?(sessionId: string, options?: {
1806
+ readonly cursor?: JsonValue_4;
1807
+ readonly throughEntryId?: string;
1808
+ /** Host-only cancellation for the bounded physical read. */
1809
+ readonly signal?: AbortSignal;
1810
+ }): Promise<KayAppCorpusEntryBatch>;
1696
1811
  /**
1697
1812
  * Read a cheap transcript change marker without loading the entry log. Unknown or deleted
1698
1813
  * sessions yield `undefined`.
@@ -1700,6 +1815,20 @@ export declare interface KayAppCorpus {
1700
1815
  readSessionSourceMark(sessionId: string): Promise<KayAppCorpusSourceMark | undefined>;
1701
1816
  }
1702
1817
 
1818
+ /** One bounded physical page from the host's incremental JSONL reader. */
1819
+ export declare interface KayAppCorpusEntryBatch {
1820
+ readonly entries: readonly SessionTreeEntry[];
1821
+ /** Opaque JSON cursor after the physical page; only the host may interpret it or open its path. */
1822
+ readonly cursor: JsonValue_4;
1823
+ /** Opaque cursor at the physical page start, for a partial logical chunk. */
1824
+ readonly pageStartCursor?: JsonValue_4;
1825
+ readonly mode: "replace" | "append";
1826
+ readonly status: "complete" | "more" | "awaiting-append" | "record-too-large";
1827
+ /** Present when a caller supplied `throughEntryId`. */
1828
+ readonly anchorFound?: boolean;
1829
+ readonly malformedRecords: number;
1830
+ }
1831
+
1703
1832
  /** One stored session, as the granted corpus enumerates them. Keyed by its stable `sessionId`. */
1704
1833
  export declare interface KayAppCorpusSession {
1705
1834
  readonly sessionId: string;
@@ -1962,6 +2091,13 @@ export declare interface KayAppEndpoints {
1962
2091
  register(name: string, handler: (payload: unknown) => unknown | Promise<unknown>): void;
1963
2092
  }
1964
2093
 
2094
+ /** A real human carrier projected into the source session's transcript. */
2095
+ export declare interface KayAppHumanMessageSessionEvent extends KayAppSessionEventBase {
2096
+ readonly type: "human-message";
2097
+ /** Exact prior persisted boundary captured by the host at projection time; `null` means empty history. */
2098
+ readonly throughEntryId: string | null;
2099
+ }
2100
+
1965
2101
  /**
1966
2102
  * A provider's nominated image model, resolved now: what a session on one of that
1967
2103
  * provider's text-only models spawns to read images. `resolved` absent = nothing
@@ -2584,17 +2720,16 @@ export declare type KayAppSessionCreator = SessionCreator;
2584
2720
 
2585
2721
  export declare type KayAppSessionDefiner = SessionDefiner;
2586
2722
 
2587
- export declare type KayAppSessionEvent = KayAppTurnSettledSessionEvent | KayAppPhaseShiftSessionEvent;
2723
+ export declare type KayAppSessionEvent = KayAppHumanMessageSessionEvent | KayAppTurnSettledSessionEvent | KayAppPhaseShiftSessionEvent;
2588
2724
 
2589
2725
  declare interface KayAppSessionEventBase {
2590
2726
  readonly sessionId: string;
2591
2727
  /**
2592
- * The event's own anchor entry: the settled turn's own last entry, or the phase-shift
2593
- * observation's `observationEntryId`. A handler bounds its OWN corpus read using this id (via
2594
- * whatever packet-building helpers the plugin already owns); the door hands out no
2595
- * `readEntries()` closure, and re-validating what was read against the CURRENT branch — a
2596
- * rewind can race between publish and read — is the handler's own job, exactly as
2597
- * `resolveClosedPhase` already does today for the phase extractor.
2728
+ * The event's own anchor entry: the projected human carrier, the settled turn's own last
2729
+ * entry, or the phase-shift observation's `observationEntryId`. A handler bounds its OWN logical
2730
+ * corpus interval using this id (via whatever packet-building helpers the plugin already owns);
2731
+ * the door hands out no `readEntries()` closure, and re-validating what was read against the
2732
+ * CURRENT branch — a rewind can race between publish and read — is the handler's own job.
2598
2733
  */
2599
2734
  readonly entryId: string;
2600
2735
  /** ISO-8601 publish time. */
@@ -2631,6 +2766,8 @@ export declare type KayAppSessionEventCause = {
2631
2766
  * substitute a run id resolved another way.
2632
2767
  */
2633
2768
  readonly runId?: string;
2769
+ /** Exact prior persisted boundary for a projected human-message event; null means empty history. */
2770
+ readonly throughEntryId?: string | null;
2634
2771
  };
2635
2772
  /**
2636
2773
  * Exact-match dedupe key. The host REFUSES a second run carrying the same key outright (a
@@ -2693,12 +2830,12 @@ export declare interface KayAppSessionEventsSubscribeOptions {
2693
2830
  }
2694
2831
 
2695
2832
  /**
2696
- * A closed, extensible union: today's two root events a lane could fire on
2697
- * (`turn-settled`) and react to (`phase-shift`), collapsed onto one subscribable set now that
2698
- * there is no dispatcher chaining one lane's completion into another's `when`. Adding a third
2699
- * type is additive, never breaking.
2833
+ * A closed, extensible union: a projected human message, a settled turn, or an accepted
2834
+ * phase-shift observation. They share one subscribable set now that there is no dispatcher
2835
+ * chaining one job's completion into another's `when`. Adding a fourth type is additive, never
2836
+ * breaking.
2700
2837
  */
2701
- export declare type KayAppSessionEventType = "turn-settled" | "phase-shift";
2838
+ export declare type KayAppSessionEventType = "human-message" | "turn-settled" | "phase-shift";
2702
2839
 
2703
2840
  export declare type KayAppSessionIntent = SessionIntent;
2704
2841
 
@@ -4501,9 +4638,11 @@ declare const SessionCausedByEvent: z.ZodObject<{
4501
4638
  type: z.ZodEnum<{
4502
4639
  "turn-settled": "turn-settled";
4503
4640
  "phase-shift": "phase-shift";
4641
+ "human-message": "human-message";
4504
4642
  }>;
4505
4643
  entryId: z.ZodString;
4506
4644
  runId: z.ZodOptional<z.ZodString>;
4645
+ throughEntryId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
4507
4646
  }, z.core.$strict>>;
4508
4647
  dedupeKey: z.ZodOptional<z.ZodString>;
4509
4648
  }, z.core.$strict>;
@@ -4697,9 +4836,11 @@ declare const SessionProvenanceRecord: z.ZodObject<{
4697
4836
  type: z.ZodEnum<{
4698
4837
  "turn-settled": "turn-settled";
4699
4838
  "phase-shift": "phase-shift";
4839
+ "human-message": "human-message";
4700
4840
  }>;
4701
4841
  entryId: z.ZodString;
4702
4842
  runId: z.ZodOptional<z.ZodString>;
4843
+ throughEntryId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
4703
4844
  }, z.core.$strict>>;
4704
4845
  dedupeKey: z.ZodOptional<z.ZodString>;
4705
4846
  }, z.core.$strict>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",