@mtreeai/msapling-cli 2.3.6-beta.27 → 2.3.6-beta.28
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/dist/index.js +695 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -356,6 +356,98 @@ var init_src = __esm({
|
|
|
356
356
|
async disableOllama() {
|
|
357
357
|
return await this.request("/api/ollama/disable", { method: "POST" });
|
|
358
358
|
}
|
|
359
|
+
// Parity Task Card implementations
|
|
360
|
+
// Card 1: Usage Tracking (synced from /api/usage/sync-offline)
|
|
361
|
+
async syncOfflineUsage() {
|
|
362
|
+
return await this.request("/api/usage/sync-offline", { method: "POST" });
|
|
363
|
+
}
|
|
364
|
+
// Card 2: Budget Buckets (7 bucket types)
|
|
365
|
+
async getBillingBuckets() {
|
|
366
|
+
return await this.request("/api/billing/buckets");
|
|
367
|
+
}
|
|
368
|
+
// Card 4: Image Generation
|
|
369
|
+
async generateImage(prompt4, model) {
|
|
370
|
+
return await this.request("/api/image/generate", {
|
|
371
|
+
method: "POST",
|
|
372
|
+
body: JSON.stringify({ prompt: prompt4, model })
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
// Card 5: Voice/Audio Operations
|
|
376
|
+
async listVoices() {
|
|
377
|
+
return await this.request("/api/audio/voices");
|
|
378
|
+
}
|
|
379
|
+
async speak(text, voice) {
|
|
380
|
+
return await this.request("/api/audio/speak", {
|
|
381
|
+
method: "POST",
|
|
382
|
+
body: JSON.stringify({ text, voice })
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
// Card 8: Chat Sharing
|
|
386
|
+
async shareChat(chatId, expiryDays) {
|
|
387
|
+
return await this.request(`/api/share/chat/${encodeURIComponent(chatId)}/share`, {
|
|
388
|
+
method: "POST",
|
|
389
|
+
body: JSON.stringify({ expiry_days: expiryDays })
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async listShares() {
|
|
393
|
+
return await this.request("/api/share");
|
|
394
|
+
}
|
|
395
|
+
async fetchSharedChat(token) {
|
|
396
|
+
return await this.request(`/api/shared/${encodeURIComponent(token)}`);
|
|
397
|
+
}
|
|
398
|
+
// Card 9: Notifications (preferences only)
|
|
399
|
+
async getNotificationPreferences() {
|
|
400
|
+
return await this.request("/api/notifications/preferences");
|
|
401
|
+
}
|
|
402
|
+
async setNotificationPreferences(prefs) {
|
|
403
|
+
return await this.request("/api/notifications/preferences", {
|
|
404
|
+
method: "PATCH",
|
|
405
|
+
body: JSON.stringify(prefs)
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
// Card 10: MLineage Events List
|
|
409
|
+
async listMLineageEvents() {
|
|
410
|
+
return await this.request("/api/mlineage/events");
|
|
411
|
+
}
|
|
412
|
+
// Card 11: Per-Project Model Config
|
|
413
|
+
async setProjectModel(projectId, model) {
|
|
414
|
+
return await this.request(`/api/projects/${encodeURIComponent(projectId)}`, {
|
|
415
|
+
method: "PATCH",
|
|
416
|
+
body: JSON.stringify({ default_model: model })
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
// Card 12: MFA/TOTP
|
|
420
|
+
async enrollMFA(method) {
|
|
421
|
+
return await this.request("/api/mfa/enroll", {
|
|
422
|
+
method: "POST",
|
|
423
|
+
body: JSON.stringify({ method })
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
async verifyMFA(code) {
|
|
427
|
+
return await this.request("/api/mfa/verify", {
|
|
428
|
+
method: "POST",
|
|
429
|
+
body: JSON.stringify({ code })
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
// Card 13: MCP Client Surface
|
|
433
|
+
async mcpConnect(serverUrl) {
|
|
434
|
+
return await this.request("/api/mcp/connect", {
|
|
435
|
+
method: "POST",
|
|
436
|
+
body: JSON.stringify({ server_url: serverUrl })
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
async mcpTools() {
|
|
440
|
+
return await this.request("/api/mcp/tools");
|
|
441
|
+
}
|
|
442
|
+
async mcpInvoke(method, args2) {
|
|
443
|
+
return await this.request("/api/mcp/invoke", {
|
|
444
|
+
method: "POST",
|
|
445
|
+
body: JSON.stringify({ method, args: args2 })
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
async mcpDisconnect() {
|
|
449
|
+
return await this.request("/api/mcp/disconnect", { method: "POST" });
|
|
450
|
+
}
|
|
359
451
|
// CLI-KEYS-BYOK-01 (Iter 35): BYOK provider-key management. Per LAB
|
|
360
452
|
// routers/keys.py — /api/keys/{status,save,{provider}}.
|
|
361
453
|
async getProviderKeys() {
|
|
@@ -732,6 +824,32 @@ var init_src = __esm({
|
|
|
732
824
|
async getActiveTasks() {
|
|
733
825
|
return this.request("/api/task-monitor/active");
|
|
734
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* Webhook Management (LAB-WEBHOOK-CRUD-01)
|
|
829
|
+
*/
|
|
830
|
+
async listWebhooks() {
|
|
831
|
+
return this.request("/api/webhooks");
|
|
832
|
+
}
|
|
833
|
+
async createWebhook(url, events) {
|
|
834
|
+
return this.request("/api/webhooks", {
|
|
835
|
+
method: "POST",
|
|
836
|
+
body: JSON.stringify({ url, events })
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
async deleteWebhook(id) {
|
|
840
|
+
await this.request(`/api/webhooks/${encodeURIComponent(id)}`, {
|
|
841
|
+
method: "DELETE"
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
async listWebhookDeliveries(webhookId) {
|
|
845
|
+
const path2 = webhookId ? `/api/webhooks/deliveries?webhook_id=${encodeURIComponent(webhookId)}` : "/api/webhooks/deliveries";
|
|
846
|
+
return this.request(path2);
|
|
847
|
+
}
|
|
848
|
+
async retryWebhookDelivery(deliveryId) {
|
|
849
|
+
return this.request(`/api/webhooks/deliveries/${encodeURIComponent(deliveryId)}/retry`, {
|
|
850
|
+
method: "POST"
|
|
851
|
+
});
|
|
852
|
+
}
|
|
735
853
|
/**
|
|
736
854
|
* Wakeup Management (LAB-CHAT-PARITY-04)
|
|
737
855
|
*/
|
|
@@ -9575,11 +9693,19 @@ var init_usage = __esm({
|
|
|
9575
9693
|
init_esm_shims();
|
|
9576
9694
|
usageCommand = {
|
|
9577
9695
|
name: "usage",
|
|
9578
|
-
|
|
9696
|
+
args: "[--json] [--since DATE]",
|
|
9697
|
+
description: "Show detailed usage, fuel balance, and daily quota; sync offline usage",
|
|
9579
9698
|
category: "chat",
|
|
9580
9699
|
handler: async (args2, context) => {
|
|
9581
9700
|
try {
|
|
9701
|
+
const isJson = args2.includes("--json");
|
|
9582
9702
|
const user = await context.client.getLiveUsage();
|
|
9703
|
+
await context.client.syncOfflineUsage().catch(() => {
|
|
9704
|
+
});
|
|
9705
|
+
if (isJson) {
|
|
9706
|
+
context.addMessage("system", JSON.stringify(user, null, 2));
|
|
9707
|
+
return;
|
|
9708
|
+
}
|
|
9583
9709
|
context.addMessage("system", "MSapling Usage Dashboard:");
|
|
9584
9710
|
context.addMessage("system", ` - Fuel Credits: $${user.fuel_credits.toFixed(4)}`);
|
|
9585
9711
|
context.addMessage("system", ` - Daily Spending Limit: ${user.monthly_spending_limit ? "$" + user.monthly_spending_limit : "Unlimited"}`);
|
|
@@ -9680,12 +9806,31 @@ var init_project = __esm({
|
|
|
9680
9806
|
LETTERS2 = "abcdefghijklmnopqrstuvwxyz";
|
|
9681
9807
|
projectCommand = {
|
|
9682
9808
|
name: "project",
|
|
9683
|
-
args: "[number|letter|name|id]",
|
|
9684
|
-
description: "List or switch active project",
|
|
9809
|
+
args: "[number|letter|name|id|config]",
|
|
9810
|
+
description: "List or switch active project, or set per-project config",
|
|
9685
9811
|
category: "project",
|
|
9686
9812
|
handler: async (args2, context) => {
|
|
9687
9813
|
const arg = args2.join(" ").trim();
|
|
9688
9814
|
const currentId = context.getProjectId() || null;
|
|
9815
|
+
if (args2[0] === "config") {
|
|
9816
|
+
const modelIdx = args2.indexOf("--model");
|
|
9817
|
+
const model = modelIdx >= 0 ? args2[modelIdx + 1] : void 0;
|
|
9818
|
+
if (!model) {
|
|
9819
|
+
context.addMessage("system", "Usage: /project config --model <MODEL>");
|
|
9820
|
+
return;
|
|
9821
|
+
}
|
|
9822
|
+
if (!currentId) {
|
|
9823
|
+
context.addMessage("error", "No active project. Use /project <id> first.");
|
|
9824
|
+
return;
|
|
9825
|
+
}
|
|
9826
|
+
try {
|
|
9827
|
+
await context.client.setProjectModel(currentId, model);
|
|
9828
|
+
context.addMessage("system", `Project default model set to: ${model}`);
|
|
9829
|
+
} catch (e) {
|
|
9830
|
+
context.addMessage("error", `Failed to set model: ${e.message}`);
|
|
9831
|
+
}
|
|
9832
|
+
return;
|
|
9833
|
+
}
|
|
9689
9834
|
if (args2[0] === "new" || args2[0] === "create") {
|
|
9690
9835
|
const name = args2.slice(1).join(" ").trim();
|
|
9691
9836
|
if (!name) {
|
|
@@ -10632,7 +10777,7 @@ var init_version = __esm({
|
|
|
10632
10777
|
description: "Show version information for CLI and core packages",
|
|
10633
10778
|
category: "debug",
|
|
10634
10779
|
handler: async (_args, context) => {
|
|
10635
|
-
const cliVersion = true ? "2.3.6-beta.
|
|
10780
|
+
const cliVersion = true ? "2.3.6-beta.28" : "(dev)";
|
|
10636
10781
|
const coreVersion = true ? "2.3.2" : "(dev)";
|
|
10637
10782
|
const runtime = process.version;
|
|
10638
10783
|
context.addMessage("system", "MSapling Version Info");
|
|
@@ -10641,7 +10786,7 @@ var init_version = __esm({
|
|
|
10641
10786
|
context.addMessage("system", row2("Core (@msapling/core)", coreVersion));
|
|
10642
10787
|
context.addMessage("system", row2("Runtime (Node/Bun)", runtime));
|
|
10643
10788
|
try {
|
|
10644
|
-
const ts = "2026-05-
|
|
10789
|
+
const ts = "2026-05-29T17:03:26.902Z";
|
|
10645
10790
|
if (ts && ts !== "__BUILD_TIMESTAMP__") {
|
|
10646
10791
|
context.addMessage("system", row2("Build Timestamp", ts));
|
|
10647
10792
|
}
|
|
@@ -11359,6 +11504,529 @@ var init_totp = __esm({
|
|
|
11359
11504
|
}
|
|
11360
11505
|
});
|
|
11361
11506
|
|
|
11507
|
+
// src/commands/budget.ts
|
|
11508
|
+
var budgetCommand;
|
|
11509
|
+
var init_budget = __esm({
|
|
11510
|
+
"src/commands/budget.ts"() {
|
|
11511
|
+
"use strict";
|
|
11512
|
+
init_esm_shims();
|
|
11513
|
+
budgetCommand = {
|
|
11514
|
+
name: "budget",
|
|
11515
|
+
description: "Show budget buckets (lifetime, sub, top_up, free, guest, byok, ollama)",
|
|
11516
|
+
category: "config",
|
|
11517
|
+
handler: async (args2, context) => {
|
|
11518
|
+
try {
|
|
11519
|
+
const data = await context.client.getBillingBuckets();
|
|
11520
|
+
context.addMessage("system", "Budget Buckets:");
|
|
11521
|
+
if (data && typeof data === "object") {
|
|
11522
|
+
for (const [key, val] of Object.entries(data)) {
|
|
11523
|
+
const bucket = val;
|
|
11524
|
+
const remaining = bucket.remaining ?? bucket.balance ?? 0;
|
|
11525
|
+
const limit = bucket.limit ?? bucket.cap ?? 0;
|
|
11526
|
+
context.addMessage("system", ` - ${key}: $${remaining.toFixed(4)} / $${limit.toFixed(4)}`);
|
|
11527
|
+
}
|
|
11528
|
+
} else {
|
|
11529
|
+
context.addMessage("system", JSON.stringify(data, null, 2));
|
|
11530
|
+
}
|
|
11531
|
+
} catch (e) {
|
|
11532
|
+
context.addMessage("error", `Failed to fetch budget: ${e.message}`);
|
|
11533
|
+
}
|
|
11534
|
+
}
|
|
11535
|
+
};
|
|
11536
|
+
}
|
|
11537
|
+
});
|
|
11538
|
+
|
|
11539
|
+
// src/commands/image.ts
|
|
11540
|
+
var imageCommand;
|
|
11541
|
+
var init_image = __esm({
|
|
11542
|
+
"src/commands/image.ts"() {
|
|
11543
|
+
"use strict";
|
|
11544
|
+
init_esm_shims();
|
|
11545
|
+
imageCommand = {
|
|
11546
|
+
name: "image",
|
|
11547
|
+
args: "<prompt> [--model MODEL] [--output FILE]",
|
|
11548
|
+
description: "Generate an image from a text prompt",
|
|
11549
|
+
category: "chat",
|
|
11550
|
+
handler: async (args2, context) => {
|
|
11551
|
+
let prompt4 = "";
|
|
11552
|
+
let model = "dall-e-3";
|
|
11553
|
+
let outputFile = null;
|
|
11554
|
+
for (let i = 0; i < args2.length; i++) {
|
|
11555
|
+
if (args2[i] === "--model" && i + 1 < args2.length) {
|
|
11556
|
+
model = args2[++i];
|
|
11557
|
+
continue;
|
|
11558
|
+
}
|
|
11559
|
+
if (args2[i] === "--output" && i + 1 < args2.length) {
|
|
11560
|
+
outputFile = args2[++i];
|
|
11561
|
+
continue;
|
|
11562
|
+
}
|
|
11563
|
+
prompt4 += (prompt4 ? " " : "") + args2[i];
|
|
11564
|
+
}
|
|
11565
|
+
if (!prompt4) {
|
|
11566
|
+
context.addMessage("system", "Usage: /image <prompt> [--model MODEL] [--output FILE]");
|
|
11567
|
+
return;
|
|
11568
|
+
}
|
|
11569
|
+
try {
|
|
11570
|
+
const result = await context.client.generateImage(prompt4, model);
|
|
11571
|
+
context.addMessage("system", `Image generated: ${result.url ?? result.image_url ?? "processing"}`);
|
|
11572
|
+
} catch (e) {
|
|
11573
|
+
context.addMessage("error", `Image generation failed: ${e.message}`);
|
|
11574
|
+
}
|
|
11575
|
+
}
|
|
11576
|
+
};
|
|
11577
|
+
}
|
|
11578
|
+
});
|
|
11579
|
+
|
|
11580
|
+
// src/commands/voice.ts
|
|
11581
|
+
var voiceCommand;
|
|
11582
|
+
var init_voice = __esm({
|
|
11583
|
+
"src/commands/voice.ts"() {
|
|
11584
|
+
"use strict";
|
|
11585
|
+
init_esm_shims();
|
|
11586
|
+
voiceCommand = {
|
|
11587
|
+
name: "voice",
|
|
11588
|
+
args: "[list|speak|transcribe] [args...]",
|
|
11589
|
+
description: "Voice operations: list, speak, or transcribe audio",
|
|
11590
|
+
category: "chat",
|
|
11591
|
+
handler: async (args2, context) => {
|
|
11592
|
+
const sub = (args2[0] ?? "list").toLowerCase();
|
|
11593
|
+
const rest = args2.slice(1);
|
|
11594
|
+
try {
|
|
11595
|
+
if (sub === "list") {
|
|
11596
|
+
const voices = await context.client.listVoices();
|
|
11597
|
+
context.addMessage("system", "Available voices:");
|
|
11598
|
+
if (Array.isArray(voices)) {
|
|
11599
|
+
for (const voice of voices) {
|
|
11600
|
+
context.addMessage("system", ` - ${voice.id ?? voice.name}: ${voice.name ?? voice.id}`);
|
|
11601
|
+
}
|
|
11602
|
+
} else if (typeof voices === "object") {
|
|
11603
|
+
for (const [key, val] of Object.entries(voices)) {
|
|
11604
|
+
context.addMessage("system", ` - ${key}`);
|
|
11605
|
+
}
|
|
11606
|
+
}
|
|
11607
|
+
return;
|
|
11608
|
+
}
|
|
11609
|
+
if (sub === "speak") {
|
|
11610
|
+
const text = rest.join(" ").trim();
|
|
11611
|
+
if (!text) {
|
|
11612
|
+
context.addMessage("system", "Usage: /voice speak --text <TEXT> --voice <VOICE>");
|
|
11613
|
+
return;
|
|
11614
|
+
}
|
|
11615
|
+
const voiceIdx = rest.indexOf("--voice");
|
|
11616
|
+
const voice = voiceIdx >= 0 ? rest[voiceIdx + 1] : "default";
|
|
11617
|
+
const result = await context.client.speak(text, voice);
|
|
11618
|
+
context.addMessage("system", `Audio generated: ${result.url ?? result.audio_url ?? "processing"}`);
|
|
11619
|
+
return;
|
|
11620
|
+
}
|
|
11621
|
+
if (sub === "transcribe") {
|
|
11622
|
+
context.addMessage("system", "Transcribe: pipe audio file to this command (not yet implemented)");
|
|
11623
|
+
return;
|
|
11624
|
+
}
|
|
11625
|
+
context.addMessage("error", `Unknown /voice subcommand '${sub}'. Try: list, speak, transcribe.`);
|
|
11626
|
+
} catch (e) {
|
|
11627
|
+
context.addMessage("error", `Voice: ${e.message}`);
|
|
11628
|
+
}
|
|
11629
|
+
}
|
|
11630
|
+
};
|
|
11631
|
+
}
|
|
11632
|
+
});
|
|
11633
|
+
|
|
11634
|
+
// src/commands/wakeup.ts
|
|
11635
|
+
var wakeupCommand;
|
|
11636
|
+
var init_wakeup = __esm({
|
|
11637
|
+
"src/commands/wakeup.ts"() {
|
|
11638
|
+
"use strict";
|
|
11639
|
+
init_esm_shims();
|
|
11640
|
+
wakeupCommand = {
|
|
11641
|
+
name: "wakeup",
|
|
11642
|
+
args: "[create|list|cancel] [...args]",
|
|
11643
|
+
description: "Manage wakeups (scheduled tasks): create, list, or cancel",
|
|
11644
|
+
category: "config",
|
|
11645
|
+
handler: async (args2, context) => {
|
|
11646
|
+
const sub = (args2[0] ?? "list").toLowerCase();
|
|
11647
|
+
const rest = args2.slice(1);
|
|
11648
|
+
try {
|
|
11649
|
+
if (sub === "list") {
|
|
11650
|
+
const wakeups = await context.client.listWakeups();
|
|
11651
|
+
context.addMessage("system", "Wakeups:");
|
|
11652
|
+
if (Array.isArray(wakeups)) {
|
|
11653
|
+
for (const wu of wakeups) {
|
|
11654
|
+
context.addMessage("system", ` - ${wu.id}: ${wu.reason ?? wu.prompt ?? "scheduled"}`);
|
|
11655
|
+
}
|
|
11656
|
+
} else {
|
|
11657
|
+
context.addMessage("system", JSON.stringify(wakeups, null, 2));
|
|
11658
|
+
}
|
|
11659
|
+
return;
|
|
11660
|
+
}
|
|
11661
|
+
if (sub === "create") {
|
|
11662
|
+
const delayIdx = rest.indexOf("--delay");
|
|
11663
|
+
const delay = delayIdx >= 0 ? Number(rest[delayIdx + 1]) : 60;
|
|
11664
|
+
const reasonIdx = rest.indexOf("--reason");
|
|
11665
|
+
const reason = reasonIdx >= 0 ? rest[reasonIdx + 1] : void 0;
|
|
11666
|
+
const promptIdx = rest.indexOf("--prompt");
|
|
11667
|
+
const prompt4 = promptIdx >= 0 ? rest.slice(promptIdx + 1).join(" ") : void 0;
|
|
11668
|
+
const result = await context.client.createWakeup({
|
|
11669
|
+
delay_seconds: delay,
|
|
11670
|
+
reason,
|
|
11671
|
+
prompt: prompt4
|
|
11672
|
+
});
|
|
11673
|
+
context.addMessage("system", `Wakeup created: ${result.id ?? "ok"}`);
|
|
11674
|
+
return;
|
|
11675
|
+
}
|
|
11676
|
+
if (sub === "cancel") {
|
|
11677
|
+
const id = rest[0];
|
|
11678
|
+
if (!id) {
|
|
11679
|
+
context.addMessage("system", "Usage: /wakeup cancel <ID>");
|
|
11680
|
+
return;
|
|
11681
|
+
}
|
|
11682
|
+
await context.client.cancelWakeup(id);
|
|
11683
|
+
context.addMessage("system", `Wakeup cancelled: ${id}`);
|
|
11684
|
+
return;
|
|
11685
|
+
}
|
|
11686
|
+
context.addMessage("error", `Unknown /wakeup subcommand '${sub}'. Try: list, create, cancel.`);
|
|
11687
|
+
} catch (e) {
|
|
11688
|
+
context.addMessage("error", `Wakeup: ${e.message}`);
|
|
11689
|
+
}
|
|
11690
|
+
}
|
|
11691
|
+
};
|
|
11692
|
+
}
|
|
11693
|
+
});
|
|
11694
|
+
|
|
11695
|
+
// src/commands/share.ts
|
|
11696
|
+
var shareCommand;
|
|
11697
|
+
var init_share = __esm({
|
|
11698
|
+
"src/commands/share.ts"() {
|
|
11699
|
+
"use strict";
|
|
11700
|
+
init_esm_shims();
|
|
11701
|
+
shareCommand = {
|
|
11702
|
+
name: "share",
|
|
11703
|
+
args: "[create|list|fetch] [...args]",
|
|
11704
|
+
description: "Share chats: create, list, or fetch shared conversations",
|
|
11705
|
+
category: "chat",
|
|
11706
|
+
handler: async (args2, context) => {
|
|
11707
|
+
const sub = (args2[0] ?? "list").toLowerCase();
|
|
11708
|
+
const rest = args2.slice(1);
|
|
11709
|
+
try {
|
|
11710
|
+
if (sub === "list") {
|
|
11711
|
+
const shares = await context.client.listShares();
|
|
11712
|
+
context.addMessage("system", "Shared Chats:");
|
|
11713
|
+
if (Array.isArray(shares)) {
|
|
11714
|
+
for (const share of shares) {
|
|
11715
|
+
const expiry = share.expiry_at ? ` (expires ${share.expiry_at})` : "";
|
|
11716
|
+
context.addMessage("system", ` - ${share.token}: chat ${share.chat_id}${expiry}`);
|
|
11717
|
+
}
|
|
11718
|
+
} else {
|
|
11719
|
+
context.addMessage("system", JSON.stringify(shares, null, 2));
|
|
11720
|
+
}
|
|
11721
|
+
return;
|
|
11722
|
+
}
|
|
11723
|
+
if (sub === "create") {
|
|
11724
|
+
const chatId = rest[0];
|
|
11725
|
+
const expiryIdx = rest.indexOf("--expiry");
|
|
11726
|
+
const expiry = expiryIdx >= 0 ? Number(rest[expiryIdx + 1]) : void 0;
|
|
11727
|
+
if (!chatId) {
|
|
11728
|
+
context.addMessage("system", "Usage: /share create <CHAT-ID> [--expiry DAYS]");
|
|
11729
|
+
return;
|
|
11730
|
+
}
|
|
11731
|
+
const result = await context.client.shareChat(chatId, expiry);
|
|
11732
|
+
context.addMessage("system", `Share created: ${result.token ?? result.url ?? "ok"}`);
|
|
11733
|
+
return;
|
|
11734
|
+
}
|
|
11735
|
+
if (sub === "fetch") {
|
|
11736
|
+
const token = rest[0];
|
|
11737
|
+
if (!token) {
|
|
11738
|
+
context.addMessage("system", "Usage: /share fetch <TOKEN>");
|
|
11739
|
+
return;
|
|
11740
|
+
}
|
|
11741
|
+
const result = await context.client.fetchSharedChat(token);
|
|
11742
|
+
context.addMessage("system", `Fetched shared chat: ${result.chat_id ?? result.id}`);
|
|
11743
|
+
return;
|
|
11744
|
+
}
|
|
11745
|
+
context.addMessage("error", `Unknown /share subcommand '${sub}'. Try: list, create, fetch.`);
|
|
11746
|
+
} catch (e) {
|
|
11747
|
+
context.addMessage("error", `Share: ${e.message}`);
|
|
11748
|
+
}
|
|
11749
|
+
}
|
|
11750
|
+
};
|
|
11751
|
+
}
|
|
11752
|
+
});
|
|
11753
|
+
|
|
11754
|
+
// src/commands/notify.ts
|
|
11755
|
+
var notifyCommand;
|
|
11756
|
+
var init_notify = __esm({
|
|
11757
|
+
"src/commands/notify.ts"() {
|
|
11758
|
+
"use strict";
|
|
11759
|
+
init_esm_shims();
|
|
11760
|
+
notifyCommand = {
|
|
11761
|
+
name: "notify",
|
|
11762
|
+
args: "[preferences] [--get|--set KEY=VALUE]",
|
|
11763
|
+
description: "Manage notification preferences (SSE stream not yet implemented)",
|
|
11764
|
+
category: "config",
|
|
11765
|
+
handler: async (args2, context) => {
|
|
11766
|
+
try {
|
|
11767
|
+
if (args2.length === 0 || args2[0] === "preferences" || args2[0] === "--get") {
|
|
11768
|
+
const prefs = await context.client.getNotificationPreferences();
|
|
11769
|
+
context.addMessage("system", "Notification Preferences:");
|
|
11770
|
+
context.addMessage("system", JSON.stringify(prefs, null, 2));
|
|
11771
|
+
return;
|
|
11772
|
+
}
|
|
11773
|
+
if (args2[0] === "--set") {
|
|
11774
|
+
const updates = {};
|
|
11775
|
+
for (let i = 1; i < args2.length; i++) {
|
|
11776
|
+
const pair = args2[i].split("=");
|
|
11777
|
+
if (pair.length === 2) {
|
|
11778
|
+
updates[pair[0]] = pair[1] === "true" ? true : pair[1] === "false" ? false : pair[1];
|
|
11779
|
+
}
|
|
11780
|
+
}
|
|
11781
|
+
const result = await context.client.setNotificationPreferences(updates);
|
|
11782
|
+
context.addMessage("system", `Preferences updated: ${result.status ?? "ok"}`);
|
|
11783
|
+
return;
|
|
11784
|
+
}
|
|
11785
|
+
context.addMessage("error", "Usage: /notify [--get] or /notify --set KEY=VALUE ...");
|
|
11786
|
+
} catch (e) {
|
|
11787
|
+
context.addMessage("error", `Notify: ${e.message}`);
|
|
11788
|
+
}
|
|
11789
|
+
}
|
|
11790
|
+
};
|
|
11791
|
+
}
|
|
11792
|
+
});
|
|
11793
|
+
|
|
11794
|
+
// src/commands/mlineage.ts
|
|
11795
|
+
var mlineageCommand;
|
|
11796
|
+
var init_mlineage = __esm({
|
|
11797
|
+
"src/commands/mlineage.ts"() {
|
|
11798
|
+
"use strict";
|
|
11799
|
+
init_esm_shims();
|
|
11800
|
+
mlineageCommand = {
|
|
11801
|
+
name: "mlineage",
|
|
11802
|
+
args: "[events] [--follow]",
|
|
11803
|
+
description: "List MLineage events (follow mode not yet implemented)",
|
|
11804
|
+
category: "chat",
|
|
11805
|
+
handler: async (args2, context) => {
|
|
11806
|
+
try {
|
|
11807
|
+
const follow = args2.includes("--follow");
|
|
11808
|
+
const events = await context.client.listMLineageEvents();
|
|
11809
|
+
context.addMessage("system", "MLineage Events:");
|
|
11810
|
+
if (Array.isArray(events)) {
|
|
11811
|
+
for (const evt of events) {
|
|
11812
|
+
context.addMessage("system", ` - ${evt.id}: ${evt.type} @ ${evt.timestamp}`);
|
|
11813
|
+
}
|
|
11814
|
+
} else {
|
|
11815
|
+
context.addMessage("system", JSON.stringify(events, null, 2));
|
|
11816
|
+
}
|
|
11817
|
+
if (follow) {
|
|
11818
|
+
context.addMessage("system", "(follow mode not yet implemented)");
|
|
11819
|
+
}
|
|
11820
|
+
} catch (e) {
|
|
11821
|
+
context.addMessage("error", `MLineage: ${e.message}`);
|
|
11822
|
+
}
|
|
11823
|
+
}
|
|
11824
|
+
};
|
|
11825
|
+
}
|
|
11826
|
+
});
|
|
11827
|
+
|
|
11828
|
+
// src/commands/mfa.ts
|
|
11829
|
+
var mfaCommand;
|
|
11830
|
+
var init_mfa = __esm({
|
|
11831
|
+
"src/commands/mfa.ts"() {
|
|
11832
|
+
"use strict";
|
|
11833
|
+
init_esm_shims();
|
|
11834
|
+
mfaCommand = {
|
|
11835
|
+
name: "mfa",
|
|
11836
|
+
args: "[enroll|verify] [...args]",
|
|
11837
|
+
description: "Enroll or verify MFA/TOTP",
|
|
11838
|
+
category: "config",
|
|
11839
|
+
handler: async (args2, context) => {
|
|
11840
|
+
const sub = (args2[0] ?? "status").toLowerCase();
|
|
11841
|
+
const rest = args2.slice(1);
|
|
11842
|
+
try {
|
|
11843
|
+
if (sub === "enroll") {
|
|
11844
|
+
const method = rest[0] ?? "totp";
|
|
11845
|
+
const result = await context.client.enrollMFA(method);
|
|
11846
|
+
context.addMessage("system", `MFA enrollment initiated: ${method}`);
|
|
11847
|
+
if (result.qr_code) {
|
|
11848
|
+
context.addMessage("system", `QR Code: ${result.qr_code}`);
|
|
11849
|
+
}
|
|
11850
|
+
if (result.secret) {
|
|
11851
|
+
context.addMessage("system", `Secret: ${result.secret}`);
|
|
11852
|
+
}
|
|
11853
|
+
return;
|
|
11854
|
+
}
|
|
11855
|
+
if (sub === "verify") {
|
|
11856
|
+
const code = rest[0];
|
|
11857
|
+
if (!code) {
|
|
11858
|
+
context.addMessage("system", "Usage: /mfa verify <CODE>");
|
|
11859
|
+
return;
|
|
11860
|
+
}
|
|
11861
|
+
const result = await context.client.verifyMFA(code);
|
|
11862
|
+
context.addMessage("system", `MFA verified: ${result.status ?? "ok"}`);
|
|
11863
|
+
return;
|
|
11864
|
+
}
|
|
11865
|
+
context.addMessage("error", `Unknown /mfa subcommand '${sub}'. Try: enroll, verify.`);
|
|
11866
|
+
} catch (e) {
|
|
11867
|
+
context.addMessage("error", `MFA: ${e.message}`);
|
|
11868
|
+
}
|
|
11869
|
+
}
|
|
11870
|
+
};
|
|
11871
|
+
}
|
|
11872
|
+
});
|
|
11873
|
+
|
|
11874
|
+
// src/commands/mcp.ts
|
|
11875
|
+
var mcpCommand;
|
|
11876
|
+
var init_mcp = __esm({
|
|
11877
|
+
"src/commands/mcp.ts"() {
|
|
11878
|
+
"use strict";
|
|
11879
|
+
init_esm_shims();
|
|
11880
|
+
mcpCommand = {
|
|
11881
|
+
name: "mcp",
|
|
11882
|
+
args: "[connect|invoke|tools|disconnect] [...args]",
|
|
11883
|
+
description: "MCP client surface: connect, invoke, list tools, disconnect",
|
|
11884
|
+
category: "config",
|
|
11885
|
+
handler: async (args2, context) => {
|
|
11886
|
+
const sub = (args2[0] ?? "tools").toLowerCase();
|
|
11887
|
+
const rest = args2.slice(1);
|
|
11888
|
+
try {
|
|
11889
|
+
if (sub === "connect") {
|
|
11890
|
+
const url = rest[0];
|
|
11891
|
+
if (!url) {
|
|
11892
|
+
context.addMessage("system", "Usage: /mcp connect <server-url>");
|
|
11893
|
+
return;
|
|
11894
|
+
}
|
|
11895
|
+
const result = await context.client.mcpConnect(url);
|
|
11896
|
+
context.addMessage("system", `MCP Connected: ${result.status ?? "ok"}`);
|
|
11897
|
+
return;
|
|
11898
|
+
}
|
|
11899
|
+
if (sub === "tools") {
|
|
11900
|
+
const tools = await context.client.mcpTools();
|
|
11901
|
+
context.addMessage("system", "Available MCP Tools:");
|
|
11902
|
+
if (Array.isArray(tools)) {
|
|
11903
|
+
for (const tool of tools) {
|
|
11904
|
+
context.addMessage("system", ` - ${tool.name}: ${tool.description ?? ""}`);
|
|
11905
|
+
}
|
|
11906
|
+
} else if (typeof tools === "object") {
|
|
11907
|
+
context.addMessage("system", JSON.stringify(tools, null, 2));
|
|
11908
|
+
}
|
|
11909
|
+
return;
|
|
11910
|
+
}
|
|
11911
|
+
if (sub === "invoke") {
|
|
11912
|
+
const method = rest[0];
|
|
11913
|
+
if (!method) {
|
|
11914
|
+
context.addMessage("system", "Usage: /mcp invoke <method> [args...]");
|
|
11915
|
+
return;
|
|
11916
|
+
}
|
|
11917
|
+
const argsStr = rest.slice(1).join(" ");
|
|
11918
|
+
let argsObj;
|
|
11919
|
+
try {
|
|
11920
|
+
argsObj = argsStr ? JSON.parse(argsStr) : void 0;
|
|
11921
|
+
} catch {
|
|
11922
|
+
argsObj = { raw: argsStr };
|
|
11923
|
+
}
|
|
11924
|
+
const result = await context.client.mcpInvoke(method, argsObj);
|
|
11925
|
+
context.addMessage("system", `MCP Result: ${JSON.stringify(result)}`);
|
|
11926
|
+
return;
|
|
11927
|
+
}
|
|
11928
|
+
if (sub === "disconnect") {
|
|
11929
|
+
const result = await context.client.mcpDisconnect();
|
|
11930
|
+
context.addMessage("system", `MCP Disconnected: ${result.status ?? "ok"}`);
|
|
11931
|
+
return;
|
|
11932
|
+
}
|
|
11933
|
+
context.addMessage("error", `Unknown /mcp subcommand '${sub}'. Try: connect, tools, invoke, disconnect.`);
|
|
11934
|
+
} catch (e) {
|
|
11935
|
+
context.addMessage("error", `MCP: ${e.message}`);
|
|
11936
|
+
}
|
|
11937
|
+
}
|
|
11938
|
+
};
|
|
11939
|
+
}
|
|
11940
|
+
});
|
|
11941
|
+
|
|
11942
|
+
// src/commands/webhook.ts
|
|
11943
|
+
var webhookCommand;
|
|
11944
|
+
var init_webhook = __esm({
|
|
11945
|
+
"src/commands/webhook.ts"() {
|
|
11946
|
+
"use strict";
|
|
11947
|
+
init_esm_shims();
|
|
11948
|
+
webhookCommand = {
|
|
11949
|
+
name: "webhook",
|
|
11950
|
+
args: "[list|add|rm|deliveries|retry] [...args]",
|
|
11951
|
+
description: "Manage webhooks: create, list, delete, and view delivery logs",
|
|
11952
|
+
category: "project",
|
|
11953
|
+
handler: async (args2, context) => {
|
|
11954
|
+
const sub = (args2[0] ?? "list").toLowerCase();
|
|
11955
|
+
const rest = args2.slice(1);
|
|
11956
|
+
try {
|
|
11957
|
+
if (sub === "list") {
|
|
11958
|
+
const webhooks = await context.client.listWebhooks();
|
|
11959
|
+
context.addMessage("system", "Webhooks:");
|
|
11960
|
+
if (Array.isArray(webhooks) && webhooks.length > 0) {
|
|
11961
|
+
for (const wh of webhooks) {
|
|
11962
|
+
const id = wh.id ?? wh.webhook_id ?? "?";
|
|
11963
|
+
const url = wh.url ?? "?";
|
|
11964
|
+
const events = wh.events ? wh.events.join(", ") : "";
|
|
11965
|
+
context.addMessage("system", ` - ${id}: ${url} (${events})`);
|
|
11966
|
+
}
|
|
11967
|
+
} else {
|
|
11968
|
+
context.addMessage("system", " (no webhooks)");
|
|
11969
|
+
}
|
|
11970
|
+
return;
|
|
11971
|
+
}
|
|
11972
|
+
if (sub === "add") {
|
|
11973
|
+
const url = rest[0];
|
|
11974
|
+
const events = rest.slice(1);
|
|
11975
|
+
if (!url || events.length === 0) {
|
|
11976
|
+
context.addMessage("system", "Usage: /webhook add <url> <event1> [event2] ...");
|
|
11977
|
+
return;
|
|
11978
|
+
}
|
|
11979
|
+
const result = await context.client.createWebhook(url, events);
|
|
11980
|
+
const id = result.id ?? result.webhook_id ?? "?";
|
|
11981
|
+
context.addMessage("system", `Webhook created: ${id} \u2192 ${url}`);
|
|
11982
|
+
return;
|
|
11983
|
+
}
|
|
11984
|
+
if (sub === "rm" || sub === "delete") {
|
|
11985
|
+
const id = rest[0];
|
|
11986
|
+
if (!id) {
|
|
11987
|
+
context.addMessage("system", "Usage: /webhook rm <id>");
|
|
11988
|
+
return;
|
|
11989
|
+
}
|
|
11990
|
+
await context.client.deleteWebhook(id);
|
|
11991
|
+
context.addMessage("system", `Deleted webhook: ${id}`);
|
|
11992
|
+
return;
|
|
11993
|
+
}
|
|
11994
|
+
if (sub === "deliveries") {
|
|
11995
|
+
const webhookId = rest[0] || void 0;
|
|
11996
|
+
const deliveries = await context.client.listWebhookDeliveries(webhookId);
|
|
11997
|
+
const title = webhookId ? `Deliveries for webhook ${webhookId}:` : "Recent deliveries:";
|
|
11998
|
+
context.addMessage("system", title);
|
|
11999
|
+
if (Array.isArray(deliveries) && deliveries.length > 0) {
|
|
12000
|
+
for (const d of deliveries) {
|
|
12001
|
+
const id = d.id ?? d.delivery_id ?? "?";
|
|
12002
|
+
const status = d.status ?? "?";
|
|
12003
|
+
const at = d.delivered_at ?? d.created_at ?? "?";
|
|
12004
|
+
context.addMessage("system", ` - ${id}: ${status} (${at})`);
|
|
12005
|
+
}
|
|
12006
|
+
} else {
|
|
12007
|
+
context.addMessage("system", " (no deliveries)");
|
|
12008
|
+
}
|
|
12009
|
+
return;
|
|
12010
|
+
}
|
|
12011
|
+
if (sub === "retry") {
|
|
12012
|
+
const deliveryId = rest[0];
|
|
12013
|
+
if (!deliveryId) {
|
|
12014
|
+
context.addMessage("system", "Usage: /webhook retry <delivery-id>");
|
|
12015
|
+
return;
|
|
12016
|
+
}
|
|
12017
|
+
const result = await context.client.retryWebhookDelivery(deliveryId);
|
|
12018
|
+
context.addMessage("system", `Retrying delivery: ${deliveryId} (${result.status ?? "queued"})`);
|
|
12019
|
+
return;
|
|
12020
|
+
}
|
|
12021
|
+
context.addMessage("error", `Unknown /webhook subcommand '${sub}'. Try: list, add, rm, deliveries, retry.`);
|
|
12022
|
+
} catch (e) {
|
|
12023
|
+
context.addMessage("error", `Webhook: ${e.message}`);
|
|
12024
|
+
}
|
|
12025
|
+
}
|
|
12026
|
+
};
|
|
12027
|
+
}
|
|
12028
|
+
});
|
|
12029
|
+
|
|
11362
12030
|
// src/commands/index.ts
|
|
11363
12031
|
var commands_exports = {};
|
|
11364
12032
|
__export(commands_exports, {
|
|
@@ -11412,6 +12080,16 @@ var init_commands = __esm({
|
|
|
11412
12080
|
init_todo();
|
|
11413
12081
|
init_outputStyle();
|
|
11414
12082
|
init_totp();
|
|
12083
|
+
init_budget();
|
|
12084
|
+
init_image();
|
|
12085
|
+
init_voice();
|
|
12086
|
+
init_wakeup();
|
|
12087
|
+
init_share();
|
|
12088
|
+
init_notify();
|
|
12089
|
+
init_mlineage();
|
|
12090
|
+
init_mfa();
|
|
12091
|
+
init_mcp();
|
|
12092
|
+
init_webhook();
|
|
11415
12093
|
commands = [
|
|
11416
12094
|
loginCommand,
|
|
11417
12095
|
unlockCommand,
|
|
@@ -11451,7 +12129,17 @@ var init_commands = __esm({
|
|
|
11451
12129
|
noteCommand,
|
|
11452
12130
|
todoCommand,
|
|
11453
12131
|
outputStyleCommand,
|
|
11454
|
-
totpCommand
|
|
12132
|
+
totpCommand,
|
|
12133
|
+
budgetCommand,
|
|
12134
|
+
imageCommand,
|
|
12135
|
+
voiceCommand,
|
|
12136
|
+
wakeupCommand,
|
|
12137
|
+
shareCommand,
|
|
12138
|
+
notifyCommand,
|
|
12139
|
+
mlineageCommand,
|
|
12140
|
+
mfaCommand,
|
|
12141
|
+
mcpCommand,
|
|
12142
|
+
webhookCommand
|
|
11455
12143
|
];
|
|
11456
12144
|
}
|
|
11457
12145
|
});
|
|
@@ -15054,7 +15742,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
15054
15742
|
var Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
|
|
15055
15743
|
/* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
|
|
15056
15744
|
"\u25CF MSapling CLI v",
|
|
15057
|
-
"2.3.6-beta.
|
|
15745
|
+
"2.3.6-beta.28"
|
|
15058
15746
|
] }),
|
|
15059
15747
|
/* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Platinum Tier Architecture" }) })
|
|
15060
15748
|
] });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mtreeai/msapling-cli",
|
|
3
|
-
"version": "2.3.6-beta.
|
|
3
|
+
"version": "2.3.6-beta.28",
|
|
4
4
|
"description": "MSapling CLI — React/Ink terminal client for the MSapling backend (chat, projects, MDrive, agent tools). Proprietary; redistribution prohibited.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "MSapling Team",
|