@modootoday/pmcp 0.9.1 → 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 +177 -8
- package/dist/attachment-tU5FZrgZ.d.ts +17 -0
- package/dist/chunk-HNAVQG6R.js +1198 -0
- package/dist/chunk-JRSR4JBR.js +88 -0
- package/dist/chunk-MSTKY33C.js +147 -0
- package/dist/{chunk-VQHNG3KM.js → chunk-VRZFM2M5.js} +53 -75
- package/dist/chunk-XEH4ZGGJ.js +336 -0
- package/dist/chunk-XOH2CW6P.js +297 -0
- package/dist/{chunk-QCOJ3WCM.js → chunk-ZUFFVIHQ.js} +166 -117
- package/dist/cli.js +507 -74
- package/dist/config-CJ43_oBS.d.ts +49 -0
- package/dist/embed-BBhv3y5x.d.ts +53 -0
- package/dist/encoder-DGRy9skC.d.ts +36 -0
- package/dist/http.d.ts +7 -38
- package/dist/http.js +18 -7
- package/dist/index.d.ts +25 -44
- package/dist/index.js +31 -11
- package/dist/mailbox/index.d.ts +44 -0
- package/dist/mailbox/index.js +387 -0
- package/dist/{server-BBZDjzWZ.d.ts → server-CwWcRjqz.d.ts} +135 -15
- package/dist/service-qpCsOXkQ.d.ts +116 -0
- package/dist/stdio.d.ts +10 -4
- package/dist/stdio.js +9 -4
- package/package.json +5 -1
- package/dist/catalog-BU5VLLyd.d.ts +0 -121
- package/dist/chunk-7DD2ADL2.js +0 -160
- package/dist/chunk-AJYMOFVX.js +0 -41
- package/dist/chunk-R2QPKEI4.js +0 -134
package/dist/cli.js
CHANGED
|
@@ -1,31 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
loadEmbedder,
|
|
4
|
-
openEntryVectors
|
|
5
|
-
} from "./chunk-7DD2ADL2.js";
|
|
6
|
-
import {
|
|
7
|
-
ConfigError,
|
|
8
3
|
ProjectError,
|
|
9
4
|
TOOLS,
|
|
10
5
|
doctor,
|
|
11
|
-
|
|
6
|
+
prepareSearch,
|
|
12
7
|
project,
|
|
13
|
-
readConfig,
|
|
14
8
|
readSpec,
|
|
15
9
|
renderFrontmatter,
|
|
16
10
|
spawnRunner,
|
|
17
11
|
splitFrontmatter,
|
|
18
12
|
validateCatalog,
|
|
19
13
|
validateSkillDir
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import
|
|
14
|
+
} from "./chunk-ZUFFVIHQ.js";
|
|
15
|
+
import {
|
|
16
|
+
loadEmbedder,
|
|
17
|
+
openEntryVectors
|
|
18
|
+
} from "./chunk-XEH4ZGGJ.js";
|
|
22
19
|
import {
|
|
23
|
-
serve
|
|
24
|
-
|
|
20
|
+
serve,
|
|
21
|
+
serveWithMailbox
|
|
22
|
+
} from "./chunk-JRSR4JBR.js";
|
|
25
23
|
import {
|
|
26
24
|
kindOf,
|
|
27
25
|
readCatalog
|
|
28
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-VRZFM2M5.js";
|
|
27
|
+
import {
|
|
28
|
+
MailboxError,
|
|
29
|
+
MailboxService,
|
|
30
|
+
MailboxStore,
|
|
31
|
+
failure,
|
|
32
|
+
initializeMailboxConfig,
|
|
33
|
+
mailboxConfigFrom,
|
|
34
|
+
readBinding,
|
|
35
|
+
readCredential,
|
|
36
|
+
restoreBackup,
|
|
37
|
+
writePrivateJson
|
|
38
|
+
} from "./chunk-HNAVQG6R.js";
|
|
39
|
+
import {
|
|
40
|
+
ConfigError,
|
|
41
|
+
findConfig,
|
|
42
|
+
readConfig
|
|
43
|
+
} from "./chunk-MSTKY33C.js";
|
|
44
|
+
import {
|
|
45
|
+
embeddingModels,
|
|
46
|
+
operationSchema,
|
|
47
|
+
resolveEncoder
|
|
48
|
+
} from "./chunk-XOH2CW6P.js";
|
|
29
49
|
|
|
30
50
|
// src/cli/command.ts
|
|
31
51
|
var ArgumentError = class extends Error {
|
|
@@ -204,6 +224,13 @@ var Ui = class {
|
|
|
204
224
|
}
|
|
205
225
|
};
|
|
206
226
|
|
|
227
|
+
// src/commands/reindex.ts
|
|
228
|
+
import { existsSync, mkdirSync } from "fs";
|
|
229
|
+
import { dirname } from "path";
|
|
230
|
+
|
|
231
|
+
// src/commands/embedding.ts
|
|
232
|
+
import { resolve } from "path";
|
|
233
|
+
|
|
207
234
|
// src/commands/roots.ts
|
|
208
235
|
var CATALOG_OPTIONS = [
|
|
209
236
|
{
|
|
@@ -290,6 +317,87 @@ function catalogFrom(context, onReject) {
|
|
|
290
317
|
return readCatalog(catalogOptionsFrom(context, onReject));
|
|
291
318
|
}
|
|
292
319
|
|
|
320
|
+
// src/commands/embedding.ts
|
|
321
|
+
var EMBEDDING_OPTIONS = [
|
|
322
|
+
{
|
|
323
|
+
name: "model",
|
|
324
|
+
describe: "Embedding preset or model ID; list presets with pmcp models",
|
|
325
|
+
placeholder: "<name>"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: "dtype",
|
|
329
|
+
describe: "Weight precision; uses the selected model default when omitted",
|
|
330
|
+
placeholder: "<q4|q8|fp32>"
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: "dimensions",
|
|
334
|
+
describe: "Supported output width; uses the model's full output when omitted",
|
|
335
|
+
placeholder: "<number>"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: "model-revision",
|
|
339
|
+
describe: "Model revision used for loading and index identity",
|
|
340
|
+
placeholder: "<revision>"
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: "model-path",
|
|
344
|
+
describe: "Local model artifact directory",
|
|
345
|
+
placeholder: "<dir>"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: "model-cache",
|
|
349
|
+
describe: "Model cache directory",
|
|
350
|
+
placeholder: "<dir>"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
name: "query-prefix",
|
|
354
|
+
describe: "Custom model's query instruction prefix",
|
|
355
|
+
placeholder: "<text>"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: "passage-prefix",
|
|
359
|
+
describe: "Custom model's document instruction prefix",
|
|
360
|
+
placeholder: "<text>"
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
name: "pooling",
|
|
364
|
+
describe: "Custom model's pooling method",
|
|
365
|
+
placeholder: "<mean|cls>"
|
|
366
|
+
}
|
|
367
|
+
];
|
|
368
|
+
function embeddingFrom(context) {
|
|
369
|
+
const configuration = configFrom(context)?.embedding ?? {};
|
|
370
|
+
const dimension = one(context.args, "dimensions");
|
|
371
|
+
const modelPath = one(context.args, "model-path");
|
|
372
|
+
const cacheDir = one(context.args, "model-cache");
|
|
373
|
+
const queryPrefix = one(context.args, "query-prefix");
|
|
374
|
+
const passagePrefix = one(context.args, "passage-prefix");
|
|
375
|
+
const pooling = one(context.args, "pooling");
|
|
376
|
+
const selection = {
|
|
377
|
+
...configuration,
|
|
378
|
+
modelId: one(context.args, "model") ?? configuration.modelId,
|
|
379
|
+
dtype: one(context.args, "dtype") ?? configuration.dtype,
|
|
380
|
+
dimensions: dimension === void 0 ? configuration.dimensions : Number(dimension),
|
|
381
|
+
revision: one(context.args, "model-revision") ?? configuration.revision,
|
|
382
|
+
modelPath: modelPath === void 0 ? configuration.modelPath : resolve(context.cwd, modelPath),
|
|
383
|
+
cacheDir: cacheDir === void 0 ? configuration.cacheDir : resolve(context.cwd, cacheDir),
|
|
384
|
+
encoder: {
|
|
385
|
+
...configuration.encoder,
|
|
386
|
+
...queryPrefix === void 0 ? {} : { queryPrefix },
|
|
387
|
+
...passagePrefix === void 0 ? {} : { passagePrefix },
|
|
388
|
+
...pooling === void 0 ? {} : { pooling }
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
try {
|
|
392
|
+
resolveEncoder(selection.modelId, selection);
|
|
393
|
+
} catch (error) {
|
|
394
|
+
throw new ArgumentError(
|
|
395
|
+
error instanceof Error ? error.message : "Invalid embedding options"
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
return selection;
|
|
399
|
+
}
|
|
400
|
+
|
|
293
401
|
// src/commands/reindex.ts
|
|
294
402
|
function indexPath(root) {
|
|
295
403
|
return `${root}/.cache/pmcp/vectors.sqlite`;
|
|
@@ -300,10 +408,12 @@ var indexCommand = {
|
|
|
300
408
|
usage: "pmcp index [--root <dir>] [--model <id>]",
|
|
301
409
|
options: [
|
|
302
410
|
...CATALOG_OPTIONS,
|
|
411
|
+
...EMBEDDING_OPTIONS,
|
|
412
|
+
{ name: "local-only", describe: "Refuse model downloads", boolean: true },
|
|
303
413
|
{
|
|
304
|
-
name: "
|
|
305
|
-
describe: "
|
|
306
|
-
|
|
414
|
+
name: "force",
|
|
415
|
+
describe: "Re-encode the selected model even when descriptions match",
|
|
416
|
+
boolean: true
|
|
307
417
|
},
|
|
308
418
|
{
|
|
309
419
|
name: "json",
|
|
@@ -323,8 +433,28 @@ var indexCommand = {
|
|
|
323
433
|
return 1;
|
|
324
434
|
}
|
|
325
435
|
const dryRun = context.args.flags.has("dry-run");
|
|
326
|
-
const
|
|
327
|
-
const
|
|
436
|
+
const selection = embeddingFrom(context);
|
|
437
|
+
const selected = resolveEncoder(selection.modelId, selection);
|
|
438
|
+
const path = indexPath(rootsFrom(context)[0] ?? ".");
|
|
439
|
+
const descriptions = new Map(
|
|
440
|
+
entries.map((entry2) => [entry2.name, entry2.description])
|
|
441
|
+
);
|
|
442
|
+
const force = context.args.flags.has("force");
|
|
443
|
+
if (dryRun) {
|
|
444
|
+
const existing = existsSync(path) ? await openEntryVectors(path, { readOnly: true }) : null;
|
|
445
|
+
try {
|
|
446
|
+
const pending = !force && existing ? existing.stale(selected.indexKey, descriptions) : [...descriptions.keys()];
|
|
447
|
+
for (const name of pending) context.ui.line(` would encode ${name}`);
|
|
448
|
+
context.ui.info("dry run, nothing written");
|
|
449
|
+
return 0;
|
|
450
|
+
} finally {
|
|
451
|
+
existing?.close();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
const embedder = await loadEmbedder(selected.modelId, {
|
|
455
|
+
...selection,
|
|
456
|
+
localOnly: context.args.flags.has("local-only")
|
|
457
|
+
});
|
|
328
458
|
if (embedder === null) {
|
|
329
459
|
context.ui.error(
|
|
330
460
|
"semantic ranking needs an encoder that is not installed"
|
|
@@ -333,9 +463,8 @@ var indexCommand = {
|
|
|
333
463
|
context.ui.info("ranking stays lexical until then, which is the default");
|
|
334
464
|
return 3;
|
|
335
465
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
);
|
|
466
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
467
|
+
const store = await openEntryVectors(path);
|
|
339
468
|
if (store === null) {
|
|
340
469
|
context.ui.error(
|
|
341
470
|
"no sqlite in this runtime, so vectors cannot be stored"
|
|
@@ -343,29 +472,29 @@ var indexCommand = {
|
|
|
343
472
|
return 1;
|
|
344
473
|
}
|
|
345
474
|
try {
|
|
346
|
-
const
|
|
347
|
-
const stale = new Set(
|
|
475
|
+
const key = embedder.indexKey ?? selected.indexKey;
|
|
476
|
+
const stale = new Set(
|
|
477
|
+
force ? [...descriptions.keys()] : store.stale(key, descriptions)
|
|
478
|
+
);
|
|
348
479
|
const todo = entries.filter((entry2) => stale.has(entry2.name));
|
|
349
480
|
context.ui.info(
|
|
350
481
|
`${todo.length} of ${entries.length} to encode`,
|
|
351
482
|
embedder.modelId
|
|
352
483
|
);
|
|
353
|
-
if (dryRun) {
|
|
354
|
-
for (const entry2 of todo)
|
|
355
|
-
context.ui.line(` would encode ${entry2.name}`);
|
|
356
|
-
context.ui.info("dry run, nothing written");
|
|
357
|
-
return 0;
|
|
358
|
-
}
|
|
359
484
|
for (const entry2 of todo) {
|
|
360
485
|
const vector = embedder.embedPassage ? await embedder.embedPassage(entry2.description) : await embedder.embed(entry2.description);
|
|
361
|
-
store.write(
|
|
486
|
+
store.write(key, entry2.name, entry2.description, vector);
|
|
362
487
|
}
|
|
363
|
-
const indexed = store.read(
|
|
488
|
+
const indexed = store.read(key).size;
|
|
364
489
|
if (context.args.flags.has("json")) {
|
|
365
490
|
context.ui.data(
|
|
366
491
|
`${JSON.stringify(
|
|
367
492
|
{
|
|
368
493
|
model: embedder.modelId,
|
|
494
|
+
indexKey: key,
|
|
495
|
+
dtype: selected.dtype,
|
|
496
|
+
revision: selected.revision,
|
|
497
|
+
dimensions: embedder.dims || selected.dimensions,
|
|
369
498
|
encoded: todo.length,
|
|
370
499
|
indexed,
|
|
371
500
|
catalog: entries.length
|
|
@@ -391,6 +520,31 @@ var indexCommand = {
|
|
|
391
520
|
}
|
|
392
521
|
};
|
|
393
522
|
|
|
523
|
+
// src/commands/models.ts
|
|
524
|
+
var modelsCommand = {
|
|
525
|
+
name: "models",
|
|
526
|
+
describe: "List embedding presets without loading or downloading models",
|
|
527
|
+
usage: "pmcp models [--json]",
|
|
528
|
+
options: [
|
|
529
|
+
{ name: "json", describe: "Emit preset metadata as JSON", boolean: true }
|
|
530
|
+
],
|
|
531
|
+
run(context) {
|
|
532
|
+
const models = embeddingModels();
|
|
533
|
+
if (context.args.flags.has("json")) {
|
|
534
|
+
context.ui.data(`${JSON.stringify(models, null, 2)}
|
|
535
|
+
`);
|
|
536
|
+
return 0;
|
|
537
|
+
}
|
|
538
|
+
context.ui.table(
|
|
539
|
+
models.map((model) => [
|
|
540
|
+
model.name,
|
|
541
|
+
`${model.modelId} (${model.dtype}; dimensions: ${model.dimensions.join(", ")})`
|
|
542
|
+
])
|
|
543
|
+
);
|
|
544
|
+
return 0;
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
|
|
394
548
|
// src/commands/list.ts
|
|
395
549
|
var listCommand = {
|
|
396
550
|
name: "list",
|
|
@@ -446,6 +600,11 @@ var listCommand = {
|
|
|
446
600
|
}
|
|
447
601
|
};
|
|
448
602
|
|
|
603
|
+
// src/cli/invocation.ts
|
|
604
|
+
function invocation(env = process.env) {
|
|
605
|
+
return env["npm_command"] === "exec" ? "npx -y @modootoday/pmcp" : "pmcp";
|
|
606
|
+
}
|
|
607
|
+
|
|
449
608
|
// src/commands/serve.ts
|
|
450
609
|
var serveCommand = {
|
|
451
610
|
name: "serve",
|
|
@@ -453,31 +612,101 @@ var serveCommand = {
|
|
|
453
612
|
usage: "pmcp serve [--root <dir>] [--scope <prefix>] [--marketplace <dir>] [--package <dir>] [--workspace <dir>] [--config <file> | --no-config] [--prompts]",
|
|
454
613
|
options: [
|
|
455
614
|
...CATALOG_OPTIONS,
|
|
615
|
+
...EMBEDDING_OPTIONS,
|
|
616
|
+
{
|
|
617
|
+
name: "lexical",
|
|
618
|
+
describe: "Skip semantic index and model loading",
|
|
619
|
+
boolean: true
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
name: "mailbox-actor-file",
|
|
623
|
+
describe: "Private launcher actor credential for opt-in mailbox",
|
|
624
|
+
placeholder: "<file>"
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
name: "mailbox-binding-file",
|
|
628
|
+
describe: "Private attachment file written by the launcher",
|
|
629
|
+
placeholder: "<file>"
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
name: "mailbox-runtime",
|
|
633
|
+
describe: "Launcher-assigned canonical runtime",
|
|
634
|
+
placeholder: "<runtime>"
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
name: "mailbox-replace-session",
|
|
638
|
+
describe: "Exact old attachment ID to replace",
|
|
639
|
+
placeholder: "<id>"
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
name: "mailbox-native-session",
|
|
643
|
+
describe: "Launcher-owned native session ID",
|
|
644
|
+
placeholder: "<id>"
|
|
645
|
+
},
|
|
456
646
|
{
|
|
457
647
|
name: "prompts",
|
|
458
648
|
describe: "Also offer one prompt per skill, for hosts that turn prompts into commands.",
|
|
459
649
|
boolean: true
|
|
460
650
|
}
|
|
461
651
|
],
|
|
462
|
-
run(context) {
|
|
463
|
-
|
|
464
|
-
|
|
652
|
+
async run(context) {
|
|
653
|
+
const selection = embeddingFrom(context);
|
|
654
|
+
const project2 = configFrom(context);
|
|
655
|
+
const mailbox = project2 ? mailboxConfigFrom(project2, context.env) : void 0;
|
|
656
|
+
const actorFile = one(context.args, "mailbox-actor-file") ?? context.env.PMCP_MAILBOX_ACTOR_FILE;
|
|
657
|
+
const runtime = one(context.args, "mailbox-runtime") ?? context.env.PMCP_MAILBOX_RUNTIME;
|
|
658
|
+
const catalog = catalogOptionsFrom(context);
|
|
659
|
+
const search = context.args.flags.has("lexical") || selection.enabled === false ? void 0 : await prepareSearch(catalog, {
|
|
660
|
+
indexPath: indexPath(rootsFrom(context)[0] ?? "."),
|
|
661
|
+
...selection,
|
|
662
|
+
localOnly: true
|
|
465
663
|
});
|
|
664
|
+
if (search && search.reason !== "index_missing") {
|
|
665
|
+
const hint = search.reason ? ` reason=${search.reason}; run ${invocation(context.env)} index with the selected model` : "";
|
|
666
|
+
process.stderr.write(`pmcp: search ranking=${search.ranking}${hint}
|
|
667
|
+
`);
|
|
668
|
+
}
|
|
669
|
+
const serving = {
|
|
670
|
+
prompts: context.args.flags.has("prompts"),
|
|
671
|
+
...search?.options
|
|
672
|
+
};
|
|
673
|
+
if (actorFile) {
|
|
674
|
+
if (!mailbox?.enabled)
|
|
675
|
+
throw new ArgumentError("Enable [mailbox] before attaching an actor");
|
|
676
|
+
if (!runtime)
|
|
677
|
+
throw new ArgumentError(
|
|
678
|
+
"Provide --mailbox-runtime or PMCP_MAILBOX_RUNTIME"
|
|
679
|
+
);
|
|
680
|
+
await serveWithMailbox(
|
|
681
|
+
catalogOptionsFrom(context),
|
|
682
|
+
{
|
|
683
|
+
config: mailbox,
|
|
684
|
+
actorFile,
|
|
685
|
+
runtime,
|
|
686
|
+
bindingFile: one(context.args, "mailbox-binding-file") ?? context.env.PMCP_MAILBOX_BINDING_FILE,
|
|
687
|
+
replaceSessionId: one(context.args, "mailbox-replace-session"),
|
|
688
|
+
nativeSessionId: one(context.args, "mailbox-native-session")
|
|
689
|
+
},
|
|
690
|
+
serving
|
|
691
|
+
);
|
|
692
|
+
return 0;
|
|
693
|
+
}
|
|
694
|
+
if ([...context.args.options.keys()].some(
|
|
695
|
+
(name) => name.startsWith("mailbox-")
|
|
696
|
+
) || runtime || context.env.PMCP_MAILBOX_BINDING_FILE) {
|
|
697
|
+
throw new ArgumentError("Provide a launcher mailbox actor file");
|
|
698
|
+
}
|
|
699
|
+
serve(catalogOptionsFrom(context), serving);
|
|
466
700
|
return 0;
|
|
467
701
|
}
|
|
468
702
|
};
|
|
469
703
|
|
|
470
|
-
// src/cli/invocation.ts
|
|
471
|
-
function invocation(env = process.env) {
|
|
472
|
-
return env["npm_command"] === "exec" ? "npx -y @modootoday/pmcp" : "pmcp";
|
|
473
|
-
}
|
|
474
|
-
|
|
475
704
|
// src/remote/session.ts
|
|
476
705
|
import {
|
|
477
706
|
chmodSync,
|
|
478
707
|
closeSync,
|
|
479
708
|
fchmodSync,
|
|
480
|
-
mkdirSync,
|
|
709
|
+
mkdirSync as mkdirSync2,
|
|
481
710
|
openSync,
|
|
482
711
|
readFileSync,
|
|
483
712
|
rmSync,
|
|
@@ -609,7 +838,7 @@ function readSession(home) {
|
|
|
609
838
|
function writeSession(session, home) {
|
|
610
839
|
const path = sessionPath(home);
|
|
611
840
|
const directory = globalDir(home);
|
|
612
|
-
|
|
841
|
+
mkdirSync2(directory, { recursive: true, mode: 448 });
|
|
613
842
|
chmodSync(directory, 448);
|
|
614
843
|
const fd = openSync(path, "w", 384);
|
|
615
844
|
try {
|
|
@@ -655,7 +884,7 @@ var DEFAULT_RESOURCE = "https://api.pmcp.build";
|
|
|
655
884
|
var DEFAULT_SCOPE = "pmcp:catalog:read pmcp:distribution:read";
|
|
656
885
|
var fetcher = (url, init) => fetch(url, init);
|
|
657
886
|
var setting = (env, name, fallback) => env[name] ?? fallback;
|
|
658
|
-
var wait = (ms) => new Promise((
|
|
887
|
+
var wait = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
659
888
|
var loginCommand = {
|
|
660
889
|
name: "login",
|
|
661
890
|
describe: "Sign in on this machine, to obtain skills this project lacks",
|
|
@@ -824,7 +1053,7 @@ function sayStanding(context, line) {
|
|
|
824
1053
|
|
|
825
1054
|
// src/installed.ts
|
|
826
1055
|
import { readFileSync as readFileSync2 } from "fs";
|
|
827
|
-
import { dirname, join as join2, resolve } from "path";
|
|
1056
|
+
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
828
1057
|
function object(value) {
|
|
829
1058
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
830
1059
|
}
|
|
@@ -845,7 +1074,7 @@ function locate(name, project2) {
|
|
|
845
1074
|
);
|
|
846
1075
|
} catch (error) {
|
|
847
1076
|
if (!absent(error)) return { name, reason: "unreadable_manifest" };
|
|
848
|
-
const parent =
|
|
1077
|
+
const parent = dirname2(directory);
|
|
849
1078
|
if (parent === directory) return { name, reason: "not_installed" };
|
|
850
1079
|
directory = parent;
|
|
851
1080
|
continue;
|
|
@@ -867,7 +1096,7 @@ function locate(name, project2) {
|
|
|
867
1096
|
}
|
|
868
1097
|
}
|
|
869
1098
|
function readInstalledDependencies(projectDirectory) {
|
|
870
|
-
const project2 =
|
|
1099
|
+
const project2 = resolve2(projectDirectory);
|
|
871
1100
|
const manifest = JSON.parse(
|
|
872
1101
|
readFileSync2(join2(project2, "package.json"), "utf8")
|
|
873
1102
|
);
|
|
@@ -902,8 +1131,8 @@ function readInstalledDependencies(projectDirectory) {
|
|
|
902
1131
|
|
|
903
1132
|
// src/install/plan.ts
|
|
904
1133
|
import { createHash } from "crypto";
|
|
905
|
-
import { existsSync, readFileSync as readFileSync3 } from "fs";
|
|
906
|
-
import { dirname as
|
|
1134
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
|
|
1135
|
+
import { dirname as dirname3, join as join3, relative, resolve as resolve3, sep } from "path";
|
|
907
1136
|
import semver from "semver";
|
|
908
1137
|
function matchingSkills(catalog, inventory) {
|
|
909
1138
|
const matches = [];
|
|
@@ -955,25 +1184,25 @@ function manifestAt(directory) {
|
|
|
955
1184
|
return value;
|
|
956
1185
|
}
|
|
957
1186
|
function installContext(directory) {
|
|
958
|
-
const project2 =
|
|
1187
|
+
const project2 = resolve3(directory);
|
|
959
1188
|
const manifest = manifestAt(project2);
|
|
960
1189
|
let root = project2;
|
|
961
1190
|
let ancestor = project2;
|
|
962
1191
|
for (; ; ) {
|
|
963
|
-
if (ancestor !== project2 &&
|
|
1192
|
+
if (ancestor !== project2 && existsSync2(join3(ancestor, "package.json"))) {
|
|
964
1193
|
const candidate = manifestAt(ancestor);
|
|
965
1194
|
if (candidate.workspaces !== void 0) {
|
|
966
1195
|
root = ancestor;
|
|
967
1196
|
break;
|
|
968
1197
|
}
|
|
969
|
-
if (LOCKS.some((file) =>
|
|
1198
|
+
if (LOCKS.some((file) => existsSync2(join3(ancestor, file)))) break;
|
|
970
1199
|
}
|
|
971
|
-
if (
|
|
1200
|
+
if (existsSync2(join3(ancestor, ".git")) || dirname3(ancestor) === ancestor)
|
|
972
1201
|
break;
|
|
973
|
-
ancestor =
|
|
1202
|
+
ancestor = dirname3(ancestor);
|
|
974
1203
|
}
|
|
975
1204
|
const owner = manifestAt(root);
|
|
976
|
-
const lockNames = LOCKS.filter((file) =>
|
|
1205
|
+
const lockNames = LOCKS.filter((file) => existsSync2(join3(root, file)));
|
|
977
1206
|
const lockManagers = new Set(
|
|
978
1207
|
lockNames.map((file) => {
|
|
979
1208
|
if (file.startsWith("bun.")) return "bun";
|
|
@@ -997,7 +1226,7 @@ function installContext(directory) {
|
|
|
997
1226
|
throw new Error(
|
|
998
1227
|
"declare packageManager or install project dependencies first"
|
|
999
1228
|
);
|
|
1000
|
-
if (root !== project2 && LOCKS.some((file) =>
|
|
1229
|
+
if (root !== project2 && LOCKS.some((file) => existsSync2(join3(project2, file)))) {
|
|
1001
1230
|
throw new Error(
|
|
1002
1231
|
"nested project has its own lockfile; resolve the workspace boundary first"
|
|
1003
1232
|
);
|
|
@@ -1114,7 +1343,7 @@ function planInstall(options) {
|
|
|
1114
1343
|
}
|
|
1115
1344
|
|
|
1116
1345
|
// src/commands/remote-options.ts
|
|
1117
|
-
import { resolve as
|
|
1346
|
+
import { resolve as resolve4 } from "path";
|
|
1118
1347
|
|
|
1119
1348
|
// src/remote/catalog.ts
|
|
1120
1349
|
import { readFileSync as readFileSync5, statSync } from "fs";
|
|
@@ -1122,7 +1351,7 @@ import semver2 from "semver";
|
|
|
1122
1351
|
import { z } from "zod";
|
|
1123
1352
|
|
|
1124
1353
|
// src/remote/catalog-cache.ts
|
|
1125
|
-
import { mkdirSync as
|
|
1354
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync, writeFileSync } from "fs";
|
|
1126
1355
|
import { join as join4 } from "path";
|
|
1127
1356
|
var MAX_CACHE_BYTES = 8 * 1024 * 1024;
|
|
1128
1357
|
function memoryCatalogCache() {
|
|
@@ -1156,7 +1385,7 @@ function fileCatalogCache(dir) {
|
|
|
1156
1385
|
write(origin, entry2) {
|
|
1157
1386
|
try {
|
|
1158
1387
|
if (entry2.body.length > MAX_CACHE_BYTES) return;
|
|
1159
|
-
|
|
1388
|
+
mkdirSync3(dir, { recursive: true });
|
|
1160
1389
|
const temporary = `${path}.${String(process.pid)}`;
|
|
1161
1390
|
writeFileSync(
|
|
1162
1391
|
temporary,
|
|
@@ -1347,7 +1576,7 @@ var REMOTE_OPTIONS = [
|
|
|
1347
1576
|
{ name: "json", describe: "Print machine-readable results.", boolean: true }
|
|
1348
1577
|
];
|
|
1349
1578
|
function projectFrom(context) {
|
|
1350
|
-
return
|
|
1579
|
+
return resolve4(context.cwd, one(context.args, "project") ?? ".");
|
|
1351
1580
|
}
|
|
1352
1581
|
function apiOrigin(context) {
|
|
1353
1582
|
return one(context.args, "api") ?? context.env["PMCP_API_ORIGIN"] ?? DEFAULT_API_ORIGIN;
|
|
@@ -1357,7 +1586,7 @@ async function remoteCatalog(context) {
|
|
|
1357
1586
|
if (file) {
|
|
1358
1587
|
if (one(context.args, "api"))
|
|
1359
1588
|
throw new Error("choose --catalog or --api, not both");
|
|
1360
|
-
return readCatalogFile(
|
|
1589
|
+
return readCatalogFile(resolve4(context.cwd, file));
|
|
1361
1590
|
}
|
|
1362
1591
|
return fetchCatalog(apiOrigin(context), fetch, fileCatalogCache(globalDir()));
|
|
1363
1592
|
}
|
|
@@ -1582,7 +1811,7 @@ function applyInstallPlan(plan, runner = packageManagerRunner) {
|
|
|
1582
1811
|
// src/install/verify-content.ts
|
|
1583
1812
|
import { createHash as createHash2 } from "crypto";
|
|
1584
1813
|
import { readdirSync, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
|
|
1585
|
-
import { join as join5, relative as relative2, resolve as
|
|
1814
|
+
import { join as join5, relative as relative2, resolve as resolve5, sep as sep2 } from "path";
|
|
1586
1815
|
var SKILL = "SKILL.md";
|
|
1587
1816
|
var SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", ".cache"]);
|
|
1588
1817
|
function skillFiles(root) {
|
|
@@ -1623,7 +1852,7 @@ function contentDigest(files) {
|
|
|
1623
1852
|
return `sha256:${hash.digest("hex")}`;
|
|
1624
1853
|
}
|
|
1625
1854
|
function verifyInstalledContent(project2, packageName2, expected) {
|
|
1626
|
-
const root =
|
|
1855
|
+
const root = resolve5(project2, "node_modules", ...packageName2.split("/"));
|
|
1627
1856
|
const files = skillFiles(root);
|
|
1628
1857
|
const actual = contentDigest(files);
|
|
1629
1858
|
return {
|
|
@@ -2005,14 +2234,14 @@ import { homedir as homedir2 } from "os";
|
|
|
2005
2234
|
// src/project/edit.ts
|
|
2006
2235
|
import {
|
|
2007
2236
|
cpSync,
|
|
2008
|
-
existsSync as
|
|
2009
|
-
mkdirSync as
|
|
2237
|
+
existsSync as existsSync3,
|
|
2238
|
+
mkdirSync as mkdirSync4,
|
|
2010
2239
|
readFileSync as readFileSync7,
|
|
2011
2240
|
rmSync as rmSync3,
|
|
2012
2241
|
statSync as statSync3,
|
|
2013
2242
|
writeFileSync as writeFileSync3
|
|
2014
2243
|
} from "fs";
|
|
2015
|
-
import { basename, dirname as
|
|
2244
|
+
import { basename, dirname as dirname4, join as join7 } from "path";
|
|
2016
2245
|
var CROSS_TOOL = ["name", "description"];
|
|
2017
2246
|
var tomlValue = (value) => JSON.stringify(value);
|
|
2018
2247
|
function findEntry(entries, wanted) {
|
|
@@ -2045,14 +2274,14 @@ function addEntry(root, entry2) {
|
|
|
2045
2274
|
}
|
|
2046
2275
|
if (kind === "skill") {
|
|
2047
2276
|
const dest2 = join7(root, ".agents/skills", name);
|
|
2048
|
-
if (
|
|
2277
|
+
if (existsSync3(dest2))
|
|
2049
2278
|
throw new ProjectError(`.agents/skills/${name} already exists`);
|
|
2050
|
-
const source = entry2.root ??
|
|
2051
|
-
|
|
2279
|
+
const source = entry2.root ?? dirname4(entry2.path);
|
|
2280
|
+
mkdirSync4(dirname4(dest2), { recursive: true });
|
|
2052
2281
|
if (statSync3(source).isDirectory()) {
|
|
2053
2282
|
cpSync(source, dest2, { recursive: true });
|
|
2054
2283
|
} else {
|
|
2055
|
-
|
|
2284
|
+
mkdirSync4(dest2);
|
|
2056
2285
|
}
|
|
2057
2286
|
const head = renderFrontmatter({
|
|
2058
2287
|
...meta,
|
|
@@ -2067,7 +2296,7 @@ ${body.replace(/^\n/u, "")}`
|
|
|
2067
2296
|
return { kind, name, path: `.agents/skills/${name}` };
|
|
2068
2297
|
}
|
|
2069
2298
|
const dest = join7(root, ".agents/agents", name);
|
|
2070
|
-
if (
|
|
2299
|
+
if (existsSync3(dest))
|
|
2071
2300
|
throw new ProjectError(`.agents/agents/${name} already exists`);
|
|
2072
2301
|
const kept = {};
|
|
2073
2302
|
const moved = {};
|
|
@@ -2075,7 +2304,7 @@ ${body.replace(/^\n/u, "")}`
|
|
|
2075
2304
|
if (CROSS_TOOL.includes(key)) kept[key] = value;
|
|
2076
2305
|
else moved[key] = value;
|
|
2077
2306
|
}
|
|
2078
|
-
|
|
2307
|
+
mkdirSync4(dest, { recursive: true });
|
|
2079
2308
|
writeFileSync3(
|
|
2080
2309
|
join7(dest, "agent.md"),
|
|
2081
2310
|
`${renderFrontmatter(kept)}
|
|
@@ -2087,7 +2316,7 @@ ${body.replace(/^\n/u, "")}`
|
|
|
2087
2316
|
`[agents.${name}.claude]`,
|
|
2088
2317
|
...Object.entries(moved).map(([k, v]) => `${k} = ${tomlValue(v)}`)
|
|
2089
2318
|
];
|
|
2090
|
-
const before =
|
|
2319
|
+
const before = existsSync3(config) ? readFileSync7(config, "utf8") : "";
|
|
2091
2320
|
const sep3 = before === "" || before.endsWith("\n\n") ? "" : "\n";
|
|
2092
2321
|
writeFileSync3(config, `${before}${sep3}${lines.join("\n")}
|
|
2093
2322
|
`);
|
|
@@ -2110,14 +2339,14 @@ function withoutTables(toml, name) {
|
|
|
2110
2339
|
function removeAsset(root, name) {
|
|
2111
2340
|
const removed = [];
|
|
2112
2341
|
for (const rel of [`.agents/skills/${name}`, `.agents/agents/${name}`]) {
|
|
2113
|
-
if (!
|
|
2342
|
+
if (!existsSync3(join7(root, rel))) continue;
|
|
2114
2343
|
rmSync3(join7(root, rel), { recursive: true, force: true });
|
|
2115
2344
|
removed.push(rel);
|
|
2116
2345
|
}
|
|
2117
2346
|
if (removed.length === 0)
|
|
2118
2347
|
throw new ProjectError(`no skill or agent named ${name} in .agents/`);
|
|
2119
2348
|
const config = join7(root, "pmcp.toml");
|
|
2120
|
-
if (
|
|
2349
|
+
if (existsSync3(config)) {
|
|
2121
2350
|
const before = readFileSync7(config, "utf8");
|
|
2122
2351
|
const after = withoutTables(before, name);
|
|
2123
2352
|
if (after !== before) writeFileSync3(config, after);
|
|
@@ -2287,11 +2516,214 @@ var validateCommand = {
|
|
|
2287
2516
|
}
|
|
2288
2517
|
};
|
|
2289
2518
|
|
|
2519
|
+
// src/commands/mailbox.ts
|
|
2520
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
|
|
2521
|
+
import { resolve as resolve6 } from "path";
|
|
2522
|
+
var allowed = {
|
|
2523
|
+
init: ["config", "state-dir"],
|
|
2524
|
+
actor: ["config", "actor", "actor-file", "parent-binding"],
|
|
2525
|
+
rotate: ["config", "actor", "actor-file", "operator"],
|
|
2526
|
+
send: ["config", "actor-file", "binding-file", "input"],
|
|
2527
|
+
inbox: ["config", "actor-file", "binding-file", "input"],
|
|
2528
|
+
read: ["config", "actor-file", "binding-file", "input"],
|
|
2529
|
+
ack: ["config", "actor-file", "binding-file", "input"],
|
|
2530
|
+
sessions: ["config", "actor-file", "binding-file"],
|
|
2531
|
+
export: ["config", "operator", "output", "scope-actor"],
|
|
2532
|
+
backup: ["config", "operator", "output"],
|
|
2533
|
+
restore: ["config", "operator", "input", "output"]
|
|
2534
|
+
};
|
|
2535
|
+
function required(context, name) {
|
|
2536
|
+
const value = one(context.args, name);
|
|
2537
|
+
if (!value) throw new ArgumentError(`Provide --${name}`);
|
|
2538
|
+
return value;
|
|
2539
|
+
}
|
|
2540
|
+
var mailboxCommand = {
|
|
2541
|
+
name: "mailbox",
|
|
2542
|
+
describe: "Manage opt-in local peer mail and launcher credentials",
|
|
2543
|
+
usage: "pmcp mailbox operation [--config <file>] [options]",
|
|
2544
|
+
options: [
|
|
2545
|
+
{ name: "config", describe: "Project pmcp.toml", placeholder: "<file>" },
|
|
2546
|
+
{
|
|
2547
|
+
name: "state-dir",
|
|
2548
|
+
describe: "Private mailbox state directory",
|
|
2549
|
+
placeholder: "<dir>"
|
|
2550
|
+
},
|
|
2551
|
+
{ name: "actor", describe: "Registered actor ID", placeholder: "<id>" },
|
|
2552
|
+
{
|
|
2553
|
+
name: "actor-file",
|
|
2554
|
+
describe: "Private actor credential file",
|
|
2555
|
+
placeholder: "<file>"
|
|
2556
|
+
},
|
|
2557
|
+
{
|
|
2558
|
+
name: "binding-file",
|
|
2559
|
+
describe: "Private existing attachment file",
|
|
2560
|
+
placeholder: "<file>"
|
|
2561
|
+
},
|
|
2562
|
+
{
|
|
2563
|
+
name: "parent-binding",
|
|
2564
|
+
describe: "Live parent attachment for bounded child delegation",
|
|
2565
|
+
placeholder: "<file>"
|
|
2566
|
+
},
|
|
2567
|
+
{
|
|
2568
|
+
name: "input",
|
|
2569
|
+
describe: "Operation input JSON or backup source",
|
|
2570
|
+
placeholder: "<file>"
|
|
2571
|
+
},
|
|
2572
|
+
{
|
|
2573
|
+
name: "output",
|
|
2574
|
+
describe: "New export or backup destination",
|
|
2575
|
+
placeholder: "<file>"
|
|
2576
|
+
},
|
|
2577
|
+
{
|
|
2578
|
+
name: "scope-actor",
|
|
2579
|
+
describe: "Limit export to one actor's correspondence",
|
|
2580
|
+
placeholder: "<id>"
|
|
2581
|
+
},
|
|
2582
|
+
{
|
|
2583
|
+
name: "operator",
|
|
2584
|
+
describe: "Explicit local administrator intent",
|
|
2585
|
+
boolean: true
|
|
2586
|
+
}
|
|
2587
|
+
],
|
|
2588
|
+
async run(context) {
|
|
2589
|
+
const [verb, ...extra] = context.args.positional;
|
|
2590
|
+
const supported = verb ? allowed[verb] : void 0;
|
|
2591
|
+
if (!supported || extra.length > 0)
|
|
2592
|
+
throw new ArgumentError("Provide one supported mailbox operation");
|
|
2593
|
+
for (const key of [...context.args.options.keys(), ...context.args.flags]) {
|
|
2594
|
+
if (!supported.includes(key))
|
|
2595
|
+
throw new ArgumentError(`--${key} is not supported by mailbox ${verb}`);
|
|
2596
|
+
}
|
|
2597
|
+
if (verb === "init") {
|
|
2598
|
+
const config2 = initializeMailboxConfig(
|
|
2599
|
+
resolve6(context.cwd, one(context.args, "config") ?? "pmcp.toml"),
|
|
2600
|
+
one(context.args, "state-dir")
|
|
2601
|
+
);
|
|
2602
|
+
const store2 = await MailboxStore.open(config2);
|
|
2603
|
+
await store2.close();
|
|
2604
|
+
context.ui.data(
|
|
2605
|
+
`${JSON.stringify({ ok: true, data: { projectId: config2.projectId } })}
|
|
2606
|
+
`
|
|
2607
|
+
);
|
|
2608
|
+
return 0;
|
|
2609
|
+
}
|
|
2610
|
+
const project2 = configFrom(context);
|
|
2611
|
+
const config = project2 ? mailboxConfigFrom(project2, context.env) : void 0;
|
|
2612
|
+
if (!config?.enabled)
|
|
2613
|
+
throw new MailboxError(
|
|
2614
|
+
"mailbox_disabled",
|
|
2615
|
+
"Enable [mailbox] in pmcp.toml first"
|
|
2616
|
+
);
|
|
2617
|
+
if (["export", "backup", "restore", "rotate"].includes(verb)) {
|
|
2618
|
+
if (!context.args.flags.has("operator"))
|
|
2619
|
+
throw new ArgumentError("Provide --operator for local administration");
|
|
2620
|
+
}
|
|
2621
|
+
if (verb === "restore") {
|
|
2622
|
+
await restoreBackup(required(context, "input"), {
|
|
2623
|
+
...config,
|
|
2624
|
+
databasePath: resolve6(context.cwd, required(context, "output"))
|
|
2625
|
+
});
|
|
2626
|
+
context.ui.data(
|
|
2627
|
+
`${JSON.stringify({ ok: true, data: { restored: true } })}
|
|
2628
|
+
`
|
|
2629
|
+
);
|
|
2630
|
+
return 0;
|
|
2631
|
+
}
|
|
2632
|
+
const store = await MailboxStore.open(config);
|
|
2633
|
+
let binding;
|
|
2634
|
+
let ownsBinding = false;
|
|
2635
|
+
try {
|
|
2636
|
+
if (verb === "actor") {
|
|
2637
|
+
const parentFile = one(context.args, "parent-binding");
|
|
2638
|
+
const parent = parentFile ? readBinding(parentFile) : void 0;
|
|
2639
|
+
const destination = required(context, "actor-file");
|
|
2640
|
+
const credential2 = await store.registerActor(
|
|
2641
|
+
required(context, "actor"),
|
|
2642
|
+
parent?.actorId,
|
|
2643
|
+
(value) => writePrivateJson(destination, value),
|
|
2644
|
+
6e4,
|
|
2645
|
+
parent
|
|
2646
|
+
);
|
|
2647
|
+
context.ui.data(
|
|
2648
|
+
`${JSON.stringify({ ok: true, data: { actorId: credential2.actorId } })}
|
|
2649
|
+
`
|
|
2650
|
+
);
|
|
2651
|
+
return 0;
|
|
2652
|
+
}
|
|
2653
|
+
if (verb === "rotate") {
|
|
2654
|
+
const destination = required(context, "actor-file");
|
|
2655
|
+
const credential2 = await store.rotateActor(
|
|
2656
|
+
required(context, "actor"),
|
|
2657
|
+
(value) => writePrivateJson(destination, value)
|
|
2658
|
+
);
|
|
2659
|
+
context.ui.data(
|
|
2660
|
+
`${JSON.stringify({ ok: true, data: { actorId: credential2.actorId } })}
|
|
2661
|
+
`
|
|
2662
|
+
);
|
|
2663
|
+
return 0;
|
|
2664
|
+
}
|
|
2665
|
+
if (verb === "backup" || verb === "export") {
|
|
2666
|
+
const destination = required(context, "output");
|
|
2667
|
+
if (verb === "backup") {
|
|
2668
|
+
await store.backup(destination);
|
|
2669
|
+
} else {
|
|
2670
|
+
const records = await store.exportRecords(
|
|
2671
|
+
one(context.args, "scope-actor")
|
|
2672
|
+
);
|
|
2673
|
+
writeFileSync4(
|
|
2674
|
+
destination,
|
|
2675
|
+
`${records.map((record) => JSON.stringify(record)).join("\n")}
|
|
2676
|
+
`,
|
|
2677
|
+
{ flag: "wx", mode: 384 }
|
|
2678
|
+
);
|
|
2679
|
+
}
|
|
2680
|
+
context.ui.data(
|
|
2681
|
+
`${JSON.stringify({ ok: true, data: { completed: verb } })}
|
|
2682
|
+
`
|
|
2683
|
+
);
|
|
2684
|
+
return 0;
|
|
2685
|
+
}
|
|
2686
|
+
const operation = operationSchema.parse(verb);
|
|
2687
|
+
const actorFile = one(context.args, "actor-file");
|
|
2688
|
+
const bindingFile = one(context.args, "binding-file");
|
|
2689
|
+
if (Boolean(actorFile) === Boolean(bindingFile))
|
|
2690
|
+
throw new ArgumentError("Choose one --actor-file or --binding-file");
|
|
2691
|
+
if (bindingFile) {
|
|
2692
|
+
binding = readBinding(bindingFile);
|
|
2693
|
+
} else {
|
|
2694
|
+
binding = await store.attach(readCredential(actorFile), "operator");
|
|
2695
|
+
ownsBinding = true;
|
|
2696
|
+
}
|
|
2697
|
+
const inputFile = one(context.args, "input");
|
|
2698
|
+
const input = inputFile ? JSON.parse(readFileSync8(inputFile, "utf8")) : {};
|
|
2699
|
+
const result = await new MailboxService(store, binding).call(
|
|
2700
|
+
operation,
|
|
2701
|
+
input
|
|
2702
|
+
);
|
|
2703
|
+
context.ui.data(`${JSON.stringify(result)}
|
|
2704
|
+
`);
|
|
2705
|
+
return result.ok ? 0 : 1;
|
|
2706
|
+
} catch (error) {
|
|
2707
|
+
if (error instanceof ArgumentError) throw error;
|
|
2708
|
+
context.ui.data(`${JSON.stringify(failure(error))}
|
|
2709
|
+
`);
|
|
2710
|
+
return 1;
|
|
2711
|
+
} finally {
|
|
2712
|
+
try {
|
|
2713
|
+
if (ownsBinding && binding) await store.detach(binding);
|
|
2714
|
+
} finally {
|
|
2715
|
+
await store.close();
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
};
|
|
2720
|
+
|
|
2290
2721
|
// src/commands/index.ts
|
|
2291
2722
|
var COMMANDS = [
|
|
2292
2723
|
serveCommand,
|
|
2293
2724
|
listCommand,
|
|
2294
2725
|
indexCommand,
|
|
2726
|
+
modelsCommand,
|
|
2295
2727
|
loginCommand,
|
|
2296
2728
|
logoutCommand,
|
|
2297
2729
|
whoamiCommand,
|
|
@@ -2301,7 +2733,8 @@ var COMMANDS = [
|
|
|
2301
2733
|
syncCommand,
|
|
2302
2734
|
projectCommand,
|
|
2303
2735
|
doctorCommand,
|
|
2304
|
-
validateCommand
|
|
2736
|
+
validateCommand,
|
|
2737
|
+
mailboxCommand
|
|
2305
2738
|
];
|
|
2306
2739
|
var PLANNED = [];
|
|
2307
2740
|
var GLOBAL = /* @__PURE__ */ new Set(["-q", "--quiet", "--no-color", "--color"]);
|
|
@@ -2347,7 +2780,7 @@ function dispatch(argv, options = {}) {
|
|
|
2347
2780
|
}
|
|
2348
2781
|
return run(command, rest, { ui, env, cwd });
|
|
2349
2782
|
}
|
|
2350
|
-
var VERSION = "0.
|
|
2783
|
+
var VERSION = "0.10.0";
|
|
2351
2784
|
async function run(command, argv, context) {
|
|
2352
2785
|
try {
|
|
2353
2786
|
return await command.run({
|