@mmmbuto/qwen-code-termux 0.16.1-termux → 0.18.0-termux

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 (185) hide show
  1. package/README.md +79 -109
  2. package/bundled/new-app/SKILL.md +22 -0
  3. package/bundled/qc-helper/SKILL.md +29 -24
  4. package/bundled/qc-helper/docs/_meta.ts +1 -0
  5. package/bundled/qc-helper/docs/configuration/_meta.ts +0 -3
  6. package/bundled/qc-helper/docs/configuration/settings.md +37 -31
  7. package/bundled/qc-helper/docs/configuration/themes.md +39 -0
  8. package/bundled/qc-helper/docs/features/_meta.ts +1 -3
  9. package/bundled/qc-helper/docs/features/approval-mode.md +35 -35
  10. package/bundled/qc-helper/docs/features/auto-mode.md +54 -9
  11. package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  12. package/bundled/qc-helper/docs/features/channels/feishu.md +170 -0
  13. package/bundled/qc-helper/docs/features/commands.md +115 -35
  14. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  15. package/bundled/qc-helper/docs/features/headless.md +32 -0
  16. package/bundled/qc-helper/docs/features/markdown-rendering.md +21 -1
  17. package/bundled/qc-helper/docs/features/memory.md +22 -5
  18. package/bundled/qc-helper/docs/features/scheduled-tasks.md +1 -1
  19. package/bundled/qc-helper/docs/features/status-line.md +168 -32
  20. package/bundled/qc-helper/docs/features/sub-agents.md +60 -0
  21. package/bundled/qc-helper/docs/features/worktree.md +345 -0
  22. package/bundled/qc-helper/docs/overview.md +4 -4
  23. package/bundled/qc-helper/docs/quickstart.md +4 -4
  24. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
  25. package/bundled/qc-helper/docs/qwen-serve.md +234 -24
  26. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +16 -0
  27. package/bundled/qc-helper/docs/support/Uninstall.md +19 -1
  28. package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
  29. package/bundled/simplify/SKILL.md +123 -0
  30. package/chunks/agent-IDS4HMOX.js +56 -0
  31. package/chunks/agent-headless-5Q2EUSPS.js +50 -0
  32. package/chunks/{anthropicContentGenerator-SSGKR6DO.js → anthropicContentGenerator-2HBRNQ3B.js} +52 -9
  33. package/chunks/{askUserQuestion-PJWUUXKN.js → askUserQuestion-75TDJVK2.js} +45 -3
  34. package/chunks/{ca-UZ7BANMN.js → ca-BARBRL6N.js} +89 -5
  35. package/chunks/{chunk-GGNTZ2NH.js → chunk-2Y5SYSD3.js} +368 -597
  36. package/chunks/{chunk-2LA2TREA.js → chunk-3AA2DK35.js} +1448 -207
  37. package/chunks/{chunk-I2V5WXHJ.js → chunk-3AUHFMSK.js} +80 -38
  38. package/chunks/chunk-3DHXZ6EV.js +241 -0
  39. package/chunks/{chunk-PR4T27R7.js → chunk-3HTIVKZE.js} +42 -8
  40. package/chunks/chunk-3HX5LZ6R.js +1798 -0
  41. package/chunks/chunk-3PJXIDKI.js +2517 -0
  42. package/chunks/{chunk-MYAKAFEC.js → chunk-55ZMG67I.js} +7451 -3517
  43. package/chunks/{chunk-66CXYE4B.js → chunk-5IFG2VC4.js} +293 -242
  44. package/chunks/chunk-64WXLC72.js +98 -0
  45. package/chunks/{chunk-C6WMLUNB.js → chunk-72LDN5PP.js} +1 -1
  46. package/chunks/{chunk-F23NCRJ2.js → chunk-A7B4ISQP.js} +1 -1
  47. package/chunks/chunk-B7HXHOHU.js +393 -0
  48. package/chunks/{chunk-XEGHDASV.js → chunk-D3RHSPAS.js} +435 -540
  49. package/chunks/{chunk-XKS5KBFJ.js → chunk-EYENRK4D.js} +694 -384
  50. package/chunks/chunk-H6BD2ELD.js +36 -0
  51. package/chunks/{chunk-XP27SJMH.js → chunk-HR7SV7AY.js} +79 -48
  52. package/chunks/{chunk-D5NTAHYL.js → chunk-IDX6COTE.js} +7 -2
  53. package/chunks/{chunk-SHT4VJWU.js → chunk-IWKSG2AR.js} +2 -2
  54. package/chunks/chunk-J37FGIOA.js +1623 -0
  55. package/chunks/chunk-J5MDQKJL.js +2230 -0
  56. package/chunks/{chunk-USE2VQ5P.js → chunk-JTQAQBTV.js} +21 -0
  57. package/chunks/{chunk-NCTLV2NB.js → chunk-KQJMQJPI.js} +1 -1
  58. package/chunks/{chunk-5FBA5XC2.js → chunk-KRIHGKNA.js} +1 -1
  59. package/chunks/chunk-LD2XBG6Z.js +102 -0
  60. package/chunks/{chunk-MAY32HXD.js → chunk-M6VTDSVR.js} +3 -1
  61. package/chunks/chunk-MRO43B25.js +30 -0
  62. package/chunks/{chunk-N4WOREMD.js → chunk-NVFMZBX2.js} +43 -3
  63. package/chunks/chunk-OHEGWO4L.js +264 -0
  64. package/chunks/{chunk-K6O2NBMF.js → chunk-OQ7NJIY7.js} +4604 -6397
  65. package/chunks/chunk-QQDPRDVW.js +25 -0
  66. package/chunks/{chunk-KXZ4TJB4.js → chunk-SEGYWKIH.js} +1 -1
  67. package/chunks/chunk-SKBPNJEW.js +45 -0
  68. package/chunks/{chunk-4AOCVI6J.js → chunk-SNGELLWX.js} +52 -6
  69. package/chunks/{chunk-3OCRHZA3.js → chunk-TD4OPI4T.js} +56742 -44104
  70. package/chunks/{chunk-DQ4QTG7E.js → chunk-VV4F63BD.js} +11 -11
  71. package/chunks/chunk-XBY7E2FX.js +605 -0
  72. package/chunks/{chunk-JKMBWLFB.js → chunk-YILFYI5W.js} +48 -26
  73. package/chunks/chunk-YOGAOMYB.js +159 -0
  74. package/chunks/{chunk-QWSRH265.js → chunk-Z2Z3GUXZ.js} +777 -776
  75. package/chunks/{chunk-SDHRQFOS.js → chunk-ZTZ4DDQE.js} +2 -2
  76. package/chunks/computer-use-W2TYQNEE.js +825 -0
  77. package/chunks/contextCommand-6FGX3A7J.js +52 -0
  78. package/chunks/{cron-create-3ZBBN7WB.js → cron-create-APL5LU6I.js} +3 -3
  79. package/chunks/{cron-delete-NAGKKIIG.js → cron-delete-4SBJSCN4.js} +3 -3
  80. package/chunks/{cron-list-PAGRXNAI.js → cron-list-2AMGOMVO.js} +3 -3
  81. package/chunks/{de-V4IE2OOZ.js → de-YGKK2BC4.js} +89 -5
  82. package/chunks/{devtools-TWVXEJQB.js → devtools-FM6GJPYG.js} +2 -1
  83. package/chunks/{dist-4L54HRX2.js → dist-4LXD6L6X.js} +24 -5
  84. package/chunks/dist-H6ONXVLG.js +94146 -0
  85. package/chunks/{dist-XKWIWPWQ.js → dist-KAZ3SEBX.js} +1083 -3856
  86. package/chunks/{dist-BXDUQ2QY.js → dist-PK7DFCAW.js} +1 -1
  87. package/chunks/{edit-NVO3FOAK.js → edit-ZCEZC264.js} +30 -22
  88. package/chunks/{en-HGJ2SPLM.js → en-DHGYHIHX.js} +127 -6
  89. package/chunks/{enter-worktree-UEBG4WFC.js → enter-worktree-BBHCFCHG.js} +30 -20
  90. package/chunks/enterPlanMode-3M6KTD3B.js +158 -0
  91. package/chunks/{exit-worktree-UZ3MAQZN.js → exit-worktree-73YPIEQO.js} +27 -19
  92. package/chunks/exitPlanMode-TYZM6BAE.js +703 -0
  93. package/chunks/{fr-CJULI7ZX.js → fr-JXBKPJKQ.js} +89 -5
  94. package/chunks/{geminiContentGenerator-3UZFXGNT.js → geminiContentGenerator-7N2V3VW2.js} +8 -6
  95. package/chunks/{getMachineId-bsd-JXOSIJV2.js → getMachineId-bsd-4CASPIU4.js} +4 -4
  96. package/chunks/{getMachineId-darwin-TE4QRR42.js → getMachineId-darwin-HPQPEMZR.js} +4 -4
  97. package/chunks/{getMachineId-linux-S3OL52XK.js → getMachineId-linux-AUARKYHL.js} +3 -3
  98. package/chunks/{getMachineId-unsupported-DWUSBAPX.js → getMachineId-unsupported-S32ZDA2T.js} +3 -3
  99. package/chunks/{getMachineId-win-AAC5P3AP.js → getMachineId-win-4EFLHYIJ.js} +4 -4
  100. package/chunks/{glob-KNHSFFFG.js → glob-5XBCPQ2A.js} +27 -19
  101. package/chunks/{grep-LACWDZW4.js → grep-VIUU3A7X.js} +30 -19
  102. package/chunks/{ja-L7CHRQEW.js → ja-TGPZSP2B.js} +89 -5
  103. package/chunks/{keychain-token-storage-335UOLJ6.js → keychain-token-storage-6IU6ORQN.js} +3 -3
  104. package/chunks/{ls-AGXQOKSG.js → ls-JRGYIGLY.js} +4 -4
  105. package/chunks/{lsp-UDMUHNPA.js → lsp-SHMKFOAC.js} +3 -3
  106. package/chunks/{monitor-ETKWPJEH.js → monitor-6R4LIJL5.js} +40 -25
  107. package/chunks/{multipart-parser-3QWGTLK3.js → multipart-parser-AJ4WASWR.js} +2 -2
  108. package/chunks/{notebook-edit-QJJLPNYT.js → notebook-edit-5E7ULDVQ.js} +28 -20
  109. package/chunks/{openaiContentGenerator-CNNN424U.js → openaiContentGenerator-ZVHFKM3O.js} +17 -14
  110. package/chunks/{pt-M6JULLEQ.js → pt-TIBG6BIO.js} +89 -5
  111. package/chunks/{qwenContentGenerator-BOLCGK3R.js → qwenContentGenerator-B2VTVSPJ.js} +31 -23
  112. package/chunks/{qwenOAuth2-EEJGROP7.js → qwenOAuth2-2KCKWDCF.js} +6 -4
  113. package/chunks/read-file-GIT7BCDR.js +27 -0
  114. package/chunks/ripGrep-MWKFVYMS.js +48 -0
  115. package/chunks/{ru-QILM4HBC.js → ru-JBCHCK4L.js} +89 -5
  116. package/chunks/scheduler-5VOOYGBH.js +308 -0
  117. package/chunks/send-message-4QNWQJF4.js +244 -0
  118. package/chunks/{serve-OLSI7WSR.js → serve-MN6HZBWN.js} +14262 -7414
  119. package/chunks/shell-NQZQGFM2.js +56 -0
  120. package/chunks/{skill-D6YRHTTI.js → skill-WCFW4644.js} +145 -119
  121. package/chunks/{src-TMOD5X6F.js → src-7XL4G4DC.js} +88 -46
  122. package/chunks/{src-4QH4FZ6I.js → src-IHA6DTUV.js} +452 -62
  123. package/chunks/{syntheticOutput-5PVFDDJ4.js → syntheticOutput-YTYS2ZMQ.js} +4 -4
  124. package/chunks/task-create-MPORPYN6.js +19 -0
  125. package/chunks/task-list-R2YDYPZT.js +151 -0
  126. package/chunks/{task-stop-AJKPSR6R.js → task-stop-SYWJYBCM.js} +3 -3
  127. package/chunks/task-update-E4NSLKMQ.js +408 -0
  128. package/chunks/team-create-7R7KA5IP.js +314 -0
  129. package/chunks/team-delete-25OIWUPN.js +116 -0
  130. package/chunks/{todoWrite-VLAUG4CA.js → todoWrite-4YHMIF4X.js} +16 -5
  131. package/chunks/{tool-search-MZGHUUKD.js → tool-search-YBRVZCLI.js} +29 -11
  132. package/chunks/{tts-notification-K3X7X7MN.js → tts-notification-7SOEMQK4.js} +5 -4
  133. package/chunks/{web-fetch-OILB464A.js → web-fetch-MFIRHIHI.js} +5 -5
  134. package/chunks/workflow-5RIKVCIE.js +960 -0
  135. package/chunks/{write-file-BIQAA57V.js → write-file-DMQTJZOM.js} +32 -24
  136. package/chunks/{zh-PWL2NKY3.js → zh-7H5OQC4I.js} +135 -11
  137. package/chunks/{zh-TW-S3YGWICZ.js → zh-TW-P4IDHD3M.js} +128 -11
  138. package/cli.js +45402 -20570
  139. package/examples/agent/agents/diary.md +86 -0
  140. package/examples/agent/qwen-extension.json +5 -0
  141. package/examples/commands/commands/fs/grep-code.md +3 -0
  142. package/examples/commands/qwen-extension.json +5 -0
  143. package/examples/context/QWEN.md +8 -0
  144. package/examples/context/qwen-extension.json +5 -0
  145. package/examples/mcp-server/example.ts +60 -0
  146. package/examples/mcp-server/package.json +18 -0
  147. package/examples/mcp-server/qwen-extension.json +12 -0
  148. package/examples/mcp-server/tsconfig.json +13 -0
  149. package/examples/skills/qwen-extension.json +5 -0
  150. package/examples/skills/skills/synonyms/SKILL.md +48 -0
  151. package/examples/starter/QWEN.md +30 -0
  152. package/examples/starter/README.md +59 -0
  153. package/examples/starter/agents/diary.md +86 -0
  154. package/examples/starter/commands/writing/polish.md +13 -0
  155. package/examples/starter/example.ts +64 -0
  156. package/examples/starter/package.json +18 -0
  157. package/examples/starter/qwen-extension.json +12 -0
  158. package/examples/starter/skills/synonyms/SKILL.md +48 -0
  159. package/examples/starter/tsconfig.json +13 -0
  160. package/fzfWorker.js +1083 -0
  161. package/locales/ca.js +118 -5
  162. package/locales/de.js +117 -5
  163. package/locales/en.js +169 -7
  164. package/locales/fr.js +119 -5
  165. package/locales/ja.js +114 -5
  166. package/locales/pt.js +117 -5
  167. package/locales/ru.js +116 -5
  168. package/locales/zh-TW.js +161 -12
  169. package/locales/zh.js +169 -12
  170. package/package.json +4 -2
  171. package/scripts/postinstall.cjs +2 -1
  172. package/bundled/qc-helper/docs/features/checkpointing.md +0 -77
  173. package/chunks/agent-7ZN3CRHR.js +0 -48
  174. package/chunks/chunk-6PCB2DEF.js +0 -434
  175. package/chunks/chunk-EM6ETG2K.js +0 -60
  176. package/chunks/chunk-G7YTSRES.js +0 -150
  177. package/chunks/contextCommand-7IBASARL.js +0 -44
  178. package/chunks/exitPlanMode-PZAMWIRW.js +0 -227
  179. package/chunks/multipart-parser-IXGBIOIN.js +0 -384
  180. package/chunks/read-file-CCUEUFG2.js +0 -24
  181. package/chunks/ripGrep-TADOH2HK.js +0 -40
  182. package/chunks/send-message-YL44UZFC.js +0 -151
  183. package/chunks/shell-7KKKC5G7.js +0 -48
  184. package/chunks/src-IPWIHNMI.js +0 -1406
  185. package/chunks/undici-F6ZOXSS5.js +0 -8
