@modootoday/pmcp 0.9.2 → 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.
@@ -0,0 +1,387 @@
1
+ import {
2
+ HEARTBEAT_INTERVAL_MS,
3
+ MailboxError,
4
+ MailboxService,
5
+ MailboxStore,
6
+ PRESENCE_TTL_MS,
7
+ SCHEMA_VERSION,
8
+ attachMailbox,
9
+ failure,
10
+ initializeMailboxConfig,
11
+ mailboxConfigFrom,
12
+ openDatabase,
13
+ readBinding,
14
+ readCredential,
15
+ restoreBackup,
16
+ writeBindingFile,
17
+ writePrivateJson
18
+ } from "../chunk-HNAVQG6R.js";
19
+ import "../chunk-MSTKY33C.js";
20
+ import {
21
+ inboxSchema,
22
+ messageSchema,
23
+ operationSchema,
24
+ registerMailboxTools,
25
+ sendSchema,
26
+ sessionsSchema
27
+ } from "../chunk-XOH2CW6P.js";
28
+
29
+ // src/mailbox/notifications.ts
30
+ import { randomUUID } from "crypto";
31
+ var NotificationOutbox = class {
32
+ constructor(store) {
33
+ this.store = store;
34
+ }
35
+ store;
36
+ discover(binding, nativeTarget) {
37
+ return this.store.run(() => {
38
+ this.store.assertBinding(binding);
39
+ if (!nativeTarget) {
40
+ throw new MailboxError("invalid_target", "Native target is required");
41
+ }
42
+ this.store.database.run(
43
+ "UPDATE mailbox_notifications SET state = 'stale', lease_token = NULL, lease_until_ms = NULL WHERE actor_id = ? AND session_id != ? AND state IN ('pending', 'leased')",
44
+ binding.actorId,
45
+ binding.sessionId
46
+ );
47
+ this.store.database.run(
48
+ "INSERT OR IGNORE INTO mailbox_notifications(message_id, actor_id, session_id, generation, native_target, state, next_attempt_ms) SELECT DISTINCT r.message_id, r.actor_id, ?, ?, ?, 'pending', ? FROM mailbox_receipts r WHERE r.actor_id = ? AND r.ack_at_ms IS NULL AND (r.session_id IS NULL OR r.session_id = ?) AND NOT EXISTS (SELECT 1 FROM mailbox_notifications n WHERE n.message_id = r.message_id AND n.actor_id = r.actor_id AND n.session_id = ?) ORDER BY r.message_id LIMIT 100",
49
+ binding.sessionId,
50
+ binding.generation,
51
+ nativeTarget,
52
+ this.store.now(),
53
+ binding.actorId,
54
+ binding.sessionId,
55
+ binding.sessionId
56
+ );
57
+ });
58
+ }
59
+ retryUnsent(binding, claim) {
60
+ return this.store.run(() => {
61
+ this.assertLease(binding, claim);
62
+ const attempts = Number(claim.attempts);
63
+ this.store.database.run(
64
+ "UPDATE mailbox_notifications SET state = ?, outcome_code = 'known_unsent', lease_token = NULL, lease_until_ms = NULL, next_attempt_ms = ? WHERE message_id = ? AND actor_id = ? AND session_id = ?",
65
+ attempts >= 3 ? "failed" : "pending",
66
+ this.store.now() + Math.min(2e3, 100 * 2 ** (attempts - 1)),
67
+ claim.message_id,
68
+ binding.actorId,
69
+ binding.sessionId
70
+ );
71
+ });
72
+ }
73
+ reconcile(binding, messageId, delivered) {
74
+ return this.store.run(() => {
75
+ this.store.assertBinding(binding);
76
+ const row = this.store.database.get(
77
+ "SELECT state, attempts FROM mailbox_notifications WHERE message_id = ? AND actor_id = ? AND session_id = ?",
78
+ messageId,
79
+ binding.actorId,
80
+ binding.sessionId
81
+ );
82
+ if (row?.state !== "uncertain") {
83
+ throw new MailboxError(
84
+ "reconciliation_conflict",
85
+ "Only uncertain delivery can be reconciled"
86
+ );
87
+ }
88
+ let state = "pending";
89
+ if (delivered) {
90
+ state = "accepted";
91
+ } else if (Number(row.attempts) >= 3) {
92
+ state = "failed";
93
+ }
94
+ this.store.database.run(
95
+ "UPDATE mailbox_notifications SET state = ?, outcome_code = 'operator_reconciled', next_attempt_ms = ? WHERE message_id = ? AND actor_id = ? AND session_id = ?",
96
+ state,
97
+ this.store.now(),
98
+ messageId,
99
+ binding.actorId,
100
+ binding.sessionId
101
+ );
102
+ });
103
+ }
104
+ enqueue(messageId, binding, nativeTarget) {
105
+ return this.store.run(() => {
106
+ this.store.assertBinding(binding);
107
+ const receipt = this.store.database.get(
108
+ "SELECT session_id FROM mailbox_receipts WHERE message_id = ? AND actor_id = ? AND (session_id IS NULL OR session_id = ?)",
109
+ messageId,
110
+ binding.actorId,
111
+ binding.sessionId
112
+ );
113
+ if (!receipt || !nativeTarget) {
114
+ throw new MailboxError(
115
+ "unknown_message",
116
+ "Notification target is not a recipient"
117
+ );
118
+ }
119
+ this.store.database.run(
120
+ "INSERT OR IGNORE INTO mailbox_notifications(message_id, actor_id, session_id, generation, native_target, state, next_attempt_ms) VALUES (?, ?, ?, ?, ?, 'pending', ?)",
121
+ messageId,
122
+ binding.actorId,
123
+ binding.sessionId,
124
+ binding.generation,
125
+ nativeTarget,
126
+ this.store.now()
127
+ );
128
+ });
129
+ }
130
+ claim(binding) {
131
+ return this.store.run(() => {
132
+ this.store.assertBinding(binding);
133
+ this.store.database.run(
134
+ "UPDATE mailbox_notifications SET state = 'uncertain', outcome_code = 'dispatcher_lost', lease_token = NULL WHERE actor_id = ? AND state = 'leased' AND lease_until_ms <= ?",
135
+ binding.actorId,
136
+ this.store.now()
137
+ );
138
+ const row = this.store.database.get(
139
+ "SELECT * FROM mailbox_notifications WHERE actor_id = ? AND session_id = ? AND generation = ? AND state = 'pending' AND next_attempt_ms <= ? AND attempts < 3 ORDER BY next_attempt_ms LIMIT 1",
140
+ binding.actorId,
141
+ binding.sessionId,
142
+ binding.generation,
143
+ this.store.now()
144
+ );
145
+ if (!row) {
146
+ return void 0;
147
+ }
148
+ const leaseToken = randomUUID();
149
+ this.store.database.run(
150
+ "UPDATE mailbox_notifications SET state = 'leased', attempts = attempts + 1, lease_token = ?, lease_until_ms = ? WHERE message_id = ? AND actor_id = ? AND session_id = ?",
151
+ leaseToken,
152
+ this.store.now() + 2e4,
153
+ row.message_id,
154
+ binding.actorId,
155
+ binding.sessionId
156
+ );
157
+ return { ...row, leaseToken, attempts: Number(row.attempts) + 1 };
158
+ });
159
+ }
160
+ renew(binding, claim) {
161
+ return this.store.run(() => {
162
+ this.assertLease(binding, claim);
163
+ this.store.database.run(
164
+ "UPDATE mailbox_notifications SET lease_until_ms = ? WHERE message_id = ? AND actor_id = ? AND session_id = ?",
165
+ this.store.now() + 2e4,
166
+ claim.message_id,
167
+ binding.actorId,
168
+ binding.sessionId
169
+ );
170
+ });
171
+ }
172
+ assertLease(binding, claim) {
173
+ this.store.assertBinding(binding);
174
+ const lease = this.store.database.get(
175
+ "SELECT state, lease_token, lease_until_ms FROM mailbox_notifications WHERE message_id = ? AND actor_id = ? AND session_id = ?",
176
+ claim.message_id,
177
+ binding.actorId,
178
+ binding.sessionId
179
+ );
180
+ if (lease?.state !== "leased" || lease.lease_token !== claim.leaseToken || Number(lease.lease_until_ms) <= this.store.now()) {
181
+ throw new MailboxError(
182
+ "stale_lease",
183
+ "Notification lease is no longer current"
184
+ );
185
+ }
186
+ }
187
+ complete(binding, claim, outcome) {
188
+ return this.store.run(() => {
189
+ this.assertLease(binding, claim);
190
+ this.store.database.run(
191
+ "UPDATE mailbox_notifications SET state = ?, outcome_code = ?, lease_token = NULL, lease_until_ms = NULL WHERE message_id = ? AND actor_id = ? AND session_id = ?",
192
+ outcome,
193
+ outcome,
194
+ claim.message_id,
195
+ binding.actorId,
196
+ binding.sessionId
197
+ );
198
+ });
199
+ }
200
+ };
201
+
202
+ // src/mailbox/recovery.ts
203
+ import {
204
+ createCipheriv,
205
+ createDecipheriv,
206
+ createHash,
207
+ randomBytes,
208
+ randomUUID as randomUUID2
209
+ } from "crypto";
210
+ import {
211
+ closeSync,
212
+ existsSync,
213
+ fsyncSync,
214
+ linkSync,
215
+ mkdirSync,
216
+ openSync,
217
+ readFileSync,
218
+ rmSync,
219
+ unlinkSync,
220
+ writeFileSync
221
+ } from "fs";
222
+ import { dirname, join } from "path";
223
+ var hash = (value) => createHash("sha256").update(value).digest("hex");
224
+ async function createRecoveryBundle(store, credentials, destination, key) {
225
+ if (key.length !== 32 || existsSync(destination)) {
226
+ throw new MailboxError(
227
+ "invalid_recovery_target",
228
+ "Use a new destination and a 32-byte recovery key"
229
+ );
230
+ }
231
+ const temporary = `${destination}.${randomUUID2()}.tmp`;
232
+ const snapshot = `${temporary}.sqlite`;
233
+ mkdirSync(dirname(destination), { recursive: true, mode: 448 });
234
+ try {
235
+ await store.backup(snapshot);
236
+ const probe = await openDatabase(snapshot);
237
+ try {
238
+ if (probe.get("PRAGMA integrity_check")?.integrity_check !== "ok" || probe.all("PRAGMA foreign_key_check").length > 0) {
239
+ throw new MailboxError(
240
+ "storage_corrupt",
241
+ "Recovery snapshot failed validation"
242
+ );
243
+ }
244
+ for (const credential of credentials) {
245
+ if (credential.projectId !== store.config.projectId || probe.get(
246
+ "SELECT credential_hash FROM mailbox_actors WHERE id = ?",
247
+ credential.actorId
248
+ )?.credential_hash !== hash(credential.secret)) {
249
+ throw new MailboxError(
250
+ "credential_mismatch",
251
+ "Escrow credential does not match the snapshot"
252
+ );
253
+ }
254
+ }
255
+ } finally {
256
+ probe.close();
257
+ }
258
+ const database = readFileSync(snapshot);
259
+ const manifest = {
260
+ version: 1,
261
+ schemaVersion: SCHEMA_VERSION,
262
+ projectId: store.config.projectId,
263
+ createdAtMs: store.now(),
264
+ providerRuntime: process.version,
265
+ databaseSha256: hash(database),
266
+ database: database.toString("base64"),
267
+ credentials
268
+ };
269
+ const iv = randomBytes(12);
270
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
271
+ cipher.setAAD(Buffer.from("pmcp-mailbox-recovery-v1"));
272
+ const encrypted = Buffer.concat([
273
+ cipher.update(JSON.stringify(manifest)),
274
+ cipher.final()
275
+ ]);
276
+ writeFileSync(
277
+ temporary,
278
+ Buffer.concat([Buffer.from("PMB1"), iv, cipher.getAuthTag(), encrypted]),
279
+ { flag: "wx", mode: 384 }
280
+ );
281
+ const handle = openSync(temporary, "r");
282
+ try {
283
+ fsyncSync(handle);
284
+ } finally {
285
+ closeSync(handle);
286
+ }
287
+ linkSync(temporary, destination);
288
+ const directory = openSync(dirname(destination), "r");
289
+ try {
290
+ fsyncSync(directory);
291
+ } finally {
292
+ closeSync(directory);
293
+ }
294
+ } finally {
295
+ for (const file of [
296
+ temporary,
297
+ snapshot,
298
+ `${snapshot}-wal`,
299
+ `${snapshot}-shm`
300
+ ]) {
301
+ rmSync(file, { force: true });
302
+ }
303
+ }
304
+ }
305
+ async function restoreRecoveryBundle(source, config, key) {
306
+ let manifest;
307
+ try {
308
+ const bundle = readFileSync(source);
309
+ if (key.length !== 32 || bundle.subarray(0, 4).toString() !== "PMB1") {
310
+ throw new Error("Invalid header");
311
+ }
312
+ const decipher = createDecipheriv(
313
+ "aes-256-gcm",
314
+ key,
315
+ bundle.subarray(4, 16)
316
+ );
317
+ decipher.setAAD(Buffer.from("pmcp-mailbox-recovery-v1"));
318
+ decipher.setAuthTag(bundle.subarray(16, 32));
319
+ manifest = JSON.parse(
320
+ Buffer.concat([
321
+ decipher.update(bundle.subarray(32)),
322
+ decipher.final()
323
+ ]).toString("utf8")
324
+ );
325
+ if (manifest.version !== 1 || !Number.isInteger(manifest.schemaVersion) || manifest.schemaVersion < 1 || manifest.schemaVersion > SCHEMA_VERSION || manifest.projectId !== config.projectId || hash(Buffer.from(manifest.database, "base64")) !== manifest.databaseSha256) {
326
+ throw new Error("Invalid manifest");
327
+ }
328
+ } catch {
329
+ throw new MailboxError(
330
+ "invalid_recovery_bundle",
331
+ "Recovery bundle cannot be authenticated or validated"
332
+ );
333
+ }
334
+ const directory = dirname(config.databasePath);
335
+ mkdirSync(directory, { mode: 448 });
336
+ const snapshot = join(directory, ".snapshot.sqlite");
337
+ let store;
338
+ try {
339
+ writeFileSync(snapshot, Buffer.from(manifest.database, "base64"), {
340
+ flag: "wx",
341
+ mode: 384
342
+ });
343
+ await restoreBackup(snapshot, config);
344
+ store = await MailboxStore.open(config);
345
+ const actors = await store.run(
346
+ () => store.database.all("SELECT id FROM mailbox_actors ORDER BY id"),
347
+ false
348
+ );
349
+ const credentials = [];
350
+ for (const actor of actors) {
351
+ credentials.push(await store.rotateActor(actor.id));
352
+ }
353
+ await store.close();
354
+ unlinkSync(snapshot);
355
+ return credentials;
356
+ } catch (error) {
357
+ await store?.close();
358
+ rmSync(directory, { recursive: true, force: true });
359
+ throw error;
360
+ }
361
+ }
362
+ export {
363
+ HEARTBEAT_INTERVAL_MS,
364
+ MailboxError,
365
+ MailboxService,
366
+ MailboxStore,
367
+ NotificationOutbox,
368
+ PRESENCE_TTL_MS,
369
+ attachMailbox,
370
+ createRecoveryBundle,
371
+ failure,
372
+ inboxSchema,
373
+ initializeMailboxConfig,
374
+ mailboxConfigFrom,
375
+ messageSchema,
376
+ operationSchema,
377
+ readBinding,
378
+ readCredential,
379
+ registerMailboxTools,
380
+ restoreBackup,
381
+ restoreRecoveryBundle,
382
+ sendSchema,
383
+ sessionsSchema,
384
+ writeBindingFile,
385
+ writePrivateJson
386
+ };
387
+ //# sourceMappingURL=index.js.map
@@ -1,6 +1,125 @@
1
- import { S as SkillEntry, M as MetadataValue, C as CatalogOptions, A as AssetKind } from './catalog-BU5VLLyd.js';
2
1
  import { z } from 'zod';
