@zqagent/core 0.2.20 → 0.3.7

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 (238) hide show
  1. package/README.md +1 -1
  2. package/README.oss.en.md +3 -3
  3. package/README.oss.md +8 -3
  4. package/README.oss.zh-TW.md +3 -3
  5. package/dist/McpClient-CEQBUPuC.d.cts +145 -0
  6. package/dist/McpClient-CEQBUPuC.d.ts +145 -0
  7. package/dist/{ToolRegistry-C3pTFiaJ.d.cts → ToolRegistry-Cy0fQxrb.d.ts} +2 -111
  8. package/dist/{ToolRegistry-C3pTFiaJ.d.ts → ToolRegistry-DouDvn9E.d.cts} +2 -111
  9. package/dist/{explore-RtZtb-V6.d.ts → TurnEngine-BPKhWuSI.d.cts} +108 -73
  10. package/dist/{explore-BgRhj6SP.d.cts → TurnEngine-DtGEuVLT.d.ts} +108 -73
  11. package/dist/conflictGuard-BBOOIxxK.d.cts +42 -0
  12. package/dist/conflictGuard-BBOOIxxK.d.ts +42 -0
  13. package/dist/index.cjs +5930 -1114
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +577 -195
  16. package/dist/index.d.ts +577 -195
  17. package/dist/index.js +5761 -979
  18. package/dist/index.js.map +1 -1
  19. package/dist/internal/crypto/secrets.cjs +25 -0
  20. package/dist/internal/crypto/secrets.cjs.map +1 -0
  21. package/dist/internal/crypto/secrets.d.cts +2 -0
  22. package/dist/internal/crypto/secrets.d.ts +2 -0
  23. package/dist/internal/crypto/secrets.js +3 -0
  24. package/dist/internal/crypto/secrets.js.map +1 -0
  25. package/dist/internal/engine/FileLogHook.cjs +179 -0
  26. package/dist/internal/engine/FileLogHook.cjs.map +1 -0
  27. package/dist/internal/engine/FileLogHook.d.cts +67 -0
  28. package/dist/internal/engine/FileLogHook.d.ts +67 -0
  29. package/dist/internal/engine/FileLogHook.js +144 -0
  30. package/dist/internal/engine/FileLogHook.js.map +1 -0
  31. package/dist/internal/engine/approvalView.cjs +25 -0
  32. package/dist/internal/engine/approvalView.cjs.map +1 -0
  33. package/dist/internal/engine/approvalView.d.cts +1 -0
  34. package/dist/internal/engine/approvalView.d.ts +1 -0
  35. package/dist/internal/engine/approvalView.js +3 -0
  36. package/dist/internal/engine/approvalView.js.map +1 -0
  37. package/dist/internal/engine/limits.cjs +59 -0
  38. package/dist/internal/engine/limits.cjs.map +1 -0
  39. package/dist/internal/engine/limits.d.cts +32 -0
  40. package/dist/internal/engine/limits.d.ts +32 -0
  41. package/dist/internal/engine/limits.js +31 -0
  42. package/dist/internal/engine/limits.js.map +1 -0
  43. package/dist/internal/engine/sessionNaming.cjs +47 -0
  44. package/dist/internal/engine/sessionNaming.cjs.map +1 -0
  45. package/dist/internal/engine/sessionNaming.d.cts +25 -0
  46. package/dist/internal/engine/sessionNaming.d.ts +25 -0
  47. package/dist/internal/engine/sessionNaming.js +20 -0
  48. package/dist/internal/engine/sessionNaming.js.map +1 -0
  49. package/dist/internal/llmConfig.cjs +561 -0
  50. package/dist/internal/llmConfig.cjs.map +1 -0
  51. package/dist/internal/llmConfig.d.cts +75 -0
  52. package/dist/internal/llmConfig.d.ts +75 -0
  53. package/dist/internal/llmConfig.js +535 -0
  54. package/dist/internal/llmConfig.js.map +1 -0
  55. package/dist/internal/mcp/builtin/index.cjs +685 -0
  56. package/dist/internal/mcp/builtin/index.cjs.map +1 -0
  57. package/dist/internal/mcp/builtin/index.d.cts +21 -0
  58. package/dist/internal/mcp/builtin/index.d.ts +21 -0
  59. package/dist/internal/mcp/builtin/index.js +652 -0
  60. package/dist/internal/mcp/builtin/index.js.map +1 -0
  61. package/dist/internal/mcp/config.cjs +278 -0
  62. package/dist/internal/mcp/config.cjs.map +1 -0
  63. package/dist/internal/mcp/config.d.cts +61 -0
  64. package/dist/internal/mcp/config.d.ts +61 -0
  65. package/dist/internal/mcp/config.js +235 -0
  66. package/dist/internal/mcp/config.js.map +1 -0
  67. package/dist/internal/mcp/presets.cjs +184 -0
  68. package/dist/internal/mcp/presets.cjs.map +1 -0
  69. package/dist/internal/mcp/presets.d.cts +39 -0
  70. package/dist/internal/mcp/presets.d.ts +39 -0
  71. package/dist/internal/mcp/presets.js +158 -0
  72. package/dist/internal/mcp/presets.js.map +1 -0
  73. package/dist/internal/node-name.cjs +45 -0
  74. package/dist/internal/node-name.cjs.map +1 -0
  75. package/dist/internal/node-name.d.cts +3 -0
  76. package/dist/internal/node-name.d.ts +3 -0
  77. package/dist/internal/node-name.js +10 -0
  78. package/dist/internal/node-name.js.map +1 -0
  79. package/dist/internal/paths.cjs +63 -0
  80. package/dist/internal/paths.cjs.map +1 -0
  81. package/dist/internal/paths.d.cts +17 -0
  82. package/dist/internal/paths.d.ts +17 -0
  83. package/dist/internal/paths.js +25 -0
  84. package/dist/internal/paths.js.map +1 -0
  85. package/dist/internal/providers/diagnostics.cjs +288 -0
  86. package/dist/internal/providers/diagnostics.cjs.map +1 -0
  87. package/dist/internal/providers/diagnostics.d.cts +103 -0
  88. package/dist/internal/providers/diagnostics.d.ts +103 -0
  89. package/dist/internal/providers/diagnostics.js +250 -0
  90. package/dist/internal/providers/diagnostics.js.map +1 -0
  91. package/dist/internal/providers/models.cjs +699 -0
  92. package/dist/internal/providers/models.cjs.map +1 -0
  93. package/dist/internal/providers/models.d.cts +136 -0
  94. package/dist/internal/providers/models.d.ts +136 -0
  95. package/dist/internal/providers/models.js +654 -0
  96. package/dist/internal/providers/models.js.map +1 -0
  97. package/dist/internal/terminal.cjs +161 -0
  98. package/dist/internal/terminal.cjs.map +1 -0
  99. package/dist/internal/terminal.d.cts +58 -0
  100. package/dist/internal/terminal.d.ts +58 -0
  101. package/dist/internal/terminal.js +128 -0
  102. package/dist/internal/terminal.js.map +1 -0
  103. package/dist/internal/tools/execAsync.cjs +187 -0
  104. package/dist/internal/tools/execAsync.cjs.map +1 -0
  105. package/dist/internal/tools/execAsync.d.cts +30 -0
  106. package/dist/internal/tools/execAsync.d.ts +30 -0
  107. package/dist/internal/tools/execAsync.js +162 -0
  108. package/dist/internal/tools/execAsync.js.map +1 -0
  109. package/dist/internal/tools/git.cjs +935 -0
  110. package/dist/internal/tools/git.cjs.map +1 -0
  111. package/dist/internal/tools/git.d.cts +206 -0
  112. package/dist/internal/tools/git.d.ts +206 -0
  113. package/dist/internal/tools/git.js +883 -0
  114. package/dist/internal/tools/git.js.map +1 -0
  115. package/dist/internal/tools/pathSafety.cjs +99 -0
  116. package/dist/internal/tools/pathSafety.cjs.map +1 -0
  117. package/dist/internal/tools/pathSafety.d.cts +44 -0
  118. package/dist/internal/tools/pathSafety.d.ts +44 -0
  119. package/dist/internal/tools/pathSafety.js +61 -0
  120. package/dist/internal/tools/pathSafety.js.map +1 -0
  121. package/dist/internal/tools/plan.cjs +146 -0
  122. package/dist/internal/tools/plan.cjs.map +1 -0
  123. package/dist/internal/tools/plan.d.cts +48 -0
  124. package/dist/internal/tools/plan.d.ts +48 -0
  125. package/dist/internal/tools/plan.js +117 -0
  126. package/dist/internal/tools/plan.js.map +1 -0
  127. package/dist/internal/tools/ripgrep.cjs +118 -0
  128. package/dist/internal/tools/ripgrep.cjs.map +1 -0
  129. package/dist/internal/tools/ripgrep.d.cts +6 -0
  130. package/dist/internal/tools/ripgrep.d.ts +6 -0
  131. package/dist/internal/tools/ripgrep.js +89 -0
  132. package/dist/internal/tools/ripgrep.js.map +1 -0
  133. package/dist/internal/tools/sandbox.cjs +253 -0
  134. package/dist/internal/tools/sandbox.cjs.map +1 -0
  135. package/dist/internal/tools/sandbox.d.cts +67 -0
  136. package/dist/internal/tools/sandbox.d.ts +67 -0
  137. package/dist/internal/tools/sandbox.js +213 -0
  138. package/dist/internal/tools/sandbox.js.map +1 -0
  139. package/dist/internal/tools/shell.cjs +771 -0
  140. package/dist/internal/tools/shell.cjs.map +1 -0
  141. package/dist/internal/tools/shell.d.cts +47 -0
  142. package/dist/internal/tools/shell.d.ts +47 -0
  143. package/dist/internal/tools/shell.js +731 -0
  144. package/dist/internal/tools/shell.js.map +1 -0
  145. package/dist/internal/tools/shellRuntime.cjs +220 -0
  146. package/dist/internal/tools/shellRuntime.cjs.map +1 -0
  147. package/dist/internal/tools/shellRuntime.d.cts +67 -0
  148. package/dist/internal/tools/shellRuntime.d.ts +67 -0
  149. package/dist/internal/tools/shellRuntime.js +181 -0
  150. package/dist/internal/tools/shellRuntime.js.map +1 -0
  151. package/dist/internal/update/controller.cjs +1035 -0
  152. package/dist/internal/update/controller.cjs.map +1 -0
  153. package/dist/internal/update/controller.d.cts +150 -0
  154. package/dist/internal/update/controller.d.ts +150 -0
  155. package/dist/internal/update/controller.js +991 -0
  156. package/dist/internal/update/controller.js.map +1 -0
  157. package/dist/internal/update/platform.cjs +234 -0
  158. package/dist/internal/update/platform.cjs.map +1 -0
  159. package/dist/internal/update/platform.d.cts +77 -0
  160. package/dist/internal/update/platform.d.ts +77 -0
  161. package/dist/internal/update/platform.js +184 -0
  162. package/dist/internal/update/platform.js.map +1 -0
  163. package/dist/tools/ask.d.cts +3 -1
  164. package/dist/tools/ask.d.ts +3 -1
  165. package/dist/tools/diff.cjs +17 -6
  166. package/dist/tools/diff.cjs.map +1 -1
  167. package/dist/tools/diff.d.cts +5 -2
  168. package/dist/tools/diff.d.ts +5 -2
  169. package/dist/tools/diff.js +17 -6
  170. package/dist/tools/diff.js.map +1 -1
  171. package/dist/tools/directories.d.cts +3 -1
  172. package/dist/tools/directories.d.ts +3 -1
  173. package/dist/tools/explore.cjs +1778 -204
  174. package/dist/tools/explore.cjs.map +1 -1
  175. package/dist/tools/explore.d.cts +82 -2
  176. package/dist/tools/explore.d.ts +82 -2
  177. package/dist/tools/explore.js +1780 -204
  178. package/dist/tools/explore.js.map +1 -1
  179. package/dist/tools/files.cjs +56 -21
  180. package/dist/tools/files.cjs.map +1 -1
  181. package/dist/tools/files.d.cts +6 -3
  182. package/dist/tools/files.d.ts +6 -3
  183. package/dist/tools/files.js +56 -21
  184. package/dist/tools/files.js.map +1 -1
  185. package/dist/tools/git.cjs +34 -25
  186. package/dist/tools/git.cjs.map +1 -1
  187. package/dist/tools/git.d.cts +4 -204
  188. package/dist/tools/git.d.ts +4 -204
  189. package/dist/tools/git.js +34 -25
  190. package/dist/tools/git.js.map +1 -1
  191. package/dist/tools/media.cjs +280 -3
  192. package/dist/tools/media.cjs.map +1 -1
  193. package/dist/tools/media.d.cts +3 -1
  194. package/dist/tools/media.d.ts +3 -1
  195. package/dist/tools/media.js +278 -1
  196. package/dist/tools/media.js.map +1 -1
  197. package/dist/tools/plan.cjs +62 -0
  198. package/dist/tools/plan.cjs.map +1 -1
  199. package/dist/tools/plan.d.cts +4 -17
  200. package/dist/tools/plan.d.ts +4 -17
  201. package/dist/tools/plan.js +59 -0
  202. package/dist/tools/plan.js.map +1 -1
  203. package/dist/tools/search.cjs +3 -0
  204. package/dist/tools/search.cjs.map +1 -1
  205. package/dist/tools/search.d.cts +3 -1
  206. package/dist/tools/search.d.ts +3 -1
  207. package/dist/tools/search.js +3 -0
  208. package/dist/tools/search.js.map +1 -1
  209. package/dist/tools/shell.cjs +76 -11
  210. package/dist/tools/shell.cjs.map +1 -1
  211. package/dist/tools/shell.d.cts +5 -39
  212. package/dist/tools/shell.d.ts +5 -39
  213. package/dist/tools/shell.js +75 -11
  214. package/dist/tools/shell.js.map +1 -1
  215. package/dist/tools/todo.d.cts +3 -1
  216. package/dist/tools/todo.d.ts +3 -1
  217. package/dist/tools/web.cjs +279 -5
  218. package/dist/tools/web.cjs.map +1 -1
  219. package/dist/tools/web.d.cts +3 -1
  220. package/dist/tools/web.d.ts +3 -1
  221. package/dist/tools/web.js +275 -3
  222. package/dist/tools/web.js.map +1 -1
  223. package/dist/types-BYyXWWPW.d.cts +237 -0
  224. package/dist/types-BYyXWWPW.d.ts +237 -0
  225. package/package.json +26 -37
  226. package/bin/zqagent +0 -2
  227. package/dist/cli/index.cjs +0 -25218
  228. package/dist/cli/index.cjs.map +0 -1
  229. package/dist/cli/index.d.cts +0 -2
  230. package/dist/cli/index.d.ts +0 -2
  231. package/dist/cli/index.js +0 -25201
  232. package/dist/cli/index.js.map +0 -1
  233. package/dist/server/index.cjs +0 -20510
  234. package/dist/server/index.cjs.map +0 -1
  235. package/dist/server/index.d.cts +0 -2
  236. package/dist/server/index.d.ts +0 -2
  237. package/dist/server/index.js +0 -20493
  238. package/dist/server/index.js.map +0 -1
