cicy-desktop 2.1.41 → 2.1.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.41",
3
+ "version": "2.1.42",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
@@ -17,4 +17,5 @@ module.exports = [
17
17
  require("./ipc-bridge"),
18
18
  require("./hook-gemini"),
19
19
  require("./chrome-tools"),
20
+ require("./list-tools"),
20
21
  ];
@@ -0,0 +1,46 @@
1
+ const { z } = require("zod");
2
+ const { loadToolCatalog } = require("../server/tool-catalog");
3
+ const { zodToJsonSchema } = require("../server/tool-registry");
4
+
5
+ // A meta-tool: lets any electronRPC caller (renderer, <webview>, agent-desktop
6
+ // `rpc list_tools`) discover the full set of registered tools at runtime —
7
+ // previously the only index was HTTP /openapi.json, unreachable over the IPC /
8
+ // desktop_event bridge.
9
+ module.exports = (registerTool) => {
10
+ registerTool(
11
+ "list_tools",
12
+ "列出本机 cicy-desktop 当前注册的所有 electronRPC 工具(name/description/tag;可选 inputSchema)。用于运行时发现可调用工具全集。",
13
+ z.object({
14
+ tag: z.string().optional().describe("只列某个 tag 下的工具,如 Chrome / System / General"),
15
+ schema: z.boolean().optional().describe("为 true 时附带每个工具的 inputSchema(JSON Schema)"),
16
+ names_only: z.boolean().optional().describe("为 true 时只返回工具名数组"),
17
+ }),
18
+ async ({ tag, schema, names_only } = {}) => {
19
+ const cat = loadToolCatalog();
20
+ let records = Array.from(cat.toolsByName.values());
21
+ if (tag) records = records.filter((r) => (r.tag || "General") === tag);
22
+ records.sort(
23
+ (a, b) => (a.tag || "General").localeCompare(b.tag || "General") || a.name.localeCompare(b.name)
24
+ );
25
+
26
+ let payload;
27
+ if (names_only) {
28
+ payload = { count: records.length, tools: records.map((r) => r.name) };
29
+ } else {
30
+ payload = {
31
+ count: records.length,
32
+ tags: [...new Set(records.map((r) => r.tag || "General"))].sort(),
33
+ tools: records.map((r) => {
34
+ const t = { name: r.name, description: r.description, tag: r.tag || "General" };
35
+ if (schema) {
36
+ try { t.inputSchema = zodToJsonSchema(r.schema); } catch { t.inputSchema = null; }
37
+ }
38
+ return t;
39
+ }),
40
+ };
41
+ }
42
+ return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
43
+ },
44
+ { tag: "System" }
45
+ );
46
+ };