@prismer/sdk 1.8.1 → 1.8.2
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/chunk-BWZXMXL7.mjs +4762 -0
- package/dist/chunk-VSAVCMMZ.mjs +4761 -0
- package/dist/cli.d.mts +15 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.js +570 -284
- package/dist/cli.mjs +3838 -0
- package/dist/index.d.mts +60 -5
- package/dist/index.d.ts +60 -5
- package/dist/index.js +32 -3
- package/dist/index.mjs +50 -4681
- package/icon +21 -0
- package/package.json +8 -3
- package/dist/chunk-Y6FXYEAI.mjs +0 -10
- package/dist/webhook.d.mts +0 -114
- package/dist/webhook.d.ts +0 -114
- package/dist/webhook.js +0 -200
- package/dist/webhook.mjs +0 -175
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
"use strict";
|
|
3
2
|
var __create = Object.create;
|
|
4
3
|
var __defProp = Object.defineProperty;
|
|
@@ -36,8 +35,8 @@ __export(cli_exports, {
|
|
|
36
35
|
});
|
|
37
36
|
module.exports = __toCommonJS(cli_exports);
|
|
38
37
|
var import_commander = require("commander");
|
|
39
|
-
var
|
|
40
|
-
var
|
|
38
|
+
var fs3 = __toESM(require("fs"));
|
|
39
|
+
var path3 = __toESM(require("path"));
|
|
41
40
|
var os2 = __toESM(require("os"));
|
|
42
41
|
var TOML2 = __toESM(require("@iarna/toml"));
|
|
43
42
|
|
|
@@ -163,7 +162,7 @@ var RealtimeWSClient = class extends TypedEmitter {
|
|
|
163
162
|
if (this._state === "connected" || this._state === "connecting") return;
|
|
164
163
|
this._state = "connecting";
|
|
165
164
|
this.intentionalClose = false;
|
|
166
|
-
return new Promise((
|
|
165
|
+
return new Promise((resolve2, reject) => {
|
|
167
166
|
try {
|
|
168
167
|
this.ws = new this.WS(this.wsUrl);
|
|
169
168
|
} catch (err) {
|
|
@@ -185,7 +184,7 @@ var RealtimeWSClient = class extends TypedEmitter {
|
|
|
185
184
|
this.emit("connected", void 0);
|
|
186
185
|
this.ws.removeEventListener("message", onFirstMessage);
|
|
187
186
|
this.ws.addEventListener("message", this.handleMessage);
|
|
188
|
-
|
|
187
|
+
resolve2();
|
|
189
188
|
}
|
|
190
189
|
} catch (_) {
|
|
191
190
|
}
|
|
@@ -257,12 +256,12 @@ var RealtimeWSClient = class extends TypedEmitter {
|
|
|
257
256
|
}
|
|
258
257
|
ping() {
|
|
259
258
|
const requestId = `ping-${++this.pingCounter}`;
|
|
260
|
-
return new Promise((
|
|
259
|
+
return new Promise((resolve2, reject) => {
|
|
261
260
|
const timer = setTimeout(() => {
|
|
262
261
|
this.pendingPings.delete(requestId);
|
|
263
262
|
reject(new Error("Ping timeout"));
|
|
264
263
|
}, 1e4);
|
|
265
|
-
this.pendingPings.set(requestId, { resolve, timer });
|
|
264
|
+
this.pendingPings.set(requestId, { resolve: resolve2, timer });
|
|
266
265
|
this.sendRaw({ type: "ping", payload: { requestId } });
|
|
267
266
|
});
|
|
268
267
|
}
|
|
@@ -515,9 +514,9 @@ var WRITE_PATTERNS = [
|
|
|
515
514
|
{ method: "POST", pattern: /\/api\/im\/community\/posts\/[^/]+\/comments$/, opType: "community_comment" },
|
|
516
515
|
{ method: "POST", pattern: /\/api\/im\/community\/vote$/, opType: "community_vote" }
|
|
517
516
|
];
|
|
518
|
-
function matchWriteOp(method,
|
|
517
|
+
function matchWriteOp(method, path4) {
|
|
519
518
|
for (const { method: m, pattern, opType } of WRITE_PATTERNS) {
|
|
520
|
-
if (method === m && pattern.test(
|
|
519
|
+
if (method === m && pattern.test(path4)) return opType;
|
|
521
520
|
}
|
|
522
521
|
return null;
|
|
523
522
|
}
|
|
@@ -585,18 +584,18 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
585
584
|
/**
|
|
586
585
|
* Dispatch an IM request. Write ops go through outbox; reads check local cache.
|
|
587
586
|
*/
|
|
588
|
-
async dispatch(method,
|
|
589
|
-
const opType = matchWriteOp(method,
|
|
587
|
+
async dispatch(method, path4, body, query) {
|
|
588
|
+
const opType = matchWriteOp(method, path4);
|
|
590
589
|
if (opType) {
|
|
591
|
-
return this.dispatchWrite(opType, method,
|
|
590
|
+
return this.dispatchWrite(opType, method, path4, body, query);
|
|
592
591
|
}
|
|
593
592
|
if (method === "GET") {
|
|
594
|
-
const cached = await this.readFromCache(
|
|
593
|
+
const cached = await this.readFromCache(path4, query);
|
|
595
594
|
if (cached !== null) return cached;
|
|
596
595
|
}
|
|
597
596
|
try {
|
|
598
|
-
const result = await this.networkRequest(method,
|
|
599
|
-
if (method === "GET") this.cacheReadResult(
|
|
597
|
+
const result = await this.networkRequest(method, path4, body, query);
|
|
598
|
+
if (method === "GET") this.cacheReadResult(path4, query, result);
|
|
600
599
|
return result;
|
|
601
600
|
} catch {
|
|
602
601
|
if (!this._isOnline) {
|
|
@@ -606,7 +605,7 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
606
605
|
}
|
|
607
606
|
}
|
|
608
607
|
// ── Outbox: write operations ──────────────────────────────
|
|
609
|
-
async dispatchWrite(opType, method,
|
|
608
|
+
async dispatchWrite(opType, method, path4, body, query) {
|
|
610
609
|
const clientId = generateId();
|
|
611
610
|
const idempotencyKey = `sdk-${clientId}`;
|
|
612
611
|
let enrichedBody = body;
|
|
@@ -620,7 +619,7 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
620
619
|
let localMessage;
|
|
621
620
|
if (opType === "message.send" && body && typeof body === "object") {
|
|
622
621
|
const b = body;
|
|
623
|
-
const convIdMatch =
|
|
622
|
+
const convIdMatch = path4.match(/\/(?:messages|direct|groups)\/([^/]+)/);
|
|
624
623
|
const conversationId = convIdMatch?.[1] ?? "";
|
|
625
624
|
localMessage = {
|
|
626
625
|
id: `local-${clientId}`,
|
|
@@ -641,7 +640,7 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
641
640
|
id: clientId,
|
|
642
641
|
type: opType,
|
|
643
642
|
method,
|
|
644
|
-
path:
|
|
643
|
+
path: path4,
|
|
645
644
|
body: enrichedBody,
|
|
646
645
|
query,
|
|
647
646
|
status: "pending",
|
|
@@ -961,28 +960,28 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
961
960
|
return 0;
|
|
962
961
|
}
|
|
963
962
|
// ── Read cache ────────────────────────────────────────────
|
|
964
|
-
async readFromCache(
|
|
965
|
-
if (/\/api\/im\/conversations$/.test(
|
|
963
|
+
async readFromCache(path4, query) {
|
|
964
|
+
if (/\/api\/im\/conversations$/.test(path4)) {
|
|
966
965
|
const convos = await this.storage.getConversations({ limit: 50 });
|
|
967
966
|
if (convos.length > 0) return { ok: true, data: convos };
|
|
968
967
|
}
|
|
969
|
-
const msgMatch =
|
|
968
|
+
const msgMatch = path4.match(/\/api\/im\/messages\/([^/]+)$/);
|
|
970
969
|
if (msgMatch) {
|
|
971
970
|
const convId = msgMatch[1];
|
|
972
971
|
const limit = query?.limit ? parseInt(query.limit) : 50;
|
|
973
972
|
const messages = await this.storage.getMessages(convId, { limit, before: query?.before });
|
|
974
973
|
if (messages.length > 0) return { ok: true, data: messages };
|
|
975
974
|
}
|
|
976
|
-
if (/\/api\/im\/contacts$/.test(
|
|
975
|
+
if (/\/api\/im\/contacts$/.test(path4)) {
|
|
977
976
|
const contacts = await this.storage.getContacts();
|
|
978
977
|
if (contacts.length > 0) return { ok: true, data: contacts };
|
|
979
978
|
}
|
|
980
979
|
return null;
|
|
981
980
|
}
|
|
982
|
-
async cacheReadResult(
|
|
981
|
+
async cacheReadResult(path4, _query, result) {
|
|
983
982
|
if (!result?.ok || !result?.data) return;
|
|
984
983
|
try {
|
|
985
|
-
if (/\/api\/im\/conversations$/.test(
|
|
984
|
+
if (/\/api\/im\/conversations$/.test(path4) && Array.isArray(result.data)) {
|
|
986
985
|
const convos = result.data.map((c) => ({
|
|
987
986
|
id: c.id,
|
|
988
987
|
type: c.type ?? "direct",
|
|
@@ -996,7 +995,7 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
996
995
|
}));
|
|
997
996
|
await this.storage.putConversations(convos);
|
|
998
997
|
}
|
|
999
|
-
const msgMatch =
|
|
998
|
+
const msgMatch = path4.match(/\/api\/im\/messages\/([^/]+)$/);
|
|
1000
999
|
if (msgMatch && Array.isArray(result.data)) {
|
|
1001
1000
|
const messages = result.data.map((m) => ({
|
|
1002
1001
|
id: m.id,
|
|
@@ -1011,7 +1010,7 @@ var OfflineManager = class extends OfflineEmitter {
|
|
|
1011
1010
|
}));
|
|
1012
1011
|
await this.storage.putMessages(messages);
|
|
1013
1012
|
}
|
|
1014
|
-
if (/\/api\/im\/contacts$/.test(
|
|
1013
|
+
if (/\/api\/im\/contacts$/.test(path4) && Array.isArray(result.data)) {
|
|
1015
1014
|
await this.storage.putContacts(result.data);
|
|
1016
1015
|
}
|
|
1017
1016
|
} catch {
|
|
@@ -1784,7 +1783,8 @@ var DirectClient = class {
|
|
|
1784
1783
|
content,
|
|
1785
1784
|
type: options?.type ?? "text",
|
|
1786
1785
|
metadata: options?.metadata,
|
|
1787
|
-
parentId: options?.parentId
|
|
1786
|
+
parentId: options?.parentId,
|
|
1787
|
+
quotedMessageId: options?.quotedMessageId
|
|
1788
1788
|
});
|
|
1789
1789
|
}
|
|
1790
1790
|
/** Get direct message history with a user */
|
|
@@ -1817,7 +1817,8 @@ var GroupsClient = class {
|
|
|
1817
1817
|
content,
|
|
1818
1818
|
type: options?.type ?? "text",
|
|
1819
1819
|
metadata: options?.metadata,
|
|
1820
|
-
parentId: options?.parentId
|
|
1820
|
+
parentId: options?.parentId,
|
|
1821
|
+
quotedMessageId: options?.quotedMessageId
|
|
1821
1822
|
});
|
|
1822
1823
|
}
|
|
1823
1824
|
/** Get group message history */
|
|
@@ -1894,7 +1895,8 @@ var MessagesClient = class {
|
|
|
1894
1895
|
content,
|
|
1895
1896
|
type: options?.type ?? "text",
|
|
1896
1897
|
metadata: options?.metadata,
|
|
1897
|
-
parentId: options?.parentId
|
|
1898
|
+
parentId: options?.parentId,
|
|
1899
|
+
quotedMessageId: options?.quotedMessageId
|
|
1898
1900
|
});
|
|
1899
1901
|
}
|
|
1900
1902
|
/** Get message history for a conversation */
|
|
@@ -1916,6 +1918,17 @@ var MessagesClient = class {
|
|
|
1916
1918
|
async markDelivered(conversationId, messageIds) {
|
|
1917
1919
|
return this._r("POST", "/api/im/messages/delivered", { conversationId, messageIds });
|
|
1918
1920
|
}
|
|
1921
|
+
/**
|
|
1922
|
+
* Add or remove an emoji reaction on a message (v1.8.2).
|
|
1923
|
+
* Idempotent — adding an existing reaction or removing a non-existent one is a no-op.
|
|
1924
|
+
* Returns the full reactions snapshot: `{ "👍": ["userId-a", ...], ... }`.
|
|
1925
|
+
*/
|
|
1926
|
+
async react(conversationId, messageId, emoji, options) {
|
|
1927
|
+
return this._r("POST", `/api/im/messages/${conversationId}/${messageId}/reactions`, {
|
|
1928
|
+
emoji,
|
|
1929
|
+
...options?.remove ? { remove: true } : {}
|
|
1930
|
+
});
|
|
1931
|
+
}
|
|
1919
1932
|
};
|
|
1920
1933
|
var ContactsClient = class {
|
|
1921
1934
|
constructor(_r) {
|
|
@@ -2111,8 +2124,20 @@ var TasksClient = class {
|
|
|
2111
2124
|
return this._r("POST", `/api/im/tasks/${taskId}/complete`, options);
|
|
2112
2125
|
}
|
|
2113
2126
|
/** Fail a task with error */
|
|
2114
|
-
async fail(taskId,
|
|
2115
|
-
return this._r("POST", `/api/im/tasks/${taskId}/fail`, { error, metadata });
|
|
2127
|
+
async fail(taskId, error2, metadata) {
|
|
2128
|
+
return this._r("POST", `/api/im/tasks/${taskId}/fail`, { error: error2, metadata });
|
|
2129
|
+
}
|
|
2130
|
+
/** Approve a completed task */
|
|
2131
|
+
async approve(taskId) {
|
|
2132
|
+
return this._r("POST", `/api/im/tasks/${taskId}/approve`);
|
|
2133
|
+
}
|
|
2134
|
+
/** Reject a task with reason */
|
|
2135
|
+
async reject(taskId, reason) {
|
|
2136
|
+
return this._r("POST", `/api/im/tasks/${taskId}/reject`, { reason });
|
|
2137
|
+
}
|
|
2138
|
+
/** Cancel a task */
|
|
2139
|
+
async cancel(taskId) {
|
|
2140
|
+
return this._r("DELETE", `/api/im/tasks/${taskId}`);
|
|
2116
2141
|
}
|
|
2117
2142
|
};
|
|
2118
2143
|
var MemoryClient = class {
|
|
@@ -2534,30 +2559,30 @@ var EvolutionClient = class {
|
|
|
2534
2559
|
}
|
|
2535
2560
|
const localPaths = [];
|
|
2536
2561
|
try {
|
|
2537
|
-
const
|
|
2538
|
-
const
|
|
2562
|
+
const fs4 = await import("fs");
|
|
2563
|
+
const path4 = await import("path");
|
|
2539
2564
|
const os3 = await import("os");
|
|
2540
2565
|
const home = os3.homedir();
|
|
2541
|
-
const pluginBase = process.env.PRISMER_PLUGIN_DIR ||
|
|
2566
|
+
const pluginBase = process.env.PRISMER_PLUGIN_DIR || path4.join(home, ".claude", "plugins", "prismer");
|
|
2542
2567
|
const platformPaths = options?.project ? {
|
|
2543
|
-
"claude-code":
|
|
2544
|
-
"openclaw":
|
|
2545
|
-
"opencode":
|
|
2546
|
-
"plugin":
|
|
2568
|
+
"claude-code": path4.join(options.projectRoot || ".", ".claude", "skills", slug),
|
|
2569
|
+
"openclaw": path4.join(options.projectRoot || ".", "skills", slug),
|
|
2570
|
+
"opencode": path4.join(options.projectRoot || ".", ".opencode", "skills", slug),
|
|
2571
|
+
"plugin": path4.join(options.projectRoot || ".", ".claude", "plugins", "prismer", "skills", slug)
|
|
2547
2572
|
} : {
|
|
2548
|
-
"claude-code":
|
|
2549
|
-
"openclaw":
|
|
2550
|
-
"opencode":
|
|
2551
|
-
"plugin":
|
|
2573
|
+
"claude-code": path4.join(home, ".claude", "skills", slug),
|
|
2574
|
+
"openclaw": path4.join(home, ".openclaw", "skills", slug),
|
|
2575
|
+
"opencode": path4.join(home, ".config", "opencode", "skills", slug),
|
|
2576
|
+
"plugin": path4.join(pluginBase, "skills", slug)
|
|
2552
2577
|
};
|
|
2553
2578
|
const targets = options?.platforms || Object.keys(platformPaths);
|
|
2554
2579
|
for (const platform of targets) {
|
|
2555
2580
|
const dir = platformPaths[platform];
|
|
2556
2581
|
if (!dir) continue;
|
|
2557
2582
|
try {
|
|
2558
|
-
|
|
2559
|
-
const filePath =
|
|
2560
|
-
|
|
2583
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
2584
|
+
const filePath = path4.join(dir, "SKILL.md");
|
|
2585
|
+
fs4.writeFileSync(filePath, content, "utf-8");
|
|
2561
2586
|
localPaths.push(filePath);
|
|
2562
2587
|
} catch {
|
|
2563
2588
|
}
|
|
@@ -2575,21 +2600,21 @@ var EvolutionClient = class {
|
|
|
2575
2600
|
const slug = safeSlug(slugOrId);
|
|
2576
2601
|
if (!slug) return { ...result, data: { uninstalled: result.data?.uninstalled ?? false, removedPaths } };
|
|
2577
2602
|
try {
|
|
2578
|
-
const
|
|
2579
|
-
const
|
|
2603
|
+
const fs4 = await import("fs");
|
|
2604
|
+
const path4 = await import("path");
|
|
2580
2605
|
const os3 = await import("os");
|
|
2581
2606
|
const home = os3.homedir();
|
|
2582
|
-
const pluginBase = process.env.PRISMER_PLUGIN_DIR ||
|
|
2607
|
+
const pluginBase = process.env.PRISMER_PLUGIN_DIR || path4.join(home, ".claude", "plugins", "prismer");
|
|
2583
2608
|
const dirs = [
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2609
|
+
path4.join(home, ".claude", "skills", slug),
|
|
2610
|
+
path4.join(home, ".openclaw", "skills", slug),
|
|
2611
|
+
path4.join(home, ".config", "opencode", "skills", slug),
|
|
2612
|
+
path4.join(pluginBase, "skills", slug)
|
|
2588
2613
|
];
|
|
2589
2614
|
for (const dir of dirs) {
|
|
2590
2615
|
try {
|
|
2591
|
-
if (
|
|
2592
|
-
|
|
2616
|
+
if (fs4.existsSync(dir)) {
|
|
2617
|
+
fs4.rmSync(dir, { recursive: true });
|
|
2593
2618
|
removedPaths.push(dir);
|
|
2594
2619
|
}
|
|
2595
2620
|
} catch {
|
|
@@ -2626,25 +2651,25 @@ var EvolutionClient = class {
|
|
|
2626
2651
|
failed++;
|
|
2627
2652
|
continue;
|
|
2628
2653
|
}
|
|
2629
|
-
const
|
|
2630
|
-
const
|
|
2654
|
+
const fs4 = await import("fs");
|
|
2655
|
+
const path4 = await import("path");
|
|
2631
2656
|
const os3 = await import("os");
|
|
2632
2657
|
const home = os3.homedir();
|
|
2633
|
-
const pluginBase = process.env.PRISMER_PLUGIN_DIR ||
|
|
2658
|
+
const pluginBase = process.env.PRISMER_PLUGIN_DIR || path4.join(home, ".claude", "plugins", "prismer");
|
|
2634
2659
|
const platformPaths = {
|
|
2635
|
-
"claude-code":
|
|
2636
|
-
"openclaw":
|
|
2637
|
-
"opencode":
|
|
2638
|
-
"plugin":
|
|
2660
|
+
"claude-code": path4.join(home, ".claude", "skills", slug),
|
|
2661
|
+
"openclaw": path4.join(home, ".openclaw", "skills", slug),
|
|
2662
|
+
"opencode": path4.join(home, ".config", "opencode", "skills", slug),
|
|
2663
|
+
"plugin": path4.join(pluginBase, "skills", slug)
|
|
2639
2664
|
};
|
|
2640
2665
|
const targets = options?.platforms || Object.keys(platformPaths);
|
|
2641
2666
|
for (const platform of targets) {
|
|
2642
2667
|
const dir = platformPaths[platform];
|
|
2643
2668
|
if (!dir) continue;
|
|
2644
2669
|
try {
|
|
2645
|
-
|
|
2646
|
-
const filePath =
|
|
2647
|
-
|
|
2670
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
2671
|
+
const filePath = path4.join(dir, "SKILL.md");
|
|
2672
|
+
fs4.writeFileSync(filePath, content, "utf-8");
|
|
2648
2673
|
paths.push(filePath);
|
|
2649
2674
|
} catch {
|
|
2650
2675
|
}
|
|
@@ -2784,11 +2809,11 @@ var FilesClient = class {
|
|
|
2784
2809
|
let bytes;
|
|
2785
2810
|
let fileName;
|
|
2786
2811
|
if (typeof input === "string") {
|
|
2787
|
-
const
|
|
2788
|
-
const
|
|
2789
|
-
const buf = await
|
|
2812
|
+
const fs4 = await import("fs");
|
|
2813
|
+
const path4 = await import("path");
|
|
2814
|
+
const buf = await fs4.promises.readFile(input);
|
|
2790
2815
|
bytes = new Uint8Array(buf);
|
|
2791
|
-
fileName = opts?.fileName ||
|
|
2816
|
+
fileName = opts?.fileName || path4.basename(input);
|
|
2792
2817
|
} else if (typeof Blob !== "undefined" && input instanceof Blob) {
|
|
2793
2818
|
const ab = await input.arrayBuffer();
|
|
2794
2819
|
bytes = new Uint8Array(ab);
|
|
@@ -3000,20 +3025,20 @@ var PrismerClient = class {
|
|
|
3000
3025
|
let imRequest = this._offlineManager ? (m, p, b, q) => this._offlineManager.dispatch(m, p, b, q) : (m, p, b, q) => this._request(m, p, b, q);
|
|
3001
3026
|
if (config.identity) {
|
|
3002
3027
|
const baseRequest = imRequest;
|
|
3003
|
-
imRequest = (method,
|
|
3004
|
-
if (method === "POST" &&
|
|
3028
|
+
imRequest = (method, path4, body, query) => {
|
|
3029
|
+
if (method === "POST" && path4.includes("/messages") && body) {
|
|
3005
3030
|
const b = body;
|
|
3006
3031
|
if (!b.signature && !b.skipSigning) {
|
|
3007
3032
|
const ready = this._identityReady || Promise.resolve();
|
|
3008
3033
|
return ready.then(() => {
|
|
3009
3034
|
if (this._identity) {
|
|
3010
|
-
return this._signAndSend(baseRequest, method,
|
|
3035
|
+
return this._signAndSend(baseRequest, method, path4, b, query);
|
|
3011
3036
|
}
|
|
3012
|
-
return baseRequest(method,
|
|
3037
|
+
return baseRequest(method, path4, body, query);
|
|
3013
3038
|
});
|
|
3014
3039
|
}
|
|
3015
3040
|
}
|
|
3016
|
-
return baseRequest(method,
|
|
3041
|
+
return baseRequest(method, path4, body, query);
|
|
3017
3042
|
};
|
|
3018
3043
|
}
|
|
3019
3044
|
this.im = new IMClient(
|
|
@@ -3031,9 +3056,9 @@ var PrismerClient = class {
|
|
|
3031
3056
|
return this._identity;
|
|
3032
3057
|
}
|
|
3033
3058
|
/** Auto-sign a message body and send (v1.8.0 S1) */
|
|
3034
|
-
async _signAndSend(baseRequest, method,
|
|
3059
|
+
async _signAndSend(baseRequest, method, path4, body, query) {
|
|
3035
3060
|
if (this._identityReady) await this._identityReady;
|
|
3036
|
-
if (!this._identity) return baseRequest(method,
|
|
3061
|
+
if (!this._identity) return baseRequest(method, path4, body, query);
|
|
3037
3062
|
const content = body.content || "";
|
|
3038
3063
|
const contentHashBytes = new Uint8Array(
|
|
3039
3064
|
await crypto.subtle.digest("SHA-256", new TextEncoder().encode(content))
|
|
@@ -3043,7 +3068,7 @@ var PrismerClient = class {
|
|
|
3043
3068
|
const payload = `1|${this._identity.did}|${body.type || "text"}|${timestamp}|${contentHash}`;
|
|
3044
3069
|
const payloadBytes = new TextEncoder().encode(payload);
|
|
3045
3070
|
const signature = await this._identity.sign(payloadBytes);
|
|
3046
|
-
return baseRequest(method,
|
|
3071
|
+
return baseRequest(method, path4, {
|
|
3047
3072
|
...body,
|
|
3048
3073
|
secVersion: 1,
|
|
3049
3074
|
senderDid: this._identity.did,
|
|
@@ -3075,11 +3100,11 @@ var PrismerClient = class {
|
|
|
3075
3100
|
// --------------------------------------------------------------------------
|
|
3076
3101
|
// Internal request helper
|
|
3077
3102
|
// --------------------------------------------------------------------------
|
|
3078
|
-
async _request(method,
|
|
3103
|
+
async _request(method, path4, body, query, _isRetry) {
|
|
3079
3104
|
const controller = new AbortController();
|
|
3080
3105
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
3081
3106
|
try {
|
|
3082
|
-
let url = `${this.baseUrl}${
|
|
3107
|
+
let url = `${this.baseUrl}${path4}`;
|
|
3083
3108
|
if (query && Object.keys(query).length > 0) {
|
|
3084
3109
|
url += "?" + new URLSearchParams(query).toString();
|
|
3085
3110
|
}
|
|
@@ -3097,12 +3122,12 @@ var PrismerClient = class {
|
|
|
3097
3122
|
}
|
|
3098
3123
|
const response = await this.fetchFn(url, init);
|
|
3099
3124
|
const data = await response.json();
|
|
3100
|
-
if (response.status === 401 && this.apiKey.startsWith("eyJ") && !_isRetry && !
|
|
3125
|
+
if (response.status === 401 && this.apiKey.startsWith("eyJ") && !_isRetry && !path4.includes("/token/refresh")) {
|
|
3101
3126
|
try {
|
|
3102
3127
|
const refreshRes = await this._request("POST", "/api/im/token/refresh", void 0, void 0, true);
|
|
3103
3128
|
if (refreshRes?.ok && refreshRes?.data?.token) {
|
|
3104
3129
|
this.apiKey = refreshRes.data.token;
|
|
3105
|
-
return this._request(method,
|
|
3130
|
+
return this._request(method, path4, body, query, true);
|
|
3106
3131
|
}
|
|
3107
3132
|
} catch {
|
|
3108
3133
|
}
|
|
@@ -3112,14 +3137,14 @@ var PrismerClient = class {
|
|
|
3112
3137
|
return { ...data, success: false, ok: false, error: err };
|
|
3113
3138
|
}
|
|
3114
3139
|
return data;
|
|
3115
|
-
} catch (
|
|
3116
|
-
if (
|
|
3140
|
+
} catch (error2) {
|
|
3141
|
+
if (error2 instanceof Error && error2.name === "AbortError") {
|
|
3117
3142
|
return { success: false, ok: false, error: { code: "TIMEOUT", message: "Request timed out" } };
|
|
3118
3143
|
}
|
|
3119
3144
|
return {
|
|
3120
3145
|
success: false,
|
|
3121
3146
|
ok: false,
|
|
3122
|
-
error: { code: "NETWORK_ERROR", message:
|
|
3147
|
+
error: { code: "NETWORK_ERROR", message: error2 instanceof Error ? error2.message : "Unknown error" }
|
|
3123
3148
|
};
|
|
3124
3149
|
} finally {
|
|
3125
3150
|
clearTimeout(timeoutId);
|
|
@@ -3181,6 +3206,125 @@ var PrismerClient = class {
|
|
|
3181
3206
|
}
|
|
3182
3207
|
};
|
|
3183
3208
|
|
|
3209
|
+
// src/ui.ts
|
|
3210
|
+
var pc = __toESM(require("picocolors"));
|
|
3211
|
+
var clack = __toESM(require("@clack/prompts"));
|
|
3212
|
+
var fs = __toESM(require("fs"));
|
|
3213
|
+
var path = __toESM(require("path"));
|
|
3214
|
+
var isTTY = !!process.stdout.isTTY || !!process.env.FORCE_COLOR;
|
|
3215
|
+
function displayBanner() {
|
|
3216
|
+
if (!isTTY) return;
|
|
3217
|
+
let iconPath;
|
|
3218
|
+
try {
|
|
3219
|
+
iconPath = path.resolve(__dirname, "..", "icon");
|
|
3220
|
+
if (!fs.existsSync(iconPath)) {
|
|
3221
|
+
iconPath = path.resolve(__dirname, "..", "..", "icon");
|
|
3222
|
+
}
|
|
3223
|
+
if (!fs.existsSync(iconPath)) return;
|
|
3224
|
+
const raw = fs.readFileSync(iconPath, "utf-8");
|
|
3225
|
+
const lines = raw.split("\n");
|
|
3226
|
+
const termWidth = process.stdout.columns || 80;
|
|
3227
|
+
const colorized = lines.map((line) => {
|
|
3228
|
+
const trimmed = line.trimEnd();
|
|
3229
|
+
if (!trimmed) return "";
|
|
3230
|
+
let result = "";
|
|
3231
|
+
let visibleLen = 0;
|
|
3232
|
+
for (const ch of trimmed) {
|
|
3233
|
+
if (visibleLen >= termWidth - 1) break;
|
|
3234
|
+
if (ch === "\u2592") {
|
|
3235
|
+
result += pc.cyan(ch);
|
|
3236
|
+
} else if (ch === "\u2593") {
|
|
3237
|
+
result += pc.white(ch);
|
|
3238
|
+
} else if (ch === "\u2588") {
|
|
3239
|
+
result += pc.white(ch);
|
|
3240
|
+
} else {
|
|
3241
|
+
result += ch;
|
|
3242
|
+
}
|
|
3243
|
+
visibleLen++;
|
|
3244
|
+
}
|
|
3245
|
+
return result;
|
|
3246
|
+
});
|
|
3247
|
+
while (colorized.length > 0 && colorized[colorized.length - 1].trim() === "") {
|
|
3248
|
+
colorized.pop();
|
|
3249
|
+
}
|
|
3250
|
+
console.log(colorized.join("\n"));
|
|
3251
|
+
console.log();
|
|
3252
|
+
} catch {
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
var SYMBOLS = {
|
|
3256
|
+
success: isTTY ? "\u2713" : "[ok]",
|
|
3257
|
+
// ✓
|
|
3258
|
+
error: isTTY ? "\u2717" : "[error]",
|
|
3259
|
+
// ✗
|
|
3260
|
+
warn: isTTY ? "\u26A0" : "[warn]",
|
|
3261
|
+
// ⚠
|
|
3262
|
+
info: isTTY ? "\u2139" : "[info]"
|
|
3263
|
+
// ℹ
|
|
3264
|
+
};
|
|
3265
|
+
function success(msg) {
|
|
3266
|
+
console.log(pc.green(`${SYMBOLS.success} ${msg}`));
|
|
3267
|
+
}
|
|
3268
|
+
function error(msg) {
|
|
3269
|
+
console.error(pc.red(`${SYMBOLS.error} ${msg}`));
|
|
3270
|
+
}
|
|
3271
|
+
function warn(msg) {
|
|
3272
|
+
console.warn(pc.yellow(`${SYMBOLS.warn} ${msg}`));
|
|
3273
|
+
}
|
|
3274
|
+
function info(msg) {
|
|
3275
|
+
console.log(pc.blue(`${SYMBOLS.info} ${msg}`));
|
|
3276
|
+
}
|
|
3277
|
+
function dim2(msg) {
|
|
3278
|
+
console.log(pc.dim(msg));
|
|
3279
|
+
}
|
|
3280
|
+
async function withSpinner(message, fn) {
|
|
3281
|
+
if (!isTTY) {
|
|
3282
|
+
return fn();
|
|
3283
|
+
}
|
|
3284
|
+
const s = clack.spinner();
|
|
3285
|
+
s.start(message);
|
|
3286
|
+
try {
|
|
3287
|
+
const result = await fn();
|
|
3288
|
+
s.stop(pc.green(`${SYMBOLS.success} ${message}`));
|
|
3289
|
+
return result;
|
|
3290
|
+
} catch (err) {
|
|
3291
|
+
s.stop(pc.red(`${SYMBOLS.error} ${message}`));
|
|
3292
|
+
throw err;
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
function table(headers, rows) {
|
|
3296
|
+
if (headers.length === 0) return;
|
|
3297
|
+
const widths = headers.map((h, i) => {
|
|
3298
|
+
const dataMax = rows.reduce((max, row) => Math.max(max, (row[i] || "").length), 0);
|
|
3299
|
+
return Math.max(h.length, dataMax);
|
|
3300
|
+
});
|
|
3301
|
+
const PAD = 2;
|
|
3302
|
+
const headerLine = headers.map((h, i) => h.padEnd(widths[i] + PAD)).join("");
|
|
3303
|
+
if (isTTY) {
|
|
3304
|
+
console.log(pc.bold(headerLine));
|
|
3305
|
+
const separator = widths.map((w) => "\u2500".repeat(w)).join(" ");
|
|
3306
|
+
console.log(pc.dim(separator));
|
|
3307
|
+
} else {
|
|
3308
|
+
console.log(headerLine);
|
|
3309
|
+
const separator = widths.map((w) => "-".repeat(w)).join(" ");
|
|
3310
|
+
console.log(separator);
|
|
3311
|
+
}
|
|
3312
|
+
for (const row of rows) {
|
|
3313
|
+
const line = headers.map((_, i) => (row[i] || "").padEnd(widths[i] + PAD)).join("");
|
|
3314
|
+
console.log(line);
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
function keyValue(pairs) {
|
|
3318
|
+
const keys = Object.keys(pairs);
|
|
3319
|
+
if (keys.length === 0) return;
|
|
3320
|
+
const maxKeyLen = keys.reduce((max, k) => Math.max(max, k.length), 0);
|
|
3321
|
+
for (const key of keys) {
|
|
3322
|
+
const label = isTTY ? pc.bold(key.padEnd(maxKeyLen)) : key.padEnd(maxKeyLen);
|
|
3323
|
+
const value = pairs[key];
|
|
3324
|
+
console.log(` ${label} ${value}`);
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3184
3328
|
// src/commands/im.ts
|
|
3185
3329
|
function register(parent, getIMClient2, _getAPIClient) {
|
|
3186
3330
|
const im = parent.command("im").description("IM messaging, groups, conversations, and credits");
|
|
@@ -3877,7 +4021,7 @@ function register3(parent, getIMClient2, _getAPIClient) {
|
|
|
3877
4021
|
const maxIterations = 30;
|
|
3878
4022
|
let lastStatus;
|
|
3879
4023
|
for (let i = 0; i < maxIterations; i++) {
|
|
3880
|
-
await new Promise((
|
|
4024
|
+
await new Promise((resolve2) => setTimeout(resolve2, 2e3));
|
|
3881
4025
|
if (!opts.json) process.stdout.write(".");
|
|
3882
4026
|
const statusRes = await client.im.evolution.getReportStatus(traceId);
|
|
3883
4027
|
if (!statusRes.ok) break;
|
|
@@ -4262,14 +4406,13 @@ function register3(parent, getIMClient2, _getAPIClient) {
|
|
|
4262
4406
|
// src/commands/task.ts
|
|
4263
4407
|
function register4(parent, getIMClient2, _getAPIClient) {
|
|
4264
4408
|
const task = parent.command("task").description("Manage tasks in the task marketplace");
|
|
4265
|
-
task.command("create").description("Create a new task").requiredOption("--title <title>", "task title").option("--description <description>", "task description").option("--
|
|
4409
|
+
task.command("create").description("Create a new task").requiredOption("--title <title>", "task title").option("--description <description>", "task description").option("--capability <capability>", "required agent capability").option("--budget <budget>", "budget in credits", parseFloat).option("--json", "output raw JSON response").action(async (opts) => {
|
|
4266
4410
|
const client = getIMClient2();
|
|
4267
4411
|
try {
|
|
4268
4412
|
const res = await client.im.tasks.create({
|
|
4269
4413
|
title: opts.title,
|
|
4270
4414
|
description: opts.description,
|
|
4271
|
-
|
|
4272
|
-
requiredCapability: opts.capability,
|
|
4415
|
+
capability: opts.capability,
|
|
4273
4416
|
budget: opts.budget
|
|
4274
4417
|
});
|
|
4275
4418
|
if (opts.json) {
|
|
@@ -4290,12 +4433,10 @@ function register4(parent, getIMClient2, _getAPIClient) {
|
|
|
4290
4433
|
process.stdout.write(`Title: ${t.title}
|
|
4291
4434
|
`);
|
|
4292
4435
|
process.stdout.write(`Status: ${t.status}
|
|
4293
|
-
`);
|
|
4294
|
-
process.stdout.write(`Priority: ${t.priority}
|
|
4295
4436
|
`);
|
|
4296
4437
|
if (t.description) process.stdout.write(`Description: ${t.description}
|
|
4297
4438
|
`);
|
|
4298
|
-
if (t.
|
|
4439
|
+
if (t.capability) process.stdout.write(`Capability: ${t.capability}
|
|
4299
4440
|
`);
|
|
4300
4441
|
if (t.budget !== void 0) process.stdout.write(`Budget: ${t.budget}
|
|
4301
4442
|
`);
|
|
@@ -4329,17 +4470,16 @@ function register4(parent, getIMClient2, _getAPIClient) {
|
|
|
4329
4470
|
return;
|
|
4330
4471
|
}
|
|
4331
4472
|
const idW = 24;
|
|
4332
|
-
const statusW =
|
|
4333
|
-
const priorityW = 10;
|
|
4473
|
+
const statusW = 12;
|
|
4334
4474
|
const titleW = 40;
|
|
4335
|
-
const header = "ID".padEnd(idW) + "STATUS".padEnd(statusW) + "
|
|
4336
|
-
const sep = "-".repeat(idW + statusW +
|
|
4475
|
+
const header = "ID".padEnd(idW) + "STATUS".padEnd(statusW) + "TITLE";
|
|
4476
|
+
const sep = "-".repeat(idW + statusW + titleW);
|
|
4337
4477
|
process.stdout.write(header + "\n");
|
|
4338
4478
|
process.stdout.write(sep + "\n");
|
|
4339
4479
|
for (const t of tasks) {
|
|
4340
4480
|
const title = t.title.length > titleW ? t.title.slice(0, titleW - 3) + "..." : t.title;
|
|
4341
4481
|
process.stdout.write(
|
|
4342
|
-
String(t.id).padEnd(idW) + String(t.status).padEnd(statusW) +
|
|
4482
|
+
String(t.id).padEnd(idW) + String(t.status).padEnd(statusW) + title + "\n"
|
|
4343
4483
|
);
|
|
4344
4484
|
}
|
|
4345
4485
|
process.stdout.write(`
|
|
@@ -4371,14 +4511,16 @@ ${tasks.length} task(s) listed.
|
|
|
4371
4511
|
process.stdout.write(`Title: ${t.title}
|
|
4372
4512
|
`);
|
|
4373
4513
|
process.stdout.write(`Status: ${t.status}
|
|
4374
|
-
`);
|
|
4375
|
-
process.stdout.write(`Priority: ${t.priority}
|
|
4376
4514
|
`);
|
|
4377
4515
|
if (t.description) process.stdout.write(`Description: ${t.description}
|
|
4378
4516
|
`);
|
|
4379
|
-
if (t.
|
|
4517
|
+
if (t.capability) process.stdout.write(`Capability: ${t.capability}
|
|
4380
4518
|
`);
|
|
4381
4519
|
if (t.budget !== void 0) process.stdout.write(`Budget: ${t.budget}
|
|
4520
|
+
`);
|
|
4521
|
+
if (t.progress != null) process.stdout.write(`Progress: ${t.progress}
|
|
4522
|
+
`);
|
|
4523
|
+
if (t.statusMessage) process.stdout.write(`Status Msg: ${t.statusMessage}
|
|
4382
4524
|
`);
|
|
4383
4525
|
if (t.creatorId) process.stdout.write(`Creator: ${t.creatorId}
|
|
4384
4526
|
`);
|
|
@@ -4387,6 +4529,8 @@ ${tasks.length} task(s) listed.
|
|
|
4387
4529
|
if (t.createdAt) process.stdout.write(`Created: ${t.createdAt}
|
|
4388
4530
|
`);
|
|
4389
4531
|
if (t.updatedAt) process.stdout.write(`Updated: ${t.updatedAt}
|
|
4532
|
+
`);
|
|
4533
|
+
if (t.completedAt) process.stdout.write(`Completed: ${t.completedAt}
|
|
4390
4534
|
`);
|
|
4391
4535
|
if (t.result) process.stdout.write(`Result: ${t.result}
|
|
4392
4536
|
`);
|
|
@@ -4433,8 +4577,6 @@ Logs (${logs.length}):
|
|
|
4433
4577
|
process.stdout.write(`Title: ${t.title}
|
|
4434
4578
|
`);
|
|
4435
4579
|
process.stdout.write(`Status: ${t.status}
|
|
4436
|
-
`);
|
|
4437
|
-
process.stdout.write(`Priority: ${t.priority}
|
|
4438
4580
|
`);
|
|
4439
4581
|
} catch (err) {
|
|
4440
4582
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -4443,13 +4585,15 @@ Logs (${logs.length}):
|
|
|
4443
4585
|
process.exit(1);
|
|
4444
4586
|
}
|
|
4445
4587
|
});
|
|
4446
|
-
task.command("update <task-id>").description("Update a task").option("--title <title>", "new title").option("--description <description>", "new description").option("--
|
|
4588
|
+
task.command("update <task-id>").description("Update a task").option("--title <title>", "new title").option("--description <description>", "new description").option("--status <status>", "new status").option("--progress <progress>", "progress (0.0 to 1.0)", parseFloat).option("--status-message <statusMessage>", "status message").option("--json", "output raw JSON response").action(async (taskId, opts) => {
|
|
4447
4589
|
const client = getIMClient2();
|
|
4448
4590
|
try {
|
|
4449
4591
|
const res = await client.im.tasks.update(taskId, {
|
|
4450
4592
|
title: opts.title,
|
|
4451
4593
|
description: opts.description,
|
|
4452
|
-
|
|
4594
|
+
status: opts.status,
|
|
4595
|
+
progress: opts.progress,
|
|
4596
|
+
statusMessage: opts.statusMessage
|
|
4453
4597
|
});
|
|
4454
4598
|
if (opts.json) {
|
|
4455
4599
|
process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
@@ -4470,7 +4614,9 @@ Logs (${logs.length}):
|
|
|
4470
4614
|
`);
|
|
4471
4615
|
process.stdout.write(`Status: ${t.status}
|
|
4472
4616
|
`);
|
|
4473
|
-
process.stdout.write(`
|
|
4617
|
+
if (t.progress != null) process.stdout.write(`Progress: ${t.progress}
|
|
4618
|
+
`);
|
|
4619
|
+
if (t.statusMessage) process.stdout.write(`Message: ${t.statusMessage}
|
|
4474
4620
|
`);
|
|
4475
4621
|
} catch (err) {
|
|
4476
4622
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -4541,6 +4687,96 @@ Logs (${logs.length}):
|
|
|
4541
4687
|
} catch (err) {
|
|
4542
4688
|
const message = err instanceof Error ? err.message : String(err);
|
|
4543
4689
|
process.stderr.write(`Error: ${message}
|
|
4690
|
+
`);
|
|
4691
|
+
process.exit(1);
|
|
4692
|
+
}
|
|
4693
|
+
});
|
|
4694
|
+
task.command("approve <task-id>").description("Approve a completed task").option("--json", "output raw JSON response").action(async (taskId, opts) => {
|
|
4695
|
+
const client = getIMClient2();
|
|
4696
|
+
try {
|
|
4697
|
+
const res = await client.im.tasks.approve(taskId);
|
|
4698
|
+
if (opts.json) {
|
|
4699
|
+
process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
4700
|
+
return;
|
|
4701
|
+
}
|
|
4702
|
+
if (!res.ok) {
|
|
4703
|
+
process.stderr.write(`Error: ${res.error?.message || "Unknown error"}
|
|
4704
|
+
`);
|
|
4705
|
+
process.exit(1);
|
|
4706
|
+
}
|
|
4707
|
+
const t = res.data;
|
|
4708
|
+
process.stdout.write(`Task approved successfully
|
|
4709
|
+
|
|
4710
|
+
`);
|
|
4711
|
+
process.stdout.write(`ID: ${t.id}
|
|
4712
|
+
`);
|
|
4713
|
+
process.stdout.write(`Title: ${t.title}
|
|
4714
|
+
`);
|
|
4715
|
+
process.stdout.write(`Status: ${t.status}
|
|
4716
|
+
`);
|
|
4717
|
+
} catch (err) {
|
|
4718
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4719
|
+
process.stderr.write(`Error: ${message}
|
|
4720
|
+
`);
|
|
4721
|
+
process.exit(1);
|
|
4722
|
+
}
|
|
4723
|
+
});
|
|
4724
|
+
task.command("reject <task-id>").description("Reject a task").requiredOption("--reason <reason>", "reason for rejection").option("--json", "output raw JSON response").action(async (taskId, opts) => {
|
|
4725
|
+
const client = getIMClient2();
|
|
4726
|
+
try {
|
|
4727
|
+
const res = await client.im.tasks.reject(taskId, opts.reason);
|
|
4728
|
+
if (opts.json) {
|
|
4729
|
+
process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
4730
|
+
return;
|
|
4731
|
+
}
|
|
4732
|
+
if (!res.ok) {
|
|
4733
|
+
process.stderr.write(`Error: ${res.error?.message || "Unknown error"}
|
|
4734
|
+
`);
|
|
4735
|
+
process.exit(1);
|
|
4736
|
+
}
|
|
4737
|
+
const t = res.data;
|
|
4738
|
+
process.stdout.write(`Task rejected
|
|
4739
|
+
|
|
4740
|
+
`);
|
|
4741
|
+
process.stdout.write(`ID: ${t.id}
|
|
4742
|
+
`);
|
|
4743
|
+
process.stdout.write(`Title: ${t.title}
|
|
4744
|
+
`);
|
|
4745
|
+
process.stdout.write(`Status: ${t.status}
|
|
4746
|
+
`);
|
|
4747
|
+
} catch (err) {
|
|
4748
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4749
|
+
process.stderr.write(`Error: ${message}
|
|
4750
|
+
`);
|
|
4751
|
+
process.exit(1);
|
|
4752
|
+
}
|
|
4753
|
+
});
|
|
4754
|
+
task.command("cancel <task-id>").description("Cancel a task").option("--json", "output raw JSON response").action(async (taskId, opts) => {
|
|
4755
|
+
const client = getIMClient2();
|
|
4756
|
+
try {
|
|
4757
|
+
const res = await client.im.tasks.cancel(taskId);
|
|
4758
|
+
if (opts.json) {
|
|
4759
|
+
process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
4760
|
+
return;
|
|
4761
|
+
}
|
|
4762
|
+
if (!res.ok) {
|
|
4763
|
+
process.stderr.write(`Error: ${res.error?.message || "Unknown error"}
|
|
4764
|
+
`);
|
|
4765
|
+
process.exit(1);
|
|
4766
|
+
}
|
|
4767
|
+
const t = res.data;
|
|
4768
|
+
process.stdout.write(`Task cancelled
|
|
4769
|
+
|
|
4770
|
+
`);
|
|
4771
|
+
process.stdout.write(`ID: ${t.id}
|
|
4772
|
+
`);
|
|
4773
|
+
process.stdout.write(`Title: ${t.title}
|
|
4774
|
+
`);
|
|
4775
|
+
process.stdout.write(`Status: ${t.status}
|
|
4776
|
+
`);
|
|
4777
|
+
} catch (err) {
|
|
4778
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4779
|
+
process.stderr.write(`Error: ${message}
|
|
4544
4780
|
`);
|
|
4545
4781
|
process.exit(1);
|
|
4546
4782
|
}
|
|
@@ -4774,7 +5010,7 @@ function printFileTable(files) {
|
|
|
4774
5010
|
const idLen = Math.max(2, ...files.map((f) => f.id.length));
|
|
4775
5011
|
const scopeLen = Math.max(5, ...files.map((f) => f.scope.length));
|
|
4776
5012
|
const pathLen = Math.max(4, ...files.map((f) => f.path.length));
|
|
4777
|
-
const row = (id, scope,
|
|
5013
|
+
const row = (id, scope, path4) => `${id.padEnd(idLen)} ${scope.padEnd(scopeLen)} ${path4.padEnd(pathLen)}`;
|
|
4778
5014
|
process.stdout.write(row("ID", "SCOPE", "PATH") + "\n");
|
|
4779
5015
|
process.stdout.write(`${"-".repeat(idLen)} ${"-".repeat(scopeLen)} ${"-".repeat(pathLen)}
|
|
4780
5016
|
`);
|
|
@@ -5144,11 +5380,11 @@ function register8(parent, getIMClient2, _getAPIClient) {
|
|
|
5144
5380
|
try {
|
|
5145
5381
|
const capabilities = opts.agentCapabilities ? opts.agentCapabilities.split(",").map((s) => s.trim()) : void 0;
|
|
5146
5382
|
const res = await client.im.workspace.init({
|
|
5147
|
-
name,
|
|
5383
|
+
workspaceId: name,
|
|
5148
5384
|
userId: opts.userId,
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5385
|
+
userDisplayName: opts.userName,
|
|
5386
|
+
agentName: opts.agentId,
|
|
5387
|
+
agentDisplayName: opts.agentName,
|
|
5152
5388
|
agentType: opts.agentType,
|
|
5153
5389
|
...capabilities !== void 0 && { agentCapabilities: capabilities }
|
|
5154
5390
|
});
|
|
@@ -5172,14 +5408,16 @@ function register8(parent, getIMClient2, _getAPIClient) {
|
|
|
5172
5408
|
workspace.command("init-group <name>").description("Initialize a group workspace with a set of members").requiredOption("--members <json>", "JSON array of member objects").option("--json", "Output raw JSON response").action(async (name, opts) => {
|
|
5173
5409
|
const client = getIMClient2();
|
|
5174
5410
|
try {
|
|
5175
|
-
let
|
|
5411
|
+
let users;
|
|
5176
5412
|
try {
|
|
5177
|
-
|
|
5413
|
+
const parsed = JSON.parse(opts.members);
|
|
5414
|
+
if (!Array.isArray(parsed)) throw new Error("not an array");
|
|
5415
|
+
users = parsed;
|
|
5178
5416
|
} catch {
|
|
5179
|
-
process.stderr.write("Error: --members must be a valid JSON array\n");
|
|
5417
|
+
process.stderr.write("Error: --members must be a valid JSON array of {userId, displayName}\n");
|
|
5180
5418
|
process.exit(1);
|
|
5181
5419
|
}
|
|
5182
|
-
const res = await client.im.workspace.initGroup({ name,
|
|
5420
|
+
const res = await client.im.workspace.initGroup({ workspaceId: name, title: name, users });
|
|
5183
5421
|
if (!res.ok) {
|
|
5184
5422
|
process.stderr.write(`Error: ${res.error?.message || JSON.stringify(res.error)}
|
|
5185
5423
|
`);
|
|
@@ -5660,8 +5898,8 @@ function register10(parent, getIMClient2, _getAPIClient) {
|
|
|
5660
5898
|
}
|
|
5661
5899
|
|
|
5662
5900
|
// src/daemon.ts
|
|
5663
|
-
var
|
|
5664
|
-
var
|
|
5901
|
+
var fs2 = __toESM(require("fs"));
|
|
5902
|
+
var path2 = __toESM(require("path"));
|
|
5665
5903
|
var import_path = require("path");
|
|
5666
5904
|
var os = __toESM(require("os"));
|
|
5667
5905
|
var import_os = require("os");
|
|
@@ -5669,22 +5907,22 @@ var http = __toESM(require("http"));
|
|
|
5669
5907
|
var import_http = require("http");
|
|
5670
5908
|
var import_child_process = require("child_process");
|
|
5671
5909
|
var TOML = __toESM(require("@iarna/toml"));
|
|
5672
|
-
var CONFIG_DIR =
|
|
5673
|
-
var CONFIG_PATH =
|
|
5674
|
-
var PID_PATH =
|
|
5675
|
-
var PORT_PATH =
|
|
5676
|
-
var CACHE_DIR =
|
|
5677
|
-
var EVOLUTION_CACHE_PATH =
|
|
5678
|
-
var OUTBOX_PATH =
|
|
5910
|
+
var CONFIG_DIR = path2.join(os.homedir(), ".prismer");
|
|
5911
|
+
var CONFIG_PATH = path2.join(CONFIG_DIR, "config.toml");
|
|
5912
|
+
var PID_PATH = path2.join(CONFIG_DIR, "daemon.pid");
|
|
5913
|
+
var PORT_PATH = path2.join(CONFIG_DIR, "daemon.port");
|
|
5914
|
+
var CACHE_DIR = path2.join(CONFIG_DIR, "cache");
|
|
5915
|
+
var EVOLUTION_CACHE_PATH = path2.join(CACHE_DIR, "evolution.json");
|
|
5916
|
+
var OUTBOX_PATH = path2.join(CACHE_DIR, "outbox.json");
|
|
5679
5917
|
var SYNC_INTERVAL_MS = 6e4;
|
|
5680
5918
|
var FLUSH_INTERVAL_MS = 3e4;
|
|
5681
5919
|
var API_TIMEOUT_MS = 1e4;
|
|
5682
5920
|
var EVENTS_FILE = (0, import_path.join)(CACHE_DIR, "events.json");
|
|
5683
5921
|
var MAX_EVENTS = 1e3;
|
|
5684
5922
|
function loadConfig() {
|
|
5685
|
-
if (!
|
|
5923
|
+
if (!fs2.existsSync(CONFIG_PATH)) return null;
|
|
5686
5924
|
try {
|
|
5687
|
-
const raw =
|
|
5925
|
+
const raw = fs2.readFileSync(CONFIG_PATH, "utf-8");
|
|
5688
5926
|
const parsed = TOML.parse(raw);
|
|
5689
5927
|
const apiKey = parsed?.default?.api_key || "";
|
|
5690
5928
|
const baseUrl = parsed?.default?.base_url || "https://prismer.cloud";
|
|
@@ -5695,13 +5933,13 @@ function loadConfig() {
|
|
|
5695
5933
|
}
|
|
5696
5934
|
}
|
|
5697
5935
|
function ensureCacheDir() {
|
|
5698
|
-
if (!
|
|
5699
|
-
|
|
5936
|
+
if (!fs2.existsSync(CACHE_DIR)) {
|
|
5937
|
+
fs2.mkdirSync(CACHE_DIR, { recursive: true });
|
|
5700
5938
|
}
|
|
5701
5939
|
}
|
|
5702
5940
|
function loadEvents() {
|
|
5703
5941
|
try {
|
|
5704
|
-
return JSON.parse(
|
|
5942
|
+
return JSON.parse(fs2.readFileSync(EVENTS_FILE, "utf-8"));
|
|
5705
5943
|
} catch {
|
|
5706
5944
|
return [];
|
|
5707
5945
|
}
|
|
@@ -5710,7 +5948,7 @@ function appendEvent(event) {
|
|
|
5710
5948
|
const events = loadEvents();
|
|
5711
5949
|
events.push(event);
|
|
5712
5950
|
if (events.length > MAX_EVENTS) events.splice(0, events.length - MAX_EVENTS);
|
|
5713
|
-
|
|
5951
|
+
fs2.writeFileSync(EVENTS_FILE, JSON.stringify(events), { encoding: "utf-8", mode: 384 });
|
|
5714
5952
|
}
|
|
5715
5953
|
function emitSyncEvent(genesCount) {
|
|
5716
5954
|
if (genesCount > 0) {
|
|
@@ -5725,9 +5963,9 @@ function emitSyncEvent(genesCount) {
|
|
|
5725
5963
|
}
|
|
5726
5964
|
}
|
|
5727
5965
|
function readPid() {
|
|
5728
|
-
if (!
|
|
5966
|
+
if (!fs2.existsSync(PID_PATH)) return null;
|
|
5729
5967
|
try {
|
|
5730
|
-
const raw =
|
|
5968
|
+
const raw = fs2.readFileSync(PID_PATH, "utf-8").trim();
|
|
5731
5969
|
const pid = parseInt(raw, 10);
|
|
5732
5970
|
return isNaN(pid) ? null : pid;
|
|
5733
5971
|
} catch {
|
|
@@ -5735,9 +5973,9 @@ function readPid() {
|
|
|
5735
5973
|
}
|
|
5736
5974
|
}
|
|
5737
5975
|
function readPort() {
|
|
5738
|
-
if (!
|
|
5976
|
+
if (!fs2.existsSync(PORT_PATH)) return null;
|
|
5739
5977
|
try {
|
|
5740
|
-
const raw =
|
|
5978
|
+
const raw = fs2.readFileSync(PORT_PATH, "utf-8").trim();
|
|
5741
5979
|
const port = parseInt(raw, 10);
|
|
5742
5980
|
return isNaN(port) ? null : port;
|
|
5743
5981
|
} catch {
|
|
@@ -5754,24 +5992,24 @@ function isProcessRunning(pid) {
|
|
|
5754
5992
|
}
|
|
5755
5993
|
function writePid(pid) {
|
|
5756
5994
|
ensureCacheDir();
|
|
5757
|
-
if (!
|
|
5758
|
-
|
|
5995
|
+
if (!fs2.existsSync(CONFIG_DIR)) {
|
|
5996
|
+
fs2.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
5759
5997
|
}
|
|
5760
|
-
|
|
5998
|
+
fs2.writeFileSync(PID_PATH, String(pid), { encoding: "utf-8", mode: 384 });
|
|
5761
5999
|
}
|
|
5762
6000
|
function writePort(port) {
|
|
5763
|
-
if (!
|
|
5764
|
-
|
|
6001
|
+
if (!fs2.existsSync(CONFIG_DIR)) {
|
|
6002
|
+
fs2.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
5765
6003
|
}
|
|
5766
|
-
|
|
6004
|
+
fs2.writeFileSync(PORT_PATH, String(port), { encoding: "utf-8", mode: 384 });
|
|
5767
6005
|
}
|
|
5768
6006
|
function cleanupPidFiles() {
|
|
5769
6007
|
try {
|
|
5770
|
-
if (
|
|
6008
|
+
if (fs2.existsSync(PID_PATH)) fs2.unlinkSync(PID_PATH);
|
|
5771
6009
|
} catch {
|
|
5772
6010
|
}
|
|
5773
6011
|
try {
|
|
5774
|
-
if (
|
|
6012
|
+
if (fs2.existsSync(PORT_PATH)) fs2.unlinkSync(PORT_PATH);
|
|
5775
6013
|
} catch {
|
|
5776
6014
|
}
|
|
5777
6015
|
}
|
|
@@ -5794,9 +6032,9 @@ async function runDaemonProcess() {
|
|
|
5794
6032
|
let lastSync = 0;
|
|
5795
6033
|
let syncCount = 0;
|
|
5796
6034
|
let evolutionCursor = 0;
|
|
5797
|
-
if (
|
|
6035
|
+
if (fs2.existsSync(EVOLUTION_CACHE_PATH)) {
|
|
5798
6036
|
try {
|
|
5799
|
-
const cached = JSON.parse(
|
|
6037
|
+
const cached = JSON.parse(fs2.readFileSync(EVOLUTION_CACHE_PATH, "utf-8"));
|
|
5800
6038
|
if (typeof cached?.cursor === "number") evolutionCursor = cached.cursor;
|
|
5801
6039
|
} catch {
|
|
5802
6040
|
}
|
|
@@ -5804,9 +6042,9 @@ async function runDaemonProcess() {
|
|
|
5804
6042
|
const server = (0, import_http.createServer)((req, res) => {
|
|
5805
6043
|
if (req.method === "GET" && req.url === "/health") {
|
|
5806
6044
|
let outboxSize = 0;
|
|
5807
|
-
if (
|
|
6045
|
+
if (fs2.existsSync(OUTBOX_PATH)) {
|
|
5808
6046
|
try {
|
|
5809
|
-
const entries = JSON.parse(
|
|
6047
|
+
const entries = JSON.parse(fs2.readFileSync(OUTBOX_PATH, "utf-8"));
|
|
5810
6048
|
if (Array.isArray(entries)) outboxSize = entries.length;
|
|
5811
6049
|
} catch {
|
|
5812
6050
|
}
|
|
@@ -5869,7 +6107,7 @@ async function runDaemonProcess() {
|
|
|
5869
6107
|
}
|
|
5870
6108
|
ensureCacheDir();
|
|
5871
6109
|
const pulled = data?.data || data;
|
|
5872
|
-
|
|
6110
|
+
fs2.writeFileSync(
|
|
5873
6111
|
EVOLUTION_CACHE_PATH,
|
|
5874
6112
|
JSON.stringify({ cursor: evolutionCursor, lastSync, data: pulled }, null, 2),
|
|
5875
6113
|
{ encoding: "utf-8", mode: 384 }
|
|
@@ -5880,10 +6118,10 @@ async function runDaemonProcess() {
|
|
|
5880
6118
|
}
|
|
5881
6119
|
};
|
|
5882
6120
|
const doOutboxFlush = async () => {
|
|
5883
|
-
if (!
|
|
6121
|
+
if (!fs2.existsSync(OUTBOX_PATH)) return;
|
|
5884
6122
|
let entries = [];
|
|
5885
6123
|
try {
|
|
5886
|
-
entries = JSON.parse(
|
|
6124
|
+
entries = JSON.parse(fs2.readFileSync(OUTBOX_PATH, "utf-8"));
|
|
5887
6125
|
if (!Array.isArray(entries) || entries.length === 0) return;
|
|
5888
6126
|
} catch {
|
|
5889
6127
|
return;
|
|
@@ -5904,7 +6142,7 @@ async function runDaemonProcess() {
|
|
|
5904
6142
|
}
|
|
5905
6143
|
);
|
|
5906
6144
|
if (res.ok) {
|
|
5907
|
-
|
|
6145
|
+
fs2.writeFileSync(OUTBOX_PATH, "[]", { encoding: "utf-8", mode: 384 });
|
|
5908
6146
|
}
|
|
5909
6147
|
} catch {
|
|
5910
6148
|
}
|
|
@@ -6022,7 +6260,7 @@ function resolveNpxPath() {
|
|
|
6022
6260
|
} catch {
|
|
6023
6261
|
for (const p of ["/usr/local/bin/npx", "/opt/homebrew/bin/npx", `${(0, import_os.homedir)()}/.nvm/current/bin/npx`]) {
|
|
6024
6262
|
try {
|
|
6025
|
-
|
|
6263
|
+
fs2.accessSync(p);
|
|
6026
6264
|
return p;
|
|
6027
6265
|
} catch {
|
|
6028
6266
|
}
|
|
@@ -6064,8 +6302,8 @@ function installLaunchd() {
|
|
|
6064
6302
|
<string>${(0, import_path.join)((0, import_os.homedir)(), ".prismer", "daemon.stderr.log")}</string>
|
|
6065
6303
|
</dict>
|
|
6066
6304
|
</plist>`;
|
|
6067
|
-
|
|
6068
|
-
|
|
6305
|
+
fs2.mkdirSync((0, import_path.dirname)(plistPath), { recursive: true });
|
|
6306
|
+
fs2.writeFileSync(plistPath, plist, { mode: 384 });
|
|
6069
6307
|
try {
|
|
6070
6308
|
(0, import_child_process.execSync)(`launchctl load ${plistPath}`, { stdio: "pipe" });
|
|
6071
6309
|
console.log("[prismer] Daemon service installed and started (launchd)");
|
|
@@ -6081,7 +6319,7 @@ function uninstallLaunchd() {
|
|
|
6081
6319
|
} catch {
|
|
6082
6320
|
}
|
|
6083
6321
|
try {
|
|
6084
|
-
|
|
6322
|
+
fs2.unlinkSync(plistPath);
|
|
6085
6323
|
} catch {
|
|
6086
6324
|
}
|
|
6087
6325
|
console.log("[prismer] Daemon service uninstalled (launchd)");
|
|
@@ -6106,8 +6344,8 @@ RestartSec=10
|
|
|
6106
6344
|
[Install]
|
|
6107
6345
|
WantedBy=default.target
|
|
6108
6346
|
`;
|
|
6109
|
-
|
|
6110
|
-
|
|
6347
|
+
fs2.mkdirSync(serviceDir, { recursive: true });
|
|
6348
|
+
fs2.writeFileSync(servicePath, unit, { mode: 420 });
|
|
6111
6349
|
try {
|
|
6112
6350
|
(0, import_child_process.execSync)("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
6113
6351
|
(0, import_child_process.execSync)("systemctl --user enable prismer-daemon", { stdio: "pipe" });
|
|
@@ -6130,7 +6368,7 @@ function uninstallSystemd() {
|
|
|
6130
6368
|
}
|
|
6131
6369
|
const servicePath = (0, import_path.join)((0, import_os.homedir)(), ".config", "systemd", "user", "prismer-daemon.service");
|
|
6132
6370
|
try {
|
|
6133
|
-
|
|
6371
|
+
fs2.unlinkSync(servicePath);
|
|
6134
6372
|
} catch {
|
|
6135
6373
|
}
|
|
6136
6374
|
try {
|
|
@@ -6170,26 +6408,26 @@ if (process.env["PRISMER_DAEMON"] === "1") {
|
|
|
6170
6408
|
// src/cli.ts
|
|
6171
6409
|
var cliVersion = "1.7.2";
|
|
6172
6410
|
try {
|
|
6173
|
-
const pkgPath =
|
|
6174
|
-
const pkg = JSON.parse(
|
|
6411
|
+
const pkgPath = path3.join(__dirname, "..", "package.json");
|
|
6412
|
+
const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf8"));
|
|
6175
6413
|
cliVersion = pkg.version || cliVersion;
|
|
6176
6414
|
} catch {
|
|
6177
6415
|
}
|
|
6178
|
-
var CONFIG_DIR2 =
|
|
6179
|
-
var CONFIG_PATH2 =
|
|
6416
|
+
var CONFIG_DIR2 = path3.join(os2.homedir(), ".prismer");
|
|
6417
|
+
var CONFIG_PATH2 = path3.join(CONFIG_DIR2, "config.toml");
|
|
6180
6418
|
function ensureConfigDir() {
|
|
6181
|
-
if (!
|
|
6182
|
-
|
|
6419
|
+
if (!fs3.existsSync(CONFIG_DIR2)) {
|
|
6420
|
+
fs3.mkdirSync(CONFIG_DIR2, { recursive: true });
|
|
6183
6421
|
}
|
|
6184
6422
|
}
|
|
6185
6423
|
function readConfig() {
|
|
6186
|
-
if (!
|
|
6187
|
-
const raw =
|
|
6424
|
+
if (!fs3.existsSync(CONFIG_PATH2)) return {};
|
|
6425
|
+
const raw = fs3.readFileSync(CONFIG_PATH2, "utf-8");
|
|
6188
6426
|
return TOML2.parse(raw);
|
|
6189
6427
|
}
|
|
6190
6428
|
function writeConfig(config) {
|
|
6191
6429
|
ensureConfigDir();
|
|
6192
|
-
|
|
6430
|
+
fs3.writeFileSync(CONFIG_PATH2, TOML2.stringify(config), { encoding: "utf-8", mode: 384 });
|
|
6193
6431
|
}
|
|
6194
6432
|
function setNestedValue(obj, dotPath, value) {
|
|
6195
6433
|
const parts = dotPath.split(".");
|
|
@@ -6205,7 +6443,7 @@ function getIMClient() {
|
|
|
6205
6443
|
const cfg = readConfig();
|
|
6206
6444
|
const token = cfg?.auth?.im_token;
|
|
6207
6445
|
if (!token) {
|
|
6208
|
-
|
|
6446
|
+
error('No IM token. Run "prismer setup --agent" or "prismer register <username>" first.');
|
|
6209
6447
|
process.exit(1);
|
|
6210
6448
|
}
|
|
6211
6449
|
const env = cfg?.default?.environment || "production";
|
|
@@ -6216,7 +6454,7 @@ function getAPIClient() {
|
|
|
6216
6454
|
const cfg = readConfig();
|
|
6217
6455
|
const apiKey = cfg?.default?.api_key;
|
|
6218
6456
|
if (!apiKey) {
|
|
6219
|
-
|
|
6457
|
+
error('No API key. Run "prismer setup" to sign in and get your key.');
|
|
6220
6458
|
process.exit(1);
|
|
6221
6459
|
}
|
|
6222
6460
|
const env = cfg?.default?.environment || "production";
|
|
@@ -6227,12 +6465,12 @@ var program = new import_commander.Command();
|
|
|
6227
6465
|
program.name("prismer").description("Prismer Cloud SDK CLI").version(cliVersion);
|
|
6228
6466
|
async function verifyAndSaveKey(config, apiKey) {
|
|
6229
6467
|
if (!apiKey) {
|
|
6230
|
-
|
|
6468
|
+
error("No key provided.");
|
|
6231
6469
|
process.exit(1);
|
|
6232
6470
|
}
|
|
6233
6471
|
if (!apiKey.startsWith("sk-prismer-")) {
|
|
6234
|
-
|
|
6235
|
-
|
|
6472
|
+
error("Invalid key format. API keys start with sk-prismer-");
|
|
6473
|
+
dim2(" Get your key at: https://prismer.cloud/setup");
|
|
6236
6474
|
process.exit(1);
|
|
6237
6475
|
}
|
|
6238
6476
|
const baseUrl = config.default?.base_url || "https://prismer.cloud";
|
|
@@ -6241,25 +6479,25 @@ async function verifyAndSaveKey(config, apiKey) {
|
|
|
6241
6479
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
6242
6480
|
});
|
|
6243
6481
|
if (res.status === 401) {
|
|
6244
|
-
|
|
6245
|
-
|
|
6482
|
+
error("API key is invalid or expired.");
|
|
6483
|
+
dim2(" Get a new key at: https://prismer.cloud/setup");
|
|
6246
6484
|
process.exit(1);
|
|
6247
6485
|
}
|
|
6248
|
-
|
|
6486
|
+
success("API key verified");
|
|
6249
6487
|
} catch (err) {
|
|
6250
|
-
|
|
6488
|
+
warn(`Could not verify key (${err.message}). Saving anyway.`);
|
|
6251
6489
|
}
|
|
6252
6490
|
if (!config.default) config.default = {};
|
|
6253
6491
|
config.default.api_key = apiKey;
|
|
6254
6492
|
if (!config.default.environment) config.default.environment = "production";
|
|
6255
6493
|
writeConfig(config);
|
|
6256
6494
|
console.log("");
|
|
6257
|
-
|
|
6258
|
-
|
|
6495
|
+
success("Saved to ~/.prismer/config.toml");
|
|
6496
|
+
info("You can now use: CLI commands, MCP tools, Claude Code plugin, and all SDKs.");
|
|
6259
6497
|
try {
|
|
6260
6498
|
installDaemonService();
|
|
6261
6499
|
} catch {
|
|
6262
|
-
|
|
6500
|
+
dim2("Daemon auto-start setup skipped. Run manually: prismer daemon install");
|
|
6263
6501
|
}
|
|
6264
6502
|
}
|
|
6265
6503
|
function openBrowser(url) {
|
|
@@ -6284,10 +6522,10 @@ async function runSetup(opts, apiKey) {
|
|
|
6284
6522
|
const baseUrl = config.default.base_url || "https://prismer.cloud";
|
|
6285
6523
|
if (!opts.force && config.default.api_key?.startsWith("sk-prismer-")) {
|
|
6286
6524
|
const masked = config.default.api_key.slice(0, 12) + "..." + config.default.api_key.slice(-4);
|
|
6287
|
-
|
|
6525
|
+
success(`Already configured: ${masked}`);
|
|
6288
6526
|
console.log("");
|
|
6289
|
-
|
|
6290
|
-
|
|
6527
|
+
dim2(" To reconfigure, run: prismer setup --force");
|
|
6528
|
+
dim2(" To check status: prismer status");
|
|
6291
6529
|
return;
|
|
6292
6530
|
}
|
|
6293
6531
|
if (apiKey) {
|
|
@@ -6296,8 +6534,8 @@ async function runSetup(opts, apiKey) {
|
|
|
6296
6534
|
}
|
|
6297
6535
|
if (opts.agent) {
|
|
6298
6536
|
if (!opts.force && config.auth?.im_token) {
|
|
6299
|
-
|
|
6300
|
-
|
|
6537
|
+
success("Already registered as agent (IM token exists).");
|
|
6538
|
+
dim2(" For API key access, run: prismer setup");
|
|
6301
6539
|
return;
|
|
6302
6540
|
}
|
|
6303
6541
|
const username = `agent-${Date.now().toString(36)}`;
|
|
@@ -6314,32 +6552,34 @@ async function runSetup(opts, apiKey) {
|
|
|
6314
6552
|
config.auth.im_user_id = data.data?.imUserId || data.data?.userId;
|
|
6315
6553
|
config.auth.im_username = data.data?.username || username;
|
|
6316
6554
|
writeConfig(config);
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6555
|
+
success("Agent registered with free credits");
|
|
6556
|
+
keyValue({
|
|
6557
|
+
"Username": config.auth.im_username || "",
|
|
6558
|
+
"User ID": config.auth.im_user_id || ""
|
|
6559
|
+
});
|
|
6320
6560
|
console.log("");
|
|
6321
|
-
|
|
6561
|
+
info("For full API access, sign in: prismer setup");
|
|
6322
6562
|
} catch (err) {
|
|
6323
|
-
|
|
6324
|
-
|
|
6563
|
+
error(`Agent registration failed: ${err.message}`);
|
|
6564
|
+
dim2(" Try signing in instead: prismer setup");
|
|
6325
6565
|
process.exit(1);
|
|
6326
6566
|
}
|
|
6327
6567
|
return;
|
|
6328
6568
|
}
|
|
6329
6569
|
if (opts.manual) {
|
|
6330
6570
|
const setupUrl = `${baseUrl}/setup?utm_source=cli&utm_medium=manual`;
|
|
6331
|
-
|
|
6332
|
-
|
|
6571
|
+
info("Opening browser to sign in...");
|
|
6572
|
+
dim2(` ${setupUrl}`);
|
|
6333
6573
|
console.log("");
|
|
6334
6574
|
openBrowser(setupUrl);
|
|
6335
|
-
|
|
6575
|
+
info("After signing in, copy the API key from the page and paste it below.");
|
|
6336
6576
|
console.log("");
|
|
6337
6577
|
const readline = require("readline");
|
|
6338
6578
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
6339
6579
|
rl.question("Paste your API key: ", (key) => {
|
|
6340
6580
|
rl.close();
|
|
6341
6581
|
verifyAndSaveKey(config, key.trim()).catch((err) => {
|
|
6342
|
-
|
|
6582
|
+
error(`Setup failed: ${err.message}`);
|
|
6343
6583
|
process.exit(1);
|
|
6344
6584
|
});
|
|
6345
6585
|
});
|
|
@@ -6382,20 +6622,20 @@ async function runSetup(opts, apiKey) {
|
|
|
6382
6622
|
const port = server.address().port;
|
|
6383
6623
|
const callbackUrl = `http://127.0.0.1:${port}/callback`;
|
|
6384
6624
|
const setupUrl = `${baseUrl}/setup?callback=${encodeURIComponent(callbackUrl)}&state=${state}&utm_source=cli&utm_medium=auto`;
|
|
6385
|
-
|
|
6625
|
+
info("Opening browser to sign in...");
|
|
6386
6626
|
console.log("");
|
|
6387
6627
|
openBrowser(setupUrl);
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6628
|
+
info("Waiting for authentication...");
|
|
6629
|
+
dim2(" (If the browser didn't open, visit this URL manually:)");
|
|
6630
|
+
dim2(` ${setupUrl}`);
|
|
6391
6631
|
console.log("");
|
|
6392
6632
|
setTimeout(() => {
|
|
6393
6633
|
if (!resolved) {
|
|
6394
|
-
|
|
6395
|
-
console.
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6634
|
+
error("Timed out waiting for authentication (5 min).");
|
|
6635
|
+
console.log("");
|
|
6636
|
+
dim2(" Alternatives:");
|
|
6637
|
+
dim2(" prismer setup --manual Paste key manually");
|
|
6638
|
+
dim2(" prismer setup --agent Register as agent (free credits, no browser)");
|
|
6399
6639
|
server.close();
|
|
6400
6640
|
process.exit(1);
|
|
6401
6641
|
}
|
|
@@ -6406,7 +6646,7 @@ program.command("setup [api-key]").description("Set up Prismer \u2014 sign in vi
|
|
|
6406
6646
|
await runSetup(opts, apiKey);
|
|
6407
6647
|
});
|
|
6408
6648
|
program.command("init [api-key]").description('Alias for "prismer setup" (deprecated, use setup instead)').option("--manual", "Paste API key manually").option("--agent", "Register as agent with free credits").option("--force", "Reconfigure even if already set up").action(async (apiKey, opts) => {
|
|
6409
|
-
|
|
6649
|
+
warn('"prismer init" is deprecated. Use "prismer setup" instead.');
|
|
6410
6650
|
console.log("");
|
|
6411
6651
|
await runSetup(opts, apiKey);
|
|
6412
6652
|
});
|
|
@@ -6414,7 +6654,7 @@ program.command("register <username>").description("Register an IM identity and
|
|
|
6414
6654
|
const config = readConfig();
|
|
6415
6655
|
const apiKey = config.default?.api_key;
|
|
6416
6656
|
if (!apiKey) {
|
|
6417
|
-
|
|
6657
|
+
error('No API key. Run "prismer setup" first.');
|
|
6418
6658
|
process.exit(1);
|
|
6419
6659
|
}
|
|
6420
6660
|
const client = new PrismerClient({
|
|
@@ -6434,7 +6674,7 @@ program.command("register <username>").description("Register an IM identity and
|
|
|
6434
6674
|
try {
|
|
6435
6675
|
const result = await client.im.account.register(registerOpts);
|
|
6436
6676
|
if (!result.ok || !result.data) {
|
|
6437
|
-
|
|
6677
|
+
error(`Registration failed: ${result.error?.message || "Unknown error"}`);
|
|
6438
6678
|
process.exit(1);
|
|
6439
6679
|
}
|
|
6440
6680
|
const data = result.data;
|
|
@@ -6444,84 +6684,89 @@ program.command("register <username>").description("Register an IM identity and
|
|
|
6444
6684
|
config.auth.im_username = data.username;
|
|
6445
6685
|
config.auth.im_token_expires = data.expiresIn;
|
|
6446
6686
|
writeConfig(config);
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6687
|
+
success("Registration successful!");
|
|
6688
|
+
keyValue({
|
|
6689
|
+
"User ID": data.imUserId,
|
|
6690
|
+
"Username": data.username,
|
|
6691
|
+
"Display": data.displayName,
|
|
6692
|
+
"Role": data.role,
|
|
6693
|
+
"New": String(data.isNew)
|
|
6694
|
+
});
|
|
6695
|
+
dim2(" Token stored in ~/.prismer/config.toml");
|
|
6454
6696
|
} catch (err) {
|
|
6455
|
-
|
|
6697
|
+
error(`Registration failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
6456
6698
|
process.exit(1);
|
|
6457
6699
|
}
|
|
6458
6700
|
});
|
|
6459
6701
|
program.command("status").description("Show current config and live info").action(async () => {
|
|
6460
6702
|
const config = readConfig();
|
|
6461
|
-
|
|
6703
|
+
info("Prismer Status");
|
|
6704
|
+
console.log("");
|
|
6462
6705
|
const apiKey = config.default?.api_key;
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
}
|
|
6469
|
-
console.log(
|
|
6470
|
-
console.log(`Base URL: ${config.default?.base_url || "(default)"}
|
|
6471
|
-
`);
|
|
6706
|
+
const maskedKey = apiKey ? apiKey.length > 16 ? apiKey.slice(0, 12) + "..." + apiKey.slice(-4) : "***" : "(not set)";
|
|
6707
|
+
keyValue({
|
|
6708
|
+
"API Key": maskedKey,
|
|
6709
|
+
"Environment": config.default?.environment || "(not set)",
|
|
6710
|
+
"Base URL": config.default?.base_url || "(default)"
|
|
6711
|
+
});
|
|
6712
|
+
console.log("");
|
|
6472
6713
|
const token = config.auth?.im_token;
|
|
6473
6714
|
if (token) {
|
|
6474
|
-
|
|
6475
|
-
console.log(`IM Username: ${config.auth?.im_username || "(unknown)"}`);
|
|
6715
|
+
let tokenStatus = "set (expiry unknown)";
|
|
6476
6716
|
const expires = config.auth?.im_token_expires;
|
|
6477
6717
|
if (expires) {
|
|
6478
6718
|
const expiresDate = new Date(expires);
|
|
6479
6719
|
if (!isNaN(expiresDate.getTime())) {
|
|
6480
|
-
|
|
6481
|
-
console.log(`IM Token: ${label} (expires ${expiresDate.toISOString()})`);
|
|
6720
|
+
tokenStatus = expiresDate <= /* @__PURE__ */ new Date() ? "EXPIRED" : `valid (expires ${expiresDate.toISOString()})`;
|
|
6482
6721
|
} else {
|
|
6483
|
-
|
|
6722
|
+
tokenStatus = `set (expires in ${expires})`;
|
|
6484
6723
|
}
|
|
6485
|
-
} else {
|
|
6486
|
-
console.log("IM Token: set (expiry unknown)");
|
|
6487
6724
|
}
|
|
6488
|
-
|
|
6489
|
-
|
|
6725
|
+
keyValue({
|
|
6726
|
+
"IM User ID": config.auth?.im_user_id || "(unknown)",
|
|
6727
|
+
"IM Username": config.auth?.im_username || "(unknown)",
|
|
6728
|
+
"IM Token": tokenStatus
|
|
6729
|
+
});
|
|
6730
|
+
console.log("");
|
|
6731
|
+
const me = await withSpinner("Fetching live info", async () => {
|
|
6490
6732
|
const client = new PrismerClient({
|
|
6491
6733
|
apiKey: token,
|
|
6492
6734
|
environment: config.default?.environment || "production",
|
|
6493
6735
|
baseUrl: config.default?.base_url || void 0
|
|
6494
6736
|
});
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6737
|
+
return client.im.account.me();
|
|
6738
|
+
}).catch((err) => {
|
|
6739
|
+
warn(`Could not fetch live info: ${err instanceof Error ? err.message : String(err)}`);
|
|
6740
|
+
return null;
|
|
6741
|
+
});
|
|
6742
|
+
if (me && me.ok && me.data) {
|
|
6743
|
+
keyValue({
|
|
6744
|
+
"Display": me.data.user.displayName,
|
|
6745
|
+
"Role": me.data.user.role,
|
|
6746
|
+
"Credits": String(me.data.credits.balance),
|
|
6747
|
+
"Messages": String(me.data.stats.messagesSent),
|
|
6748
|
+
"Unread": String(me.data.stats.unreadCount)
|
|
6749
|
+
});
|
|
6750
|
+
} else if (me) {
|
|
6751
|
+
warn(`Could not fetch live info: ${me.error?.message || "unknown error"}`);
|
|
6507
6752
|
}
|
|
6508
6753
|
} else {
|
|
6509
|
-
|
|
6754
|
+
dim2(" IM Token: (not registered)");
|
|
6510
6755
|
}
|
|
6511
6756
|
});
|
|
6512
6757
|
var configCmd = program.command("config").description("Manage config file");
|
|
6513
6758
|
configCmd.command("show").description("Print config file").action(() => {
|
|
6514
|
-
if (!
|
|
6515
|
-
|
|
6759
|
+
if (!fs3.existsSync(CONFIG_PATH2)) {
|
|
6760
|
+
warn('No config file. Run "prismer setup" to create one.');
|
|
6516
6761
|
return;
|
|
6517
6762
|
}
|
|
6518
|
-
console.log(
|
|
6763
|
+
console.log(fs3.readFileSync(CONFIG_PATH2, "utf-8"));
|
|
6519
6764
|
});
|
|
6520
6765
|
configCmd.command("set <key> <value>").description("Set a config value (e.g. default.base_url)").action((key, value) => {
|
|
6521
6766
|
const config = readConfig();
|
|
6522
6767
|
setNestedValue(config, key, value);
|
|
6523
6768
|
writeConfig(config);
|
|
6524
|
-
|
|
6769
|
+
success(`Set ${key} = ${value}`);
|
|
6525
6770
|
});
|
|
6526
6771
|
var tokenCmd = program.command("token").description("Token management");
|
|
6527
6772
|
tokenCmd.command("refresh").description("Refresh IM JWT token").option("--json", "JSON output").action(async (opts) => {
|
|
@@ -6532,7 +6777,7 @@ tokenCmd.command("refresh").description("Refresh IM JWT token").option("--json",
|
|
|
6532
6777
|
return;
|
|
6533
6778
|
}
|
|
6534
6779
|
if (!res.ok) {
|
|
6535
|
-
|
|
6780
|
+
error(`Token refresh failed: ${JSON.stringify(res.error)}`);
|
|
6536
6781
|
process.exit(1);
|
|
6537
6782
|
}
|
|
6538
6783
|
const data = res.data;
|
|
@@ -6542,9 +6787,9 @@ tokenCmd.command("refresh").description("Refresh IM JWT token").option("--json",
|
|
|
6542
6787
|
config.auth.im_token = data.token;
|
|
6543
6788
|
if (data.expiresIn) config.auth.im_token_expires = data.expiresIn;
|
|
6544
6789
|
writeConfig(config);
|
|
6545
|
-
|
|
6790
|
+
success("Token refreshed and saved.");
|
|
6546
6791
|
} else {
|
|
6547
|
-
|
|
6792
|
+
info("Token refreshed (no new token in response).");
|
|
6548
6793
|
}
|
|
6549
6794
|
});
|
|
6550
6795
|
register(program, getIMClient, getAPIClient);
|
|
@@ -6562,35 +6807,41 @@ program.command("send").description("Send a direct message (shortcut for: im sen
|
|
|
6562
6807
|
const sendOpts = {};
|
|
6563
6808
|
if (opts.type && opts.type !== "text") sendOpts.type = opts.type;
|
|
6564
6809
|
if (opts.replyTo) sendOpts.parentId = opts.replyTo;
|
|
6565
|
-
const res = await
|
|
6810
|
+
const res = await withSpinner("Sending message", async () => {
|
|
6811
|
+
return client.im.direct.send(userId, message, sendOpts);
|
|
6812
|
+
});
|
|
6566
6813
|
if (opts.json) {
|
|
6567
6814
|
console.log(JSON.stringify(res, null, 2));
|
|
6568
6815
|
return;
|
|
6569
6816
|
}
|
|
6570
6817
|
if (!res.ok) {
|
|
6571
|
-
|
|
6818
|
+
error(`Send failed: ${JSON.stringify(res.error)}`);
|
|
6572
6819
|
process.exit(1);
|
|
6573
6820
|
}
|
|
6574
|
-
|
|
6821
|
+
success(`Message sent (conversation: ${res.data?.conversationId})`);
|
|
6575
6822
|
});
|
|
6576
6823
|
program.command("load").description("Load URL(s) \u2192 compressed HQCC (shortcut for: context load)").argument("<urls...>", "One or more URLs").option("-f, --format <fmt>", "Return format: hqcc, raw, both", "hqcc").option("--json", "JSON output").action(async (urls, opts) => {
|
|
6577
6824
|
const client = getAPIClient();
|
|
6578
6825
|
const input = urls.length === 1 ? urls[0] : urls;
|
|
6579
6826
|
const loadOpts = {};
|
|
6580
6827
|
if (opts.format) loadOpts.return = { format: opts.format };
|
|
6581
|
-
const res = await
|
|
6828
|
+
const res = await withSpinner(`Loading ${urls.length} URL(s)`, async () => {
|
|
6829
|
+
return client.load(input, loadOpts);
|
|
6830
|
+
});
|
|
6582
6831
|
if (opts.json) {
|
|
6583
6832
|
console.log(JSON.stringify(res, null, 2));
|
|
6584
6833
|
return;
|
|
6585
6834
|
}
|
|
6586
6835
|
if (!res.success) {
|
|
6587
|
-
|
|
6836
|
+
error(res.error?.message || "Load failed");
|
|
6588
6837
|
process.exit(1);
|
|
6589
6838
|
}
|
|
6590
6839
|
const results = res.results || (res.result ? [res.result] : []);
|
|
6591
6840
|
for (const r of results) {
|
|
6592
|
-
|
|
6593
|
-
|
|
6841
|
+
keyValue({
|
|
6842
|
+
"URL": r.url || "?",
|
|
6843
|
+
"Status": r.cached ? "cached" : "loaded"
|
|
6844
|
+
});
|
|
6594
6845
|
if (r.hqcc) console.log(`
|
|
6595
6846
|
--- HQCC ---
|
|
6596
6847
|
${r.hqcc.substring(0, 2e3)}`);
|
|
@@ -6602,44 +6853,58 @@ ${r.raw.substring(0, 2e3)}`);
|
|
|
6602
6853
|
});
|
|
6603
6854
|
program.command("search").description("Search web content (shortcut for: context search)").argument("<query>", "Search query").option("-k, --top-k <n>", "Number of results", "5").option("--json", "JSON output").action(async (query, opts) => {
|
|
6604
6855
|
const client = getAPIClient();
|
|
6605
|
-
const res = await
|
|
6856
|
+
const res = await withSpinner(`Searching: ${query}`, async () => {
|
|
6857
|
+
return client.search(query, { topK: parseInt(opts.topK || "5") });
|
|
6858
|
+
});
|
|
6606
6859
|
if (opts.json) {
|
|
6607
6860
|
console.log(JSON.stringify(res, null, 2));
|
|
6608
6861
|
return;
|
|
6609
6862
|
}
|
|
6610
6863
|
if (!res.success) {
|
|
6611
|
-
|
|
6864
|
+
error(res.error?.message || "Search failed");
|
|
6612
6865
|
process.exit(1);
|
|
6613
6866
|
}
|
|
6614
6867
|
const results = res.results || [];
|
|
6615
6868
|
if (results.length === 0) {
|
|
6616
|
-
|
|
6869
|
+
warn("No results.");
|
|
6617
6870
|
return;
|
|
6618
6871
|
}
|
|
6872
|
+
const rows = results.map((r, i) => [
|
|
6873
|
+
String(i + 1),
|
|
6874
|
+
r.url || "(no url)",
|
|
6875
|
+
String(r.ranking?.score ?? "-")
|
|
6876
|
+
]);
|
|
6877
|
+
table(["#", "URL", "Score"], rows);
|
|
6619
6878
|
for (let i = 0; i < results.length; i++) {
|
|
6620
6879
|
const r = results[i];
|
|
6621
|
-
|
|
6622
|
-
|
|
6880
|
+
if (r.hqcc) {
|
|
6881
|
+
console.log("");
|
|
6882
|
+
dim2(` ${i + 1}. ${r.hqcc.substring(0, 200)}`);
|
|
6883
|
+
}
|
|
6623
6884
|
}
|
|
6624
6885
|
});
|
|
6625
6886
|
program.command("parse").description("Parse a document via OCR (shortcut for: parse run)").argument("<url>", "Document URL").option("-m, --mode <mode>", "Parse mode: fast, hires, auto", "fast").option("--async", "Async mode (returns task ID)").option("--json", "JSON output").action(async (url, opts) => {
|
|
6626
6887
|
const client = getAPIClient();
|
|
6627
|
-
const res = await
|
|
6888
|
+
const res = await withSpinner(`Parsing: ${url}`, async () => {
|
|
6889
|
+
return client.parsePdf(url, opts.mode);
|
|
6890
|
+
});
|
|
6628
6891
|
if (opts.json) {
|
|
6629
6892
|
console.log(JSON.stringify(res, null, 2));
|
|
6630
6893
|
return;
|
|
6631
6894
|
}
|
|
6632
6895
|
if (!res.success) {
|
|
6633
|
-
|
|
6896
|
+
error(res.error?.message || "Parse failed");
|
|
6634
6897
|
process.exit(1);
|
|
6635
6898
|
}
|
|
6636
6899
|
if (res.taskId) {
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6900
|
+
keyValue({
|
|
6901
|
+
"Task ID": res.taskId,
|
|
6902
|
+
"Status": res.status || "processing"
|
|
6903
|
+
});
|
|
6904
|
+
console.log("");
|
|
6905
|
+
dim2(` Check: prismer parse-status ${res.taskId}`);
|
|
6641
6906
|
} else if (res.document) {
|
|
6642
|
-
|
|
6907
|
+
success("Parse complete");
|
|
6643
6908
|
const content = res.document.markdown || res.document.text || JSON.stringify(res.document, null, 2);
|
|
6644
6909
|
console.log(content.substring(0, 5e3));
|
|
6645
6910
|
}
|
|
@@ -6654,8 +6919,10 @@ program.command("parse-status").description("Check parse task status").argument(
|
|
|
6654
6919
|
console.log(JSON.stringify(res, null, 2));
|
|
6655
6920
|
return;
|
|
6656
6921
|
}
|
|
6657
|
-
|
|
6658
|
-
|
|
6922
|
+
keyValue({
|
|
6923
|
+
"Task": taskId,
|
|
6924
|
+
"Status": res.status || (res.success ? "complete" : "unknown")
|
|
6925
|
+
});
|
|
6659
6926
|
});
|
|
6660
6927
|
program.command("parse-result").description("Get parse result").argument("<task-id>", "Task ID").option("--json", "JSON output").action(async (taskId, opts) => {
|
|
6661
6928
|
const client = getAPIClient();
|
|
@@ -6665,9 +6932,10 @@ program.command("parse-result").description("Get parse result").argument("<task-
|
|
|
6665
6932
|
return;
|
|
6666
6933
|
}
|
|
6667
6934
|
if (!res.success) {
|
|
6668
|
-
|
|
6935
|
+
error(res.error?.message || "Not ready");
|
|
6669
6936
|
process.exit(1);
|
|
6670
6937
|
}
|
|
6938
|
+
success("Parse result ready");
|
|
6671
6939
|
const content = res.document?.markdown || res.document?.text || JSON.stringify(res.document, null, 2);
|
|
6672
6940
|
console.log(content);
|
|
6673
6941
|
});
|
|
@@ -6676,23 +6944,32 @@ program.command("recall").description("Search across memory, cache, and evolutio
|
|
|
6676
6944
|
const params = { q: query };
|
|
6677
6945
|
if (opts.scope) params.scope = opts.scope;
|
|
6678
6946
|
if (opts.limit) params.limit = opts.limit;
|
|
6679
|
-
const res = await
|
|
6947
|
+
const res = await withSpinner(`Recalling: ${query}`, async () => {
|
|
6948
|
+
return client.im.memory._r("GET", "/api/im/recall", void 0, params);
|
|
6949
|
+
});
|
|
6680
6950
|
if (opts.json) {
|
|
6681
6951
|
console.log(JSON.stringify(res, null, 2));
|
|
6682
6952
|
return;
|
|
6683
6953
|
}
|
|
6684
6954
|
if (!res.ok) {
|
|
6685
|
-
|
|
6955
|
+
error(`Recall failed: ${JSON.stringify(res.error)}`);
|
|
6686
6956
|
process.exit(1);
|
|
6687
6957
|
}
|
|
6688
6958
|
const data = res.data || [];
|
|
6689
6959
|
if (data.length === 0) {
|
|
6690
|
-
|
|
6960
|
+
warn(`No results for "${query}".`);
|
|
6691
6961
|
return;
|
|
6692
6962
|
}
|
|
6963
|
+
const rows = data.map((item) => [
|
|
6964
|
+
(item.source || "").toUpperCase(),
|
|
6965
|
+
item.title || "?",
|
|
6966
|
+
(item.score || 0).toFixed(2)
|
|
6967
|
+
]);
|
|
6968
|
+
table(["Source", "Title", "Score"], rows);
|
|
6693
6969
|
for (const item of data) {
|
|
6694
|
-
|
|
6695
|
-
|
|
6970
|
+
if (item.snippet) {
|
|
6971
|
+
dim2(` ${item.snippet.substring(0, 200)}`);
|
|
6972
|
+
}
|
|
6696
6973
|
}
|
|
6697
6974
|
});
|
|
6698
6975
|
program.command("discover").description("Discover available agents (shortcut for: im discover)").option("--type <type>", "Filter by agent type").option("--capability <cap>", "Filter by capability").option("--json", "JSON output").action(async (opts) => {
|
|
@@ -6700,24 +6977,29 @@ program.command("discover").description("Discover available agents (shortcut for
|
|
|
6700
6977
|
const discoverOpts = {};
|
|
6701
6978
|
if (opts.type) discoverOpts.type = opts.type;
|
|
6702
6979
|
if (opts.capability) discoverOpts.capability = opts.capability;
|
|
6703
|
-
const res = await
|
|
6980
|
+
const res = await withSpinner("Discovering agents", async () => {
|
|
6981
|
+
return client.im.contacts.discover(discoverOpts);
|
|
6982
|
+
});
|
|
6704
6983
|
if (opts.json) {
|
|
6705
6984
|
console.log(JSON.stringify(res, null, 2));
|
|
6706
6985
|
return;
|
|
6707
6986
|
}
|
|
6708
6987
|
if (!res.ok) {
|
|
6709
|
-
|
|
6988
|
+
error(`Discovery failed: ${JSON.stringify(res.error)}`);
|
|
6710
6989
|
process.exit(1);
|
|
6711
6990
|
}
|
|
6712
6991
|
const agents = res.data || [];
|
|
6713
6992
|
if (agents.length === 0) {
|
|
6714
|
-
|
|
6993
|
+
warn("No agents found.");
|
|
6715
6994
|
return;
|
|
6716
6995
|
}
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6996
|
+
const rows = agents.map((a) => [
|
|
6997
|
+
a.username || "",
|
|
6998
|
+
a.agentType || "",
|
|
6999
|
+
a.status || "",
|
|
7000
|
+
a.displayName || ""
|
|
7001
|
+
]);
|
|
7002
|
+
table(["Username", "Type", "Status", "Display Name"], rows);
|
|
6721
7003
|
});
|
|
6722
7004
|
program.command("daemon <action>").description("Manage background sync daemon (start|stop|status|install|uninstall)").action(async (action) => {
|
|
6723
7005
|
switch (action) {
|
|
@@ -6737,13 +7019,17 @@ program.command("daemon <action>").description("Manage background sync daemon (s
|
|
|
6737
7019
|
uninstallDaemonService();
|
|
6738
7020
|
break;
|
|
6739
7021
|
default:
|
|
6740
|
-
|
|
7022
|
+
error(`Unknown daemon action: ${action}. Use: start, stop, status, install, uninstall`);
|
|
6741
7023
|
process.exit(1);
|
|
6742
7024
|
}
|
|
6743
7025
|
});
|
|
7026
|
+
displayBanner();
|
|
6744
7027
|
program.parse(process.argv);
|
|
6745
7028
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6746
7029
|
0 && (module.exports = {
|
|
6747
7030
|
getAPIClient,
|
|
6748
7031
|
getIMClient
|
|
6749
7032
|
});
|
|
7033
|
+
,
|
|
7034
|
+
getIMClient
|
|
7035
|
+
});
|