@@ -0,0 +1,181 @@
1
+ // src/tools/shellRuntime.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ var WINDOWS_SUFFIXES = [".exe", ".cmd", ".bat", ".com", ""];
5
+ function pathApi(platform) {
6
+ return platform === "win32" ? path.win32 : path.posix;
7
+ }
8
+ function defaultFileExists(p) {
9
+ try {
10
+ return fs.statSync(p).isFile();
11
+ } catch {
12
+ return false;
13
+ }
14
+ }
15
+ function joinPath(platform, ...parts) {
16
+ return pathApi(platform).join(...parts);
17
+ }
18
+ function findExecutable(name, ctx) {
19
+ if (name.includes("/") || name.includes("\\")) {
20
+ return ctx.fileExists(name) ? name : null;
21
+ }
22
+ const suffixes = ctx.platform === "win32" ? WINDOWS_SUFFIXES : [""];
23
+ const delimiter = ctx.platform === "win32" ? ";" : ":";
24
+ const dirs = (ctx.env.PATH ?? "").split(delimiter).filter((d) => d.length > 0);
25
+ for (const dir of dirs) {
26
+ for (const suffix of suffixes) {
27
+ const candidate = joinPath(ctx.platform, dir, name + suffix);
28
+ if (ctx.fileExists(candidate)) return candidate;
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ function kindFromBasename(base) {
34
+ const b = base.toLowerCase().replace(/\.(exe|cmd|bat|com)$/, "");
35
+ if (b === "busybox") return "busybox";
36
+ if (b === "powershell" || b === "pwsh") return "powershell";
37
+ if (b === "cmd") return "cmd";
38
+ return "sh";
39
+ }
40
+ function busyboxArgs(file, command) {
41
+ const base = (file ? path.win32.basename(file) : "busybox").toLowerCase().replace(/\.(exe|cmd|bat|com)$/, "");
42
+ return base === "busybox" ? ["sh", "-c", command] : ["-c", command];
43
+ }
44
+ function argsFor(kind, command) {
45
+ switch (kind) {
46
+ case "busybox":
47
+ return ["sh", "-c", command];
48
+ case "powershell":
49
+ return ["-NoProfile", "-NonInteractive", "-Command", command];
50
+ case "cmd":
51
+ return ["/d", "/s", "/c", command];
52
+ default:
53
+ return ["-c", command];
54
+ }
55
+ }
56
+ function makeSpec(kind, file, label) {
57
+ return {
58
+ kind,
59
+ file,
60
+ label,
61
+ buildArgs: (command) => kind === "busybox" ? busyboxArgs(file, command) : argsFor(kind, command)
62
+ };
63
+ }
64
+ function defaultLabelFor(kind) {
65
+ switch (kind) {
66
+ case "busybox":
67
+ return "busybox ash";
68
+ case "powershell":
69
+ return "PowerShell";
70
+ case "cmd":
71
+ return "cmd.exe";
72
+ case "default":
73
+ return "\u7CFB\u7EDF\u9ED8\u8BA4 shell";
74
+ default:
75
+ return "sh";
76
+ }
77
+ }
78
+ function findBusybox(ctx, execPath) {
79
+ const explicit = (ctx.env.ZQAGENT_BUSYBOX ?? "").trim();
80
+ if (explicit) return ctx.fileExists(explicit) ? explicit : null;
81
+ const exeDir = pathApi(ctx.platform).dirname(execPath);
82
+ const candidates = [
83
+ joinPath(ctx.platform, exeDir, "busybox.exe"),
84
+ joinPath(ctx.platform, exeDir, "sh.exe"),
85
+ joinPath(ctx.platform, exeDir, "bin", "busybox.exe"),
86
+ joinPath(ctx.platform, exeDir, "bin", "sh.exe")
87
+ ];
88
+ for (const candidate of candidates) {
89
+ if (ctx.fileExists(candidate)) return candidate;
90
+ }
91
+ return null;
92
+ }
93
+ function resolveRequested(requested, ctx, execPath) {
94
+ const lower = requested.toLowerCase();
95
+ if (lower === "cmd") {
96
+ const file = findExecutable("cmd", ctx) ?? ctx.env.ComSpec ?? ctx.env.COMSPEC ?? "cmd.exe";
97
+ return makeSpec("cmd", file, "cmd.exe");
98
+ }
99
+ if (lower === "powershell" || lower === "pwsh") {
100
+ const file = findExecutable(lower, ctx) ?? findExecutable("powershell", ctx) ?? `${lower}.exe`;
101
+ return makeSpec("powershell", file, "PowerShell");
102
+ }
103
+ if (lower === "busybox") {
104
+ const found = findBusybox(ctx, execPath) ?? findExecutable("busybox", ctx);
105
+ return makeSpec("busybox", found ?? requested, "busybox ash");
106
+ }
107
+ if (["sh", "bash", "dash", "zsh", "ash"].includes(lower)) {
108
+ return makeSpec("sh", findExecutable(lower, ctx) ?? lower, lower);
109
+ }
110
+ const base = pathApi(ctx.platform).basename(requested);
111
+ const kind = kindFromBasename(base);
112
+ return makeSpec(kind, requested, base || defaultLabelFor(kind));
113
+ }
114
+ function resolveShellSpec(opts = {}) {
115
+ const platform = opts.platform ?? process.platform;
116
+ const env = opts.env ?? process.env;
117
+ const execPath = opts.execPath ?? process.execPath;
118
+ const ctx = {
119
+ platform,
120
+ env,
121
+ fileExists: opts.fileExists ?? defaultFileExists
122
+ };
123
+ const requested = (env.ZQAGENT_SHELL ?? "").trim();
124
+ if (requested && requested.toLowerCase() !== "auto") {
125
+ return resolveRequested(requested, ctx, execPath);
126
+ }
127
+ if (platform !== "win32") {
128
+ return makeSpec("default", null, "/bin/sh");
129
+ }
130
+ const busybox = findBusybox(ctx, execPath);
131
+ if (busybox) return makeSpec("busybox", busybox, "busybox ash (POSIX)");
132
+ const bash = findExecutable("bash", ctx);
133
+ if (bash) return makeSpec("sh", bash, "bash (Git for Windows)");
134
+ const shell = findExecutable("pwsh", ctx) ?? findExecutable("powershell", ctx);
135
+ if (shell) return makeSpec("powershell", shell, "PowerShell");
136
+ return makeSpec("default", null, env.ComSpec ?? env.COMSPEC ?? "cmd.exe");
137
+ }
138
+ function wrapCommand(kind, command, platform = process.platform) {
139
+ if (kind === "powershell") {
140
+ return "$OutputEncoding = [Console]::OutputEncoding = [Text.Encoding]::UTF8; " + command + "\nif ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE }";
141
+ }
142
+ if (kind === "cmd" || kind === "default" && platform === "win32") {
143
+ return `chcp 65001>nul & ${command}`;
144
+ }
145
+ return command;
146
+ }
147
+ function describeShell(spec, platform) {
148
+ if (spec.kind === "sh" || spec.kind === "busybox") {
149
+ return `\u5F53\u524D\u5E73\u53F0 ${platform}\uFF0Cshell=${spec.label}\uFF1A\u8BF7\u4F7F\u7528 POSIX \u98CE\u683C\u547D\u4EE4\u3002`;
150
+ }
151
+ if (spec.kind === "powershell") {
152
+ return `\u5F53\u524D\u5E73\u53F0 ${platform}\uFF0Cshell=PowerShell\uFF1Als/cat/rm/cp/mv/pwd \u7B49\u522B\u540D\u53EF\u7528\uFF0C\u4E5F\u53EF\u7528 cmdlet\uFF1B\u8DEF\u5F84\u5206\u9694\u7B26\u4E3A "\\"\u3002`;
153
+ }
154
+ if (spec.kind === "default" && platform !== "win32") {
155
+ return `\u5F53\u524D\u5E73\u53F0 ${platform}\uFF0Cshell=${spec.label}\uFF1A\u8BF7\u4F7F\u7528 POSIX \u98CE\u683C\u547D\u4EE4\u3002`;
156
+ }
157
+ return `\u5F53\u524D\u5E73\u53F0 ${platform}\uFF0Cshell=${spec.label}\uFF1A\u8BF7\u4F7F\u7528 Windows \u547D\u4EE4\uFF08dir/type/del/copy/move/findstr\uFF09\uFF0C\u591A\u6761\u547D\u4EE4\u7528 & \u6216 && \u8FDE\u63A5\uFF1B\u4E0D\u8981\u4F7F\u7528 ls/cat/rm/grep \u7B49 POSIX \u547D\u4EE4\u3002`;
158
+ }
159
+ function parseCdChain(command, opts = {}) {
160
+ const platform = opts.platform ?? process.platform;
161
+ const trimmed = command.trim();
162
+ const chain = /^([\s\S]*?)\s*&&\s*([\s\S]+)$/.exec(trimmed);
163
+ const head = (chain ? chain[1] : trimmed).trim();
164
+ const rest = chain ? chain[2].trim() : null;
165
+ const m = /^(?:cd|set-location|sl|pushd|push-location)\b\s*([\s\S]*)$/i.exec(head);
166
+ if (!m) return { target: null, rest: null };
167
+ let target = m[1].trim();
168
+ target = target.replace(/^-(?:path|literalpath)\s+/i, "");
169
+ if (platform === "win32") target = target.replace(/^\/d\s+/i, "");
170
+ target = target.replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1").trim();
171
+ if (!target || target === "-") return { target: null, rest: null };
172
+ return { target, rest };
173
+ }
174
+ export {
175
+ describeShell,
176
+ findExecutable,
177
+ parseCdChain,
178
+ resolveShellSpec,
179
+ wrapCommand
180
+ };
181
+ //# sourceMappingURL=shellRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/tools/shellRuntime.ts"],"sourcesContent":["/**\n * shell 运行时探测\n *\n * 决定 run_shell 用哪个 shell 执行命令,解决三件事:\n * - POSIX:沿用 Node 默认 /bin/sh,不改变既有语义;\n * - Windows:cmd.exe 没有 ls/grep/rm/cat,优先挑一个 POSIX 风格的 shell\n * (BusyBox-w32 / Git Bash / PowerShell),都没有时才回退到 %ComSpec%;\n * - 允许用 ZQAGENT_SHELL / ZQAGENT_BUSYBOX 显式覆盖,便于在装了非常规\n * shell(如内网自带的 busybox)的机器上接入。\n *\n * 本模块只做解析,不执行命令;platform / env / 文件探测均可注入,\n * 便于在 CI(Linux)上覆盖 Windows 分支。\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** shell 家族,决定命令行参数怎么拼 */\nexport type ShellKind = \"sh\" | \"busybox\" | \"powershell\" | \"cmd\" | \"default\";\n\nexport interface ShellSpec {\n kind: ShellKind;\n /** 人类可读标签,用于工具描述 */\n label: string;\n /** 可执行文件路径;null 表示交给 Node 默认(POSIX /bin/sh 或 %ComSpec%) */\n file: string | null;\n /** 拼出实际 argv(含命令本身) */\n buildArgs: (command: string) => string[];\n}\n\nexport interface ResolveShellOptions {\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n /** 判断文件是否存在,便于测试注入 */\n fileExists?: (p: string) => boolean;\n /** 用于定位「产物同目录」的 busybox,默认 process.execPath */\n execPath?: string;\n}\n\nexport interface ProbeContext {\n platform: NodeJS.Platform;\n env: NodeJS.ProcessEnv;\n fileExists: (p: string) => boolean;\n}\n\n/** Windows 可执行文件后缀(按优先级) */\nconst WINDOWS_SUFFIXES = [\".exe\", \".cmd\", \".bat\", \".com\", \"\"];\n\nfunction pathApi(platform: NodeJS.Platform) {\n return platform === \"win32\" ? path.win32 : path.posix;\n}\n\nfunction defaultFileExists(p: string): boolean {\n try {\n return fs.statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** 按目标平台(而非宿主)拼路径 */\nfunction joinPath(platform: NodeJS.Platform, ...parts: string[]): string {\n return pathApi(platform).join(...parts);\n}\n\n/**\n * 在 PATH 上查找可执行文件(同步,不 spawn 进程)。\n * name 含路径分隔符时按路径直接判定。Windows 会按 WINDOWS_SUFFIXES 补后缀。\n */\nexport function findExecutable(name: string, ctx: ProbeContext): string | null {\n if (name.includes(\"/\") || name.includes(\"\\\\\")) {\n return ctx.fileExists(name) ? name : null;\n }\n const suffixes = ctx.platform === \"win32\" ? WINDOWS_SUFFIXES : [\"\"];\n const delimiter = ctx.platform === \"win32\" ? \";\" : \":\";\n const dirs = (ctx.env.PATH ?? \"\").split(delimiter).filter((d) => d.length > 0);\n for (const dir of dirs) {\n for (const suffix of suffixes) {\n const candidate = joinPath(ctx.platform, dir, name + suffix);\n if (ctx.fileExists(candidate)) return candidate;\n }\n }\n return null;\n}\n\n/** 按文件名推断 shell 家族 */\nfunction kindFromBasename(base: string): ShellKind {\n const b = base.toLowerCase().replace(/\\.(exe|cmd|bat|com)$/, \"\");\n if (b === \"busybox\") return \"busybox\";\n if (b === \"powershell\" || b === \"pwsh\") return \"powershell\";\n if (b === \"cmd\") return \"cmd\";\n // sh/bash/dash/zsh/ash 以及不认识的名字(如 busybox 的 sh.exe 符号链接)都按 sh 处理\n return \"sh\";\n}\n\n/**\n * busybox 按 argv[0] 决定 applet:`busybox.exe` 需要显式给 applet 名\n * (`busybox.exe sh -c \"...\"`),而重命名/硬链接出来的 `sh.exe` 本身就是 ash,\n * 多传一个 \"sh\" 会被当成脚本文件名。\n */\nfunction busyboxArgs(file: string | null, command: string): string[] {\n const base = (file ? path.win32.basename(file) : \"busybox\")\n .toLowerCase()\n .replace(/\\.(exe|cmd|bat|com)$/, \"\");\n return base === \"busybox\" ? [\"sh\", \"-c\", command] : [\"-c\", command];\n}\n\nfunction argsFor(kind: ShellKind, command: string): string[] {\n switch (kind) {\n case \"busybox\":\n return [\"sh\", \"-c\", command];\n case \"powershell\":\n return [\"-NoProfile\", \"-NonInteractive\", \"-Command\", command];\n case \"cmd\":\n return [\"/d\", \"/s\", \"/c\", command];\n default:\n return [\"-c\", command];\n }\n}\n\nfunction makeSpec(kind: ShellKind, file: string | null, label: string): ShellSpec {\n return {\n kind,\n file,\n label,\n buildArgs: (command) =>\n kind === \"busybox\" ? busyboxArgs(file, command) : argsFor(kind, command),\n };\n}\n\nfunction defaultLabelFor(kind: ShellKind): string {\n switch (kind) {\n case \"busybox\":\n return \"busybox ash\";\n case \"powershell\":\n return \"PowerShell\";\n case \"cmd\":\n return \"cmd.exe\";\n case \"default\":\n return \"系统默认 shell\";\n default:\n return \"sh\";\n }\n}\n\n/**\n * 查找 BusyBox-w32。\n * 显式 ZQAGENT_BUSYBOX 优先;否则看 CLI 产物同目录及其 bin/ 子目录\n * (兼容 SEA 单文件、npm 安装与桌面 sidecar 三种布局,其中 sh.exe 是\n * busybox.exe 的重命名副本 —— busybox 按 argv[0] 决定 applet)。\n */\nfunction findBusybox(\n ctx: ProbeContext,\n execPath: string,\n): string | null {\n const explicit = (ctx.env.ZQAGENT_BUSYBOX ?? \"\").trim();\n if (explicit) return ctx.fileExists(explicit) ? explicit : null;\n\n const exeDir = pathApi(ctx.platform).dirname(execPath);\n const candidates = [\n joinPath(ctx.platform, exeDir, \"busybox.exe\"),\n joinPath(ctx.platform, exeDir, \"sh.exe\"),\n joinPath(ctx.platform, exeDir, \"bin\", \"busybox.exe\"),\n joinPath(ctx.platform, exeDir, \"bin\", \"sh.exe\"),\n ];\n for (const candidate of candidates) {\n if (ctx.fileExists(candidate)) return candidate;\n }\n return null;\n}\n\n/** 解析 ZQAGENT_SHELL 的显式取值(关键字或路径) */\nfunction resolveRequested(requested: string, ctx: ProbeContext, execPath: string): ShellSpec {\n const lower = requested.toLowerCase();\n\n if (lower === \"cmd\") {\n const file =\n findExecutable(\"cmd\", ctx) ?? ctx.env.ComSpec ?? ctx.env.COMSPEC ?? \"cmd.exe\";\n return makeSpec(\"cmd\", file, \"cmd.exe\");\n }\n if (lower === \"powershell\" || lower === \"pwsh\") {\n const file =\n findExecutable(lower, ctx) ?? findExecutable(\"powershell\", ctx) ?? `${lower}.exe`;\n return makeSpec(\"powershell\", file, \"PowerShell\");\n }\n if (lower === \"busybox\") {\n const found = findBusybox(ctx, execPath) ?? findExecutable(\"busybox\", ctx);\n return makeSpec(\"busybox\", found ?? requested, \"busybox ash\");\n }\n if ([\"sh\", \"bash\", \"dash\", \"zsh\", \"ash\"].includes(lower)) {\n return makeSpec(\"sh\", findExecutable(lower, ctx) ?? lower, lower);\n }\n\n // 视为路径(可能含空格,如 C:\\Program Files\\Git\\bin\\bash.exe)\n const base = pathApi(ctx.platform).basename(requested);\n const kind = kindFromBasename(base);\n return makeSpec(kind, requested, base || defaultLabelFor(kind));\n}\n\n/**\n * 解析当前应使用的 shell。\n * 返回值 file === null 时表示「不显式指定」,由 Node 走平台默认 shell\n * (POSIX /bin/sh / Windows %ComSpec%),即改造前的行为。\n */\nexport function resolveShellSpec(opts: ResolveShellOptions = {}): ShellSpec {\n const platform = opts.platform ?? process.platform;\n const env = opts.env ?? process.env;\n const execPath = opts.execPath ?? process.execPath;\n const ctx: ProbeContext = {\n platform,\n env,\n fileExists: opts.fileExists ?? defaultFileExists,\n };\n\n const requested = (env.ZQAGENT_SHELL ?? \"\").trim();\n if (requested && requested.toLowerCase() !== \"auto\") {\n return resolveRequested(requested, ctx, execPath);\n }\n\n // 非 Windows:保持 Node 默认(不改变既有行为)\n if (platform !== \"win32\") {\n return makeSpec(\"default\", null, \"/bin/sh\");\n }\n\n // Windows:优先 POSIX 风格 shell —— cmd.exe 缺 ls/grep/rm/cat,模型产出的\n // POSIX 命令在它下面几乎全废。\n const busybox = findBusybox(ctx, execPath);\n if (busybox) return makeSpec(\"busybox\", busybox, \"busybox ash (POSIX)\");\n\n const bash = findExecutable(\"bash\", ctx);\n if (bash) return makeSpec(\"sh\", bash, \"bash (Git for Windows)\");\n\n // PowerShell 排在 cmd 之前:它有 ls/cat/rm/cp/mv/pwd 别名,更接近模型习惯\n const shell = findExecutable(\"pwsh\", ctx) ?? findExecutable(\"powershell\", ctx);\n if (shell) return makeSpec(\"powershell\", shell, \"PowerShell\");\n\n return makeSpec(\"default\", null, env.ComSpec ?? env.COMSPEC ?? \"cmd.exe\");\n}\n\n/**\n * 为命令套上「编码设置 + 退出码传播」外壳,按 shell 家族区分。\n *\n * - PowerShell:先设置控制台输出编码为 UTF-8(同一次调用内即对后续命令生效,\n * 规避 `chcp 65001` 要等下一次调用才生效的问题),命令结束后若存在\n * `$LASTEXITCODE` 就以它作为进程退出码 —— 否则 PowerShell 对 `cmd /c ...`\n * 这类原生命令一律返回 0,工具拿到的 exit_code 不可信。\n * - cmd.exe(含 Windows 下未探测到其它 shell 时的 default):`chcp 65001` 切换\n * 代码页,避免中文被压成 `?`。\n * - POSIX sh / busybox:现代环境默认 UTF-8,不改动。\n */\nexport function wrapCommand(\n kind: ShellKind,\n command: string,\n platform: NodeJS.Platform = process.platform,\n): string {\n if (kind === \"powershell\") {\n return (\n \"$OutputEncoding = [Console]::OutputEncoding = [Text.Encoding]::UTF8; \" +\n command +\n \"\\nif ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE }\"\n );\n }\n if (kind === \"cmd\" || (kind === \"default\" && platform === \"win32\")) {\n return `chcp 65001>nul & ${command}`;\n }\n return command;\n}\n\n/** 生成给模型的运行环境提示,追加到 run_shell 描述里 */\nexport function describeShell(spec: ShellSpec, platform: NodeJS.Platform): string {\n if (spec.kind === \"sh\" || spec.kind === \"busybox\") {\n return `当前平台 ${platform},shell=${spec.label}:请使用 POSIX 风格命令。`;\n }\n if (spec.kind === \"powershell\") {\n return (\n `当前平台 ${platform},shell=PowerShell:ls/cat/rm/cp/mv/pwd 等别名可用,` +\n `也可用 cmdlet;路径分隔符为 \"\\\\\"。`\n );\n }\n if (spec.kind === \"default\" && platform !== \"win32\") {\n return `当前平台 ${platform},shell=${spec.label}:请使用 POSIX 风格命令。`;\n }\n return (\n `当前平台 ${platform},shell=${spec.label}:请使用 Windows 命令` +\n `(dir/type/del/copy/move/findstr),多条命令用 & 或 && 连接;` +\n `不要使用 ls/cat/rm/grep 等 POSIX 命令。`\n );\n}\n\n/**\n * 解析命令里的「切目录」意图,返回目录与剩余命令。\n *\n * 识别 POSIX 的 `cd dir`、PowerShell 的 `Set-Location`/`sl`、cmd 的 `cd /d dir`,\n * 以及 `pushd`/`Push-Location`(只跟踪目标目录;popd 的栈语义不在此处理)。\n * 带 `&&` 时(如 `cd /d D:\\x && dir`)只把切目录部分交给 cwd 跟踪,剩余命令\n * 在新目录下执行 —— 否则目录变更只影响那一个子 shell,无法跨调用保持。\n *\n * target 为 null 时调用方应原样执行命令(未识别到切目录意图)。\n */\nexport function parseCdChain(\n command: string,\n opts: { platform?: NodeJS.Platform } = {},\n): { target: string | null; rest: string | null } {\n const platform = opts.platform ?? process.platform;\n const trimmed = command.trim();\n\n const chain = /^([\\s\\S]*?)\\s*&&\\s*([\\s\\S]+)$/.exec(trimmed);\n const head = (chain ? chain[1] : trimmed).trim();\n const rest = chain ? chain[2].trim() : null;\n\n const m = /^(?:cd|set-location|sl|pushd|push-location)\\b\\s*([\\s\\S]*)$/i.exec(head);\n if (!m) return { target: null, rest: null };\n\n let target = m[1].trim();\n // PowerShell 显式参数与 cmd 的盘符切换\n target = target.replace(/^-(?:path|literalpath)\\s+/i, \"\");\n if (platform === \"win32\") target = target.replace(/^\\/d\\s+/i, \"\");\n // 去引号\n target = target.replace(/^\"(.*)\"$/, \"$1\").replace(/^'(.*)'$/, \"$1\").trim();\n\n // 裸 `cd` / `cd -` 不跟踪(无法确定目标目录)\n if (!target || target === \"-\") return { target: null, rest: null };\n return { target, rest };\n}\n"],"mappings":"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","names":[]}