3
2
 
3
+ /**
4
+ * SKILL.md frontmatter, read as YAML the way a host reads it, and checked against
5
+ * the Agent Skills specification (https://agentskills.io/specification).
6
+ */
7
+ type MetadataLeaf = string | readonly string[];
8
+ /** A metadata value: a leaf, or a map of leaves one level below the metadata key. */
9
+ type MetadataValue = MetadataLeaf | {
10
+ readonly [key: string]: MetadataLeaf;
11
+ };
12
+ /**
13
+ * Parsed frontmatter. A value with an unquoted ": " is a common authoring slip
14
+ * the client guide says to recover from by quoting it, so that is retried once.
15
+ */
16
+ declare function frontmatterObject(source: string): Record<string, unknown> | null;
17
+ declare const NAME_MAX = 64;
18
+ declare const DESCRIPTION_MAX = 1024;
19
+ declare const COMPATIBILITY_MAX = 500;
20
+ /**
21
+ * What the specification requires of one SKILL.md, as messages; empty when valid.
22
+ * directory is the name of the folder holding it.
23
+ */
24
+ declare function specProblems(front: Record<string, unknown> | null, directory: string): string[];
25
+
26
+ /**
27
+ * The skills the installed packages brought with them.
28
+ *
29
+ * Derived from `node_modules` at read time rather than from a list somebody
30
+ * maintains: installing a package is how its skill arrives and uninstalling it
31
+ * is how the skill leaves, so the catalog is always true of the project.
32
+ */
33
+
34
+ interface SkillEntry {
35
+ /** `<package>/<slug>`. Unique, and stable while the package is installed. */
36
+ readonly name: string;
37
+ readonly package: string;
38
+ readonly slug: string;
39
+ /** Frontmatter description. The only text `find` ranks against. */
40
+ readonly description: string;
41
+ /** Absolute path to the SKILL.md. `call` reads the body from here. */
42
+ readonly path: string;
43
+ /** open, free or paid. Set for marketplace skills, absent for packages. */
44
+ readonly tier?: string;
45
+ /** The frontmatter `metadata:` block; maps such as `requires` are kept one level down. */
46
+ readonly metadata?: Readonly<Record<string, MetadataValue>>;
47
+ /** Extra search terms. Ranked with the description, never used as triggers. */
48
+ readonly keywords?: readonly string[];
49
+ /** What the entry is. Absent means a skill. */
50
+ readonly kind?: AssetKind;
51
+ /**
52
+ * What describe and read may open: a directory, or one file for an asset
53
+ * that is a single file. Absent means the directory holding `path`.
54
+ */
55
+ readonly root?: string;
56
+ }
57
+ /** Everything the catalog serves. Commands are skills; workflows have no kind of their own. */
58
+ declare const ASSET_KINDS: readonly ["skill", "agent", "hook", "mcp"];
59
+ type AssetKind = (typeof ASSET_KINDS)[number];
60
+ declare const kindOf: (entry: Pick<SkillEntry, "kind">) => AssetKind;
61
+ interface CatalogOptions {
62
+ /** Directories to walk. Each is a `node_modules` root, not a package root. */
63
+ readonly roots: readonly string[];
64
+ /** Package name prefixes to consider. Empty means every package. */
65
+ readonly scopes?: readonly string[];
66
+ /** Marketplace directories, each holding .claude-plugin/marketplace.json. */
67
+ readonly marketplaces?: readonly string[];
68
+ /** Package directories read directly, for a package no node_modules links. */
69
+ readonly packages?: readonly string[];
70
+ /** Workspace roots: the root and every member its workspaces globs name. */
71
+ readonly workspaces?: readonly string[];
72
+ /** Told about every marketplace skill left out, and why. */
73
+ readonly onReject?: (rejection: {
74
+ path: string;
75
+ reason: string;
76
+ }) => void;
77
+ /**
78
+ * Told about a skill that is served but breaks the Agent Skills specification,
79
+ * or that lost a name collision. Loading stays lenient, as the client guide asks.
80
+ */
81
+ readonly onWarning?: (warning: {
82
+ path: string;
83
+ reason: string;
84
+ }) => void;
85
+ }
86
+ /**
87
+ * Directories a walk does not enter. Kept as short as the evidence allows: a
88
+ * name here is a package whose skill will never be found, and the cost of one
89
+ * extra readdir is far below the cost of missing a skill. Measured 20260906 --
90
+ * `lib` was on this list and hid playwright's `lib/skill/SKILL.md`, which is
91
+ * the most widely installed skill in the real world.
92
+ */
93
+ declare const SKIPPED_DIRS: ReadonlySet<string>;
94
+ /**
95
+ * How deep below a package root a SKILL.md is looked for. Three reaches every
96
+ * convention in use (skills, .agent/skills, .claude/skills, .gemini/skills,
97
+ * .codex/skills); four was measured to find nothing more.
98
+ */
99
+ declare const MAX_SKILL_DEPTH = 3;
100
+ /**
101
+ * Top-level scalar fields of a SKILL.md frontmatter, parsed as YAML, so a folded
102
+ * `description: >-` arrives as its text rather than as the indicator.
103
+ */
104
+ declare function readFrontmatter(source: string): Record<string, string>;
105
+ /** The body after the frontmatter, or the whole file when there is none. */
106
+ declare function readBody(source: string): string;
107
+ /**
108
+ * Every skill reachable from the given roots, sorted by name.
109
+ *
110
+ * A package with no skills directory contributes nothing and costs one
111
+ * `existsSync` per convention. A skill with no description is skipped rather
112
+ * than listed:
113
+ * `find` ranks descriptions, so one without a description can only ever be
114
+ * found by already knowing its name, and listing it would spend a session's
115
+ * tokens on an entry that cannot answer.
116
+ */
117
+ declare function readCatalog(options: CatalogOptions): SkillEntry[];
118
+ /** A catalog entry without its body, which is what `catalog` returns. */
119
+ declare function withoutBody({ path, ...rest }: SkillEntry): Omit<SkillEntry, "path">;
120
+ /** Path relative to a root, for a message a reader can act on. */
121
+ declare function displayPath(root: string, entry: SkillEntry): string;
122
+
4
123
  /**
5
124
  * The intent key and the cache contract.
6
125
  *
@@ -56,6 +175,7 @@ interface FindResult {
56
175
  */
