mu-agent-bridge 1.0.71 → 1.0.78

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.
Files changed (195) hide show
  1. package/README.md +17 -10
  2. package/dist/src-ts/agent.js +35 -0
  3. package/dist/src-ts/channel-sessions.js +3 -2
  4. package/dist/src-ts/cli.js +67 -37
  5. package/dist/src-ts/control-server.js +12 -30
  6. package/dist/src-ts/core-updater.js +141 -33
  7. package/dist/src-ts/daemon-process.js +2 -1
  8. package/dist/src-ts/dsh-agent.js +31 -13
  9. package/dist/src-ts/http-agent.js +36 -0
  10. package/dist/src-ts/plugin-catalog.js +11 -2
  11. package/dist/src-ts/plugin-manager.js +351 -50
  12. package/dist/src-ts/plugins/abweb/index.js +1 -1
  13. package/dist/src-ts/plugins/abweb/public/app.js +73 -5
  14. package/dist/src-ts/plugins/abweb/public/index.html +15 -0
  15. package/dist/src-ts/plugins/abweb/public/style.css +4 -0
  16. package/dist/src-ts/plugins/aun/attachments.js +3 -21
  17. package/dist/src-ts/plugins/aun/index.js +155 -21
  18. package/dist/src-ts/plugins/aun/messages.js +4 -1
  19. package/dist/src-ts/plugins/aun/public/app.js +2 -1
  20. package/dist/src-ts/plugins/aun/public/index.html +1 -1
  21. package/dist/src-ts/plugins/cdp-draft.js +5 -2
  22. package/dist/src-ts/plugins/chatgpt/cdp-client.js +26 -12
  23. package/dist/src-ts/plugins/chatgpt/index.js +80 -19
  24. package/dist/src-ts/plugins/claude-cli/index.js +19 -2
  25. package/dist/src-ts/plugins/codex-cli/index.js +19 -2
  26. package/dist/src-ts/plugins/desktop-launch.js +44 -3
  27. package/dist/src-ts/plugins/doubao/cdp-client.js +234 -45
  28. package/dist/src-ts/plugins/doubao/index.js +152 -8
  29. package/dist/src-ts/plugins/doubao/native-task.js +134 -0
  30. package/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
  31. package/dist/src-ts/plugins/dsh/index.js +172 -21
  32. package/dist/src-ts/plugins/dsh/session-history.js +31 -3
  33. package/dist/src-ts/plugins/feishu/index.js +1 -1
  34. package/dist/src-ts/plugins/local-cli/agent.js +74 -9
  35. package/dist/src-ts/plugins/personal-assistant/claude-cli-model.js +30 -0
  36. package/dist/src-ts/plugins/personal-assistant/coordination.js +57 -0
  37. package/dist/src-ts/plugins/personal-assistant/index.js +263 -0
  38. package/dist/src-ts/plugins/personal-assistant/model-client.js +181 -0
  39. package/dist/src-ts/plugins/personal-assistant/owner-context.js +56 -0
  40. package/dist/src-ts/plugins/personal-assistant/remote-ability.js +176 -0
  41. package/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
  42. package/dist/src-ts/plugins/personal-assistant/tools.js +167 -0
  43. package/dist/src-ts/plugins/qwenwork/cdp-client.js +90 -18
  44. package/dist/src-ts/plugins/qwenwork/index.js +139 -24
  45. package/dist/src-ts/plugins/workbuddy/cdp-client.js +353 -82
  46. package/dist/src-ts/plugins/workbuddy/index.js +124 -41
  47. package/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
  48. package/dist/src-ts/plugins/zcode/index.js +97 -0
  49. package/dist/src-ts/session-management.js +132 -14
  50. package/dist/src-ts/version-manager.js +6 -3
  51. package/dist/tests-ts/abweb-cli.test.js +10 -2
  52. package/dist/tests-ts/abweb-model-config.test.js +73 -0
  53. package/dist/tests-ts/agent.test.js +27 -0
  54. package/dist/tests-ts/aun-attachments.test.js +19 -17
  55. package/dist/tests-ts/aun-default-owner-page.test.js +2 -1
  56. package/dist/tests-ts/aun-messages.test.js +20 -0
  57. package/dist/tests-ts/aun-plugin.test.js +292 -19
  58. package/dist/tests-ts/bundled-package.test.js +12 -2
  59. package/dist/tests-ts/cdp-draft-recovery.test.js +182 -3
  60. package/dist/tests-ts/channel-sessions.test.js +27 -0
  61. package/dist/tests-ts/chatgpt-plugin.test.js +118 -0
  62. package/dist/tests-ts/control-server.test.js +56 -0
  63. package/dist/tests-ts/core-updater.test.js +215 -46
  64. package/dist/tests-ts/daemon-process.test.js +126 -1
  65. package/dist/tests-ts/desktop-launch.test.js +73 -0
  66. package/dist/tests-ts/doubao-native-task.test.js +237 -0
  67. package/dist/tests-ts/doubao-plugin.test.js +773 -12
  68. package/dist/tests-ts/dsh-agent.test.js +157 -8
  69. package/dist/tests-ts/dsh-cdp.test.js +148 -0
  70. package/dist/tests-ts/dsh-history.test.js +37 -0
  71. package/dist/tests-ts/feishu-plugin.test.js +1 -1
  72. package/dist/tests-ts/http-agent.test.js +18 -0
  73. package/dist/tests-ts/installer-assets.test.js +1 -1
  74. package/dist/tests-ts/local-cli.test.js +146 -1
  75. package/dist/tests-ts/model-provider-cancellation.test.js +152 -0
  76. package/dist/tests-ts/native-session-management.test.js +8 -7
  77. package/dist/tests-ts/personal-assistant-coordination.test.js +92 -0
  78. package/dist/tests-ts/personal-assistant-extensions.test.js +35 -0
  79. package/dist/tests-ts/personal-assistant-memory.test.js +117 -0
  80. package/dist/tests-ts/personal-assistant-owner-context.test.js +107 -0
  81. package/dist/tests-ts/personal-assistant-remote-ability.test.js +123 -0
  82. package/dist/tests-ts/personal-assistant.test.js +663 -0
  83. package/dist/tests-ts/platform-integration.test.js +183 -1
  84. package/dist/tests-ts/plugin-catalog.test.js +12 -2
  85. package/dist/tests-ts/plugin-manager.test.js +356 -4
  86. package/dist/tests-ts/plugin-upgrade-deadline.test.js +354 -0
  87. package/dist/tests-ts/publish-packages.test.js +42 -0
  88. package/dist/tests-ts/qwenwork-plugin.test.js +135 -1
  89. package/dist/tests-ts/qwenwork-reconnect.test.js +195 -0
  90. package/dist/tests-ts/qwenwork-sse.test.js +33 -0
  91. package/dist/tests-ts/session-access-defaults.test.js +112 -0
  92. package/dist/tests-ts/session-management.test.js +159 -4
  93. package/dist/tests-ts/version-manager.test.js +40 -0
  94. package/dist/tests-ts/workbuddy-cdp-recovery.test.js +311 -0
  95. package/dist/tests-ts/workbuddy-plugin.test.js +499 -4
  96. package/dist/tests-ts/zcode-cdp.test.js +894 -0
  97. package/dist/tests-ts/zcode-plugin.test.js +396 -0
  98. package/package.json +1 -1
  99. package/plugins/abweb/dist/src-ts/agent.js +35 -0
  100. package/plugins/abweb/dist/src-ts/plugins/abweb/index.js +1 -1
  101. package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.js +73 -5
  102. package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.ts +57 -5
  103. package/plugins/abweb/dist/src-ts/plugins/abweb/public/index.html +15 -0
  104. package/plugins/abweb/dist/src-ts/plugins/abweb/public/style.css +4 -0
  105. package/plugins/abweb/package.json +1 -1
  106. package/plugins/abweb/plugin.json +1 -1
  107. package/plugins/aun/config.schema.json +1 -1
  108. package/plugins/aun/dist/src-ts/agent.js +35 -0
  109. package/plugins/aun/dist/src-ts/plugins/aun/attachments.js +3 -21
  110. package/plugins/aun/dist/src-ts/plugins/aun/index.js +155 -21
  111. package/plugins/aun/dist/src-ts/plugins/aun/messages.js +4 -1
  112. package/plugins/aun/dist/src-ts/plugins/aun/public/app.js +2 -1
  113. package/plugins/aun/dist/src-ts/plugins/aun/public/index.html +1 -1
  114. package/plugins/aun/package.json +1 -1
  115. package/plugins/aun/plugin.json +1 -1
  116. package/plugins/chatgpt/dist/src-ts/agent.js +35 -0
  117. package/plugins/chatgpt/dist/src-ts/plugins/cdp-draft.js +5 -2
  118. package/plugins/chatgpt/dist/src-ts/plugins/chatgpt/cdp-client.js +26 -12
  119. package/plugins/chatgpt/dist/src-ts/plugins/chatgpt/index.js +80 -19
  120. package/plugins/chatgpt/dist/src-ts/plugins/desktop-launch.js +44 -3
  121. package/plugins/chatgpt/package.json +1 -1
  122. package/plugins/chatgpt/plugin.json +1 -1
  123. package/plugins/claude-cli/dist/src-ts/agent.js +35 -0
  124. package/plugins/claude-cli/dist/src-ts/plugins/claude-cli/index.js +19 -2
  125. package/plugins/claude-cli/dist/src-ts/plugins/local-cli/agent.js +74 -9
  126. package/plugins/claude-cli/package.json +1 -1
  127. package/plugins/claude-cli/plugin.json +3 -2
  128. package/plugins/codex-cli/dist/src-ts/agent.js +35 -0
  129. package/plugins/codex-cli/dist/src-ts/plugins/codex-cli/index.js +19 -2
  130. package/plugins/codex-cli/dist/src-ts/plugins/local-cli/agent.js +74 -9
  131. package/plugins/codex-cli/package.json +1 -1
  132. package/plugins/codex-cli/plugin.json +3 -2
  133. package/plugins/doubao/config.schema.json +2 -1
  134. package/plugins/doubao/dist/src-ts/agent.js +35 -0
  135. package/plugins/doubao/dist/src-ts/plugins/desktop-launch.js +44 -3
  136. package/plugins/doubao/dist/src-ts/plugins/doubao/cdp-client.js +234 -45
  137. package/plugins/doubao/dist/src-ts/plugins/doubao/index.js +152 -8
  138. package/plugins/doubao/dist/src-ts/plugins/doubao/native-task.js +134 -0
  139. package/plugins/doubao/package.json +1 -1
  140. package/plugins/doubao/plugin.json +3 -2
  141. package/plugins/dsh/config.schema.json +5 -2
  142. package/plugins/dsh/dist/src-ts/agent.js +35 -0
  143. package/plugins/dsh/dist/src-ts/dsh-agent.js +31 -13
  144. package/plugins/dsh/dist/src-ts/plugins/desktop-launch.js +44 -3
  145. package/plugins/dsh/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
  146. package/plugins/dsh/dist/src-ts/plugins/dsh/index.js +172 -21
  147. package/plugins/dsh/dist/src-ts/plugins/dsh/session-history.js +31 -3
  148. package/plugins/dsh/package.json +1 -1
  149. package/plugins/dsh/plugin.json +3 -2
  150. package/plugins/feishu/dist/src-ts/agent.js +35 -0
  151. package/plugins/feishu/dist/src-ts/plugins/feishu/index.js +1 -1
  152. package/plugins/feishu/package.json +1 -1
  153. package/plugins/feishu/plugin.json +1 -1
  154. package/plugins/personal-assistant/config.schema.json +23 -0
  155. package/plugins/personal-assistant/dist/src-ts/agent.js +69 -0
  156. package/plugins/personal-assistant/dist/src-ts/attachments.js +62 -0
  157. package/plugins/personal-assistant/dist/src-ts/plugin.js +13 -0
  158. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/claude-cli-model.js +30 -0
  159. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/coordination.js +57 -0
  160. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/index.js +263 -0
  161. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/model-client.js +181 -0
  162. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/owner-context.js +56 -0
  163. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/remote-ability.js +176 -0
  164. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
  165. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/tools.js +167 -0
  166. package/plugins/personal-assistant/package.json +39 -0
  167. package/plugins/personal-assistant/plugin.json +15 -0
  168. package/plugins/qwenwork/dist/src-ts/agent.js +35 -0
  169. package/plugins/qwenwork/dist/src-ts/plugins/cdp-draft.js +5 -2
  170. package/plugins/qwenwork/dist/src-ts/plugins/desktop-launch.js +44 -3
  171. package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/cdp-client.js +90 -18
  172. package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/index.js +139 -24
  173. package/plugins/qwenwork/package.json +1 -1
  174. package/plugins/qwenwork/plugin.json +3 -2
  175. package/plugins/workbuddy/config.schema.json +1 -1
  176. package/plugins/workbuddy/dist/src-ts/agent.js +35 -0
  177. package/plugins/workbuddy/dist/src-ts/plugins/desktop-launch.js +44 -3
  178. package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/cdp-client.js +353 -82
  179. package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/index.js +124 -41
  180. package/plugins/workbuddy/package.json +1 -1
  181. package/plugins/workbuddy/plugin.json +3 -2
  182. package/plugins/zcode/config.schema.json +13 -0
  183. package/plugins/zcode/dist/src-ts/agent.js +69 -0
  184. package/plugins/zcode/dist/src-ts/attachments.js +62 -0
  185. package/plugins/zcode/dist/src-ts/plugin.js +13 -0
  186. package/plugins/zcode/dist/src-ts/plugins/desktop-launch.js +238 -0
  187. package/plugins/zcode/dist/src-ts/plugins/workbuddy/cdp-client.js +896 -0
  188. package/plugins/zcode/dist/src-ts/plugins/workbuddy/cli-client.js +39 -0
  189. package/plugins/zcode/dist/src-ts/plugins/workbuddy/desktop-launch.js +10 -0
  190. package/plugins/zcode/dist/src-ts/plugins/workbuddy/index.js +567 -0
  191. package/plugins/zcode/dist/src-ts/plugins/workbuddy/session-history.js +121 -0
  192. package/plugins/zcode/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
  193. package/plugins/zcode/dist/src-ts/plugins/zcode/index.js +97 -0
  194. package/plugins/zcode/package.json +16 -0
  195. package/plugins/zcode/plugin.json +11 -0
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const promises_1 = require("node:fs/promises");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = require("node:path");
10
+ const node_test_1 = require("node:test");
11
+ const owner_context_1 = require("../src-ts/plugins/personal-assistant/owner-context");
12
+ async function fixture(responses) {
13
+ const dir = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "pa-owner-context-"));
14
+ const logPath = (0, node_path_1.join)(dir, "args.jsonl");
15
+ const ecPath = (0, node_path_1.join)(dir, "ec");
16
+ const responder = `const fs=require('node:fs');const args=process.argv.slice(2);const log=${JSON.stringify(logPath)};const calls=fs.existsSync(log)?fs.readFileSync(log,'utf8').split('\\n').filter(Boolean).length:0;fs.appendFileSync(log,JSON.stringify(args)+'\\n');const value=(${responses.toString()})(args,calls);process.stdout.write(JSON.stringify(value));`;
17
+ await (0, promises_1.writeFile)(ecPath, `#!/usr/bin/env node\n${responder}\n`);
18
+ await (0, promises_1.chmod)(ecPath, 0o755);
19
+ return {
20
+ ecPath,
21
+ args: async () => (await (0, promises_1.readFile)(logPath, "utf8")).trim().split("\n").filter(Boolean).map((line) => JSON.parse(line)),
22
+ cleanup: () => (0, promises_1.rm)(dir, { recursive: true, force: true }),
23
+ };
24
+ }
25
+ (0, node_test_1.test)("只用固定 Owner AID 和规范路径经 execFile 读取,内容标记为参考资料", async () => {
26
+ const fake = await fixture(() => ({ command: "cat", binary: false, text: "仅供参考" }));
27
+ try {
28
+ const store = (0, owner_context_1.createOwnerContextStore)({ ownerAid: "owner.agentid.cn", path: "/profile/context.md", ttlMs: 1000, ecPath: fake.ecPath });
29
+ const result = await store.get();
30
+ strict_1.default.equal(result.content, "仅供参考");
31
+ strict_1.default.equal(result.status, "fresh");
32
+ strict_1.default.equal(result.trust, "reference_only");
33
+ strict_1.default.deepEqual(await fake.args(), [["fs", "cat", "owner.agentid.cn:/profile/context.md", "--format", "json"]]);
34
+ }
35
+ finally {
36
+ await fake.cleanup();
37
+ }
38
+ });
39
+ (0, node_test_1.test)("TTL 内复用缓存,refresh 强制读取新值", async () => {
40
+ let now = 10_000;
41
+ const fake = await fixture((_args, calls) => ({ command: "cat", binary: false, text: `版本${calls + 1}` }));
42
+ try {
43
+ const store = (0, owner_context_1.createOwnerContextStore)({ ownerAid: "owner.agentid.cn", path: "/profile/context.md", ttlMs: 1000, ecPath: fake.ecPath, now: () => now });
44
+ strict_1.default.equal((await store.get()).content, "版本1");
45
+ now += 500;
46
+ const cached = await store.get();
47
+ strict_1.default.equal(cached.content, "版本1");
48
+ strict_1.default.equal(cached.status, "cached");
49
+ strict_1.default.equal(cached.ageMs, 500);
50
+ strict_1.default.equal((await store.refresh()).content, "版本2");
51
+ strict_1.default.equal((await fake.args()).length, 2);
52
+ }
53
+ finally {
54
+ await fake.cleanup();
55
+ }
56
+ });
57
+ (0, node_test_1.test)("刷新失败保留上次成功值并标记 stale", async () => {
58
+ let now = 10_000;
59
+ const fake = await fixture((_args, calls) => {
60
+ if (calls === 0)
61
+ return { command: "cat", binary: false, text: "最后一次有效资料" };
62
+ throw new Error("读取失败");
63
+ });
64
+ try {
65
+ const store = (0, owner_context_1.createOwnerContextStore)({ ownerAid: "owner.agentid.cn", path: "/profile/context.md", ttlMs: 1000, ecPath: fake.ecPath, now: () => now });
66
+ const first = await store.get();
67
+ now += 1500;
68
+ const stale = await store.get();
69
+ strict_1.default.equal(first.content, stale.content);
70
+ strict_1.default.equal(stale.status, "stale");
71
+ strict_1.default.equal(stale.ageMs, 1500);
72
+ strict_1.default.equal((await fake.args()).length, 2);
73
+ }
74
+ finally {
75
+ await fake.cleanup();
76
+ }
77
+ });
78
+ (0, node_test_1.test)("拒绝无效 AID、非绝对或非规范路径及无效 TTL", async () => {
79
+ const fake = await fixture(() => ({ command: "cat", binary: false, text: "unused" }));
80
+ try {
81
+ for (const options of [
82
+ { ownerAid: "owner; touch /tmp/injected", path: "/profile/context.md", ttlMs: 1000 },
83
+ { ownerAid: "owner.agentid.cn", path: "profile/context.md", ttlMs: 1000 },
84
+ { ownerAid: "owner.agentid.cn", path: "/profile/../secret.md", ttlMs: 1000 },
85
+ { ownerAid: "owner.agentid.cn", path: "/profile/context.md", ttlMs: 0 },
86
+ ]) {
87
+ strict_1.default.throws(() => (0, owner_context_1.createOwnerContextStore)({ ...options, ecPath: fake.ecPath }));
88
+ }
89
+ }
90
+ finally {
91
+ await fake.cleanup();
92
+ }
93
+ });
94
+ (0, node_test_1.test)("拒绝超限文本,且不缓存无效读取", async () => {
95
+ let now = 10_000;
96
+ const fake = await fixture((_args, calls) => ({ command: "cat", binary: false, text: calls === 0 ? "ok" : "过长" }));
97
+ try {
98
+ const store = (0, owner_context_1.createOwnerContextStore)({ ownerAid: "owner.agentid.cn", path: "/profile/context.md", ttlMs: 1000, maxBytes: 3, ecPath: fake.ecPath, now: () => now });
99
+ strict_1.default.equal((await store.get()).content, "ok");
100
+ now += 2000;
101
+ strict_1.default.equal((await store.get()).content, "ok");
102
+ strict_1.default.equal((await fake.args()).length, 2);
103
+ }
104
+ finally {
105
+ await fake.cleanup();
106
+ }
107
+ });
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const promises_1 = require("node:fs/promises");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = require("node:path");
10
+ const node_test_1 = require("node:test");
11
+ const remote_ability_1 = require("../src-ts/plugins/personal-assistant/remote-ability");
12
+ async function fixture(responses, globals = {}) {
13
+ const dir = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "pa-remote-ability-"));
14
+ const logPath = (0, node_path_1.join)(dir, "args.jsonl");
15
+ const ecPath = (0, node_path_1.join)(dir, "ec");
16
+ const defaultIndex = `const fs=require('node:fs');const logPath=${JSON.stringify(logPath)};const index=()=>({abilities:[{path:"status/read",definition_id:"status-v1",detail_ref:"ability/status.json",params_schema:{type:"object",additionalProperties:false,properties:{device:{type:"string"}},required:["device"]},result_schema:{type:"object"},effects:["read"],auth_required:false,require_confirm:false}]});const response=(overrides={})=>({type:"ability",role:"result",call_id:"call-fixed",operation_id:"op-fixed",ability_path:"status/read",definition_id:"status-v1",ok:true,execution_state:"completed",result:{online:true},...overrides});`;
17
+ const declarations = Object.entries(globals).map(([key, value]) => `const ${key}=${JSON.stringify(value)};`).join("");
18
+ const responder = `${defaultIndex}${declarations}globalThis.fs=fs;globalThis.logPath=logPath;const args=process.argv.slice(2);fs.appendFileSync(logPath,JSON.stringify(args)+'\\n');const value=(${responses.toString()})(args);process.stdout.write(JSON.stringify(value));`;
19
+ await (0, promises_1.writeFile)(ecPath, `#!/usr/bin/env node\n${responder}\n`);
20
+ await (0, promises_1.chmod)(ecPath, 0o755);
21
+ return {
22
+ client: new remote_ability_1.RemoteAbilityClient({ selfAid: "self.agentid.cn", ecPath }),
23
+ args: async () => (await (0, promises_1.readFile)(logPath, "utf8")).trim().split("\n").filter(Boolean).map((line) => JSON.parse(line)),
24
+ cleanup: () => (0, promises_1.rm)(dir, { recursive: true, force: true }),
25
+ };
26
+ }
27
+ function index(overrides = {}) {
28
+ return {
29
+ abilities: [{ path: "status/read", definition_id: "status-v1", detail_ref: "ability/status.json", params_schema: { type: "object", additionalProperties: false, properties: { device: { type: "string" } }, required: ["device"] }, result_schema: { type: "object" }, effects: ["read"], auth_required: false, require_confirm: false, ...overrides }],
30
+ };
31
+ }
32
+ function response(overrides = {}) {
33
+ return { type: "ability", role: "result", call_id: "call-fixed", operation_id: "op-fixed", ability_path: "status/read", definition_id: "status-v1", ok: true, execution_state: "completed", result: { online: true }, ...overrides };
34
+ }
35
+ (0, node_test_1.test)("命令参数经 execFile 直传,远端 schema 和只读契约控制调用", async () => {
36
+ const fixtureValue = await fixture((args) => {
37
+ if (args[0] === "fs")
38
+ return { command: "cat", binary: false, text: JSON.stringify(args[2].endsWith("index.json") ? index() : index().abilities[0]) };
39
+ if (args[0] === "msg" && args[1] === "send") {
40
+ const payload = JSON.parse(args[args.indexOf("--payload") + 1]);
41
+ return { ok: true, request_state: "completed", request_id: payload.call_id, response: response({ call_id: payload.call_id, operation_id: payload.operation_id }) };
42
+ }
43
+ throw new Error("unexpected command");
44
+ });
45
+ try {
46
+ const providerAid = "provider.agentid.cn";
47
+ await fixtureValue.client.discover(providerAid);
48
+ const unsafeText = "x; touch /tmp/remote-ability-injected";
49
+ const result = await fixtureValue.client.call(providerAid, "status/read", { device: unsafeText });
50
+ strict_1.default.equal(result.status, "completed");
51
+ strict_1.default.deepEqual(result.result, { online: true });
52
+ const args = await fixtureValue.args();
53
+ strict_1.default.deepEqual(args[0], ["fs", "cat", `${providerAid}:/ability/index.json`, "--format", "json"]);
54
+ strict_1.default.deepEqual(args[1], ["fs", "cat", `${providerAid}:/ability/status.json`, "--format", "json"]);
55
+ strict_1.default.equal(args[2][0], "msg");
56
+ strict_1.default.equal(args[2][1], "send");
57
+ strict_1.default.ok(args[2].includes("--payload"));
58
+ strict_1.default.ok(args[2].includes("--return"));
59
+ strict_1.default.ok(args[2].includes("required"));
60
+ strict_1.default.equal(args[2].includes("--shell"), false);
61
+ const payload = JSON.parse(args[2][args[2].indexOf("--payload") + 1]);
62
+ strict_1.default.equal(payload.params.device, unsafeText);
63
+ strict_1.default.match(payload.call_id, /^c-/);
64
+ strict_1.default.match(payload.operation_id, /^op-/);
65
+ }
66
+ finally {
67
+ await fixtureValue.cleanup();
68
+ }
69
+ });
70
+ (0, node_test_1.test)("拒绝无效 AID、参数 schema 和非只读或需授权契约", async () => {
71
+ const fixtureValue = await fixture((args) => ({ command: "cat", binary: false, text: JSON.stringify(args[2].endsWith("index.json") ? index() : index().abilities[0]) }));
72
+ try {
73
+ await strict_1.default.rejects(fixtureValue.client.discover("bad aid"), /AID/);
74
+ await fixtureValue.client.discover("provider.agentid.cn");
75
+ await strict_1.default.rejects(fixtureValue.client.call("provider.agentid.cn", "status/read", {}), /schema/);
76
+ await strict_1.default.rejects(fixtureValue.client.call("provider.agentid.cn", "other", { device: "x" }), /能力/);
77
+ }
78
+ finally {
79
+ await fixtureValue.cleanup();
80
+ }
81
+ for (const denied of [{ effects: ["read", "write"] }, { auth_required: true }, { require_confirm: true }, { detail_ref: "../secret.json" }]) {
82
+ const entry = index(denied).abilities[0];
83
+ const fake = await fixture((args) => args[2].endsWith("index.json") ? { abilities: [entry] } : entry, { entry });
84
+ try {
85
+ await strict_1.default.rejects(fake.client.call("provider.agentid.cn", "status/read", { device: "x" }), /契约|引用|路径/);
86
+ strict_1.default.equal((await fake.args()).filter((args) => args[0] === "msg").length, 0);
87
+ }
88
+ finally {
89
+ await fake.cleanup();
90
+ }
91
+ }
92
+ });
93
+ (0, node_test_1.test)("pending 不重发,request get 读取业务结果并校验关联字段", async () => {
94
+ const fixtureValue = await fixture((args) => {
95
+ if (args[0] === "fs")
96
+ return { command: "cat", binary: false, text: JSON.stringify(args[2].endsWith("index.json") ? index() : index().abilities[0]) };
97
+ if (args[1] === "send") {
98
+ const payload = JSON.parse(args[args.indexOf("--payload") + 1]);
99
+ return { ok: true, request_state: "pending", request_id: payload.call_id };
100
+ }
101
+ if (args[1] === "request" && args[2] === "get") {
102
+ const lines = globalThis.fs.readFileSync(globalThis.logPath, "utf8").trim().split(String.fromCharCode(10)).filter(Boolean);
103
+ const sent = JSON.parse(lines.find((line) => JSON.parse(line)[1] === "send"));
104
+ const payload = JSON.parse(sent[sent.indexOf("--payload") + 1]);
105
+ return { ok: true, request: { state: "completed", responsePayload: response({ call_id: payload.call_id, operation_id: payload.operation_id }) } };
106
+ }
107
+ throw new Error("unexpected command");
108
+ });
109
+ try {
110
+ const providerAid = "provider.agentid.cn";
111
+ const pending = await fixtureValue.client.call(providerAid, "status/read", { device: "phone" });
112
+ strict_1.default.equal(pending.status, "pending");
113
+ strict_1.default.equal((await fixtureValue.args()).filter((args) => args[1] === "send").length, 1);
114
+ const completed = await fixtureValue.client.getRequest(providerAid, pending.requestId);
115
+ strict_1.default.equal(completed.status, "completed");
116
+ strict_1.default.deepEqual(completed.result, { online: true });
117
+ strict_1.default.equal((await fixtureValue.args()).filter((args) => args[1] === "send").length, 1);
118
+ await strict_1.default.rejects(fixtureValue.client.getRequest(providerAid, "bad id"), /request_id/);
119
+ }
120
+ finally {
121
+ await fixtureValue.cleanup();
122
+ }
123
+ });