@glodon-aiot/bot-client-sdk 3.25.1-alpha.7 → 3.26.0-alpha.4

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 (70) hide show
  1. package/README.md +543 -98
  2. package/dist/es/AgentSession.mjs +230 -165
  3. package/dist/es/BotClient.mjs +186 -136
  4. package/dist/es/Config.mjs +111 -26
  5. package/dist/es/Session.mjs +12 -0
  6. package/dist/es/api/index.mjs +42 -33
  7. package/dist/es/index.mjs +68 -9
  8. package/dist/es/localFiles/adapters/FileSystemAccessAdapter.mjs +174 -0
  9. package/dist/es/localFiles/adapters/HostBridgeAdapter.mjs +172 -0
  10. package/dist/es/localFiles/adapters/MemoryWorkspaceAdapter.mjs +162 -0
  11. package/dist/es/localFiles/adapters/WorkspaceFileAdapter.mjs +50 -0
  12. package/dist/es/localFiles/adapters/fsaTypes.mjs +9 -0
  13. package/dist/es/localFiles/constants.mjs +47 -0
  14. package/dist/es/localFiles/createLocalFilesPlugin.mjs +255 -0
  15. package/dist/es/localFiles/createLocalPythonPlugin.mjs +196 -0
  16. package/dist/es/localFiles/errors.mjs +57 -0
  17. package/dist/es/localFiles/host/connectHostBridge.mjs +50 -0
  18. package/dist/es/localFiles/host/protocol.mjs +26 -0
  19. package/dist/es/localFiles/limits.mjs +22 -0
  20. package/dist/es/localFiles/schemas.mjs +327 -0
  21. package/dist/es/localFiles/security/downloadUrlPolicy.mjs +39 -0
  22. package/dist/es/localFiles/security/glob.mjs +28 -0
  23. package/dist/es/localFiles/security/pathPolicy.mjs +59 -0
  24. package/dist/es/localFiles/security/sensitiveFiles.mjs +115 -0
  25. package/dist/es/localFiles/tools/readTools.mjs +333 -0
  26. package/dist/es/localFiles/tools/runtime.mjs +108 -0
  27. package/dist/es/localFiles/tools/transferTools.mjs +228 -0
  28. package/dist/es/localFiles/tools/writeTools.mjs +173 -0
  29. package/dist/es/localFiles/transfer/SessionFileTransfer.mjs +111 -0
  30. package/dist/es/localFiles/validate.mjs +66 -0
  31. package/dist/es/localFiles/workspace/LocalWorkspace.mjs +339 -0
  32. package/dist/es/localFiles/workspace/handleStore.mjs +79 -0
  33. package/dist/es/localFiles/workspace/watchDirectory.mjs +38 -0
  34. package/dist/es/package.json.mjs +7 -4
  35. package/dist/lib/index.js +9 -4
  36. package/dist/src/AgentSession.d.ts +9 -0
  37. package/dist/src/BotClient.d.ts +12 -2
  38. package/dist/src/Config.d.ts +22 -0
  39. package/dist/src/Session.d.ts +5 -1
  40. package/dist/src/api/index.d.ts +3 -1
  41. package/dist/src/index.d.ts +4 -2
  42. package/dist/src/localFiles/adapters/FileSystemAccessAdapter.d.ts +17 -0
  43. package/dist/src/localFiles/adapters/HostBridgeAdapter.d.ts +24 -0
  44. package/dist/src/localFiles/adapters/MemoryWorkspaceAdapter.d.ts +18 -0
  45. package/dist/src/localFiles/adapters/WorkspaceFileAdapter.d.ts +26 -0
  46. package/dist/src/localFiles/adapters/fsaTypes.d.ts +39 -0
  47. package/dist/src/localFiles/constants.d.ts +50 -0
  48. package/dist/src/localFiles/createLocalFilesPlugin.d.ts +11 -0
  49. package/dist/src/localFiles/createLocalPythonPlugin.d.ts +12 -0
  50. package/dist/src/localFiles/errors.d.ts +34 -0
  51. package/dist/src/localFiles/host/connectHostBridge.d.ts +6 -0
  52. package/dist/src/localFiles/host/protocol.d.ts +33 -0
  53. package/dist/src/localFiles/index.d.ts +21 -0
  54. package/dist/src/localFiles/limits.d.ts +3 -0
  55. package/dist/src/localFiles/schemas.d.ts +30 -0
  56. package/dist/src/localFiles/security/downloadUrlPolicy.d.ts +4 -0
  57. package/dist/src/localFiles/security/glob.d.ts +3 -0
  58. package/dist/src/localFiles/security/pathPolicy.d.ts +14 -0
  59. package/dist/src/localFiles/security/sensitiveFiles.d.ts +23 -0
  60. package/dist/src/localFiles/tools/readTools.d.ts +7 -0
  61. package/dist/src/localFiles/tools/runtime.d.ts +43 -0
  62. package/dist/src/localFiles/tools/transferTools.d.ts +4 -0
  63. package/dist/src/localFiles/tools/writeTools.d.ts +4 -0
  64. package/dist/src/localFiles/transfer/SessionFileTransfer.d.ts +40 -0
  65. package/dist/src/localFiles/types.d.ts +306 -0
  66. package/dist/src/localFiles/validate.d.ts +2 -0
  67. package/dist/src/localFiles/workspace/LocalWorkspace.d.ts +99 -0
  68. package/dist/src/localFiles/workspace/handleStore.d.ts +11 -0
  69. package/dist/src/localFiles/workspace/watchDirectory.d.ts +7 -0
  70. package/package.json +7 -4