57
176
  interface Embedder {
58
177
  readonly modelId: string;
178
+ readonly indexKey?: string;
59
179
  readonly dims: number;
60
180
  /** Encodes an intent, the query side. */
61
181
  embed(text: string): Promise<Float32Array>;
@@ -421,4 +541,4 @@ declare function createSkillTools(options: SkillServerOptions): {
421
541
  };
422
542
  type SkillTools = ReturnType<typeof createSkillTools>;
423
543
 
424
- export { detectRuntime as A, type BundleFile as B, CATALOG_PAGE_MAX as C, DEFAULT_FIND_LIMIT as D, type Embedder as E, type FileKind as F, find as G, findResultSchema as H, type IntentCache as I, isUtf8Text as J, type KindFilter as K, lexicalScore as L, type Match as M, listSkillFiles as N, mimeOf as O, normaliseIntent as P, readSkillFile as Q, READ_BUDGET_BYTES as R, type SkillServerOptions as S, runtimeOfClient as T, verifiedRuntimesOf as U, type SkillTools as a, CATALOG_PAGE_SIZE as b, type CallResponse as c, type CatalogItem as d, type CatalogResponse as e, type Classified as f, DESCRIBE_FILE_LIMIT as g, type FindOptions as h, type FindResult as i, type IntentCacheStats as j, RUNTIMES as k, type Ranking as l, type ReadResult as m, type Runtime as n, type SkillBundle as o, type SkillFile as p, type SkillFileContent as q, type SkillFileListing as r, type SkillFilters as s, bundleResponseSchema as t, bundleSkill as u, catalogResponseSchema as v, classify as w, cosine as x, createSkillTools as y, describeResponseSchema as z };
544
+ export { lexicalScore as $, ASSET_KINDS as A, type BundleFile as B, type CatalogOptions as C, DEFAULT_FIND_LIMIT as D, type Embedder as E, type FileKind as F, type SkillFileListing as G, type SkillFilters as H, type IntentCache as I, bundleResponseSchema as J, type KindFilter as K, bundleSkill as L, type MetadataValue as M, NAME_MAX as N, catalogResponseSchema as O, classify as P, cosine as Q, type Ranking as R, type SkillServerOptions as S, createSkillTools as T, describeResponseSchema as U, detectRuntime as V, displayPath as W, find as X, findResultSchema as Y, isUtf8Text as Z, kindOf as _, type SkillEntry as a, listSkillFiles as a0, mimeOf as a1, normaliseIntent as a2, frontmatterObject as a3, readBody as a4, readCatalog as a5, readFrontmatter as a6, readSkillFile as a7, runtimeOfClient as a8, specProblems as a9, verifiedRuntimesOf as aa, withoutBody as ab, type SkillTools as b, type AssetKind as c, CATALOG_PAGE_MAX as d, CATALOG_PAGE_SIZE as e, COMPATIBILITY_MAX as f, type CallResponse as g, type CatalogItem as h, type CatalogResponse as i, type Classified as j, DESCRIBE_FILE_LIMIT as k, DESCRIPTION_MAX as l, type FindOptions as m, type FindResult as n, type IntentCacheStats as o, MAX_SKILL_DEPTH as p, type Match as q, type MetadataLeaf as r, READ_BUDGET_BYTES as s, RUNTIMES as t, type ReadResult as u, type Runtime as v, SKIPPED_DIRS as w, type SkillBundle as x, type SkillFile as y, type SkillFileContent as z };
@@ -0,0 +1,116 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const operationSchema: z.ZodEnum<{
4
+ read: "read";
5
+ send: "send";
6
+ inbox: "inbox";
7
+ ack: "ack";
8
+ sessions: "sessions";
9
+ }>;
10
+ type MailboxOperation = z.output<typeof operationSchema>;
11
+ declare const sessionsSchema: z.ZodObject<{}, z.core.$strict>;
12
+ declare const sendSchema: z.ZodObject<{
13
+ recipients: z.ZodArray<z.ZodObject<{
14
+ actorId: z.ZodString;
15
+ sessionId: z.ZodOptional<z.ZodUUID>;
16
+ }, z.core.$strict>>;
17
+ body: z.ZodString;
18
+ idempotencyKey: z.ZodString;
19
+ replyToId: z.ZodOptional<z.ZodUUID>;
20
+ }, z.core.$strict>;
21
+ declare const inboxSchema: z.ZodObject<{
22
+ limit: z.ZodDefault<z.ZodNumber>;
23
+ state: z.ZodDefault<z.ZodEnum<{
24
+ all: "all";
25
+ unread: "unread";
26
+ unacknowledged: "unacknowledged";
27
+ }>>;
28
+ threadId: z.ZodOptional<z.ZodUUID>;
29
+ cursor: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strict>;
31
+ declare const messageSchema: z.ZodObject<{
32
+ messageId: z.ZodUUID;
33
+ }, z.core.$strict>;
34
+
35
+ type SqlValue = string | number | null;
36
+ type Row = Record<string, unknown>;
37
+ interface Database {
38
+ exec(sql: string): void;
39
+ get(sql: string, ...values: SqlValue[]): Row | undefined;
40
+ all(sql: string, ...values: SqlValue[]): Row[];
41
+ run(sql: string, ...values: SqlValue[]): void;
42
+ close(): void;
43
+ }
44
+ interface ActorCredential {
45
+ projectId: string;
46
+ actorId: string;
47
+ secret: string;
48
+ }
49
+ interface Binding {
50
+ projectId: string;
51
+ actorId: string;
52
+ sessionId: string;
53
+ generation: number;
54
+ secret: string;
55
+ }
56
+ interface MailboxConfig {
57
+ projectId: string;
58
+ databasePath: string;
59
+ enabled: boolean;
60
+ }
61
+ type Result<T> = {
62
+ ok: true;
63
+ data: T;
64
+ } | {
65
+ ok: false;
66
+ error: {
67
+ code: string;
68
+ message: string;
69
+ retryable: boolean;
70
+ };
71
+ };
72
+ declare class MailboxError extends Error {
73
+ readonly code: string;
74
+ readonly retryable: boolean;
75
+ constructor(code: string, message: string, retryable?: boolean);
76
+ }
77
+ declare function failure(error: unknown): Result<never>;
78
+
79
+ declare const PRESENCE_TTL_MS = 120000;
80
+ declare const HEARTBEAT_INTERVAL_MS = 30000;
81
+ declare class MailboxStore {
82
+ private pending;
83
+ private closed;
84
+ readonly config: MailboxConfig;
85
+ readonly database: Database;
86
+ readonly now: () => number;
87
+ private constructor();
88
+ static open(config: MailboxConfig, now?: () => number): Promise<MailboxStore>;
89
+ checkSchema(): void;
90
+ run<T>(operation: () => T, write?: boolean): Promise<T>;
91
+ registerActor(actorId: string, parentActorId?: string, persist?: (credential: ActorCredential) => void, authorityTtlMs?: number, parentBinding?: Binding): Promise<ActorCredential>;
92
+ registerChild(parent: Binding, actorId: string, ttlMs?: number): Promise<ActorCredential>;
93
+ attach(credential: ActorCredential, runtime: string, replaceSessionId?: string, nativeSessionId?: string): Promise<Binding>;
94
+ assertBinding(binding: Binding): Row;
95
+ rotateActor(actorId: string, persist?: (credential: ActorCredential) => void): Promise<ActorCredential>;
96
+ heartbeat(binding: Binding): Promise<void>;
97
+ detach(binding: Binding): Promise<void>;
98
+ exportRecords(actorId?: string): Promise<object[]>;
99
+ backup(destination: string): Promise<void>;
100
+ close(): Promise<void>;
101
+ }
102
+ declare function restoreBackup(source: string, config: MailboxConfig): Promise<void>;
103
+
104
+ declare class MailboxService {
105
+ readonly store: MailboxStore;
106
+ readonly binding: Binding;
107
+ constructor(store: MailboxStore, binding: Binding);
108
+ call(operation: MailboxOperation, input: unknown): Promise<Result<object>>;
109
+ private send;
110
+ private visibleMessage;
111
+ private inbox;
112
+ private receipt;
113
+ private sessions;
114
+ }
115
+
116
+ export { type ActorCredential as A, type Binding as B, HEARTBEAT_INTERVAL_MS as H, MailboxService as M, PRESENCE_TTL_MS as P, type Row as R, type MailboxConfig as a, MailboxStore as b, MailboxError as c, type MailboxOperation as d, type Result as e, failure as f, sessionsSchema as g, inboxSchema as i, messageSchema as m, operationSchema as o, restoreBackup as r, sendSchema as s };
package/dist/stdio.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { C as CatalogOptions } from './catalog-BU5VLLyd.js';
2
+ import { serveStdio } from '@modelcontextprotocol/server/stdio';
3
+ import { S as SkillServerOptions, C as CatalogOptions } from './server-CwWcRjqz.js';
4
+ import { M as MailboxService } from './service-qpCsOXkQ.js';
5
+ import { M as MailboxAttachmentOptions } from './attachment-tU5FZrgZ.js';
6
+ import 'zod';
3
7
 
4
8
  /**
5
9
  * The stdio entry a host launches.
@@ -11,11 +15,13 @@ import { C as CatalogOptions } from './catalog-BU5VLLyd.js';
11
15
 
12
16
  /** `node_modules` roots to walk, from argv or from the working directory. */
13
17
  declare function resolveRoots(argv: readonly string[], cwd: string): string[];
14
- interface ServeOptions {
18
+ interface ServeOptions extends Pick<SkillServerOptions, "embedder" | "vectors" | "loadCatalog"> {
19
+ readonly mailbox?: MailboxService;
15
20
  /** One prompt per skill, for hosts that offer prompts as commands. */
16
21
  readonly prompts?: boolean;
17
22
  }
18
- declare function serve(catalog: CatalogOptions, serving?: ServeOptions): void;
23
+ declare function serve(catalog: CatalogOptions, serving?: ServeOptions): ReturnType<typeof serveStdio>;
24
+ declare function serveWithMailbox(catalog: CatalogOptions, mailbox: MailboxAttachmentOptions, serving?: ServeOptions): Promise<() => Promise<void>>;
19
25
  declare function main(argv?: readonly string[]): void;
20
26
 
21
- export { type ServeOptions, main, resolveRoots, serve };
27
+ export { type ServeOptions, main, resolveRoots, serve, serveWithMailbox };
package/dist/stdio.js CHANGED
@@ -2,12 +2,17 @@
2
2
  import {
3
3
  main,
4
4
  resolveRoots,
5
- serve
6
- } from "./chunk-EIHMCKY5.js";
7
- import "./chunk-A5NOHVHN.js";
5
+ serve,
6
+ serveWithMailbox
7
+ } from "./chunk-JRSR4JBR.js";
8
+ import "./chunk-VRZFM2M5.js";
9
+ import "./chunk-HNAVQG6R.js";
10
+ import "./chunk-MSTKY33C.js";
11
+ import "./chunk-XOH2CW6P.js";
8
12
  export {
9
13
  main,
10
14
  resolveRoots,
11
- serve
15
+ serve,
16
+ serveWithMailbox
12
17
  };
13
18
  //# sourceMappingURL=stdio.js.map