@@ -0,0 +1,825 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ Client,
5
+ StdioClientTransport
6
+ } from "./chunk-TD4OPI4T.js";
7
+ import "./chunk-K5PGHDBN.js";
8
+ import "./chunk-XBY7E2FX.js";
9
+ import "./chunk-SKBPNJEW.js";
10
+ import "./chunk-NVFMZBX2.js";
11
+ import "./chunk-O4PICXES.js";
12
+ import "./chunk-TW522KN6.js";
13
+ import "./chunk-3DHXZ6EV.js";
14
+ import "./chunk-J5MDQKJL.js";
15
+ import "./chunk-MLZQVCF3.js";
16
+ import "./chunk-LD2XBG6Z.js";
17
+ import "./chunk-OHEGWO4L.js";
18
+ import "./chunk-SNGELLWX.js";
19
+ import "./chunk-77WXWU44.js";
20
+ import "./chunk-A7B4ISQP.js";
21
+ import {
22
+ safeJsonStringify
23
+ } from "./chunk-OQ7NJIY7.js";
24
+ import "./chunk-3PJXIDKI.js";
25
+ import "./chunk-UWCTAVOD.js";
26
+ import "./chunk-OFEVLU4C.js";
27
+ import "./chunk-3HTIVKZE.js";
28
+ import "./chunk-IDX6COTE.js";
29
+ import "./chunk-KQJMQJPI.js";
30
+ import {
31
+ BaseDeclarativeTool,
32
+ BaseToolInvocation
33
+ } from "./chunk-D3RHSPAS.js";
34
+ import "./chunk-2Y5SYSD3.js";
35
+ import "./chunk-SEGYWKIH.js";
36
+ import "./chunk-64WXLC72.js";
37
+ import "./chunk-B7HXHOHU.js";
38
+ import "./chunk-EYENRK4D.js";
39
+ import "./chunk-M6VTDSVR.js";
40
+ import "./chunk-55ZMG67I.js";
41
+ import "./chunk-H6BD2ELD.js";
42
+ import "./chunk-5IFG2VC4.js";
43
+ import "./chunk-HR7SV7AY.js";
44
+ import "./chunk-ZERZSAZL.js";
45
+ import "./chunk-QN5NZ3UQ.js";
46
+ import "./chunk-BR4QREVK.js";
47
+ import "./chunk-Z2Z3GUXZ.js";
48
+ import {
49
+ init_esbuild_shims
50
+ } from "./chunk-A4BMJM77.js";
51
+ import {
52
+ __name
53
+ } from "./chunk-J2S4EL5Y.js";
54
+
55
+ // packages/core/src/tools/computer-use/index.ts
56
+ init_esbuild_shims();
57
+
58
+ // packages/core/src/tools/computer-use/tool.ts
59
+ init_esbuild_shims();
60
+
61
+ // packages/core/src/tools/computer-use/client.ts
62
+ init_esbuild_shims();
63
+
64
+ // packages/core/src/tools/computer-use/constants.ts
65
+ init_esbuild_shims();
66
+ var PINNED_OPEN_COMPUTER_USE_PACKAGE_NAME = "@qwen-code/open-computer-use";
67
+ var PINNED_OPEN_COMPUTER_USE_VERSION = "0.2.3";
68
+ function resolveComputerUsePackageSpec() {
69
+ return process.env["QWEN_COMPUTER_USE_PACKAGE"] ?? `${PINNED_OPEN_COMPUTER_USE_PACKAGE_NAME}@${PINNED_OPEN_COMPUTER_USE_VERSION}`;
70
+ }
71
+ __name(resolveComputerUsePackageSpec, "resolveComputerUsePackageSpec");
72
+
73
+ // packages/core/src/tools/computer-use/client.ts
74
+ var ComputerUseClient = class _ComputerUseClient {
75
+ static {
76
+ __name(this, "ComputerUseClient");
77
+ }
78
+ static singleton;
79
+ packageSpec;
80
+ onProgress;
81
+ client;
82
+ startPromise;
83
+ constructor(options) {
84
+ this.packageSpec = options.packageSpec;
85
+ this.onProgress = options.onProgress ?? (() => {
86
+ });
87
+ }
88
+ /**
89
+ * Shared singleton instance, created with default options on first
90
+ * access. Tests can replace it via `setSharedForTest()`.
91
+ */
92
+ static shared() {
93
+ if (!_ComputerUseClient.singleton) {
94
+ _ComputerUseClient.singleton = new _ComputerUseClient({
95
+ packageSpec: resolveComputerUsePackageSpec()
96
+ });
97
+ }
98
+ return _ComputerUseClient.singleton;
99
+ }
100
+ /** Test-only: replace the singleton. */
101
+ static setSharedForTest(replacement) {
102
+ _ComputerUseClient.singleton = replacement;
103
+ }
104
+ isStarted() {
105
+ return this.client !== void 0;
106
+ }
107
+ /**
108
+ * Start the upstream MCP server. Idempotent: concurrent callers share
109
+ * the same in-flight start promise.
110
+ *
111
+ * An optional `onProgress` callback can be supplied to receive download
112
+ * and startup messages during this call. It overrides the instance-level
113
+ * callback for the duration of the start operation only.
114
+ *
115
+ * Throws on spawn failure (network down, npx missing, etc.). The
116
+ * caller (bootstrap state machine) is responsible for mapping the
117
+ * throw into user-facing UX.
118
+ */
119
+ async start(onProgress) {
120
+ if (this.client) return;
121
+ if (this.startPromise) return this.startPromise;
122
+ this.startPromise = this.doStart(onProgress).finally(() => {
123
+ this.startPromise = void 0;
124
+ });
125
+ return this.startPromise;
126
+ }
127
+ async doStart(onProgress) {
128
+ const progress = onProgress ?? this.onProgress;
129
+ progress("Starting Computer Use...");
130
+ const downloadHintTimer = setTimeout(() => {
131
+ progress(
132
+ "Downloading Computer Use binary (this can take ~60s on first use)..."
133
+ );
134
+ }, 3e3);
135
+ try {
136
+ const transport = new StdioClientTransport({
137
+ command: "npx",
138
+ args: ["-y", this.packageSpec, "mcp"],
139
+ // Inherit env so HTTPS_PROXY etc. flow through to npx
140
+ env: { ...process.env }
141
+ });
142
+ const client = new Client(
143
+ { name: "qwen-code-computer-use", version: "1.0.0" },
144
+ { capabilities: {} }
145
+ );
146
+ await client.connect(transport);
147
+ this.client = client;
148
+ } finally {
149
+ clearTimeout(downloadHintTimer);
150
+ }
151
+ }
152
+ /**
153
+ * List the tools exposed by the upstream server. Used by the schema
154
+ * sync script and bootstrap diagnostics.
155
+ */
156
+ async listTools() {
157
+ if (!this.client) throw new Error("ComputerUseClient not started");
158
+ return this.client.listTools();
159
+ }
160
+ /**
161
+ * Call a tool by upstream name (NOT the qwen-code-facing
162
+ * `computer_use__` prefixed name). Returns the raw MCP result so the
163
+ * caller can inspect `isError` and parse text content.
164
+ *
165
+ * On transport-closed errors (e.g. macOS kills the upstream binary after
166
+ * the user grants Screen Recording permission), this method transparently
167
+ * tears down the stale connection, reconnects, and retries the call once.
168
+ * If the retry also fails, the error is re-thrown without further
169
+ * reconnect attempts.
170
+ */
171
+ async callTool(name, args) {
172
+ if (!this.client) throw new Error("ComputerUseClient not started");
173
+ try {
174
+ return await this.client.callTool({
175
+ name,
176
+ arguments: args
177
+ });
178
+ } catch (err) {
179
+ if (!isTransportClosedError(err)) throw err;
180
+ await this.stop();
181
+ await this.start();
182
+ if (!this.client) throw new Error("ComputerUseClient reconnect failed");
183
+ return await this.client.callTool({
184
+ name,
185
+ arguments: args
186
+ });
187
+ }
188
+ }
189
+ /** Tear down the child process. Safe to call multiple times. */
190
+ async stop() {
191
+ const client = this.client;
192
+ this.client = void 0;
193
+ if (client) {
194
+ try {
195
+ await client.close();
196
+ } catch {
197
+ }
198
+ }
199
+ }
200
+ };
201
+ function isTransportClosedError(err) {
202
+ const msg = err instanceof Error ? err.message : String(err);
203
+ return /connection closed|not connected/i.test(msg);
204
+ }
205
+ __name(isTransportClosedError, "isTransportClosedError");
206
+
207
+ // packages/core/src/tools/computer-use/bootstrap.ts
208
+ init_esbuild_shims();
209
+ import { execFile } from "node:child_process";
210
+ import { promisify } from "node:util";
211
+ import { homedir as homedir2 } from "node:os";
212
+
213
+ // packages/core/src/tools/computer-use/install-state.ts
214
+ init_esbuild_shims();
215
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
216
+ import { homedir } from "node:os";
217
+ import { join, dirname } from "node:path";
218
+ function installStatePathFor(home = homedir()) {
219
+ return join(home, ".qwen", "computer-use", "installed.json");
220
+ }
221
+ __name(installStatePathFor, "installStatePathFor");
222
+ async function loadInstallState(home = homedir()) {
223
+ try {
224
+ const text = await readFile(installStatePathFor(home), "utf8");
225
+ const parsed = JSON.parse(text);
226
+ if (typeof parsed?.approvedPackageSpec !== "string") return void 0;
227
+ if (typeof parsed?.approvedAtIso !== "string") return void 0;
228
+ return parsed;
229
+ } catch (err) {
230
+ if (err?.code === "ENOENT") return void 0;
231
+ return void 0;
232
+ }
233
+ }
234
+ __name(loadInstallState, "loadInstallState");
235
+ async function saveInstallState(home = homedir(), state) {
236
+ const path = installStatePathFor(home);
237
+ await mkdir(dirname(path), { recursive: true });
238
+ await writeFile(path, JSON.stringify(state, null, 2), "utf8");
239
+ }
240
+ __name(saveInstallState, "saveInstallState");
241
+ async function isPackageSpecApproved(home = homedir(), packageSpec) {
242
+ const state = await loadInstallState(home);
243
+ return state?.approvedPackageSpec === packageSpec;
244
+ }
245
+ __name(isPackageSpecApproved, "isPackageSpecApproved");
246
+
247
+ // packages/core/src/tools/computer-use/permission-detector.ts
248
+ init_esbuild_shims();
249
+
250
+ // packages/core/src/tools/computer-use/bootstrap.ts
251
+ var execFileAsync = promisify(execFile);
252
+ function parseDoctorStdout(stdout) {
253
+ const accessibilityGranted = /accessibility\s*=\s*granted/i.test(stdout);
254
+ const screenRecordingGranted = /screenrecording\s*=\s*granted/i.test(stdout);
255
+ if (!accessibilityGranted) return "accessibility";
256
+ if (!screenRecordingGranted) return "screenRecording";
257
+ return "ok";
258
+ }
259
+ __name(parseDoctorStdout, "parseDoctorStdout");
260
+ async function probePermissionsViaDoctor(packageSpec) {
261
+ try {
262
+ const { stdout } = await execFileAsync(
263
+ "npx",
264
+ ["-y", packageSpec, "doctor"],
265
+ {
266
+ timeout: 3e4,
267
+ env: process.env
268
+ }
269
+ );
270
+ return parseDoctorStdout(stdout);
271
+ } catch {
272
+ return "other";
273
+ }
274
+ }
275
+ __name(probePermissionsViaDoctor, "probePermissionsViaDoctor");
276
+ async function probePermissionStatusViaCLI(packageSpec) {
277
+ try {
278
+ const { stdout } = await execFileAsync(
279
+ "npx",
280
+ ["-y", packageSpec, "permission-status"],
281
+ {
282
+ timeout: 3e4,
283
+ env: process.env
284
+ }
285
+ );
286
+ return parseDoctorStdout(stdout);
287
+ } catch {
288
+ return "other";
289
+ }
290
+ }
291
+ __name(probePermissionStatusViaCLI, "probePermissionStatusViaCLI");
292
+ function defaultDeps() {
293
+ const packageSpec = resolveComputerUsePackageSpec();
294
+ return {
295
+ homeDir: homedir2(),
296
+ packageSpec,
297
+ platform: process.platform,
298
+ promptInstallApproval: /* @__PURE__ */ __name(async (spec) => {
299
+ process.stderr.write(
300
+ `
301
+ [Computer Use] First-time install
302
+ Package: ${spec}
303
+ This will fetch ~50MB from the npm registry the first time.
304
+ Computer Use can click, type, and read your desktop apps.
305
+ On macOS you'll be guided through Accessibility and Screen Recording permissions next.
306
+ Set QWEN_COMPUTER_USE_AUTO_APPROVE=1 to skip this prompt.
307
+ `
308
+ );
309
+ return process.env["QWEN_COMPUTER_USE_AUTO_APPROVE"] === "1";
310
+ }, "promptInstallApproval"),
311
+ probePermissions: probePermissionsViaDoctor,
312
+ probePermissionStatus: probePermissionStatusViaCLI
313
+ };
314
+ }
315
+ __name(defaultDeps, "defaultDeps");
316
+ async function runBootstrap(client, ctx, depsOverride) {
317
+ const deps = { ...defaultDeps(), ...depsOverride };
318
+ const pollIntervalMs = deps.pollIntervalMs ?? 5e3;
319
+ const pollTimeoutMs = deps.pollTimeoutMs ?? 10 * 6e4;
320
+ const approved = await isPackageSpecApproved(deps.homeDir, deps.packageSpec);
321
+ if (!approved) {
322
+ if (ctx.autoApproveInstall) {
323
+ ctx.updateOutput?.("Computer Use install auto-approved (approval mode).");
324
+ } else {
325
+ ctx.updateOutput?.("Computer Use needs to be installed (first use).");
326
+ const ok = await deps.promptInstallApproval(deps.packageSpec);
327
+ if (!ok) {
328
+ throw new Error(
329
+ `Computer Use install declined by user. Re-invoke the tool to be prompted again.`
330
+ );
331
+ }
332
+ }
333
+ await saveInstallState(deps.homeDir, {
334
+ approvedPackageSpec: deps.packageSpec,
335
+ approvedAtIso: (/* @__PURE__ */ new Date()).toISOString()
336
+ });
337
+ }
338
+ const wasAlreadyStarted = client.isStarted();
339
+ if (!wasAlreadyStarted) {
340
+ await client.start(ctx.updateOutput);
341
+ }
342
+ if (wasAlreadyStarted) return;
343
+ if (deps.platform !== "darwin") return;
344
+ const probe = await deps.probePermissions(deps.packageSpec);
345
+ if (probe === "ok" || probe === "other") {
346
+ return;
347
+ }
348
+ ctx.updateOutput?.(
349
+ `Computer Use needs macOS permissions (${probe}). The onboarding window is opening \u2014 please grant Accessibility and Screen Recording, then this will continue automatically.`
350
+ );
351
+ let lastProbeKind = probe;
352
+ const startedAt = Date.now();
353
+ for (; ; ) {
354
+ if (ctx.signal.aborted) {
355
+ throw new Error("Computer Use bootstrap aborted.");
356
+ }
357
+ if (Date.now() - startedAt > pollTimeoutMs) {
358
+ throw new Error(
359
+ `Computer Use permission grant timed out after ${Math.round(pollTimeoutMs / 1e3)}s. Re-invoke the tool to retry.`
360
+ );
361
+ }
362
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
363
+ const next = await deps.probePermissionStatus(deps.packageSpec);
364
+ if (next === "ok" || next === "other") return;
365
+ if (next !== lastProbeKind) {
366
+ ctx.updateOutput?.(
367
+ `Now waiting for ${next} permission. The onboarding window remains open \u2014 please grant this permission to continue.`
368
+ );
369
+ lastProbeKind = next;
370
+ }
371
+ const elapsedSec = Math.round((Date.now() - startedAt) / 1e3);
372
+ ctx.updateOutput?.(`Waiting for ${next} permission... (${elapsedSec}s)`);
373
+ }
374
+ }
375
+ __name(runBootstrap, "runBootstrap");
376
+
377
+ // packages/core/src/tools/computer-use/tool.ts
378
+ import { homedir as homedir3 } from "node:os";
379
+ var INSTALL_REASON = "This will install the open-computer-use binary (~50MB) via npx the first time. Computer Use can click, type, and read your desktop apps. On macOS you'll be guided through Accessibility / Screen Recording permissions next.";
380
+ var ComputerUseInvocation = class extends BaseToolInvocation {
381
+ constructor(upstreamName, params, config) {
382
+ super(params);
383
+ this.upstreamName = upstreamName;
384
+ this.config = config;
385
+ }
386
+ static {
387
+ __name(this, "ComputerUseInvocation");
388
+ }
389
+ getDescription() {
390
+ return safeJsonStringify(this.params);
391
+ }
392
+ /**
393
+ * Always returns 'ask' so every desktop action surfaces through the
394
+ * standard tool-permission dialog. The PermissionManager rule system
395
+ * handles "always allow" per tool via ProceedAlwaysTool — that's the
396
+ * single source of truth for repeat-approval behavior.
397
+ *
398
+ * Earlier this returned 'allow' once the install-state file existed,
399
+ * which conflated install approval with per-action approval and
400
+ * effectively granted blanket permission for all 9 computer_use__*
401
+ * tools (including mutating actions like click / type_text / drag)
402
+ * after the first install confirmation. See PR #4590 review for the
403
+ * full discussion.
404
+ */
405
+ async getDefaultPermission() {
406
+ return "ask";
407
+ }
408
+ /**
409
+ * Builds the confirmation dialog. Two variants:
410
+ *
411
+ * 1. Install not yet approved → show install info (download size,
412
+ * permission flow to follow). onConfirm writes the install state
413
+ * so runBootstrap() inside execute() skips its env-var fallback
414
+ * prompt for headless contexts.
415
+ *
416
+ * 2. Install already approved → show per-action info (which tool +
417
+ * which args) so the user can decide whether THIS specific action
418
+ * is OK to perform.
419
+ *
420
+ * Both variants set permissionRules so the standard "Always allow"
421
+ * outcomes (ProceedAlwaysTool / ProceedAlwaysUser / ProceedAlwaysProject)
422
+ * add a rule via PermissionManager — subsequent calls of the SAME
423
+ * tool then skip the dialog. Different tools each need their own
424
+ * "always allow" choice; install approval no longer grants blanket
425
+ * access.
426
+ *
427
+ * On Cancel: install state is NOT written; execute() / runBootstrap()
428
+ * will use the env-var fallback (QWEN_COMPUTER_USE_AUTO_APPROVE),
429
+ * which defaults to refusing — producing a clear error message.
430
+ */
431
+ async getConfirmationDetails(_abortSignal) {
432
+ const permissionRules = [`computer_use__${this.upstreamName}`];
433
+ const installApproved = await isPackageSpecApproved(
434
+ homedir3(),
435
+ resolveComputerUsePackageSpec()
436
+ );
437
+ const prompt = installApproved ? `Tool: computer_use__${this.upstreamName}
438
+
439
+ Args: ${safeJsonStringify(this.params)}
440
+
441
+ This will act on your desktop via the Computer Use binary.` : `Tool: computer_use__${this.upstreamName}
442
+
443
+ ${INSTALL_REASON}`;
444
+ const details = {
445
+ type: "info",
446
+ title: `Allow Computer Use (${this.upstreamName})`,
447
+ prompt,
448
+ permissionRules,
449
+ onConfirm: /* @__PURE__ */ __name(async (outcome, _payload) => {
450
+ if (outcome !== "cancel" /* Cancel */) {
451
+ await saveInstallState(homedir3(), {
452
+ approvedPackageSpec: resolveComputerUsePackageSpec(),
453
+ approvedAtIso: (/* @__PURE__ */ new Date()).toISOString()
454
+ });
455
+ }
456
+ }, "onConfirm")
457
+ };
458
+ return details;
459
+ }
460
+ async execute(signal, updateOutput) {
461
+ const client = ComputerUseClient.shared();
462
+ const mode = this.config?.getApprovalMode();
463
+ const autoApproveInstall = mode === "yolo" /* YOLO */ || mode === "auto-edit" /* AUTO_EDIT */ || mode === "auto" /* AUTO */;
464
+ await runBootstrap(client, { signal, updateOutput, autoApproveInstall });
465
+ let mcpResult;
466
+ try {
467
+ mcpResult = await client.callTool(this.upstreamName, this.params);
468
+ } catch (err) {
469
+ const message = err instanceof Error ? err.message : String(err);
470
+ return {
471
+ llmContent: `Computer Use tool '${this.upstreamName}' failed: ${message}`,
472
+ returnDisplay: `Error: ${message}`,
473
+ error: { message }
474
+ };
475
+ }
476
+ const llmContent = buildLlmContent(mcpResult.content, this.upstreamName);
477
+ const returnDisplay = buildDisplayText(mcpResult.content);
478
+ if (mcpResult.isError) {
479
+ const errorText = returnDisplay || `Tool '${this.upstreamName}' returned isError=true`;
480
+ return {
481
+ llmContent: llmContent || errorText,
482
+ returnDisplay: errorText,
483
+ error: { message: errorText }
484
+ };
485
+ }
486
+ return {
487
+ llmContent,
488
+ returnDisplay
489
+ };
490
+ }
491
+ };
492
+ var ComputerUseTool = class extends BaseDeclarativeTool {
493
+ constructor(upstreamName, schema, config) {
494
+ const qwenName = `computer_use__${upstreamName}`;
495
+ super(
496
+ qwenName,
497
+ qwenName,
498
+ // displayName == name; no MCP branding in UI
499
+ schema.description,
500
+ "other" /* Other */,
501
+ schema.parameterSchema,
502
+ true,
503
+ // isOutputMarkdown — many results are JSON-ish text or screenshots
504
+ true,
505
+ // canUpdateOutput — bootstrap streams progress
506
+ true,
507
+ // shouldDefer — surface only via ToolSearch
508
+ false,
509
+ // alwaysLoad
510
+ `computer use desktop click type screenshot mouse keyboard scroll drag automation gui app native`
511
+ );
512
+ this.upstreamName = upstreamName;
513
+ this.config = config;
514
+ }
515
+ static {
516
+ __name(this, "ComputerUseTool");
517
+ }
518
+ /**
519
+ * Coerce parameter types before schema validation.
520
+ * Models can send the wrong JS type for a field:
521
+ * - qwen3.6 sends `element_index: 2` (number) but upstream wants "2" (string)
522
+ * - Some models send `x: "500"` (string) but upstream wants 500 (number)
523
+ * Pre-coercing avoids spurious validation failures without loosening schema types.
524
+ */
525
+ validateToolParams(params) {
526
+ const coerced = coerceTypes(
527
+ params,
528
+ this.parameterSchema
529
+ );
530
+ return super.validateToolParams(coerced);
531
+ }
532
+ build(params) {
533
+ const coerced = coerceTypes(
534
+ params,
535
+ this.parameterSchema
536
+ );
537
+ return super.build(coerced);
538
+ }
539
+ createInvocation(params) {
540
+ return new ComputerUseInvocation(this.upstreamName, params, this.config);
541
+ }
542
+ };
543
+ function coerceTypes(params, schema) {
544
+ const properties = schema.properties;
545
+ if (!properties) return params;
546
+ const result = { ...params };
547
+ for (const [key, value] of Object.entries(result)) {
548
+ const fieldType = properties[key]?.type;
549
+ if ((fieldType === "integer" || fieldType === "number") && typeof value === "string") {
550
+ const trimmed = value.trim();
551
+ if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
552
+ const parsed = fieldType === "integer" ? parseInt(trimmed, 10) : parseFloat(trimmed);
553
+ if (Number.isFinite(parsed)) {
554
+ result[key] = parsed;
555
+ }
556
+ }
557
+ } else if (fieldType === "string" && typeof value === "number") {
558
+ result[key] = String(value);
559
+ }
560
+ }
561
+ return result;
562
+ }
563
+ __name(coerceTypes, "coerceTypes");
564
+ function buildLlmContent(content, toolName) {
565
+ const parts = [];
566
+ for (const block of content) {
567
+ if (block.type === "text" && block.text) {
568
+ parts.push({ text: block.text });
569
+ } else if ((block.type === "image" || block.type === "audio") && block.mimeType && block.data) {
570
+ parts.push({
571
+ text: `[Tool '${toolName}' provided the following ${block.type} data with mime-type: ${block.mimeType}]`
572
+ });
573
+ parts.push({
574
+ inlineData: {
575
+ mimeType: block.mimeType,
576
+ data: block.data
577
+ }
578
+ });
579
+ }
580
+ }
581
+ const hasNonText = parts.some((p) => p.inlineData !== void 0);
582
+ if (!hasNonText) {
583
+ return parts.map((p) => p.text ?? "").filter(Boolean).join("\n");
584
+ }
585
+ return parts;
586
+ }
587
+ __name(buildLlmContent, "buildLlmContent");
588
+ function buildDisplayText(content) {
589
+ return content.map((block) => block.type === "text" ? block.text ?? "" : "").filter(Boolean).join("\n");
590
+ }
591
+ __name(buildDisplayText, "buildDisplayText");
592
+
593
+ // packages/core/src/tools/computer-use/schemas.ts
594
+ init_esbuild_shims();
595
+ var COMPUTER_USE_TOOL_NAMES = [
596
+ "click",
597
+ "drag",
598
+ "get_app_state",
599
+ "list_apps",
600
+ "perform_secondary_action",
601
+ "press_key",
602
+ "scroll",
603
+ "set_value",
604
+ "type_text"
605
+ ];
606
+ var COMPUTER_USE_SCHEMAS = {
607
+ click: {
608
+ description: "Click an element by index or pixel coordinates from screenshot. This tool is part of plugin `Computer Use`.",
609
+ parameterSchema: {
610
+ type: "object",
611
+ properties: {
612
+ click_count: {
613
+ type: "integer",
614
+ description: "Number of clicks. Defaults to 1"
615
+ },
616
+ mouse_button: {
617
+ description: "Mouse button to click. Defaults to left.",
618
+ enum: ["left", "right", "middle"],
619
+ type: "string"
620
+ },
621
+ element_index: {
622
+ type: "string",
623
+ description: "Element index to click"
624
+ },
625
+ y: {
626
+ type: "number",
627
+ description: "Y coordinate in screenshot pixel coordinates"
628
+ },
629
+ app: {
630
+ type: "string",
631
+ description: "App name or bundle identifier"
632
+ },
633
+ x: {
634
+ description: "X coordinate in screenshot pixel coordinates",
635
+ type: "number"
636
+ }
637
+ },
638
+ required: ["app"],
639
+ additionalProperties: false
640
+ }
641
+ },
642
+ drag: {
643
+ description: "Drag from one point to another using pixel coordinates. This tool is part of plugin `Computer Use`.",
644
+ parameterSchema: {
645
+ type: "object",
646
+ properties: {
647
+ app: {
648
+ type: "string",
649
+ description: "App name or bundle identifier"
650
+ },
651
+ from_x: {
652
+ description: "Start X coordinate",
653
+ type: "number"
654
+ },
655
+ from_y: {
656
+ type: "number",
657
+ description: "Start Y coordinate"
658
+ },
659
+ to_x: {
660
+ description: "End X coordinate",
661
+ type: "number"
662
+ },
663
+ to_y: {
664
+ type: "number",
665
+ description: "End Y coordinate"
666
+ }
667
+ },
668
+ required: ["app", "from_x", "from_y", "to_x", "to_y"],
669
+ additionalProperties: false
670
+ }
671
+ },
672
+ get_app_state: {
673
+ description: "Start an app use session if needed, then get the state of the app's key window and return a screenshot and accessibility tree. This must be called once per assistant turn before interacting with the app. This tool is part of plugin `Computer Use`.",
674
+ parameterSchema: {
675
+ type: "object",
676
+ properties: {
677
+ app: {
678
+ description: "App name or bundle identifier",
679
+ type: "string"
680
+ }
681
+ },
682
+ required: ["app"],
683
+ additionalProperties: false
684
+ }
685
+ },
686
+ list_apps: {
687
+ description: "List the apps on this computer. Returns the set of apps that are currently running, as well as any that have been used in the last 14 days, including details on usage frequency. This tool is part of plugin `Computer Use`.",
688
+ parameterSchema: {
689
+ type: "object",
690
+ properties: {},
691
+ additionalProperties: false
692
+ }
693
+ },
694
+ perform_secondary_action: {
695
+ description: "Invoke a secondary accessibility action exposed by an element. This tool is part of plugin `Computer Use`.",
696
+ parameterSchema: {
697
+ type: "object",
698
+ properties: {
699
+ action: {
700
+ description: "Secondary accessibility action name",
701
+ type: "string"
702
+ },
703
+ app: {
704
+ description: "App name or bundle identifier",
705
+ type: "string"
706
+ },
707
+ element_index: {
708
+ description: "Element identifier",
709
+ type: "string"
710
+ }
711
+ },
712
+ required: ["app", "element_index", "action"],
713
+ additionalProperties: false
714
+ }
715
+ },
716
+ press_key: {
717
+ description: 'Press a key or key-combination on the keyboard, including modifier and navigation keys.\n - This supports xdotool\'s `key` syntax.\n - Examples: "a", "Return", "Tab", "super+c", "Up", "KP_0" (for the numpad 0 key). This tool is part of plugin `Computer Use`.',
718
+ parameterSchema: {
719
+ type: "object",
720
+ properties: {
721
+ app: {
722
+ description: "App name or bundle identifier",
723
+ type: "string"
724
+ },
725
+ key: {
726
+ type: "string",
727
+ description: "Key or key combination to press"
728
+ }
729
+ },
730
+ required: ["app", "key"],
731
+ additionalProperties: false
732
+ }
733
+ },
734
+ scroll: {
735
+ description: "Scroll an element in a direction by a number of pages. This tool is part of plugin `Computer Use`.",
736
+ parameterSchema: {
737
+ type: "object",
738
+ properties: {
739
+ pages: {
740
+ type: "number",
741
+ description: "Number of pages to scroll. Fractional values are supported. Defaults to 1"
742
+ },
743
+ app: {
744
+ description: "App name or bundle identifier",
745
+ type: "string"
746
+ },
747
+ element_index: {
748
+ description: "Element identifier",
749
+ type: "string"
750
+ },
751
+ direction: {
752
+ description: "Scroll direction: up, down, left, or right",
753
+ type: "string"
754
+ }
755
+ },
756
+ required: ["app", "element_index", "direction"],
757
+ additionalProperties: false
758
+ }
759
+ },
760
+ set_value: {
761
+ description: "Set the value of a settable accessibility element. This tool is part of plugin `Computer Use`.",
762
+ parameterSchema: {
763
+ type: "object",
764
+ properties: {
765
+ element_index: {
766
+ type: "string",
767
+ description: "Element identifier"
768
+ },
769
+ value: {
770
+ type: "string",
771
+ description: "Value to assign"
772
+ },
773
+ app: {
774
+ description: "App name or bundle identifier",
775
+ type: "string"
776
+ }
777
+ },
778
+ required: ["app", "element_index", "value"],
779
+ additionalProperties: false
780
+ }
781
+ },
782
+ type_text: {
783
+ description: "Type literal text using keyboard input. This tool is part of plugin `Computer Use`.",
784
+ parameterSchema: {
785
+ type: "object",
786
+ properties: {
787
+ app: {
788
+ type: "string",
789
+ description: "App name or bundle identifier"
790
+ },
791
+ text: {
792
+ type: "string",
793
+ description: "Literal text to type"
794
+ }
795
+ },
796
+ required: ["app", "text"],
797
+ additionalProperties: false
798
+ }
799
+ }
800
+ };
801
+
802
+ // packages/core/src/tools/computer-use/index.ts
803
+ async function registerComputerUseTools(registerLazy, config) {
804
+ for (const upstreamName of COMPUTER_USE_TOOL_NAMES) {
805
+ const schema = COMPUTER_USE_SCHEMAS[upstreamName];
806
+ const qwenName = `computer_use__${upstreamName}`;
807
+ await registerLazy(
808
+ qwenName,
809
+ async () => new ComputerUseTool(upstreamName, schema, config)
810
+ );
811
+ }
812
+ }
813
+ __name(registerComputerUseTools, "registerComputerUseTools");
814
+ export {
815
+ COMPUTER_USE_SCHEMAS,
816
+ COMPUTER_USE_TOOL_NAMES,
817
+ ComputerUseClient,
818
+ ComputerUseTool,
819
+ registerComputerUseTools
820
+ };
821
+ /**
822
+ * @license
823
+ * Copyright 2025 Qwen Team
824
+ * SPDX-License-Identifier: Apache-2.0
825
+ */