@@ -0,0 +1,50 @@
1
+ var p = (n, e) => {
2
+ if (e = Symbol[n])
3
+ return e;
4
+ throw Error("Symbol." + n + " is not defined");
5
+ };
6
+ var a = function(n, e) {
7
+ this[0] = n, this[1] = e;
8
+ }, s = (n, e, l) => {
9
+ var d = (t, f, r, c) => {
10
+ try {
11
+ var x = l[t](f), E = (f = x.value) instanceof a, g = x.done;
12
+ Promise.resolve(E ? f[0] : f).then((y) => E ? d(t === "return" ? t : "next", f[1] ? { done: y.done, value: y.value } : y, r, c) : r({ value: y, done: g })).catch((y) => d("throw", y, r, c));
13
+ } catch (y) {
14
+ c(y);
15
+ }
16
+ }, o = (t) => i[t] = (f) => new Promise((r, c) => d(t, f, r, c)), i = {};
17
+ return l = l.apply(n, e), i[Symbol.asyncIterator] = () => i, o("next"), o("throw"), o("return"), i;
18
+ }, w = (n) => {
19
+ var e = n[p("asyncIterator")], l = !1, d, o = {};
20
+ return e == null ? (e = n[p("iterator")](), d = (i) => o[i] = (t) => e[i](t)) : (e = e.call(n), d = (i) => o[i] = (t) => {
21
+ if (l) {
22
+ if (l = !1, i === "throw")
23
+ throw t;
24
+ return t;
25
+ }
26
+ return l = !0, {
27
+ done: !1,
28
+ value: new a(new Promise((f) => {
29
+ var r = e[i](t);
30
+ if (!(r instanceof Object))
31
+ throw TypeError("Object expected");
32
+ f(r);
33
+ }), 1)
34
+ };
35
+ }), o[p("iterator")] = () => o, d("next"), "throw" in e ? d("throw") : o.throw = (i) => {
36
+ throw i;
37
+ }, "return" in e && d("return"), o;
38
+ };
39
+ function k(n, e = n) {
40
+ return new DOMException(e, n);
41
+ }
42
+ function A(n) {
43
+ return s(this, null, function* () {
44
+ typeof n == "string" ? yield new TextEncoder().encode(n) : n instanceof Uint8Array ? yield n : yield* w(n);
45
+ });
46
+ }
47
+ export {
48
+ k as domError,
49
+ A as toChunks
50
+ };
@@ -0,0 +1,9 @@
1
+ function e() {
2
+ if (typeof window == "undefined")
3
+ return;
4
+ const i = window.showDirectoryPicker;
5
+ return typeof i == "function" ? i.bind(window) : void 0;
6
+ }
7
+ export {
8
+ e as getNativeDirectoryPicker
9
+ };
@@ -0,0 +1,47 @@
1
+ const s = ["list_directory", "read_file", "stat_file", "search_files", "search_text", "apply_patch", "write_file", "upload_file", "download_file"], _ = "buildin_tools", t = {
2
+ dev: _,
3
+ test: _,
4
+ prod: _,
5
+ local: _
6
+ }, E = t, c = "run_python", I = t, n = 2e4, O = 12e4, L = 16, S = "current-workspace", o = 1024, e = 1024 * 1024, T = 50, A = Object.freeze({
7
+ maxReadBytes: 1 * e,
8
+ maxWriteBytes: 5 * e,
9
+ maxSearchResults: 200,
10
+ maxConcurrentRequests: 4,
11
+ maxTransferBytes: T * e,
12
+ toolTimeoutMs: 3e4,
13
+ searchTimeoutMs: 6e4,
14
+ transferTimeoutMs: 10 * 6e4,
15
+ approvalTimeoutMs: 5 * 6e4
16
+ }), N = 200, C = 1e3, a = 8, l = 16, R = 2e3, r = 1 * e, i = 500, D = 3, F = 8 * o, M = Object.freeze(["glodon.com"]), U = Object.freeze([".git", "node_modules", ".svn", ".idea", ".vscode"]), d = Object.freeze(["~$*", ".~lock*", "*.tmp"]), f = ["apply_patch", "write_file", "upload_file", "download_file"], p = ["search_files", "search_text"], H = ["upload_file", "download_file"];
17
+ export {
18
+ F as BINARY_SNIFF_BYTES,
19
+ _ as BUILTIN_TOOLS_PLUGIN_CODE,
20
+ t as BUILTIN_TOOLS_PLUGIN_CODES,
21
+ M as DEFAULT_DOWNLOAD_URL_ALLOWLIST,
22
+ U as DEFAULT_IGNORED_DIRECTORIES,
23
+ d as DEFAULT_IGNORED_FILE_PATTERNS,
24
+ A as DEFAULT_LIMITS,
25
+ o as KiB,
26
+ N as LIST_DIRECTORY_DEFAULT_LIMIT,
27
+ C as LIST_DIRECTORY_MAX_LIMIT,
28
+ s as LOCAL_FILES_FUNCTION_CODES,
29
+ E as LOCAL_FILES_PLUGIN_CODES,
30
+ c as LOCAL_PYTHON_FUNCTION_CODE,
31
+ I as LOCAL_PYTHON_PLUGIN_CODES,
32
+ e as MiB,
33
+ n as PYTHON_DEFAULT_TIMEOUT_MS,
34
+ L as PYTHON_MAX_ARGS,
35
+ O as PYTHON_MAX_TIMEOUT_MS,
36
+ a as SEARCH_DEFAULT_DEPTH,
37
+ p as SEARCH_FUNCTION_CODES,
38
+ l as SEARCH_MAX_DEPTH,
39
+ D as TEXT_SEARCH_MAX_CONTEXT_LINES,
40
+ R as TEXT_SEARCH_MAX_FILES,
41
+ r as TEXT_SEARCH_MAX_FILE_BYTES,
42
+ i as TEXT_SEARCH_MAX_LINE_CHARS,
43
+ T as TRANSFER_FILE_SIZE_LIMIT_MB,
44
+ H as TRANSFER_FUNCTION_CODES,
45
+ S as WORKSPACE_GRANT_ID,
46
+ f as WRITE_FUNCTION_CODES
47
+ };
@@ -0,0 +1,255 @@
1
+ var J = Object.defineProperty, B = Object.defineProperties;
2
+ var K = Object.getOwnPropertyDescriptors;
3
+ var G = Object.getOwnPropertySymbols;
4
+ var z = Object.prototype.hasOwnProperty, Q = Object.prototype.propertyIsEnumerable;
5
+ var E = (e, t, r) => t in e ? J(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r, u = (e, t) => {
6
+ for (var r in t || (t = {}))
7
+ z.call(t, r) && E(e, r, t[r]);
8
+ if (G)
9
+ for (var r of G(t))
10
+ Q.call(t, r) && E(e, r, t[r]);
11
+ return e;
12
+ }, f = (e, t) => B(e, K(t));
13
+ var _ = (e, t, r) => (E(e, typeof t != "symbol" ? t + "" : t, r), r);
14
+ var F = (e, t, r) => new Promise((d, s) => {
15
+ var o = (a) => {
16
+ try {
17
+ i(r.next(a));
18
+ } catch (c) {
19
+ s(c);
20
+ }
21
+ }, n = (a) => {
22
+ try {
23
+ i(r.throw(a));
24
+ } catch (c) {
25
+ s(c);
26
+ }
27
+ }, i = (a) => a.done ? d(a.value) : Promise.resolve(a.value).then(o, n);
28
+ i((r = r.apply(e, t)).next());
29
+ });
30
+ import { v4 as U } from "uuid";
31
+ import { LOCAL_FILES_FUNCTION_CODES as V, TRANSFER_FUNCTION_CODES as X, SEARCH_FUNCTION_CODES as Y, WORKSPACE_GRANT_ID as Z } from "./constants.mjs";
32
+ import { cancelledError as g, workspaceNotGranted as $, ToolError as h, ToolCode as m, toToolError as k } from "./errors.mjs";
33
+ import { LOCAL_FILE_TOOL_SCHEMAS as ee } from "./schemas.mjs";
34
+ import { assertGrantId as te } from "./security/pathPolicy.mjs";
35
+ import { listDirectory as re, readFile as ie, statFile as ae, searchFiles as oe, searchText as ne } from "./tools/readTools.mjs";
36
+ import { uploadFile as se, downloadFile as le } from "./tools/transferTools.mjs";
37
+ import { applyPatch as de, writeFile as ce } from "./tools/writeTools.mjs";
38
+ import { validateToolInput as ue } from "./validate.mjs";
39
+ const me = {
40
+ list_directory: re,
41
+ read_file: ie,
42
+ stat_file: ae,
43
+ search_files: oe,
44
+ search_text: ne,
45
+ apply_patch: de,
46
+ write_file: ce,
47
+ upload_file: se,
48
+ download_file: le
49
+ };
50
+ class he {
51
+ constructor(t, r) {
52
+ _(this, "remaining");
53
+ _(this, "startedAt", 0);
54
+ _(this, "handle");
55
+ this.onTimeout = r, this.remaining = t;
56
+ }
57
+ resume() {
58
+ this.handle !== void 0 || this.remaining <= 0 || (this.startedAt = Date.now(), this.handle = setTimeout(() => {
59
+ this.handle = void 0, this.remaining = 0, this.onTimeout();
60
+ }, this.remaining));
61
+ }
62
+ pause() {
63
+ this.handle !== void 0 && (clearTimeout(this.handle), this.handle = void 0, this.remaining -= Date.now() - this.startedAt);
64
+ }
65
+ clear() {
66
+ this.pause(), this.remaining = 0;
67
+ }
68
+ }
69
+ function fe(e, t) {
70
+ return X.includes(t) ? e.limits.transferTimeoutMs : Y.includes(t) ? e.limits.searchTimeoutMs : e.limits.toolTimeoutMs;
71
+ }
72
+ function ge(e) {
73
+ if (typeof e != "string")
74
+ return e;
75
+ try {
76
+ return JSON.parse(e);
77
+ } catch (t) {
78
+ throw new h(m.BadRequest, "参数不是合法的 JSON 对象。");
79
+ }
80
+ }
81
+ function pe(e) {
82
+ if (!e || typeof e != "object" || Array.isArray(e))
83
+ return;
84
+ const t = e;
85
+ return (t.grantId === void 0 || t.grantId === null || t.grantId === "") && (t.grantId = Z), t.grantId;
86
+ }
87
+ function W(e) {
88
+ return new Promise((t, r) => {
89
+ e.aborted && r(g()), e.addEventListener("abort", () => r(g()), {
90
+ once: !0
91
+ });
92
+ });
93
+ }
94
+ function ve(e) {
95
+ return u({
96
+ code: e.code,
97
+ message: e.message
98
+ }, e.data ? {
99
+ data: e.data
100
+ } : {});
101
+ }
102
+ function Ie(e, t, r, d, s) {
103
+ return F(this, null, function* () {
104
+ var N, S, q, P, C, D, R, x;
105
+ const o = {
106
+ requestId: s.requestId || U(),
107
+ applicationId: s.applicationId || e.applicationId,
108
+ sessionId: s.sessionId || "",
109
+ pluginCode: s.pluginCode,
110
+ functionCode: t,
111
+ signal: s.signal
112
+ }, n = {
113
+ requestId: o.requestId,
114
+ sessionId: o.sessionId,
115
+ functionCode: t
116
+ }, i = new AbortController();
117
+ let a = !1;
118
+ const c = new he(fe(e, t), () => {
119
+ a = !0, i.abort();
120
+ }), v = () => i.abort();
121
+ (N = o.signal) == null || N.addEventListener("abort", v, {
122
+ once: !0
123
+ }), (S = o.signal) != null && S.aborted && i.abort();
124
+ let p = null, I, L = !1;
125
+ try {
126
+ const b = ge(r), l = pe(b);
127
+ l != null && te(l);
128
+ const w = ue(b, ee[t].parameters), M = (q = w.path) != null ? q : w.destPath;
129
+ if (typeof M == "string" && (n.path = M), yield e.ready, i.signal.aborted)
130
+ throw g();
131
+ const y = e.adapter;
132
+ if (!y)
133
+ throw $();
134
+ if (p = e.acquireSlot(), !p)
135
+ throw new h(m.TooManyRequests, "同时进行的文件操作过多,请稍后重试。");
136
+ I = e.track(i), L = !0, e.emit("tool:start", u({}, n)), c.resume();
137
+ const H = {
138
+ adapter: y,
139
+ workspaceName: (P = e.displayName) != null ? P : y.displayName,
140
+ limits: e.limits,
141
+ sensitive: e.sensitive,
142
+ downloadUrlAllowlist: e.downloadUrlAllowlist,
143
+ allowWorkspaceWideTextSearch: e.allowWorkspaceWideTextSearch,
144
+ transfer: e.transfer,
145
+ fetch: e.fetch,
146
+ context: f(u({}, o), {
147
+ signal: i.signal
148
+ }),
149
+ signal: i.signal,
150
+ requestApproval: (O, j) => be(e, {
151
+ approvalPath: O,
152
+ preview: j,
153
+ context: o,
154
+ functionCode: t,
155
+ signal: i.signal,
156
+ timer: c,
157
+ base: n
158
+ }),
159
+ progress: (O) => e.emit("tool:progress", u(u({}, n), O))
160
+ }, T = yield Promise.race([me[t](w, H), W(i.signal)]), A = {
161
+ code: m.Ok,
162
+ message: "ok",
163
+ data: T.data
164
+ };
165
+ T.truncated && (A.truncated = !0), (C = T.warnings) != null && C.length && (A.warnings = T.warnings), e.emit("tool:finish", f(u({}, n), {
166
+ code: m.Ok
167
+ })), d(A);
168
+ } catch (b) {
169
+ let l = k(b);
170
+ a ? l = new h(m.Timeout, "操作超时,已中止。") : i.signal.aborted && l.code !== m.Cancelled && (l = g()), ((D = l.data) == null ? void 0 : D.reason) === "workspace_not_granted" && L && e.handlePermissionLost(), l.code === m.Cancelled ? e.emit("tool:cancelled", u({}, n)) : e.emit("tool:error", f(u({}, n), {
171
+ code: l.code,
172
+ message: l.message,
173
+ reason: (R = l.data) == null ? void 0 : R.reason
174
+ })), d(ve(l));
175
+ } finally {
176
+ c.clear(), (x = o.signal) == null || x.removeEventListener("abort", v), p == null || p(), I == null || I();
177
+ }
178
+ });
179
+ }
180
+ function be(e, t) {
181
+ return F(this, null, function* () {
182
+ var i;
183
+ const r = e.getApprovalHandler();
184
+ if (!r)
185
+ throw new h(m.Forbidden, "当前环境未提供操作确认能力,无法执行写入或传输操作。", {
186
+ reason: "approval_unavailable"
187
+ });
188
+ if (t.signal.aborted)
189
+ throw g();
190
+ const d = new AbortController(), s = () => d.abort();
191
+ t.signal.addEventListener("abort", s, {
192
+ once: !0
193
+ });
194
+ const o = {
195
+ id: U(),
196
+ requestId: t.context.requestId,
197
+ sessionId: t.context.sessionId,
198
+ functionCode: t.functionCode,
199
+ path: t.approvalPath,
200
+ workspaceName: (i = e.displayName) != null ? i : "",
201
+ preview: t.preview,
202
+ signal: d.signal
203
+ };
204
+ t.timer.pause(), e.emit("tool:approval-required", f(u({}, t.base), {
205
+ path: t.approvalPath,
206
+ approvalId: o.id
207
+ }));
208
+ let n;
209
+ try {
210
+ const a = yield Promise.race([Promise.resolve().then(() => r(o)), W(d.signal), new Promise((c) => {
211
+ n = setTimeout(() => c(!1), e.limits.approvalTimeoutMs);
212
+ })]);
213
+ if (t.signal.aborted)
214
+ throw g();
215
+ if (a !== !0)
216
+ throw new h(m.Forbidden, "用户拒绝了本次操作。", {
217
+ reason: "user_rejected"
218
+ });
219
+ } catch (a) {
220
+ throw a instanceof h ? a : new h(m.Forbidden, "操作确认失败,已取消本次操作。", {
221
+ reason: "user_rejected"
222
+ });
223
+ } finally {
224
+ clearTimeout(n), t.signal.removeEventListener("abort", s), d.abort(), t.timer.resume();
225
+ }
226
+ });
227
+ }
228
+ function Se({
229
+ pluginCode: e,
230
+ workspace: t
231
+ }) {
232
+ const r = {};
233
+ return V.forEach((d) => {
234
+ r[d] = (s, o, n) => {
235
+ let i = !1;
236
+ Ie(t, d, s, (c) => {
237
+ if (!i) {
238
+ i = !0;
239
+ try {
240
+ o(c);
241
+ } catch (v) {
242
+ console.error("[LocalFiles] callback failed", v);
243
+ }
244
+ }
245
+ }, f(u({}, n), {
246
+ pluginCode: e
247
+ }));
248
+ };
249
+ }), {
250
+ [e]: r
251
+ };
252
+ }
253
+ export {
254
+ Se as createLocalFilesPlugin
255
+ };
@@ -0,0 +1,196 @@
1
+ var b = (r, i, a) => new Promise((m, c) => {
2
+ var d = (t) => {
3
+ try {
4
+ u(a.next(t));
5
+ } catch (s) {
6
+ c(s);
7
+ }
8
+ }, e = (t) => {
9
+ try {
10
+ u(a.throw(t));
11
+ } catch (s) {
12
+ c(s);
13
+ }
14
+ }, u = (t) => t.done ? m(t.value) : Promise.resolve(t.value).then(d, e);
15
+ u((a = a.apply(r, i)).next());
16
+ });
17
+ import { v4 as _ } from "uuid";
18
+ import { HostBridgeAdapter as P } from "./adapters/HostBridgeAdapter.mjs";
19
+ import { LOCAL_PYTHON_FUNCTION_CODE as T, WORKSPACE_GRANT_ID as A, PYTHON_MAX_ARGS as R, PYTHON_DEFAULT_TIMEOUT_MS as L } from "./constants.mjs";
20
+ import { ToolError as o, ToolCode as n, cancelledError as w, workspaceNotGranted as O, toToolError as q } from "./errors.mjs";
21
+ import { assertGrantId as F, normalizeWorkspacePath as M } from "./security/pathPolicy.mjs";
22
+ import { validateToolInput as C } from "./validate.mjs";
23
+ const S = /^[\p{L}\p{N}_./:@=+\-,]+$/u, B = {
24
+ type: "object",
25
+ required: ["grantId", "path"],
26
+ properties: {
27
+ grantId: {
28
+ type: "string",
29
+ enum: [A]
30
+ },
31
+ path: {
32
+ type: "string",
33
+ minLength: 1
34
+ },
35
+ args: {
36
+ type: "array",
37
+ items: {
38
+ type: "string",
39
+ minLength: 1
40
+ }
41
+ },
42
+ timeoutMs: {
43
+ type: "integer",
44
+ minimum: 1e3,
45
+ maximum: 12e4
46
+ }
47
+ }
48
+ };
49
+ function G(r) {
50
+ const i = r instanceof DOMException ? r.name : "", a = r instanceof Error ? r.message : "";
51
+ switch (i) {
52
+ case "NotFoundError":
53
+ return new o(n.NotFound, "脚本不存在。");
54
+ case "TypeMismatchError":
55
+ return new o(n.BadRequest, "只能运行 .py 文件。");
56
+ case "SecurityError":
57
+ return new o(n.BadRequest, "脚本路径不合法。");
58
+ case "AbortError":
59
+ return a.includes("已有") ? new o(n.TooManyRequests, "已有一个脚本在沙箱里运行。") : new o(n.Timeout, "脚本运行超时,已中止。");
60
+ default:
61
+ return new o(n.NotImplemented, "当前环境不能运行本地脚本。");
62
+ }
63
+ }
64
+ function j(r, i, a, m, c) {
65
+ return b(this, null, function* () {
66
+ if (!i)
67
+ throw new o(n.Forbidden, "当前环境未提供脚本运行确认,无法执行。", {
68
+ reason: "approval_unavailable"
69
+ });
70
+ if (c.aborted)
71
+ throw w();
72
+ const d = new AbortController(), e = () => d.abort();
73
+ c.addEventListener("abort", e, {
74
+ once: !0
75
+ });
76
+ let u;
77
+ try {
78
+ const t = yield Promise.race([Promise.resolve().then(() => {
79
+ var s;
80
+ return i({
81
+ requestId: m.requestId,
82
+ sessionId: m.sessionId,
83
+ path: a.path,
84
+ args: a.args,
85
+ workspaceName: (s = r.displayName) != null ? s : "",
86
+ signal: d.signal
87
+ });
88
+ }), new Promise((s) => {
89
+ u = setTimeout(() => s(!1), r.limits.approvalTimeoutMs);
90
+ })]);
91
+ if (c.aborted)
92
+ throw w();
93
+ if (t !== !0)
94
+ throw new o(n.Forbidden, "用户拒绝了本次脚本运行。", {
95
+ reason: "user_rejected"
96
+ });
97
+ } catch (t) {
98
+ throw t instanceof o ? t : new o(n.Forbidden, "脚本运行确认失败,已取消本次运行。", {
99
+ reason: "user_rejected"
100
+ });
101
+ } finally {
102
+ clearTimeout(u), c.removeEventListener("abort", e), d.abort();
103
+ }
104
+ });
105
+ }
106
+ function D(r, i, a, m, c) {
107
+ return b(this, null, function* () {
108
+ var u, t, s, g;
109
+ const d = new AbortController(), e = () => d.abort();
110
+ (u = m.signal) == null || u.addEventListener("abort", e);
111
+ try {
112
+ const l = typeof i == "string" ? JSON.parse(i) : i;
113
+ if (l && typeof l == "object" && !Array.isArray(l)) {
114
+ const h = l;
115
+ (h.grantId === void 0 || h.grantId === null || h.grantId === "") && (h.grantId = A);
116
+ }
117
+ const f = C(l, B);
118
+ F(f.grantId);
119
+ const p = M(f.path);
120
+ if (!p.toLowerCase().endsWith(".py"))
121
+ throw new o(n.BadRequest, "只能运行工程内已有的 .py 文件。");
122
+ const y = (t = f.args) != null ? t : [];
123
+ if (y.length > R || y.some((h) => !S.test(h)))
124
+ throw new o(n.BadRequest, "脚本参数不合法。每个参数单独填写,不能包含空格或 shell 语法。");
125
+ const E = r.sensitive.match(p, "read");
126
+ if (E)
127
+ throw new o(n.Forbidden, "该脚本被列为敏感文件,不能运行。", {
128
+ reason: "sensitive_file",
129
+ ruleId: E.id
130
+ });
131
+ if (yield r.ready, d.signal.aborted)
132
+ throw w();
133
+ const I = r.adapter;
134
+ if (!I)
135
+ throw O();
136
+ if (!(I instanceof P))
137
+ throw new o(n.NotImplemented, "当前环境不能运行本地脚本。");
138
+ yield j(r, c, {
139
+ path: p,
140
+ args: y
141
+ }, m, d.signal);
142
+ const v = yield I.runPython(p, y, (s = f.timeoutMs) != null ? s : L, d.signal);
143
+ r.notifyFilesChanged();
144
+ const N = {
145
+ code: n.Ok,
146
+ message: "ok",
147
+ data: v
148
+ };
149
+ a(N);
150
+ } catch (l) {
151
+ const f = d.signal.aborted ? w() : l instanceof SyntaxError ? new o(n.BadRequest, "参数不是合法的 JSON 对象。") : l instanceof o ? l : G(l), p = q(f);
152
+ a({
153
+ code: p.code,
154
+ message: p.message,
155
+ data: p.data
156
+ });
157
+ } finally {
158
+ (g = m.signal) == null || g.removeEventListener("abort", e);
159
+ }
160
+ });
161
+ }
162
+ function X({
163
+ pluginCode: r,
164
+ workspace: i,
165
+ onApprovalRequired: a
166
+ }) {
167
+ const m = (c, d, e) => {
168
+ var s, g, l;
169
+ let u = !1;
170
+ D(i, c, (f) => {
171
+ if (!u) {
172
+ u = !0;
173
+ try {
174
+ d(f);
175
+ } catch (p) {
176
+ console.error("[LocalPython] callback failed", p);
177
+ }
178
+ }
179
+ }, {
180
+ requestId: (s = e == null ? void 0 : e.requestId) != null ? s : _(),
181
+ applicationId: (g = e == null ? void 0 : e.applicationId) != null ? g : i.applicationId,
182
+ sessionId: (l = e == null ? void 0 : e.sessionId) != null ? l : "",
183
+ pluginCode: r,
184
+ functionCode: T,
185
+ signal: e == null ? void 0 : e.signal
186
+ }, a);
187
+ };
188
+ return {
189
+ [r]: {
190
+ [T]: m
191
+ }
192
+ };
193
+ }
194
+ export {
195
+ X as createLocalPythonPlugin
196
+ };
@@ -0,0 +1,57 @@
1
+ var i = Object.defineProperty;
2
+ var E = (r, t, e) => t in r ? i(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var a = (r, t, e) => (E(r, typeof t != "symbol" ? t + "" : t, e), e);
4
+ var f = /* @__PURE__ */ ((r) => (r[r.Ok = 0] = "Ok", r[r.BadRequest = 400] = "BadRequest", r[r.Forbidden = 403] = "Forbidden", r[r.NotFound = 404] = "NotFound", r[r.Timeout = 408] = "Timeout", r[r.Conflict = 409] = "Conflict", r[r.TooLarge = 413] = "TooLarge", r[r.TooManyRequests = 429] = "TooManyRequests", r[r.Cancelled = 499] = "Cancelled", r[r.Internal = 500] = "Internal", r[r.NotImplemented = 501] = "NotImplemented", r))(f || {});
5
+ class n extends Error {
6
+ constructor(e, u, s) {
7
+ super(u);
8
+ a(this, "code");
9
+ a(this, "data");
10
+ this.name = "ToolError", this.code = e, this.data = s;
11
+ }
12
+ }
13
+ const w = "尚未授权工作文件夹,请先在助手中选择或恢复访问工作文件夹。";
14
+ function m() {
15
+ return new n(403, w, {
16
+ reason: "workspace_not_granted"
17
+ });
18
+ }
19
+ function c() {
20
+ return new n(499, "操作已取消。");
21
+ }
22
+ function N(r) {
23
+ if (r != null && r.aborted)
24
+ throw c();
25
+ }
26
+ function o(r) {
27
+ if (r instanceof n)
28
+ return r;
29
+ switch (r && typeof r == "object" && "name" in r ? String(r.name) : "") {
30
+ case "NotFoundError":
31
+ return new n(404, "文件或目录不存在。");
32
+ case "TypeMismatchError":
33
+ return new n(400, "路径类型不匹配:目标是目录而不是文件,或路径中的某一段不是目录。");
34
+ case "NotAllowedError":
35
+ case "SecurityError":
36
+ return m();
37
+ case "AbortError":
38
+ return c();
39
+ case "NoModificationAllowedError":
40
+ case "InvalidModificationError":
41
+ case "InvalidStateError":
42
+ return new n(403, "文件当前不可写,可能正被其他程序占用或为只读。");
43
+ case "QuotaExceededError":
44
+ return new n(413, "磁盘空间不足或超出写入配额。");
45
+ default:
46
+ return new n(500, "本地文件操作失败,请稍后重试。");
47
+ }
48
+ }
49
+ export {
50
+ f as ToolCode,
51
+ n as ToolError,
52
+ w as WORKSPACE_NOT_GRANTED_MESSAGE,
53
+ c as cancelledError,
54
+ N as throwIfAborted,
55
+ o as toToolError,
56
+ m as workspaceNotGranted
57
+ };
@@ -0,0 +1,50 @@
1
+ import { HostBridgeAdapter as f } from "../adapters/HostBridgeAdapter.mjs";
2
+ import { getHostWebView as m, HOST_CHANNEL as g, parseHostMessage as y } from "./protocol.mjs";
3
+ let t;
4
+ function c(s) {
5
+ t == null || t(), t = void 0;
6
+ const i = m();
7
+ if (!i)
8
+ return () => {
9
+ };
10
+ const n = new f(i), d = (p) => {
11
+ const e = y(p.data);
12
+ if (e) {
13
+ if (e.type === "workspace") {
14
+ const r = e.granted === !0, o = typeof e.displayName == "string" ? e.displayName : "";
15
+ r ? (n.displayName = o || "工程目录", (s.status !== "granted" || s.displayName !== n.displayName) && s.attachAdapter(n, n.displayName)) : s.status === "granted" && s.clear();
16
+ return;
17
+ }
18
+ if (e.type === "fs-changed") {
19
+ const r = Array.isArray(e.paths) ? e.paths.filter((o) => typeof o == "string") : [];
20
+ s.notifyFilesChanged(r);
21
+ return;
22
+ }
23
+ typeof e.id == "string" && n.settle({
24
+ channel: g,
25
+ id: e.id,
26
+ ok: e.ok !== !1,
27
+ name: typeof e.name == "string" ? e.name : void 0,
28
+ entries: e.entries,
29
+ entry: e.entry,
30
+ contentBase64: typeof e.contentBase64 == "string" ? e.contentBase64 : void 0,
31
+ exitCode: typeof e.exitCode == "number" ? e.exitCode : void 0,
32
+ timedOut: e.timedOut === !0,
33
+ stdout: typeof e.stdout == "string" ? e.stdout : void 0,
34
+ stderr: typeof e.stderr == "string" ? e.stderr : void 0,
35
+ message: typeof e.message == "string" ? e.message : void 0
36
+ });
37
+ }
38
+ };
39
+ i.addEventListener("message", d), i.postMessage({
40
+ channel: g,
41
+ type: "hello"
42
+ });
43
+ const a = () => {
44
+ i.removeEventListener("message", d), t === a && (t = void 0);
45
+ };
46
+ return t = a, a;
47
+ }
48
+ export {
49
+ c as connectHostBridge
50
+ };
@@ -0,0 +1,26 @@
1
+ const n = "glodon-workspace";
2
+ function i(t) {
3
+ let e = t;
4
+ if (typeof e == "string")
5
+ try {
6
+ e = JSON.parse(e);
7
+ } catch (r) {
8
+ return;
9
+ }
10
+ if (!e || typeof e != "object")
11
+ return;
12
+ const o = e;
13
+ if (o.channel === n)
14
+ return o;
15
+ }
16
+ function s() {
17
+ var e;
18
+ const t = (e = globalThis.chrome) == null ? void 0 : e.webview;
19
+ if (!(!t || typeof t.postMessage != "function" || typeof t.addEventListener != "function"))
20
+ return t;
21
+ }
22
+ export {
23
+ n as HOST_CHANNEL,
24
+ s as getHostWebView,
25
+ i as parseHostMessage
26
+ };