@thinkingai/ae-cli 1.0.22 → 1.0.27

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 (56) hide show
  1. package/README.md +39 -1
  2. package/README.zh.md +40 -1
  3. package/dist/{auth-YM7OI23X.js → auth-TXFJHPXU.js} +3 -2
  4. package/dist/{auth-5S7SPPEJ.js → auth-W2JZ3DKA.js} +11 -4
  5. package/dist/{chunk-MPFTXJFG.js → chunk-2NGWYMLB.js} +14 -2
  6. package/dist/chunk-6T7245YE.js +478 -0
  7. package/dist/{chunk-KM57HI5B.js → chunk-B4UL2VIJ.js} +7 -1
  8. package/dist/{chunk-TMMUBSKW.js → chunk-BI5ZVD6T.js} +8 -1
  9. package/dist/chunk-MNHE6SSI.js +79 -0
  10. package/dist/chunk-MWWYGZ76.js +130 -0
  11. package/dist/{chunk-24ZKQWG2.js → chunk-SRRUNQIM.js} +51 -4
  12. package/dist/chunk-TG64AQV4.js +262 -0
  13. package/dist/{chunk-NBFTPIAH.js → chunk-VT6VC4PA.js} +15 -4
  14. package/dist/{client-7S23DVHH.js → client-IU2E5IOL.js} +6 -3
  15. package/dist/{config-RVUESJRF.js → config-WH3R3IRY.js} +3 -2
  16. package/dist/index.js +195 -20
  17. package/dist/model-CC7U5XOJ.js +131 -0
  18. package/dist/{raw-5SYAUCJQ.js → raw-TUHZQ4UB.js} +5 -4
  19. package/dist/sync-EVEDS7YE.js +383 -0
  20. package/dist/te-agent-FLTDYV3L.js +522 -0
  21. package/dist/{te-analysis-RQST6AT3.js → te-analysis-CMXADIJM.js} +101 -12
  22. package/dist/{te-audience-TJ74UJI3.js → te-audience-LPZFFSXM.js} +4 -3
  23. package/dist/{te-common-W5URM2SH.js → te-common-BXQFKTB3.js} +4 -3
  24. package/dist/{te-community-YRV2VAD4.js → te-community-K5S3VOZY.js} +4 -3
  25. package/dist/{te-dataops-ZPH72BCK.js → te-dataops-567IMCQG.js} +4 -3
  26. package/dist/{te-engage-57UKFV74.js → te-engage-TBUTGW5F.js} +105 -49
  27. package/dist/{te-kb-GD7SJRYB.js → te-kb-XHVBWP5E.js} +227 -38
  28. package/dist/{te-meta-25SLZFXJ.js → te-meta-NQ4U3VJW.js} +25 -4
  29. package/dist/te-team-556APRIU.js +529 -0
  30. package/package.json +6 -1
  31. package/skills/ae-agent/SKILL.md +133 -0
  32. package/skills/ae-analysis/references/create_entity.md +39 -0
  33. package/skills/ae-analysis/references/create_space.md +34 -0
  34. package/skills/ae-analysis/references/drilldown_user_events.md +1 -1
  35. package/skills/ae-analysis/references/drilldown_users.md +2 -2
  36. package/skills/ae-analysis/references/query_adhoc.md +3 -2
  37. package/skills/ae-analysis/references/query_entity_details.md +1 -1
  38. package/skills/ae-engage/SKILL.md +25 -2
  39. package/skills/ae-engage/references/build-task-save-guide.md +283 -0
  40. package/skills/ae-engage/references/save-task.md +304 -0
  41. package/skills/ae-kb/SKILL.md +283 -0
  42. package/skills/ae-team/SKILL.md +164 -0
  43. package/skills/ae-team/references/ai-generate.md +39 -0
  44. package/skills/ae-team/references/create.md +94 -0
  45. package/skills/ae-team/references/delete.md +39 -0
  46. package/skills/ae-team/references/list-projects.md +45 -0
  47. package/skills/ae-team/references/list-templates.md +38 -0
  48. package/skills/ae-team/references/list.md +39 -0
  49. package/skills/ae-team/references/run-artifacts.md +51 -0
  50. package/skills/ae-team/references/run-cancel.md +38 -0
  51. package/skills/ae-team/references/run-chat.md +57 -0
  52. package/skills/ae-team/references/run-reply.md +41 -0
  53. package/skills/ae-team/references/run-result.md +75 -0
  54. package/skills/ae-team/references/run-start.md +73 -0
  55. package/skills/ae-team/references/run-watch.md +82 -0
  56. package/skills/ae-team/references/update.md +47 -0
@@ -0,0 +1,130 @@
1
+ import {
2
+ loadMcpTokenStore
3
+ } from "./chunk-2NGWYMLB.js";
4
+ import {
5
+ forceMigrateFromFallback,
6
+ safeJsonParse
7
+ } from "./chunk-BI5ZVD6T.js";
8
+ import {
9
+ logger
10
+ } from "./chunk-MNHE6SSI.js";
11
+
12
+ // src/core/mcp-access.ts
13
+ function buildUrl(host, path, params = {}) {
14
+ const base = host.replace(/\/$/, "");
15
+ const p = path.startsWith("/") ? path : `/${path}`;
16
+ const url = new URL(`${base}${p}`);
17
+ for (const [key, value] of Object.entries(params)) {
18
+ if (value !== void 0 && value !== null) {
19
+ url.searchParams.set(key, String(value));
20
+ }
21
+ }
22
+ return url.toString();
23
+ }
24
+ function getMcpTokenForHost(host) {
25
+ const store = loadMcpTokenStore();
26
+ const normalizedHost = host.replace(/\/+$/, "");
27
+ if (store[host]) return store[host];
28
+ if (store[normalizedHost]) return store[normalizedHost];
29
+ for (const [key, token] of Object.entries(store)) {
30
+ if (key.replace(/\/+$/, "") === normalizedHost) {
31
+ return token;
32
+ }
33
+ }
34
+ return void 0;
35
+ }
36
+ function getTokenFromStore(store, host) {
37
+ const normalizedHost = host.replace(/\/+$/, "");
38
+ if (store[host]) return store[host];
39
+ if (store[normalizedHost]) return store[normalizedHost];
40
+ for (const [key, token] of Object.entries(store)) {
41
+ if (key.replace(/\/+$/, "") === normalizedHost) {
42
+ return token;
43
+ }
44
+ }
45
+ return void 0;
46
+ }
47
+ function refreshMcpTokenFromFallback(host) {
48
+ logger.warn(`KB MCP request failed for ${host}, trying fallback`);
49
+ const migrated = forceMigrateFromFallback();
50
+ const token = migrated ? getTokenFromStore(migrated, host) : void 0;
51
+ if (token) {
52
+ logger.info(`KB MCP token refreshed from fallback for ${host}`);
53
+ process.stderr.write(`[ae-cli] MCP token refreshed from fallback for ${host}
54
+ `);
55
+ }
56
+ return token;
57
+ }
58
+ function isMcpAuthFailure(resp, data) {
59
+ return !resp.ok || data.return_code === -1001;
60
+ }
61
+ function parseKbResponse(resp, text) {
62
+ if (resp.status === 401 || resp.status === 403) {
63
+ throw new Error(`KB MCP token auth failed: HTTP ${resp.status} ${resp.statusText}`);
64
+ }
65
+ const data = safeJsonParse(text);
66
+ if (data.return_code === -1001) {
67
+ throw new Error(`KB MCP token auth failed: ${data.return_message || "unauthorized"} (code: ${data.return_code})`);
68
+ }
69
+ if (data.return_code !== 0 && data.return_code !== void 0) {
70
+ throw new Error(`AE API error: ${data.return_message || "unknown"} (code: ${data.return_code})`);
71
+ }
72
+ return data.data !== void 0 ? data.data : data;
73
+ }
74
+ async function fetchWithMcpToken(host, input, init, mcpToken) {
75
+ const headers = new Headers(init.headers);
76
+ headers.set("mcp-token", mcpToken);
77
+ const resp = await fetch(input, { ...init, headers });
78
+ const text = await resp.text();
79
+ if (!resp.ok) {
80
+ const refreshedToken = refreshMcpTokenFromFallback(host);
81
+ if (refreshedToken) {
82
+ headers.set("mcp-token", refreshedToken);
83
+ const retryResp = await fetch(input, { ...init, headers });
84
+ return parseKbResponse(retryResp, await retryResp.text());
85
+ }
86
+ return parseKbResponse(resp, text);
87
+ }
88
+ const data = safeJsonParse(text);
89
+ if (isMcpAuthFailure(resp, data)) {
90
+ const refreshedToken = refreshMcpTokenFromFallback(host);
91
+ if (refreshedToken) {
92
+ headers.set("mcp-token", refreshedToken);
93
+ const retryResp = await fetch(input, { ...init, headers });
94
+ return parseKbResponse(retryResp, await retryResp.text());
95
+ }
96
+ }
97
+ return parseKbResponse(resp, text);
98
+ }
99
+ async function kbApi(ctx, method, path, params = {}, body) {
100
+ const host = ctx.host();
101
+ const mcpToken = getMcpTokenForHost(host);
102
+ if (!mcpToken) {
103
+ return ctx.api(method, path, params, body);
104
+ }
105
+ const upperMethod = method.toUpperCase();
106
+ return fetchWithMcpToken(host, buildUrl(host, path, params), {
107
+ method: upperMethod,
108
+ headers: {
109
+ "Content-Type": "application/json"
110
+ },
111
+ body: upperMethod === "GET" ? void 0 : JSON.stringify(body ?? {})
112
+ }, mcpToken);
113
+ }
114
+ async function kbUpload(ctx, path, form, params = {}) {
115
+ const host = ctx.host();
116
+ const mcpToken = getMcpTokenForHost(host);
117
+ if (!mcpToken) {
118
+ const { httpUpload } = await import("./client-IU2E5IOL.js");
119
+ return httpUpload(path, form, params, host);
120
+ }
121
+ return fetchWithMcpToken(host, buildUrl(host, path, params), {
122
+ method: "POST",
123
+ body: form
124
+ }, mcpToken);
125
+ }
126
+
127
+ export {
128
+ kbApi,
129
+ kbUpload
130
+ };
@@ -4,13 +4,17 @@ import {
4
4
  getConfigDir,
5
5
  safeJsonParse,
6
6
  safeReadJsonFile
7
- } from "./chunk-TMMUBSKW.js";
7
+ } from "./chunk-BI5ZVD6T.js";
8
+ import {
9
+ logger
10
+ } from "./chunk-MNHE6SSI.js";
8
11
 
9
12
  // src/core/auth.ts
10
13
  import fs from "fs";
11
14
  import path from "path";
12
15
  import { execFileSync } from "child_process";
13
16
  var TOKENS_FILE = path.join(getConfigDir(), "tokens.json");
17
+ var MCP_TOKENS_FILE = path.join(getConfigDir(), "mcp-tokens.json");
14
18
  var LEGACY_DIR = path.join(process.env.HOME || "", ".te-mcp");
15
19
  var TOKEN_TTL_MS = 20 * 60 * 60 * 1e3;
16
20
  var OSASCRIPT_POLL_INTERVAL_MS = 2e3;
@@ -90,6 +94,7 @@ function saveToken(token, hostUrl) {
90
94
  const tokens = loadAllTokens();
91
95
  tokens[hostUrl] = { token, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
92
96
  saveAllTokens(tokens);
97
+ logger.info(`Token saved for ${hostUrl}`);
93
98
  }
94
99
  function clearToken(hostUrl) {
95
100
  const tokens = loadAllTokens();
@@ -111,6 +116,23 @@ function getAuthStatus(hostUrl) {
111
116
  }
112
117
  return { authenticated: false, host: hostUrl };
113
118
  }
119
+ function getCachedMcpToken(hostUrl) {
120
+ try {
121
+ if (!fs.existsSync(MCP_TOKENS_FILE)) return void 0;
122
+ const store = safeReadJsonFile(MCP_TOKENS_FILE);
123
+ const normalizedHost = hostUrl.replace(/\/+$/, "");
124
+ if (store[hostUrl]) return store[hostUrl];
125
+ if (store[normalizedHost]) return store[normalizedHost];
126
+ for (const [key, token] of Object.entries(store)) {
127
+ if (key.replace(/\/+$/, "") === normalizedHost) {
128
+ return token;
129
+ }
130
+ }
131
+ return void 0;
132
+ } catch {
133
+ return void 0;
134
+ }
135
+ }
114
136
  function extractTokenViaOsascript(hostUrl) {
115
137
  if (process.platform !== "darwin") return { token: null, error: "not_mac" };
116
138
  const hostname = extractHostname(hostUrl);
@@ -172,6 +194,7 @@ function extractTokenFromAllTabs() {
172
194
  }
173
195
  }
174
196
  async function requestTokenViaOsascript(hostUrl) {
197
+ logger.info(`Opening Chrome to ${hostUrl} for token extraction`);
175
198
  process.stderr.write(`[ae-cli] No AE tab found in Chrome. Opening ${hostUrl} ...
176
199
  `);
177
200
  process.stderr.write(`[ae-cli] Please login, then your token will be captured automatically.
@@ -189,24 +212,36 @@ async function requestTokenViaOsascript(hostUrl) {
189
212
  ];
190
213
  execFileSync("osascript", openScript.flatMap((line) => ["-e", line]), { timeout: 5e3 });
191
214
  } catch {
215
+ logger.warn(`Failed to open Chrome, user may need to open ${hostUrl} manually`);
192
216
  process.stderr.write(`[ae-cli] Could not open browser. Please open ${hostUrl} in Chrome manually.
193
217
  `);
194
218
  }
195
219
  const deadline = Date.now() + OSASCRIPT_POLL_TIMEOUT_MS;
220
+ let pollCount = 0;
196
221
  while (Date.now() < deadline) {
197
222
  await new Promise((r) => setTimeout(r, OSASCRIPT_POLL_INTERVAL_MS));
223
+ pollCount++;
198
224
  let result = extractTokenViaOsascript(hostUrl);
199
225
  if (result.error === "no_tab") {
200
226
  const fallback = extractTokenFromAllTabs();
201
- if (fallback.token) result = fallback;
227
+ if (fallback.token) {
228
+ logger.info("Token captured via all-tabs fallback search");
229
+ result = fallback;
230
+ }
202
231
  }
203
232
  if (result.token) {
233
+ saveToken(result.token, hostUrl);
234
+ logger.info(`Token captured after ${pollCount} poll(s)`);
204
235
  process.stderr.write(`[ae-cli] Token captured from Chrome for ${hostUrl}.
205
236
  `);
206
237
  return result.token;
207
238
  }
208
- if (result.error === "no_js_permission") return null;
239
+ if (result.error === "no_js_permission") {
240
+ logger.warn("Chrome JS permission denied during polling");
241
+ return null;
242
+ }
209
243
  }
244
+ logger.warn(`Token polling timed out after ${OSASCRIPT_POLL_TIMEOUT_MS / 1e3}s (${pollCount} polls)`);
210
245
  process.stderr.write(`[ae-cli] Polling timed out after ${OSASCRIPT_POLL_TIMEOUT_MS / 1e3}s.
211
246
  `);
212
247
  return null;
@@ -219,12 +254,24 @@ Run: ae-cli config set-host`
219
254
  );
220
255
  }
221
256
  if (process.env.TE_TOKEN) {
257
+ logger.info("Using token from env:TE_TOKEN");
222
258
  return process.env.TE_TOKEN;
223
259
  }
224
260
  const cached = loadToken(hostUrl);
225
- if (cached && cached.token) return cached.token;
261
+ if (cached && cached.token) {
262
+ logger.info(`Using cached token for ${hostUrl}`);
263
+ return cached.token;
264
+ }
265
+ if (getCachedMcpToken(hostUrl)) {
266
+ logger.info(`MCP token exists for ${hostUrl}; skipping browser token extraction`);
267
+ throw new Error(
268
+ `MCP token already exists for ${hostUrl}; skipped browser login.
269
+ Use an MCP-token aware command, or run: ae-cli auth set-token <token>`
270
+ );
271
+ }
226
272
  const { token: osascriptToken, error } = extractTokenViaOsascript(hostUrl);
227
273
  if (error === "no_js_permission") {
274
+ logger.warn("Chrome JS Apple Events not enabled");
228
275
  throw new Error(
229
276
  `Chrome JavaScript from Apple Events is not enabled.
230
277
  Enable it: Chrome menu \u2192 View \u2192 Developer \u2192 Allow JavaScript from Apple Events`
@@ -0,0 +1,262 @@
1
+ // src/core/te-agent-credentials.ts
2
+ import { readFileSync } from "fs";
3
+ import { homedir } from "os";
4
+ import { join } from "path";
5
+ function getCredentialsPath() {
6
+ return join(process.env.HOME || homedir(), ".te-agent", "credentials.json");
7
+ }
8
+ function getPersistentEnvPath() {
9
+ const runtimeRoot = process.env.SANDBOX_RUNTIME_ROOT ?? "/home/ta/te_agent_ta";
10
+ return join(runtimeRoot, ".env");
11
+ }
12
+ function parseDotEnv(raw) {
13
+ const result = {};
14
+ for (const line of raw.split("\n")) {
15
+ if (/^\s*#/.test(line) || line.trim() === "") continue;
16
+ const match = /^\s*([^=]+)=(.*)$/.exec(line);
17
+ if (!match) continue;
18
+ const key = match[1].trim();
19
+ let value = match[2].trim();
20
+ if (value.startsWith('"') && value.endsWith('"')) {
21
+ value = value.slice(1, -1).replace(/\\"/g, '"');
22
+ }
23
+ if (value !== "") result[key] = value;
24
+ }
25
+ return result;
26
+ }
27
+ function readPersistentEnv() {
28
+ const envPath = getPersistentEnvPath();
29
+ try {
30
+ const raw = readFileSync(envPath, "utf8");
31
+ return parseDotEnv(raw);
32
+ } catch (err) {
33
+ if (err?.code === "ENOENT") return null;
34
+ throw new TeAgentCredentialsError(
35
+ `${envPath} \u8BFB\u53D6\u5931\u8D25\uFF1A${err?.message ?? err}`,
36
+ "\u8BF7\u68C0\u67E5\u6587\u4EF6\u6743\u9650\uFF0C\u6216\u901A\u8FC7 TE_CLAUDE_BASE_URL / SANDBOX_ID / SECRET_KEY \u6CE8\u5165\u8FD0\u884C\u65F6\u51ED\u8BC1"
37
+ );
38
+ }
39
+ }
40
+ var TeAgentCredentialsError = class extends Error {
41
+ constructor(message, hint) {
42
+ super(message);
43
+ this.hint = hint;
44
+ this.name = "TeAgentCredentialsError";
45
+ }
46
+ hint;
47
+ };
48
+ function readLegacyCredentials() {
49
+ const credPath = getCredentialsPath();
50
+ try {
51
+ const raw = readFileSync(credPath, "utf8");
52
+ const parsed = JSON.parse(raw);
53
+ const main = parsed?.mainApp;
54
+ return main && typeof main === "object" ? main : null;
55
+ } catch (err) {
56
+ if (err?.code === "ENOENT") return null;
57
+ if (err instanceof SyntaxError) {
58
+ throw new TeAgentCredentialsError(
59
+ `${credPath} \u89E3\u6790\u5931\u8D25\uFF1A${err.message}`,
60
+ "\u51ED\u8BC1\u6587\u4EF6\u53EF\u80FD\u5DF2\u635F\u574F\uFF1B\u4E5F\u53EF\u4EE5\u901A\u8FC7 TE_CLAUDE_BASE_URL / SANDBOX_ID / SECRET_KEY \u6CE8\u5165\u8FD0\u884C\u65F6\u51ED\u8BC1"
61
+ );
62
+ }
63
+ throw new TeAgentCredentialsError(
64
+ `${credPath} \u8BFB\u53D6\u5931\u8D25\uFF1A${err?.message ?? err}`,
65
+ "\u8BF7\u68C0\u67E5\u6587\u4EF6\u6743\u9650\uFF0C\u6216\u901A\u8FC7 TE_CLAUDE_BASE_URL / SANDBOX_ID / SECRET_KEY \u6CE8\u5165\u8FD0\u884C\u65F6\u51ED\u8BC1"
66
+ );
67
+ }
68
+ }
69
+ function loadTeAgentCredentials() {
70
+ const legacy = readLegacyCredentials();
71
+ const credPath = getCredentialsPath();
72
+ const envPath = getPersistentEnvPath();
73
+ const persistent = readPersistentEnv();
74
+ const url = process.env.TE_CLAUDE_BASE_URL || persistent?.TE_CLAUDE_BASE_URL || legacy?.url;
75
+ const sandboxId = process.env.SANDBOX_ID || persistent?.SANDBOX_ID || legacy?.sandboxId;
76
+ const sandboxSecretKey = process.env.SECRET_KEY || process.env.SANDBOX_SECRET_KEY || persistent?.SECRET_KEY || persistent?.SANDBOX_SECRET_KEY || legacy?.sandboxSecretKey || legacy?.secretKey;
77
+ if (typeof url !== "string" || !url) {
78
+ throw new TeAgentCredentialsError(
79
+ "TE_CLAUDE_BASE_URL \u7F3A\u5931",
80
+ `\u8BF7\u5728 te-agent \u6C99\u7BB1\u5185\u6267\u884C\uFF0C\u6216\u914D\u7F6E ${envPath} / ${credPath}`
81
+ );
82
+ }
83
+ if (typeof sandboxId !== "string" || !sandboxId) {
84
+ throw new TeAgentCredentialsError(
85
+ "SANDBOX_ID \u7F3A\u5931",
86
+ `\u8BF7\u5728 te-agent \u6C99\u7BB1\u5185\u6267\u884C\uFF0C\u6216\u914D\u7F6E ${envPath} / ${credPath}`
87
+ );
88
+ }
89
+ if (typeof sandboxSecretKey !== "string" || !sandboxSecretKey) {
90
+ throw new TeAgentCredentialsError(
91
+ "SECRET_KEY \u7F3A\u5931",
92
+ `\u8BF7\u5728 te-agent \u6C99\u7BB1\u5185\u6267\u884C\uFF0C\u6216\u914D\u7F6E ${envPath} / ${credPath}`
93
+ );
94
+ }
95
+ return { mainApp: { url, sandboxId, sandboxSecretKey } };
96
+ }
97
+ function getClaudeConfigDir() {
98
+ const fromEnv = process.env.CLAUDE_CONFIG_DIR;
99
+ if (typeof fromEnv === "string" && fromEnv.length > 0) {
100
+ return fromEnv;
101
+ }
102
+ return join(homedir(), ".claude");
103
+ }
104
+
105
+ // src/core/te-agent-client.ts
106
+ var TeAgentApiError = class extends Error {
107
+ constructor(message, status, code, body) {
108
+ super(message);
109
+ this.status = status;
110
+ this.code = code;
111
+ this.body = body;
112
+ this.name = "TeAgentApiError";
113
+ }
114
+ status;
115
+ code;
116
+ body;
117
+ };
118
+ var DEFAULT_TIMEOUT_MS = 3e4;
119
+ var UPLOAD_TIMEOUT_MS = 12e4;
120
+ async function fetchWithTimeout(url, init, timeoutMs = DEFAULT_TIMEOUT_MS) {
121
+ const controller = new AbortController();
122
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
123
+ try {
124
+ return await fetch(url, { ...init, signal: controller.signal });
125
+ } catch (err) {
126
+ if (err?.name === "AbortError") {
127
+ throw new TeAgentApiError(`\u8BF7\u6C42\u8D85\u65F6\uFF08${timeoutMs}ms\uFF09\uFF1A${url}`, 0, "TIMEOUT");
128
+ }
129
+ throw new TeAgentApiError(`\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A${err?.message ?? err}`, 0, "NETWORK_ERROR");
130
+ } finally {
131
+ clearTimeout(timer);
132
+ }
133
+ }
134
+ function signRequest(method, path, rawBody) {
135
+ const cred = loadTeAgentCredentials();
136
+ const { url: baseUrl, sandboxId, sandboxSecretKey } = cred.mainApp;
137
+ const headers = {
138
+ "X-Sandbox-Id": sandboxId,
139
+ "X-Sandbox-Secret-Key": sandboxSecretKey
140
+ };
141
+ if (method === "POST" || method === "PATCH") {
142
+ headers["Content-Type"] = "application/json";
143
+ }
144
+ return {
145
+ url: `${baseUrl.replace(/\/$/, "")}${path}`,
146
+ headers,
147
+ rawBody
148
+ };
149
+ }
150
+ async function parseResponse(response, defaultErrorPrefix) {
151
+ const text = await response.text();
152
+ let parsed = void 0;
153
+ if (text) {
154
+ try {
155
+ parsed = JSON.parse(text);
156
+ } catch {
157
+ parsed = text;
158
+ }
159
+ }
160
+ if (!response.ok) {
161
+ const message = typeof parsed === "object" && parsed && typeof parsed.error === "string" ? parsed.error : `${defaultErrorPrefix} ${response.status}`;
162
+ const code = typeof parsed === "object" && parsed && typeof parsed.code === "string" ? parsed.code : void 0;
163
+ throw new TeAgentApiError(message, response.status, code, parsed);
164
+ }
165
+ return parsed;
166
+ }
167
+ async function postToMainApp(path, body) {
168
+ const rawBody = JSON.stringify(body);
169
+ const signed = signRequest("POST", path, rawBody);
170
+ const response = await fetchWithTimeout(signed.url, {
171
+ method: "POST",
172
+ headers: signed.headers,
173
+ body: signed.rawBody
174
+ });
175
+ return parseResponse(response, "\u4E3B\u5E94\u7528\u8FD4\u56DE");
176
+ }
177
+ async function getFromMainApp(path) {
178
+ const signed = signRequest("GET", path, "");
179
+ const response = await fetchWithTimeout(signed.url, {
180
+ method: "GET",
181
+ headers: signed.headers
182
+ });
183
+ return parseResponse(response, "\u4E3B\u5E94\u7528\u8FD4\u56DE");
184
+ }
185
+ async function getSandboxModels(currentModelId) {
186
+ const qs = currentModelId ? `?current=${encodeURIComponent(currentModelId)}` : "";
187
+ const data = await getFromMainApp(`/api/sandbox/models${qs}`);
188
+ return Array.isArray(data?.models) ? data.models : [];
189
+ }
190
+ async function postSandboxModelSelection(args) {
191
+ return postToMainApp("/api/sandbox/models/select", args);
192
+ }
193
+ async function getSandboxSyncPullCandidates(args) {
194
+ const qs = new URLSearchParams({
195
+ workspacePath: args.workspacePath,
196
+ kind: args.kind
197
+ });
198
+ return getFromMainApp(
199
+ `/api/sandbox/sync/pull/candidates?${qs.toString()}`
200
+ );
201
+ }
202
+ async function postSandboxSyncPull(args) {
203
+ return postToMainApp("/api/sandbox/sync/pull", {
204
+ workspacePath: args.workspacePath,
205
+ kind: args.kind,
206
+ skills: args.skills,
207
+ mcp: args.mcp,
208
+ mode: "merge",
209
+ ifUnmodifiedSince: args.ifUnmodifiedSince
210
+ });
211
+ }
212
+ async function deleteFromMainApp(path) {
213
+ const signed = signRequest("DELETE", path, "");
214
+ const response = await fetchWithTimeout(signed.url, {
215
+ method: "DELETE",
216
+ headers: signed.headers
217
+ });
218
+ return parseResponse(response, "\u4E3B\u5E94\u7528\u8FD4\u56DE");
219
+ }
220
+ async function patchToMainApp(path, body) {
221
+ const rawBody = JSON.stringify(body);
222
+ const signed = signRequest("PATCH", path, rawBody);
223
+ const response = await fetchWithTimeout(signed.url, {
224
+ method: "PATCH",
225
+ headers: signed.headers,
226
+ body: signed.rawBody
227
+ });
228
+ return parseResponse(response, "\u4E3B\u5E94\u7528\u8FD4\u56DE");
229
+ }
230
+ async function uploadToMainApp(path, formData) {
231
+ const cred = loadTeAgentCredentials();
232
+ const baseUrl = cred.mainApp.url.replace(/\/$/, "");
233
+ const url = `${baseUrl}${path}`;
234
+ const response = await fetchWithTimeout(
235
+ url,
236
+ {
237
+ method: "POST",
238
+ headers: {
239
+ "X-Sandbox-Id": cred.mainApp.sandboxId,
240
+ "X-Sandbox-Secret-Key": cred.mainApp.sandboxSecretKey
241
+ },
242
+ body: formData
243
+ },
244
+ UPLOAD_TIMEOUT_MS
245
+ );
246
+ return parseResponse(response, "\u4E0A\u4F20\u5931\u8D25");
247
+ }
248
+
249
+ export {
250
+ TeAgentCredentialsError,
251
+ getClaudeConfigDir,
252
+ TeAgentApiError,
253
+ postToMainApp,
254
+ getFromMainApp,
255
+ getSandboxModels,
256
+ postSandboxModelSelection,
257
+ getSandboxSyncPullCandidates,
258
+ postSandboxSyncPull,
259
+ deleteFromMainApp,
260
+ patchToMainApp,
261
+ uploadToMainApp
262
+ };
@@ -2,10 +2,13 @@ import {
2
2
  clearToken,
3
3
  getToken,
4
4
  resolveHost
5
- } from "./chunk-24ZKQWG2.js";
5
+ } from "./chunk-SRRUNQIM.js";
6
6
  import {
7
7
  safeJsonParse
8
- } from "./chunk-TMMUBSKW.js";
8
+ } from "./chunk-BI5ZVD6T.js";
9
+ import {
10
+ logger
11
+ } from "./chunk-MNHE6SSI.js";
9
12
 
10
13
  // src/core/client.ts
11
14
  import WebSocket from "ws";
@@ -39,11 +42,13 @@ async function request(method, modulePath, params = {}, body = null, retry = tru
39
42
  const options = { method, headers };
40
43
  if (body && method !== "GET") options.body = JSON.stringify(body);
41
44
  const resp = await fetch(url, options);
45
+ const text = await resp.text();
46
+ const data = safeJsonParse(text);
47
+ logger.api(method, url, resp.status, body, data);
42
48
  if ((resp.status === 401 || resp.status === 403) && retry) {
43
49
  clearToken(resolvedHost);
44
50
  return request(method, modulePath, params, body, false, resolvedHost);
45
51
  }
46
- const data = safeJsonParse(await resp.text());
47
52
  if (data.return_code === -1001 && retry) {
48
53
  clearToken(resolvedHost);
49
54
  return request(method, modulePath, params, body, false, resolvedHost);
@@ -59,6 +64,9 @@ async function httpGet(modulePath, params = {}, hostUrl) {
59
64
  async function httpPost(modulePath, params = {}, body, hostUrl) {
60
65
  return request("POST", modulePath, params, body ?? {}, true, hostUrl);
61
66
  }
67
+ async function httpRequest(method, modulePath, params = {}, body, hostUrl) {
68
+ return request(method.toUpperCase(), modulePath, params, body ?? {}, true, hostUrl);
69
+ }
62
70
  async function httpDelete(modulePath, params = {}, body, hostUrl) {
63
71
  return request("DELETE", modulePath, params, body ?? null, true, hostUrl);
64
72
  }
@@ -70,11 +78,13 @@ async function uploadRequest(modulePath, form, params = {}, retry = true, hostUr
70
78
  "Authorization": `bearer ${token}`
71
79
  };
72
80
  const resp = await fetch(url, { method: "POST", headers, body: form });
81
+ const text = await resp.text();
82
+ const data = safeJsonParse(text);
83
+ logger.api("POST", url, resp.status, { upload: true }, data);
73
84
  if ((resp.status === 401 || resp.status === 403) && retry) {
74
85
  clearToken(resolvedHost);
75
86
  return uploadRequest(modulePath, form, params, false, resolvedHost);
76
87
  }
77
- const data = safeJsonParse(await resp.text());
78
88
  if (data.return_code === -1001 && retry) {
79
89
  clearToken(resolvedHost);
80
90
  return uploadRequest(modulePath, form, params, false, resolvedHost);
@@ -170,6 +180,7 @@ async function queryReportData(projectId, reportId, qp, eventModel, options = {}
170
180
  export {
171
181
  httpGet,
172
182
  httpPost,
183
+ httpRequest,
173
184
  httpDelete,
174
185
  httpUpload,
175
186
  wsQuery,
@@ -2,17 +2,20 @@ import {
2
2
  httpDelete,
3
3
  httpGet,
4
4
  httpPost,
5
+ httpRequest,
5
6
  httpUpload,
6
7
  queryReportData,
7
8
  querySql,
8
9
  wsQuery
9
- } from "./chunk-NBFTPIAH.js";
10
- import "./chunk-24ZKQWG2.js";
11
- import "./chunk-TMMUBSKW.js";
10
+ } from "./chunk-VT6VC4PA.js";
11
+ import "./chunk-SRRUNQIM.js";
12
+ import "./chunk-BI5ZVD6T.js";
13
+ import "./chunk-MNHE6SSI.js";
12
14
  export {
13
15
  httpDelete,
14
16
  httpGet,
15
17
  httpPost,
18
+ httpRequest,
16
19
  httpUpload,
17
20
  queryReportData,
18
21
  querySql,
@@ -4,14 +4,15 @@ import {
4
4
  getToken,
5
5
  loadToken,
6
6
  validateToken
7
- } from "./chunk-24ZKQWG2.js";
7
+ } from "./chunk-SRRUNQIM.js";
8
8
  import {
9
9
  addHost,
10
10
  listHosts,
11
11
  removeHost,
12
12
  setActiveHost,
13
13
  updateHostLabel
14
- } from "./chunk-TMMUBSKW.js";
14
+ } from "./chunk-BI5ZVD6T.js";
15
+ import "./chunk-MNHE6SSI.js";
15
16
 
16
17
  // src/commands/config.ts
17
18
  import * as readline from "readline";