@thinkingai/ae-cli 6.0.24 → 6.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 (130) hide show
  1. package/dist/{auth-A2XXG5K4.js → auth-7TQRGLBC.js} +10 -8
  2. package/dist/{auth-IDPKDFSY.js → auth-MEJ642P4.js} +2 -2
  3. package/dist/chunk-2NDGFQHW.js +190 -0
  4. package/dist/{chunk-NGJDCOYA.js → chunk-7QQ4233A.js} +3 -3
  5. package/dist/{chunk-PFJFZVCK.js → chunk-AJTH7LT3.js} +3 -2
  6. package/dist/{chunk-V5R5UIRM.js → chunk-BXMXMUD7.js} +65 -6
  7. package/dist/{chunk-AKORWVHJ.js → chunk-C4DH76LX.js} +1 -1
  8. package/dist/{chunk-NXJP4CES.js → chunk-GWZ5MYWE.js} +3 -3
  9. package/dist/{chunk-F3ZDMC2W.js → chunk-KCA6BA5D.js} +2 -2
  10. package/dist/{chunk-WXBCP6SD.js → chunk-KGJQCYVC.js} +1 -1
  11. package/dist/{chunk-FIT4CFIN.js → chunk-LG5YT7P7.js} +1 -1
  12. package/dist/{chunk-IDXW6MEJ.js → chunk-MDJGDI6K.js} +2 -2
  13. package/dist/{chunk-4FQ36OGO.js → chunk-R77JT7XD.js} +53 -6
  14. package/dist/{chunk-65DKFJZB.js → chunk-YCLVYFK7.js} +49 -6
  15. package/dist/{chunk-2OW2RENH.js → chunk-YNQFYBDB.js} +64 -6
  16. package/dist/{chunk-ONOA6DYB.js → chunk-ZAOL36CG.js} +1 -1
  17. package/dist/cli-token-TVQRSE46.js +18 -0
  18. package/dist/{client-7L735LVY.js → client-2643Z5AG.js} +3 -3
  19. package/dist/{config-SXD2JKSL.js → config-ZVPARN4R.js} +4 -9
  20. package/dist/index.js +24 -24
  21. package/dist/{metadata-QWUAX625.js → metadata-IPSPQBX3.js} +5 -5
  22. package/dist/{metadata-XWTEGEN2.js → metadata-N5REJ7R7.js} +5 -5
  23. package/dist/{model-3OVX42DA.js → model-T3KZJWLW.js} +2 -2
  24. package/dist/{raw-IANB4AV5.js → raw-OHSUK42D.js} +4 -4
  25. package/dist/{sync-4HQ3CXSK.js → sync-ULT5SECP.js} +3 -3
  26. package/dist/{te-agent-OYNNTJDU.js → te-agent-QLIVKRUN.js} +1146 -61
  27. package/dist/{te-analysis-CRPFK3LX.js → te-analysis-2U5EPXQC.js} +207 -69
  28. package/dist/{te-analysis-JX3V76OI.js → te-analysis-QMZ2UH7F.js} +207 -69
  29. package/dist/{te-audience-RO2IZOUC.js → te-audience-PVMKQAFH.js} +5 -5
  30. package/dist/{te-audience-77FGNG5E.js → te-audience-XMRMVD2V.js} +5 -5
  31. package/dist/{te-common-4TRJPRC5.js → te-common-CFGQXTFV.js} +5 -5
  32. package/dist/{te-common-PUXBUPOL.js → te-common-SDB3O2QG.js} +5 -5
  33. package/dist/{te-community-XKE526DS.js → te-community-6A7LKYUH.js} +5 -5
  34. package/dist/{te-community-NPDZQKMY.js → te-community-GMWFGILT.js} +5 -5
  35. package/dist/{te-dataops-PW74WP76.js → te-dataops-6LIPYNGH.js} +90 -68
  36. package/dist/{te-dataops-6KWLFNV4.js → te-dataops-Z53CTG2U.js} +90 -68
  37. package/dist/{te-engage-HTLMUN7G.js → te-engage-AGREUOW7.js} +30 -15
  38. package/dist/{te-engage-YPQIVF5H.js → te-engage-MIIUKY6M.js} +30 -15
  39. package/dist/{te-kb-DOGDQIU4.js → te-kb-KQJ53M3A.js} +4 -4
  40. package/dist/{te-meta-5ESSQ5B3.js → te-meta-QLANJ4B4.js} +5 -5
  41. package/dist/{te-meta-Z47X4VT3.js → te-meta-TOA6FWDE.js} +5 -5
  42. package/dist/{te-team-SOVKZIDD.js → te-team-TQGMNHQQ.js} +5 -5
  43. package/package.json +3 -1
  44. package/skills/ae-agent/SKILL.md +158 -189
  45. package/skills/ae-agent/references/accept-skill-share.md +39 -0
  46. package/skills/ae-agent/references/add-attachment.md +57 -0
  47. package/skills/ae-agent/references/add-mcp.md +75 -0
  48. package/skills/ae-agent/references/add-model.md +70 -0
  49. package/skills/ae-agent/references/add-skill.md +71 -0
  50. package/skills/ae-agent/references/approve-skill.md +41 -0
  51. package/skills/ae-agent/references/attachment-stats.md +50 -0
  52. package/skills/ae-agent/references/auto-provision-mcp-credentials.md +57 -0
  53. package/skills/ae-agent/references/cancel-skill-submission.md +39 -0
  54. package/skills/ae-agent/references/copy-skill.md +53 -0
  55. package/skills/ae-agent/references/create-agent.md +71 -0
  56. package/skills/ae-agent/references/create-automation.md +99 -0
  57. package/skills/ae-agent/references/del-agent.md +38 -0
  58. package/skills/ae-agent/references/del-attachment.md +35 -0
  59. package/skills/ae-agent/references/del-mcp.md +35 -0
  60. package/skills/ae-agent/references/del-model.md +37 -0
  61. package/skills/ae-agent/references/del-skill-asset.md +41 -0
  62. package/skills/ae-agent/references/del-skill-reference.md +41 -0
  63. package/skills/ae-agent/references/del-skill-script.md +41 -0
  64. package/skills/ae-agent/references/del-skill.md +36 -0
  65. package/skills/ae-agent/references/edit-skill.md +64 -0
  66. package/skills/ae-agent/references/get-agent.md +37 -0
  67. package/skills/ae-agent/references/get-skill-content.md +36 -0
  68. package/skills/ae-agent/references/list-agents.md +40 -0
  69. package/skills/ae-agent/references/list-attachments.md +42 -0
  70. package/skills/ae-agent/references/list-automations.md +41 -0
  71. package/skills/ae-agent/references/list-mcp-credentials.md +65 -0
  72. package/skills/ae-agent/references/list-mcp-market.md +58 -0
  73. package/skills/ae-agent/references/list-mcps.md +37 -0
  74. package/skills/ae-agent/references/list-models.md +38 -0
  75. package/skills/ae-agent/references/list-skill-assets.md +35 -0
  76. package/skills/ae-agent/references/list-skill-market.md +59 -0
  77. package/skills/ae-agent/references/list-skill-references.md +36 -0
  78. package/skills/ae-agent/references/list-skill-scripts.md +35 -0
  79. package/skills/ae-agent/references/list-skill-shares.md +49 -0
  80. package/skills/ae-agent/references/list-skill-submissions.md +45 -0
  81. package/skills/ae-agent/references/list-skills.md +37 -0
  82. package/skills/ae-agent/references/mcp-auth-disconnect.md +50 -0
  83. package/skills/ae-agent/references/mcp-auth-start.md +61 -0
  84. package/skills/ae-agent/references/mcp-auth-status.md +56 -0
  85. package/skills/ae-agent/references/mcp-stats.md +68 -0
  86. package/skills/ae-agent/references/mcp-token.md +63 -0
  87. package/skills/ae-agent/references/mcp-tools.md +55 -0
  88. package/skills/ae-agent/references/read-skill-asset.md +51 -0
  89. package/skills/ae-agent/references/read-skill-reference.md +50 -0
  90. package/skills/ae-agent/references/read-skill-script.md +51 -0
  91. package/skills/ae-agent/references/reject-skill-share.md +37 -0
  92. package/skills/ae-agent/references/reject-skill.md +42 -0
  93. package/skills/ae-agent/references/rescan-skills.md +44 -0
  94. package/skills/ae-agent/references/set-mcp-credential.md +67 -0
  95. package/skills/ae-agent/references/set-mcp-meta.md +52 -0
  96. package/skills/ae-agent/references/set-skill-meta.md +51 -0
  97. package/skills/ae-agent/references/share-skill.md +50 -0
  98. package/skills/ae-agent/references/submit-skill.md +51 -0
  99. package/skills/ae-agent/references/test-model.md +61 -0
  100. package/skills/ae-agent/references/toggle-mcp.md +39 -0
  101. package/skills/ae-agent/references/toggle-model.md +37 -0
  102. package/skills/ae-agent/references/toggle-skill.md +37 -0
  103. package/skills/ae-agent/references/update-agent.md +71 -0
  104. package/skills/ae-agent/references/update-automation.md +83 -0
  105. package/skills/ae-agent/references/update-mcp.md +79 -0
  106. package/skills/ae-agent/references/update-model.md +77 -0
  107. package/skills/ae-agent/references/upload-skill-asset.md +49 -0
  108. package/skills/ae-agent/references/upload-skill-reference.md +51 -0
  109. package/skills/ae-agent/references/upload-skill-script.md +49 -0
  110. package/skills/ae-agent/references/upload-skill.md +89 -0
  111. package/skills/ae-analysis/SKILL.md +4 -2
  112. package/skills/ae-analysis/references/analysis_gateway_assets.md +21 -6
  113. package/skills/ae-analysis/references/artifact_download.md +17 -0
  114. package/skills/ae-analysis/references/bi_panel_page_data_export.md +11 -1
  115. package/skills/ae-analysis/references/dashboard_copy.md +3 -1
  116. package/skills/ae-analysis/references/dashboard_daily_report_send.md +4 -2
  117. package/skills/ae-analysis/references/dashboard_daily_report_update.md +3 -1
  118. package/skills/ae-analysis/references/dashboard_definition_export.md +21 -3
  119. package/skills/ae-analysis/references/dashboard_report_data_export.md +11 -1
  120. package/skills/ae-analysis/references/project_space_create.md +1 -1
  121. package/skills/ae-analysis/references/run_inspect.md +22 -0
  122. package/skills/ae-dataops/references/dataops-flow-create.md +2 -2
  123. package/skills/ae-dataops/references/dataops-flow-monitor.md +3 -3
  124. package/skills/ae-dataops/references/dataops-integration.md +1 -0
  125. package/skills/ae-engage/references/flow-node-config-schema.md +32 -8
  126. package/skills/ae-engage/references/save-flow.md +65 -29
  127. package/skills/ae-engage/references/validate-flow-node-config.md +28 -10
  128. package/skills/ae-generate-tracking-plan/SKILL.md +9 -7
  129. package/dist/chunk-OCQPQYHZ.js +0 -105
  130. package/dist/cli-token-OZXHC3U2.js +0 -14
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  deleteFromMainApp,
3
+ getBufferFromMainApp,
3
4
  getFromMainApp,
4
5
  patchToMainApp,
5
6
  postToMainApp,
7
+ putToMainApp,
6
8
  uploadToMainApp
7
- } from "./chunk-4FQ36OGO.js";
8
- import "./chunk-65DKFJZB.js";
9
+ } from "./chunk-R77JT7XD.js";
10
+ import "./chunk-YCLVYFK7.js";
9
11
 
10
12
  // src/commands/te-agent/agents.ts
11
13
  var BASE_PATH = "/api/sandbox/agent/agents";
@@ -46,10 +48,171 @@ var listAgents = {
46
48
  dryRun: (ctx) => ({ method: "GET", url: `${BASE_PATH}${buildQuery(ctx)}` }),
47
49
  execute: async (ctx) => getFromMainApp(`${BASE_PATH}${buildQuery(ctx)}`)
48
50
  };
51
+ async function resolveInstructions(raw) {
52
+ if (raw === "@-") {
53
+ const chunks = [];
54
+ for await (const chunk of process.stdin) {
55
+ chunks.push(chunk);
56
+ }
57
+ const text = Buffer.concat(chunks).toString("utf8").trim();
58
+ if (!text) throw new Error("stdin is empty; cannot read instructions");
59
+ return text;
60
+ }
61
+ return raw;
62
+ }
63
+ var createAgent = {
64
+ service: "agent",
65
+ command: "+create-agent",
66
+ description: "Create an Agent (personal scope by default; company requires root/agent_admin)",
67
+ flags: [
68
+ { name: "name", type: "string", required: true, desc: "Agent name (1-100 chars)" },
69
+ { name: "description", type: "string", required: false, desc: "Agent description (max 2000 chars)" },
70
+ { name: "instructions", type: "string", required: false, desc: "Agent system prompt (use @- to read from stdin)" },
71
+ { name: "scope", type: "string", required: false, default: "personal", desc: "Scope: personal | company (company requires root/agent_admin)" },
72
+ { name: "model-id", type: "string", required: false, desc: "Model identifier (Model.id uuid or legacy modelId); omit to use global default" },
73
+ { name: "mcp-ids", type: "json", required: false, desc: 'MCP server record IDs as JSON array string (e.g. ["id1","id2"])' },
74
+ { name: "skill-ids", type: "json", required: false, desc: "Skill record IDs as JSON array string" },
75
+ { name: "auto-rename", type: "boolean", required: false, desc: "Auto-rename on name conflict (append -N suffix)" }
76
+ ],
77
+ risk: "write",
78
+ validate: (ctx) => {
79
+ const name = ctx.str("name");
80
+ if (!name || name.length < 1 || name.length > 100) {
81
+ throw new Error("--name length must be between 1 and 100");
82
+ }
83
+ const scope = ctx.str("scope");
84
+ if (scope && !["personal", "company"].includes(scope)) {
85
+ throw new Error("--scope must be personal or company");
86
+ }
87
+ },
88
+ dryRun: (ctx) => {
89
+ const body = {
90
+ name: ctx.str("name"),
91
+ scope: ctx.str("scope") || "personal"
92
+ };
93
+ const description = ctx.str("description");
94
+ if (description) body.description = description;
95
+ const instructions = ctx.str("instructions");
96
+ if (instructions) body.systemPrompt = instructions === "@-" ? "(from stdin)" : instructions;
97
+ const modelId = ctx.str("modelId");
98
+ if (modelId) body.model = modelId;
99
+ const mcpIds = ctx.json("mcpIds");
100
+ if (mcpIds) body.mcpServerIds = mcpIds;
101
+ const skillIds = ctx.json("skillIds");
102
+ if (skillIds) body.skillIds = skillIds;
103
+ if (ctx.bool("autoRename")) body.autoRename = true;
104
+ return { method: "POST", url: BASE_PATH, body };
105
+ },
106
+ execute: async (ctx) => {
107
+ const body = {
108
+ name: ctx.str("name"),
109
+ scope: ctx.str("scope") || "personal"
110
+ };
111
+ const description = ctx.str("description");
112
+ if (description) body.description = description;
113
+ const instructionsRaw = ctx.str("instructions");
114
+ if (instructionsRaw) body.systemPrompt = await resolveInstructions(instructionsRaw);
115
+ const modelId = ctx.str("modelId");
116
+ if (modelId) body.model = modelId;
117
+ const mcpIds = ctx.json("mcpIds");
118
+ if (mcpIds) body.mcpServerIds = mcpIds;
119
+ const skillIds = ctx.json("skillIds");
120
+ if (skillIds) body.skillIds = skillIds;
121
+ if (ctx.bool("autoRename")) body.autoRename = true;
122
+ return postToMainApp(BASE_PATH, body);
123
+ }
124
+ };
125
+ var updateAgent = {
126
+ service: "agent",
127
+ command: "+update-agent",
128
+ description: "Update an Agent (name/description/instructions/model/MCP/Skill/enabled)",
129
+ flags: [
130
+ { name: "id", type: "string", required: true, desc: "Agent record ID (CUID)" },
131
+ { name: "name", type: "string", required: false, desc: "New Agent name (1-100 chars)" },
132
+ { name: "description", type: "string", required: false, desc: "New description (max 2000 chars)" },
133
+ { name: "instructions", type: "string", required: false, desc: "New system prompt (use @- to read from stdin)" },
134
+ { name: "model-id", type: "string", required: false, desc: "New model identifier (uuid or legacy modelId); omit to keep" },
135
+ { name: "mcp-ids", type: "json", required: false, desc: "MCP server record IDs as JSON array string (replaces the list; [] clears)" },
136
+ { name: "skill-ids", type: "json", required: false, desc: "Skill record IDs as JSON array string (replaces the list; [] clears)" },
137
+ { name: "enabled", type: "boolean", required: false, desc: "Enable/disable (system/company: writes personal preference)" }
138
+ ],
139
+ risk: "write",
140
+ validate: (ctx) => {
141
+ const name = ctx.str("name");
142
+ if (name && (name.length < 1 || name.length > 100)) {
143
+ throw new Error("--name length must be between 1 and 100");
144
+ }
145
+ },
146
+ dryRun: (ctx) => {
147
+ const body = {};
148
+ const name = ctx.str("name");
149
+ if (name) body.name = name;
150
+ const description = ctx.str("description");
151
+ if (description) body.description = description;
152
+ const instructions = ctx.str("instructions");
153
+ if (instructions) body.systemPrompt = instructions === "@-" ? "(from stdin)" : instructions;
154
+ const modelId = ctx.str("modelId");
155
+ if (modelId) body.model = modelId;
156
+ const mcpIds = ctx.json("mcpIds");
157
+ if (mcpIds) body.mcpServerIds = mcpIds;
158
+ const skillIds = ctx.json("skillIds");
159
+ if (skillIds) body.skillIds = skillIds;
160
+ if (ctx.str("enabled")) body.enabled = ctx.bool("enabled");
161
+ return { method: "PATCH", url: `${BASE_PATH}/${encodeURIComponent(ctx.str("id"))}`, body };
162
+ },
163
+ execute: async (ctx) => {
164
+ const body = {};
165
+ const name = ctx.str("name");
166
+ if (name) body.name = name;
167
+ const description = ctx.str("description");
168
+ if (description) body.description = description;
169
+ const instructionsRaw = ctx.str("instructions");
170
+ if (instructionsRaw) body.systemPrompt = await resolveInstructions(instructionsRaw);
171
+ const modelId = ctx.str("modelId");
172
+ if (modelId) body.model = modelId;
173
+ const mcpIds = ctx.json("mcpIds");
174
+ if (mcpIds) body.mcpServerIds = mcpIds;
175
+ const skillIds = ctx.json("skillIds");
176
+ if (skillIds) body.skillIds = skillIds;
177
+ if (ctx.str("enabled")) body.enabled = ctx.bool("enabled");
178
+ return patchToMainApp(`${BASE_PATH}/${encodeURIComponent(ctx.str("id"))}`, body);
179
+ }
180
+ };
181
+ var delAgent = {
182
+ service: "agent",
183
+ command: "+del-agent",
184
+ description: "Soft-delete an Agent (system agents cannot be deleted)",
185
+ flags: [
186
+ { name: "id", type: "string", required: true, desc: "Agent record ID (CUID)" }
187
+ ],
188
+ risk: "write",
189
+ dryRun: (ctx) => ({
190
+ method: "DELETE",
191
+ url: `${BASE_PATH}/${encodeURIComponent(ctx.str("id"))}`
192
+ }),
193
+ execute: async (ctx) => {
194
+ return deleteFromMainApp(`${BASE_PATH}/${encodeURIComponent(ctx.str("id"))}`);
195
+ }
196
+ };
197
+ var getAgent = {
198
+ service: "agent",
199
+ command: "+get-agent",
200
+ description: "Get Agent details by ID",
201
+ flags: [
202
+ { name: "id", type: "string", required: true, desc: "Agent record ID (CUID)" }
203
+ ],
204
+ risk: "read",
205
+ dryRun: (ctx) => ({
206
+ method: "GET",
207
+ url: `${BASE_PATH}/${encodeURIComponent(ctx.str("id"))}`
208
+ }),
209
+ execute: async (ctx) => {
210
+ return getFromMainApp(`${BASE_PATH}/${encodeURIComponent(ctx.str("id"))}`);
211
+ }
212
+ };
49
213
 
50
214
  // src/commands/te-agent/models.ts
51
215
  var BASE_PATH2 = "/api/sandbox/agent/models";
52
- var LIST_PATH = "/api/sandbox/models";
53
216
  var listModels = {
54
217
  service: "agent",
55
218
  command: "+list-models",
@@ -72,26 +235,32 @@ var listModels = {
72
235
  dryRun: (ctx) => {
73
236
  const scope = ctx.str("scope");
74
237
  const params = new URLSearchParams();
75
- const current = process.env.TE_AGENT_CURRENT_MODEL_ID?.trim();
76
238
  if (scope) params.set("scope", scope);
77
- if (current) params.set("current", current);
78
239
  const qs = params.toString();
79
- return { method: "GET", url: `${LIST_PATH}${qs ? `?${qs}` : ""}` };
240
+ return { method: "GET", url: `${BASE_PATH2}${qs ? `?${qs}` : ""}` };
80
241
  },
81
242
  execute: async (ctx) => {
82
243
  const scope = ctx.str("scope");
83
244
  const params = new URLSearchParams();
84
- const current = process.env.TE_AGENT_CURRENT_MODEL_ID?.trim();
85
245
  if (scope) params.set("scope", scope);
86
- if (current) params.set("current", current);
87
246
  const qs = params.toString();
88
- return getFromMainApp(`${LIST_PATH}${qs ? `?${qs}` : ""}`);
247
+ const current = process.env.TE_AGENT_CURRENT_MODEL_ID?.trim();
248
+ const data = await getFromMainApp(
249
+ `${BASE_PATH2}${qs ? `?${qs}` : ""}`
250
+ );
251
+ const items = data?.items ?? [];
252
+ return {
253
+ models: items.map((m) => ({
254
+ ...m,
255
+ isCurrent: current ? m.id === current : false
256
+ }))
257
+ };
89
258
  }
90
259
  };
91
260
  var addModel = {
92
261
  service: "agent",
93
262
  command: "+add-model",
94
- description: "Add a custom model (personal scope)",
263
+ description: "Add a custom model (personal or company scope)",
95
264
  flags: [
96
265
  {
97
266
  name: "model-id",
@@ -119,6 +288,13 @@ var addModel = {
119
288
  type: "number",
120
289
  required: false,
121
290
  desc: "Context window length"
291
+ },
292
+ {
293
+ name: "scope",
294
+ type: "string",
295
+ required: false,
296
+ default: "personal",
297
+ desc: "Target scope: personal | company"
122
298
  }
123
299
  ],
124
300
  risk: "write",
@@ -129,6 +305,10 @@ var addModel = {
129
305
  } catch {
130
306
  throw new Error("--base-url must be a valid URL");
131
307
  }
308
+ const scope = ctx.str("scope");
309
+ if (scope && !["personal", "company"].includes(scope)) {
310
+ throw new Error("--scope must be personal or company");
311
+ }
132
312
  },
133
313
  dryRun: (ctx) => ({
134
314
  method: "POST",
@@ -140,7 +320,8 @@ var addModel = {
140
320
  apiKey: ctx.str("apiKey") || void 0,
141
321
  provider: ctx.str("provider") || void 0,
142
322
  description: ctx.str("description") || void 0,
143
- contextLength: ctx.num("contextLength") || void 0
323
+ contextLength: ctx.num("contextLength") || void 0,
324
+ scope: ctx.str("scope") || "personal"
144
325
  }
145
326
  }),
146
327
  execute: async (ctx) => {
@@ -151,31 +332,46 @@ var addModel = {
151
332
  apiKey: ctx.str("apiKey") || void 0,
152
333
  provider: ctx.str("provider") || void 0,
153
334
  description: ctx.str("description") || void 0,
154
- contextLength: ctx.num("contextLength") || void 0
335
+ contextLength: ctx.num("contextLength") || void 0,
336
+ scope: ctx.str("scope") || "personal"
155
337
  });
156
338
  }
157
339
  };
158
340
  var delModel = {
159
341
  service: "agent",
160
342
  command: "+del-model",
161
- description: "Delete a personal model",
343
+ description: "Delete a model (personal or company scope)",
162
344
  flags: [
163
345
  {
164
346
  name: "id",
165
347
  type: "string",
166
348
  required: true,
167
349
  desc: "Model record ID (CUID)"
350
+ },
351
+ {
352
+ name: "scope",
353
+ type: "string",
354
+ required: false,
355
+ default: "personal",
356
+ desc: "Target scope: personal | company"
168
357
  }
169
358
  ],
170
359
  risk: "write",
171
- dryRun: (ctx) => ({
172
- method: "DELETE",
173
- url: `${BASE_PATH2}?id=${encodeURIComponent(ctx.str("id"))}`
174
- }),
360
+ validate: (ctx) => {
361
+ const scope = ctx.str("scope");
362
+ if (scope && !["personal", "company"].includes(scope)) {
363
+ throw new Error("--scope must be personal or company");
364
+ }
365
+ },
366
+ dryRun: (ctx) => {
367
+ const scope = ctx.str("scope") || "personal";
368
+ const qs = `id=${encodeURIComponent(ctx.str("id"))}&scope=${encodeURIComponent(scope)}`;
369
+ return { method: "DELETE", url: `${BASE_PATH2}?${qs}` };
370
+ },
175
371
  execute: async (ctx) => {
176
- return deleteFromMainApp(
177
- `${BASE_PATH2}?id=${encodeURIComponent(ctx.str("id"))}`
178
- );
372
+ const scope = ctx.str("scope") || "personal";
373
+ const qs = `id=${encodeURIComponent(ctx.str("id"))}&scope=${encodeURIComponent(scope)}`;
374
+ return deleteFromMainApp(`${BASE_PATH2}?${qs}`);
179
375
  }
180
376
  };
181
377
  var toggleModel = {
@@ -209,6 +405,124 @@ var toggleModel = {
209
405
  });
210
406
  }
211
407
  };
408
+ var updateModel = {
409
+ service: "agent",
410
+ command: "+update-model",
411
+ description: "Update a custom model (id determines the record to update; personal or company scope)",
412
+ flags: [
413
+ { name: "id", type: "string", required: true, desc: "Model record ID (CUID) to update" },
414
+ { name: "model-id", type: "string", required: true, desc: "Model identifier (e.g. gpt-4o)" },
415
+ { name: "name", type: "string", required: true, desc: "Display name" },
416
+ { name: "base-url", type: "string", required: true, desc: "API base URL (must be a valid URL)" },
417
+ { name: "api-key", type: "string", required: false, desc: "API key; omit or empty to preserve the existing key" },
418
+ { name: "provider", type: "string", required: false, desc: "Provider name" },
419
+ { name: "description", type: "string", required: false, desc: "Description" },
420
+ { name: "context-length", type: "number", required: false, desc: "Context window length" },
421
+ { name: "connectivity-verified", type: "boolean", required: false, desc: "Whether connectivity was verified (default false; pass true after +test-model)" },
422
+ { name: "auto-rename", type: "boolean", required: false, desc: "Auto-rename on display name conflict (append -N suffix)" },
423
+ { name: "scope", type: "string", required: false, default: "personal", desc: "Target scope: personal | company" }
424
+ ],
425
+ risk: "write",
426
+ validate: (ctx) => {
427
+ const baseUrl = ctx.str("baseUrl");
428
+ try {
429
+ new URL(baseUrl);
430
+ } catch {
431
+ throw new Error("--base-url must be a valid URL");
432
+ }
433
+ const scope = ctx.str("scope");
434
+ if (scope && !["personal", "company"].includes(scope)) {
435
+ throw new Error("--scope must be personal or company");
436
+ }
437
+ },
438
+ dryRun: (ctx) => {
439
+ const body = {
440
+ id: ctx.str("id"),
441
+ modelId: ctx.str("modelId"),
442
+ displayName: ctx.str("name"),
443
+ baseUrl: ctx.str("baseUrl"),
444
+ connectivityVerified: ctx.bool("connectivityVerified")
445
+ };
446
+ const apiKey = ctx.str("apiKey");
447
+ if (apiKey) body.apiKey = apiKey;
448
+ const provider = ctx.str("provider");
449
+ if (provider) body.provider = provider;
450
+ const description = ctx.str("description");
451
+ if (description) body.description = description;
452
+ const contextLength = ctx.optionalNum("contextLength");
453
+ if (contextLength !== void 0) body.contextLength = contextLength;
454
+ if (ctx.bool("autoRename")) body.autoRename = true;
455
+ body.scope = ctx.str("scope") || "personal";
456
+ return { method: "POST", url: BASE_PATH2, body };
457
+ },
458
+ execute: async (ctx) => {
459
+ const body = {
460
+ id: ctx.str("id"),
461
+ modelId: ctx.str("modelId"),
462
+ displayName: ctx.str("name"),
463
+ baseUrl: ctx.str("baseUrl"),
464
+ connectivityVerified: ctx.bool("connectivityVerified")
465
+ };
466
+ const apiKey = ctx.str("apiKey");
467
+ if (apiKey) body.apiKey = apiKey;
468
+ const provider = ctx.str("provider");
469
+ if (provider) body.provider = provider;
470
+ const description = ctx.str("description");
471
+ if (description) body.description = description;
472
+ const contextLength = ctx.optionalNum("contextLength");
473
+ if (contextLength !== void 0) body.contextLength = contextLength;
474
+ if (ctx.bool("autoRename")) body.autoRename = true;
475
+ body.scope = ctx.str("scope") || "personal";
476
+ return postToMainApp(BASE_PATH2, body);
477
+ }
478
+ };
479
+ var testModel = {
480
+ service: "agent",
481
+ command: "+test-model",
482
+ description: "Test model connectivity (LLM models only)",
483
+ flags: [
484
+ { name: "model-id", type: "string", required: true, desc: "Model identifier (e.g. gpt-4o)" },
485
+ { name: "base-url", type: "string", required: true, desc: "API base URL (must be a valid URL)" },
486
+ { name: "api-key", type: "string", required: false, desc: "API key; omit to reuse the stored key of --id" },
487
+ { name: "provider", type: "string", required: false, desc: "Provider name" },
488
+ { name: "id", type: "string", required: false, desc: "Existing model config ID; when --api-key is omitted, the stored key is decrypted and reused" }
489
+ ],
490
+ risk: "read",
491
+ validate: (ctx) => {
492
+ const baseUrl = ctx.str("baseUrl");
493
+ try {
494
+ new URL(baseUrl);
495
+ } catch {
496
+ throw new Error("--base-url must be a valid URL");
497
+ }
498
+ },
499
+ dryRun: (ctx) => {
500
+ const body = {
501
+ modelId: ctx.str("modelId"),
502
+ baseUrl: ctx.str("baseUrl")
503
+ };
504
+ const apiKey = ctx.str("apiKey");
505
+ if (apiKey) body.apiKey = apiKey;
506
+ const provider = ctx.str("provider");
507
+ if (provider) body.provider = provider;
508
+ const id = ctx.str("id");
509
+ if (id) body.existingConfigId = id;
510
+ return { method: "POST", url: `${BASE_PATH2}/test`, body };
511
+ },
512
+ execute: async (ctx) => {
513
+ const body = {
514
+ modelId: ctx.str("modelId"),
515
+ baseUrl: ctx.str("baseUrl")
516
+ };
517
+ const apiKey = ctx.str("apiKey");
518
+ if (apiKey) body.apiKey = apiKey;
519
+ const provider = ctx.str("provider");
520
+ if (provider) body.provider = provider;
521
+ const id = ctx.str("id");
522
+ if (id) body.existingConfigId = id;
523
+ return postToMainApp(`${BASE_PATH2}/test`, body);
524
+ }
525
+ };
212
526
 
213
527
  // src/commands/te-agent/market-constants.ts
214
528
  var MARKET_CATEGORIES = [
@@ -245,7 +559,9 @@ function buildMarketQuery(ctx) {
245
559
 
246
560
  // src/commands/te-agent/mcps.ts
247
561
  var BASE_PATH3 = "/api/sandbox/agent/mcp-servers";
248
- var MARKET_BASE_PATH = "/api/mcp-servers";
562
+ var MARKET_BASE_PATH = "/api/sandbox/agent/mcp-servers";
563
+ var CRED_BASE_PATH = "/api/sandbox/agent/mcp-credentials";
564
+ var STATS_PATH = "/api/sandbox/agent/mcp-servers/stats";
249
565
  function buildMetaBody(ctx) {
250
566
  const body = {};
251
567
  const category = ctx.str("category");
@@ -284,7 +600,7 @@ var listMcps = {
284
600
  var addMcp = {
285
601
  service: "agent",
286
602
  command: "+add-mcp",
287
- description: "Add an MCP server (personal scope)",
603
+ description: "Add an MCP server (personal or company scope)",
288
604
  flags: [
289
605
  { name: "name", type: "string", required: true, desc: "Server name (2-64 chars, letter start, [a-zA-Z0-9_-])" },
290
606
  { name: "url", type: "string", required: true, desc: "MCP server URL" },
@@ -294,7 +610,8 @@ var addMcp = {
294
610
  { name: "headers", type: "json", required: false, desc: "HTTP headers as JSON object" },
295
611
  { name: "category", type: "string", required: false, desc: `Market category key: ${MARKET_CATEGORIES.join(" | ")}` },
296
612
  { name: "icon-emoji", type: "string", required: false, desc: "Market icon emoji (e.g. robot)" },
297
- { name: "icon-color", type: "string", required: false, desc: "Market icon color (e.g. #1E76F0)" }
613
+ { name: "icon-color", type: "string", required: false, desc: "Market icon color (e.g. #1E76F0)" },
614
+ { name: "scope", type: "string", required: false, default: "personal", desc: "Target scope: personal | company" }
298
615
  ],
299
616
  risk: "write",
300
617
  validate: (ctx) => {
@@ -321,6 +638,10 @@ var addMcp = {
321
638
  if (category && !isValidMarketCategory(category)) {
322
639
  throw new Error(`--category must be one of: ${MARKET_CATEGORIES.join(", ")}`);
323
640
  }
641
+ const scope = ctx.str("scope");
642
+ if (scope && !["personal", "company"].includes(scope)) {
643
+ throw new Error("--scope must be personal or company");
644
+ }
324
645
  },
325
646
  dryRun: (ctx) => {
326
647
  const body = {
@@ -329,7 +650,8 @@ var addMcp = {
329
650
  displayName: ctx.str("displayName") || void 0,
330
651
  description: ctx.str("description") || void 0,
331
652
  transport: ctx.str("transport") || "http",
332
- headers: ctx.json("headers") || void 0
653
+ headers: ctx.json("headers") || void 0,
654
+ scope: ctx.str("scope") || "personal"
333
655
  };
334
656
  const meta = buildMetaBody(ctx);
335
657
  if (meta) body._meta = meta;
@@ -342,7 +664,8 @@ var addMcp = {
342
664
  displayName: ctx.str("displayName") || void 0,
343
665
  description: ctx.str("description") || void 0,
344
666
  transport: ctx.str("transport") || "http",
345
- headers: ctx.json("headers") || void 0
667
+ headers: ctx.json("headers") || void 0,
668
+ scope: ctx.str("scope") || "personal"
346
669
  });
347
670
  const id = created?.item?.id;
348
671
  const meta = buildMetaBody(ctx);
@@ -461,10 +784,315 @@ var setMcpMeta = {
461
784
  );
462
785
  }
463
786
  };
787
+ var UPDATE_TRANSPORTS = ["sse", "http", "streamable-http"];
788
+ var UPDATE_AUTH_MODES = ["none", "oauth2", "header", "manual"];
789
+ var CRED_AUTH_TYPES = ["oauth", "apikey"];
790
+ function buildUpdateBody(ctx) {
791
+ const body = {};
792
+ const name = ctx.str("name");
793
+ if (name) body.name = name;
794
+ const url = ctx.str("url");
795
+ if (url) body.url = url;
796
+ const displayName = ctx.str("displayName");
797
+ if (displayName) body.displayName = displayName;
798
+ const description = ctx.str("description");
799
+ if (description) body.description = description;
800
+ const transport = ctx.str("transport");
801
+ if (transport) body.transport = transport;
802
+ const headers = ctx.json("headers");
803
+ if (headers) body.headers = headers;
804
+ const secretHeaders = ctx.json("secretHeaders");
805
+ if (secretHeaders) body.secretHeaders = secretHeaders;
806
+ const authMode = ctx.str("authMode");
807
+ if (authMode) body.authMode = authMode;
808
+ const enabledStr = ctx.str("enabled");
809
+ if (enabledStr === "true") body.enabled = true;
810
+ else if (enabledStr === "false") body.enabled = false;
811
+ if (ctx.bool("autoRename")) body.autoRename = true;
812
+ return body;
813
+ }
814
+ var updateMcp = {
815
+ service: "agent",
816
+ command: "+update-mcp",
817
+ description: "Update an MCP server config (personal owner / company root / system read-only)",
818
+ flags: [
819
+ { name: "id", type: "string", required: true, desc: "MCP server record ID (CUID)" },
820
+ { name: "name", type: "string", required: false, desc: "Server name (2-64 chars, letter start, [a-zA-Z0-9_-])" },
821
+ { name: "url", type: "string", required: false, desc: "MCP server URL (http:// or https:// only)" },
822
+ { name: "display-name", type: "string", required: false, desc: "Display name (max 100)" },
823
+ { name: "description", type: "string", required: false, desc: "Description (max 255)" },
824
+ { name: "transport", type: "string", required: false, desc: `Transport: ${UPDATE_TRANSPORTS.join(" | ")}` },
825
+ { name: "headers", type: "json", required: false, desc: "HTTP headers as JSON object" },
826
+ { name: "secret-headers", type: "json", required: false, desc: "Secret headers as JSON object (encrypted server-side)" },
827
+ { name: "auth-mode", type: "string", required: false, desc: `Auth mode: ${UPDATE_AUTH_MODES.join(" | ")}` },
828
+ { name: "enabled", type: "string", required: false, desc: "Set enabled state: true | false (omit to leave unchanged)" },
829
+ { name: "auto-rename", type: "boolean", required: false, desc: "Auto-rename on name conflict (default false)" }
830
+ ],
831
+ risk: "write",
832
+ validate: (ctx) => {
833
+ const name = ctx.str("name");
834
+ if (name && !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {
835
+ throw new Error("--name must start with a letter and contain only letters, digits, _, or -");
836
+ }
837
+ const url = ctx.str("url");
838
+ if (url) {
839
+ try {
840
+ new URL(url);
841
+ } catch {
842
+ throw new Error("--url must be a valid URL");
843
+ }
844
+ if (!/^https?:\/\//i.test(url)) {
845
+ throw new Error("--url only supports http:// or https:// protocols");
846
+ }
847
+ }
848
+ const transport = ctx.str("transport");
849
+ if (transport && !UPDATE_TRANSPORTS.includes(transport)) {
850
+ throw new Error(`--transport must be one of: ${UPDATE_TRANSPORTS.join(", ")}`);
851
+ }
852
+ const authMode = ctx.str("authMode");
853
+ if (authMode && !UPDATE_AUTH_MODES.includes(authMode)) {
854
+ throw new Error(`--auth-mode must be one of: ${UPDATE_AUTH_MODES.join(", ")}`);
855
+ }
856
+ const enabledStr = ctx.str("enabled");
857
+ if (enabledStr && enabledStr !== "true" && enabledStr !== "false") {
858
+ throw new Error("--enabled must be true or false");
859
+ }
860
+ const body = buildUpdateBody(ctx);
861
+ if (Object.keys(body).length === 0) {
862
+ throw new Error("Provide at least one field to update: --name / --url / --display-name / --description / --transport / --headers / --secret-headers / --auth-mode / --enabled / --auto-rename");
863
+ }
864
+ },
865
+ dryRun: (ctx) => ({
866
+ method: "PATCH",
867
+ url: `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}`,
868
+ body: buildUpdateBody(ctx)
869
+ }),
870
+ execute: async (ctx) => {
871
+ return patchToMainApp(
872
+ `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}`,
873
+ buildUpdateBody(ctx)
874
+ );
875
+ }
876
+ };
877
+ var mcpTools = {
878
+ service: "agent",
879
+ command: "+mcp-tools",
880
+ description: "List tools exposed by an MCP server (with OAuth auto-refresh)",
881
+ flags: [
882
+ { name: "id", type: "string", required: true, desc: "MCP server record ID (CUID)" }
883
+ ],
884
+ risk: "read",
885
+ dryRun: (ctx) => ({
886
+ method: "GET",
887
+ url: `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/tools`
888
+ }),
889
+ execute: async (ctx) => {
890
+ return getFromMainApp(`${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/tools`);
891
+ }
892
+ };
893
+ var mcpAuthStart = {
894
+ service: "agent",
895
+ command: "+mcp-auth-start",
896
+ description: "Start MCP OAuth flow (CLI mode: get authorizeUrl, then poll +mcp-auth-status)",
897
+ flags: [
898
+ { name: "id", type: "string", required: true, desc: "MCP server record ID (CUID)" },
899
+ { name: "redirect-after", type: "string", required: false, desc: "URL to redirect to after OAuth completes (must be same-origin as the service base URL)" },
900
+ { name: "cli", type: "boolean", required: false, default: true, desc: "CLI mode (always true on sandbox endpoint; server derives the callback URL)" }
901
+ ],
902
+ risk: "write",
903
+ dryRun: (ctx) => ({
904
+ method: "POST",
905
+ url: `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/auth/start`,
906
+ body: {
907
+ cliMode: true,
908
+ redirectAfter: ctx.str("redirectAfter") || void 0
909
+ }
910
+ }),
911
+ execute: async (ctx) => {
912
+ const result = await postToMainApp(
913
+ `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/auth/start`,
914
+ {
915
+ redirectAfter: ctx.str("redirectAfter") || void 0
916
+ }
917
+ );
918
+ if (result?.authorizeUrl && (process.stderr.isTTY || process.stdout.isTTY)) {
919
+ const id = ctx.str("id");
920
+ process.stderr.write(
921
+ `
922
+ \u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u4EE5\u4E0B URL \u5B8C\u6210\u6388\u6743\uFF1A
923
+ ${result.authorizeUrl}
924
+
925
+ \u6388\u6743\u5B8C\u6210\u540E\uFF0C\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u8F6E\u8BE2\u6388\u6743\u72B6\u6001\uFF1A
926
+ ae-cli agent +mcp-auth-status --id ${id}
927
+
928
+ `
929
+ );
930
+ }
931
+ return result;
932
+ }
933
+ };
934
+ var mcpAuthStatus = {
935
+ service: "agent",
936
+ command: "+mcp-auth-status",
937
+ description: "Query MCP OAuth authorization status (CLI poll after +mcp-auth-start)",
938
+ flags: [
939
+ { name: "id", type: "string", required: true, desc: "MCP server record ID (CUID)" }
940
+ ],
941
+ risk: "read",
942
+ dryRun: (ctx) => ({
943
+ method: "GET",
944
+ url: `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/auth/status`
945
+ }),
946
+ execute: async (ctx) => {
947
+ return getFromMainApp(`${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/auth/status`);
948
+ }
949
+ };
950
+ var mcpAuthDisconnect = {
951
+ service: "agent",
952
+ command: "+mcp-auth-disconnect",
953
+ description: "Disconnect MCP OAuth (clears token and disables the server)",
954
+ flags: [
955
+ { name: "id", type: "string", required: true, desc: "MCP server record ID (CUID)" }
956
+ ],
957
+ risk: "write",
958
+ dryRun: (ctx) => ({
959
+ method: "POST",
960
+ url: `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/auth/disconnect`
961
+ }),
962
+ execute: async (ctx) => {
963
+ return postToMainApp(
964
+ `${BASE_PATH3}/${encodeURIComponent(ctx.str("id"))}/auth/disconnect`,
965
+ {}
966
+ );
967
+ }
968
+ };
969
+ var listMcpCredentials = {
970
+ service: "agent",
971
+ command: "+list-mcp-credentials",
972
+ description: "List per-user credentials for system MCP servers",
973
+ flags: [],
974
+ risk: "read",
975
+ dryRun: () => ({
976
+ method: "GET",
977
+ url: CRED_BASE_PATH
978
+ }),
979
+ execute: async () => {
980
+ return getFromMainApp(CRED_BASE_PATH);
981
+ }
982
+ };
983
+ var setMcpCredential = {
984
+ service: "agent",
985
+ command: "+set-mcp-credential",
986
+ description: "Upsert a per-user MCP credential (by mcpServerId + userId)",
987
+ flags: [
988
+ { name: "mcp-server-id", type: "string", required: true, desc: "System MCP server record ID (CUID)" },
989
+ { name: "auth-type", type: "string", required: false, default: "oauth", desc: `Auth type: ${CRED_AUTH_TYPES.join(" | ")}` },
990
+ { name: "token", type: "string", required: false, desc: "Token / API key (plaintext; encrypted server-side)" },
991
+ { name: "expires-at", type: "string", required: false, desc: "ISO 8601 datetime (e.g. 2026-12-31T23:59:59Z)" }
992
+ ],
993
+ risk: "write",
994
+ validate: (ctx) => {
995
+ const authType = ctx.str("authType") || "oauth";
996
+ if (!CRED_AUTH_TYPES.includes(authType)) {
997
+ throw new Error(`--auth-type must be one of: ${CRED_AUTH_TYPES.join(", ")}`);
998
+ }
999
+ const expiresAt = ctx.str("expiresAt");
1000
+ if (expiresAt) {
1001
+ const d = new Date(expiresAt);
1002
+ if (isNaN(d.getTime())) {
1003
+ throw new Error("--expires-at must be a valid ISO 8601 datetime");
1004
+ }
1005
+ }
1006
+ },
1007
+ dryRun: (ctx) => ({
1008
+ method: "POST",
1009
+ url: CRED_BASE_PATH,
1010
+ body: {
1011
+ mcpServerId: ctx.str("mcpServerId"),
1012
+ authType: ctx.str("authType") || "oauth",
1013
+ token: ctx.str("token") || void 0,
1014
+ expiresAt: ctx.str("expiresAt") || void 0
1015
+ }
1016
+ }),
1017
+ execute: async (ctx) => {
1018
+ return postToMainApp(CRED_BASE_PATH, {
1019
+ mcpServerId: ctx.str("mcpServerId"),
1020
+ authType: ctx.str("authType") || "oauth",
1021
+ token: ctx.str("token") || void 0,
1022
+ expiresAt: ctx.str("expiresAt") || void 0
1023
+ });
1024
+ }
1025
+ };
1026
+ var autoProvisionMcpCredentials = {
1027
+ service: "agent",
1028
+ command: "+auto-provision-mcp-credentials",
1029
+ description: "Auto-provision credentials for all system MCP servers using the current access token",
1030
+ flags: [
1031
+ { name: "access-token", type: "string", required: false, desc: "Access token (defaults to the current session token from ctx.token())" }
1032
+ ],
1033
+ risk: "write",
1034
+ dryRun: (ctx) => ({
1035
+ method: "POST",
1036
+ url: `${CRED_BASE_PATH}/auto-provision`,
1037
+ body: {
1038
+ accessToken: ctx.str("accessToken") || "<current-session-token>"
1039
+ }
1040
+ }),
1041
+ execute: async (ctx) => {
1042
+ const accessToken = ctx.str("accessToken") || await ctx.token();
1043
+ return postToMainApp(`${CRED_BASE_PATH}/auto-provision`, { accessToken });
1044
+ }
1045
+ };
1046
+ var mcpToken = {
1047
+ service: "agent",
1048
+ command: "+mcp-token",
1049
+ description: "Get the plaintext MCP token (for useMcpToken=true system MCP servers)",
1050
+ flags: [],
1051
+ risk: "read",
1052
+ dryRun: () => ({
1053
+ method: "GET",
1054
+ url: `${CRED_BASE_PATH}/mcp-token`
1055
+ }),
1056
+ execute: async (ctx) => {
1057
+ const result = await getFromMainApp(`${CRED_BASE_PATH}/mcp-token`);
1058
+ if (process.stderr.isTTY) {
1059
+ process.stderr.write(
1060
+ `
1061
+ \u6CE8\u610F\uFF1A\u8FD4\u56DE\u660E\u6587 MCP Token\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1\uFF0C\u907F\u514D\u5199\u5165 shell history \u6216\u65E5\u5FD7\u3002
1062
+
1063
+ `
1064
+ );
1065
+ }
1066
+ return result;
1067
+ }
1068
+ };
1069
+ var mcpStats = {
1070
+ service: "agent",
1071
+ command: "+mcp-stats",
1072
+ description: "Show MCP call statistics for the last N days (by server / by day)",
1073
+ flags: [
1074
+ { name: "days", type: "number", required: false, default: 30, desc: "Lookback window in days (1-365, default 30)" }
1075
+ ],
1076
+ risk: "read",
1077
+ validate: (ctx) => {
1078
+ const days = ctx.optionalNum("days");
1079
+ if (days !== void 0 && (!Number.isInteger(days) || days < 1 || days > 365)) {
1080
+ throw new Error("--days must be an integer between 1 and 365");
1081
+ }
1082
+ },
1083
+ dryRun: (ctx) => {
1084
+ const days = ctx.optionalNum("days") ?? 30;
1085
+ return { method: "GET", url: `${STATS_PATH}?days=${days}` };
1086
+ },
1087
+ execute: async (ctx) => {
1088
+ const days = ctx.optionalNum("days") ?? 30;
1089
+ return getFromMainApp(`${STATS_PATH}?days=${days}`);
1090
+ }
1091
+ };
464
1092
 
465
1093
  // src/commands/te-agent/skills.ts
466
1094
  var BASE_PATH4 = "/api/sandbox/agent/skills";
467
- var MARKET_BASE_PATH2 = "/api/skills";
1095
+ var MARKET_BASE_PATH2 = "/api/sandbox/agent/skills";
468
1096
  function buildMetaBody2(ctx) {
469
1097
  const body = {};
470
1098
  const category = ctx.str("category");
@@ -475,7 +1103,7 @@ function buildMetaBody2(ctx) {
475
1103
  if (iconColor) body.iconColor = iconColor;
476
1104
  return Object.keys(body).length > 0 ? body : null;
477
1105
  }
478
- async function resolveInstructions(raw) {
1106
+ async function resolveInstructions2(raw) {
479
1107
  if (raw === "@-") {
480
1108
  const chunks = [];
481
1109
  for await (const chunk of process.stdin) {
@@ -515,7 +1143,7 @@ var listSkills = {
515
1143
  var addSkill = {
516
1144
  service: "agent",
517
1145
  command: "+add-skill",
518
- description: "Create a custom Skill (personal scope)",
1146
+ description: "Create a custom Skill (personal or company scope)",
519
1147
  flags: [
520
1148
  { name: "name", type: "string", required: true, desc: "Skill name (1-80 chars)" },
521
1149
  { name: "description", type: "string", required: true, desc: "Skill description" },
@@ -523,7 +1151,8 @@ var addSkill = {
523
1151
  { name: "display-name", type: "string", required: false, desc: "Display name (max 100)" },
524
1152
  { name: "category", type: "string", required: false, desc: `Market category key: ${MARKET_CATEGORIES.join(" | ")}` },
525
1153
  { name: "icon-emoji", type: "string", required: false, desc: "Market icon emoji (e.g. robot)" },
526
- { name: "icon-color", type: "string", required: false, desc: "Market icon color (e.g. #1E76F0)" }
1154
+ { name: "icon-color", type: "string", required: false, desc: "Market icon color (e.g. #1E76F0)" },
1155
+ { name: "scope", type: "string", required: false, default: "personal", desc: "Target scope: personal | company" }
527
1156
  ],
528
1157
  risk: "write",
529
1158
  validate: (ctx) => {
@@ -535,25 +1164,31 @@ var addSkill = {
535
1164
  if (category && !isValidMarketCategory(category)) {
536
1165
  throw new Error(`--category must be one of: ${MARKET_CATEGORIES.join(", ")}`);
537
1166
  }
1167
+ const scope = ctx.str("scope");
1168
+ if (scope && !["personal", "company"].includes(scope)) {
1169
+ throw new Error("--scope must be personal or company");
1170
+ }
538
1171
  },
539
1172
  dryRun: (ctx) => {
540
1173
  const body = {
541
1174
  name: ctx.str("name"),
542
1175
  description: ctx.str("description"),
543
1176
  instructions: ctx.str("instructions") === "@-" ? "(from stdin)" : ctx.str("instructions"),
544
- displayName: ctx.str("displayName") || void 0
1177
+ displayName: ctx.str("displayName") || void 0,
1178
+ scope: ctx.str("scope") || "personal"
545
1179
  };
546
1180
  const meta = buildMetaBody2(ctx);
547
1181
  if (meta) body._meta = meta;
548
1182
  return { method: "POST", url: BASE_PATH4, body };
549
1183
  },
550
1184
  execute: async (ctx) => {
551
- const instructions = await resolveInstructions(ctx.str("instructions"));
1185
+ const instructions = await resolveInstructions2(ctx.str("instructions"));
552
1186
  const created = await postToMainApp(BASE_PATH4, {
553
1187
  name: ctx.str("name"),
554
1188
  description: ctx.str("description"),
555
1189
  instructions,
556
- displayName: ctx.str("displayName") || void 0
1190
+ displayName: ctx.str("displayName") || void 0,
1191
+ scope: ctx.str("scope") || "personal"
557
1192
  });
558
1193
  const id = created?.item?.id;
559
1194
  const meta = buildMetaBody2(ctx);
@@ -702,8 +1337,409 @@ var copySkill = {
702
1337
  }
703
1338
  };
704
1339
 
1340
+ // src/commands/te-agent/skill-content.ts
1341
+ import { readFileSync, existsSync, writeFileSync } from "fs";
1342
+ import { resolve, basename, extname } from "path";
1343
+ var BASE_PATH5 = "/api/sandbox/agent/skills";
1344
+ async function resolveInstructions3(raw) {
1345
+ if (raw === "@-") {
1346
+ const chunks = [];
1347
+ for await (const chunk of process.stdin) {
1348
+ chunks.push(chunk);
1349
+ }
1350
+ const text = Buffer.concat(chunks).toString("utf8").trim();
1351
+ if (!text) throw new Error("stdin is empty; cannot read instructions");
1352
+ return text;
1353
+ }
1354
+ return raw;
1355
+ }
1356
+ function readFileForUpload(filePath) {
1357
+ const resolved = resolve(filePath);
1358
+ if (!existsSync(resolved)) {
1359
+ throw new Error(`File not found: ${resolved}`);
1360
+ }
1361
+ const buffer = readFileSync(resolved);
1362
+ const fileName = basename(resolved);
1363
+ const mimeType = guessMimeType(resolved);
1364
+ return { buffer, fileName, mimeType };
1365
+ }
1366
+ function guessMimeType(filePath) {
1367
+ const ext = extname(filePath).toLowerCase();
1368
+ const map = {
1369
+ ".png": "image/png",
1370
+ ".jpg": "image/jpeg",
1371
+ ".jpeg": "image/jpeg",
1372
+ ".gif": "image/gif",
1373
+ ".webp": "image/webp",
1374
+ ".svg": "image/svg+xml",
1375
+ ".pdf": "application/pdf",
1376
+ ".md": "text/markdown",
1377
+ ".txt": "text/plain",
1378
+ ".csv": "text/csv",
1379
+ ".json": "application/json",
1380
+ ".html": "text/html",
1381
+ ".xml": "application/xml",
1382
+ ".doc": "application/msword",
1383
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
1384
+ ".xls": "application/vnd.ms-excel",
1385
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
1386
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
1387
+ ".zip": "application/zip"
1388
+ };
1389
+ return map[ext] || "application/octet-stream";
1390
+ }
1391
+ function buildAssetFormData(filePath, subPath) {
1392
+ const { buffer, fileName, mimeType } = readFileForUpload(filePath);
1393
+ const fd = new FormData();
1394
+ const blob = new Blob([new Uint8Array(buffer)], { type: mimeType });
1395
+ fd.append("file", blob, fileName);
1396
+ if (subPath) fd.append("subPath", subPath);
1397
+ return fd;
1398
+ }
1399
+ function makeAssetListCommand(commandName, description, dirName) {
1400
+ return {
1401
+ service: "agent",
1402
+ command: commandName,
1403
+ description,
1404
+ flags: [
1405
+ { name: "id", type: "string", required: true, desc: "Skill record ID (CUID)" }
1406
+ ],
1407
+ risk: "read",
1408
+ dryRun: (ctx) => ({
1409
+ method: "GET",
1410
+ url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}`
1411
+ }),
1412
+ execute: async (ctx) => {
1413
+ return getFromMainApp(
1414
+ `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}`
1415
+ );
1416
+ }
1417
+ };
1418
+ }
1419
+ function makeAssetUploadCommand(commandName, description, dirName, mdOnly) {
1420
+ const validate = (ctx) => {
1421
+ const filePath = ctx.str("file");
1422
+ if (!filePath) throw new Error("--file is required");
1423
+ if (!existsSync(resolve(filePath))) throw new Error(`File not found: ${resolve(filePath)}`);
1424
+ if (mdOnly) {
1425
+ const ext = extname(filePath).toLowerCase();
1426
+ if (ext !== ".md") throw new Error("--file must be a .md file for references");
1427
+ }
1428
+ };
1429
+ return {
1430
+ service: "agent",
1431
+ command: commandName,
1432
+ description,
1433
+ flags: [
1434
+ { name: "id", type: "string", required: true, desc: "Skill record ID (CUID)" },
1435
+ { name: "file", type: "string", required: true, desc: mdOnly ? "Local .md file path to upload" : "Local file path to upload (max 1MB)" },
1436
+ { name: "sub-path", type: "string", required: false, desc: 'Sub-directory under the target dir (e.g. "sub/")' }
1437
+ ],
1438
+ risk: "write",
1439
+ validate,
1440
+ dryRun: (ctx) => ({
1441
+ method: "POST",
1442
+ url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}`,
1443
+ body: { file: ctx.str("file"), subPath: ctx.str("subPath") || "" }
1444
+ }),
1445
+ execute: async (ctx) => {
1446
+ const fd = buildAssetFormData(ctx.str("file"), ctx.str("subPath") || void 0);
1447
+ return uploadToMainApp(
1448
+ `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}`,
1449
+ fd
1450
+ );
1451
+ }
1452
+ };
1453
+ }
1454
+ function makeAssetReadCommand(commandName, description, dirName) {
1455
+ return {
1456
+ service: "agent",
1457
+ command: commandName,
1458
+ description,
1459
+ flags: [
1460
+ { name: "id", type: "string", required: true, desc: "Skill record ID (CUID)" },
1461
+ { name: "path", type: "string", required: true, desc: 'Relative file path within the directory (e.g. "guide.md" or "sub/icon.png")' },
1462
+ { name: "output", type: "string", required: false, desc: "Write binary content to a local file (preserves binary data)" }
1463
+ ],
1464
+ risk: "read",
1465
+ dryRun: (ctx) => ({
1466
+ method: "GET",
1467
+ url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}/${encodeURIComponent(ctx.str("path"))}`
1468
+ }),
1469
+ execute: async (ctx) => {
1470
+ const filePath = ctx.str("path");
1471
+ const encodedPath = filePath.split("/").map((seg) => encodeURIComponent(seg)).join("/");
1472
+ const url = `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}/${encodedPath}`;
1473
+ const { buffer, fileName } = await getBufferFromMainApp(url);
1474
+ const outputPath = ctx.str("output");
1475
+ if (outputPath) {
1476
+ const resolved = resolve(outputPath);
1477
+ writeFileSync(resolved, buffer);
1478
+ return { saved: true, path: resolved, size: buffer.length, fileName };
1479
+ }
1480
+ const content = buffer.toString("utf8");
1481
+ return { content, fileName };
1482
+ }
1483
+ };
1484
+ }
1485
+ function makeAssetDelCommand(commandName, description, dirName) {
1486
+ return {
1487
+ service: "agent",
1488
+ command: commandName,
1489
+ description,
1490
+ flags: [
1491
+ { name: "id", type: "string", required: true, desc: "Skill record ID (CUID)" },
1492
+ { name: "path", type: "string", required: true, desc: "Relative file path within the directory to delete" }
1493
+ ],
1494
+ risk: "write",
1495
+ dryRun: (ctx) => ({
1496
+ method: "DELETE",
1497
+ url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}/${encodeURIComponent(ctx.str("path"))}`
1498
+ }),
1499
+ execute: async (ctx) => {
1500
+ const filePath = ctx.str("path");
1501
+ const encodedPath = filePath.split("/").map((seg) => encodeURIComponent(seg)).join("/");
1502
+ return deleteFromMainApp(
1503
+ `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/${dirName}/${encodedPath}`
1504
+ );
1505
+ }
1506
+ };
1507
+ }
1508
+ var editSkill = {
1509
+ service: "agent",
1510
+ command: "+edit-skill",
1511
+ description: "Edit a personal Skill content (name / description / instructions / icon)",
1512
+ flags: [
1513
+ { name: "id", type: "string", required: true, desc: "Skill record ID (CUID)" },
1514
+ { name: "name", type: "string", required: false, desc: "New Skill name (1-80 chars)" },
1515
+ { name: "description", type: "string", required: false, desc: "New Skill description" },
1516
+ { name: "instructions", type: "string", required: false, desc: "New instructions (use @- to read from stdin)" },
1517
+ { name: "display-name", type: "string", required: false, desc: "New display name (max 100)" },
1518
+ { name: "category", type: "string", required: false, desc: `Market category key: ${MARKET_CATEGORIES.join(" | ")}` },
1519
+ { name: "icon-emoji", type: "string", required: false, desc: "Market icon emoji (e.g. robot)" },
1520
+ { name: "icon-color", type: "string", required: false, desc: "Market icon color (e.g. #1E76F0)" }
1521
+ ],
1522
+ risk: "write",
1523
+ validate: (ctx) => {
1524
+ const name = ctx.str("name");
1525
+ if (name && (name.length < 1 || name.length > 80)) {
1526
+ throw new Error("--name length must be between 1 and 80");
1527
+ }
1528
+ const category = ctx.str("category");
1529
+ if (category && !isValidMarketCategory(category)) {
1530
+ throw new Error(`--category must be one of: ${MARKET_CATEGORIES.join(", ")}`);
1531
+ }
1532
+ const hasAny = ctx.str("name") || ctx.str("description") || ctx.str("instructions") || ctx.str("displayName") || ctx.str("category") || ctx.str("iconEmoji") || ctx.str("iconColor");
1533
+ if (!hasAny) {
1534
+ throw new Error("Provide at least one of --name / --description / --instructions / --display-name / --category / --icon-emoji / --icon-color");
1535
+ }
1536
+ },
1537
+ dryRun: (ctx) => {
1538
+ const body = {};
1539
+ if (ctx.str("name")) body.name = ctx.str("name");
1540
+ if (ctx.str("description")) body.description = ctx.str("description");
1541
+ body.instructions = ctx.str("instructions") === "@-" ? "(from stdin)" : ctx.str("instructions") || void 0;
1542
+ if (ctx.str("displayName")) body.displayName = ctx.str("displayName");
1543
+ if (ctx.str("category")) body.category = ctx.str("category");
1544
+ if (ctx.str("iconEmoji")) body.iconEmoji = ctx.str("iconEmoji");
1545
+ if (ctx.str("iconColor")) body.iconColor = ctx.str("iconColor");
1546
+ return {
1547
+ method: "PUT",
1548
+ url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}`,
1549
+ body
1550
+ };
1551
+ },
1552
+ execute: async (ctx) => {
1553
+ const body = {};
1554
+ if (ctx.str("name")) body.name = ctx.str("name");
1555
+ if (ctx.str("description")) body.description = ctx.str("description");
1556
+ if (ctx.str("instructions")) {
1557
+ body.instructions = await resolveInstructions3(ctx.str("instructions"));
1558
+ }
1559
+ if (ctx.str("displayName")) body.displayName = ctx.str("displayName");
1560
+ if (ctx.str("category")) body.category = ctx.str("category");
1561
+ if (ctx.str("iconEmoji")) body.iconEmoji = ctx.str("iconEmoji");
1562
+ if (ctx.str("iconColor")) body.iconColor = ctx.str("iconColor");
1563
+ return putToMainApp(`${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}`, body);
1564
+ }
1565
+ };
1566
+ var getSkillContent = {
1567
+ service: "agent",
1568
+ command: "+get-skill-content",
1569
+ description: "Read a Skill SKILL.md text content",
1570
+ flags: [
1571
+ { name: "id", type: "string", required: true, desc: "Skill record ID (CUID)" }
1572
+ ],
1573
+ risk: "read",
1574
+ dryRun: (ctx) => ({
1575
+ method: "GET",
1576
+ url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/content`
1577
+ }),
1578
+ execute: async (ctx) => {
1579
+ return getFromMainApp(
1580
+ `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}/content`
1581
+ );
1582
+ }
1583
+ };
1584
+ var listSkillAssets = makeAssetListCommand(
1585
+ "+list-skill-assets",
1586
+ "List all files in a Skill assets directory",
1587
+ "assets"
1588
+ );
1589
+ var uploadSkillAsset = makeAssetUploadCommand(
1590
+ "+upload-skill-asset",
1591
+ "Upload a single file to a Skill assets directory (max 1MB)",
1592
+ "assets",
1593
+ false
1594
+ );
1595
+ var readSkillAsset = makeAssetReadCommand(
1596
+ "+read-skill-asset",
1597
+ "Read a Skill asset file (binary-safe; use --output to save to disk)",
1598
+ "assets"
1599
+ );
1600
+ var delSkillAsset = makeAssetDelCommand(
1601
+ "+del-skill-asset",
1602
+ "Delete a file from a Skill assets directory",
1603
+ "assets"
1604
+ );
1605
+ var listSkillReferences = makeAssetListCommand(
1606
+ "+list-skill-references",
1607
+ "List all .md files in a Skill references directory",
1608
+ "references"
1609
+ );
1610
+ var uploadSkillReference = makeAssetUploadCommand(
1611
+ "+upload-skill-reference",
1612
+ "Upload a single .md file to a Skill references directory (max 1MB)",
1613
+ "references",
1614
+ true
1615
+ );
1616
+ var readSkillReference = makeAssetReadCommand(
1617
+ "+read-skill-reference",
1618
+ "Read a Skill reference .md file (binary-safe; use --output to save to disk)",
1619
+ "references"
1620
+ );
1621
+ var delSkillReference = makeAssetDelCommand(
1622
+ "+del-skill-reference",
1623
+ "Delete a file from a Skill references directory",
1624
+ "references"
1625
+ );
1626
+ var listSkillScripts = makeAssetListCommand(
1627
+ "+list-skill-scripts",
1628
+ "List all files in a Skill scripts directory",
1629
+ "scripts"
1630
+ );
1631
+ var uploadSkillScript = makeAssetUploadCommand(
1632
+ "+upload-skill-script",
1633
+ "Upload a single file to a Skill scripts directory (max 1MB)",
1634
+ "scripts",
1635
+ false
1636
+ );
1637
+ var readSkillScript = makeAssetReadCommand(
1638
+ "+read-skill-script",
1639
+ "Read a Skill script file (binary-safe; use --output to save to disk)",
1640
+ "scripts"
1641
+ );
1642
+ var delSkillScript = makeAssetDelCommand(
1643
+ "+del-skill-script",
1644
+ "Delete a file from a Skill scripts directory",
1645
+ "scripts"
1646
+ );
1647
+ var uploadSkill = {
1648
+ service: "agent",
1649
+ command: "+upload-skill",
1650
+ description: "Upload a ZIP-format Skill (parses SKILL.md + extracts to target dir)",
1651
+ flags: [
1652
+ { name: "file", type: "string", required: true, desc: "Local .zip file path" },
1653
+ { name: "scope", type: "string", required: false, default: "personal", desc: "Target scope: personal | company" },
1654
+ { name: "auto-rename", type: "boolean", required: false, desc: "Auto-rename on name conflict" },
1655
+ { name: "replace-skill-id", type: "string", required: false, desc: "Replace an existing Skill (CUID) instead of creating a new one" },
1656
+ { name: "category", type: "string", required: false, desc: `Market category key: ${MARKET_CATEGORIES.join(" | ")}` },
1657
+ { name: "name", type: "string", required: false, desc: "Override Skill name (from ZIP SKILL.md if omitted)" },
1658
+ { name: "display-name", type: "string", required: false, desc: "Override display name" },
1659
+ { name: "description", type: "string", required: false, desc: "Override description" },
1660
+ { name: "instructions", type: "string", required: false, desc: "Override instructions (use @- to read from stdin)" },
1661
+ { name: "icon-emoji", type: "string", required: false, desc: "Market icon emoji (e.g. robot)" },
1662
+ { name: "icon-color", type: "string", required: false, desc: "Market icon color (e.g. #1E76F0)" }
1663
+ ],
1664
+ risk: "write",
1665
+ validate: (ctx) => {
1666
+ const filePath = ctx.str("file");
1667
+ if (!filePath) throw new Error("--file is required");
1668
+ const resolved = resolve(filePath);
1669
+ if (!existsSync(resolved)) throw new Error(`File not found: ${resolved}`);
1670
+ const ext = extname(resolved).toLowerCase();
1671
+ if (ext !== ".zip") throw new Error("--file must be a .zip file");
1672
+ const scope = ctx.str("scope");
1673
+ if (scope && !["personal", "company"].includes(scope)) {
1674
+ throw new Error("--scope must be personal or company");
1675
+ }
1676
+ const category = ctx.str("category");
1677
+ if (category && !isValidMarketCategory(category)) {
1678
+ throw new Error(`--category must be one of: ${MARKET_CATEGORIES.join(", ")}`);
1679
+ }
1680
+ },
1681
+ dryRun: (ctx) => {
1682
+ const body = {
1683
+ file: ctx.str("file"),
1684
+ scope: ctx.str("scope") || "personal"
1685
+ };
1686
+ if (ctx.bool("autoRename")) body.autoRename = true;
1687
+ if (ctx.str("replaceSkillId")) body.replaceSkillId = ctx.str("replaceSkillId");
1688
+ if (ctx.str("category")) body.category = ctx.str("category");
1689
+ if (ctx.str("name")) body.name = ctx.str("name");
1690
+ if (ctx.str("displayName")) body.displayName = ctx.str("displayName");
1691
+ if (ctx.str("description")) body.description = ctx.str("description");
1692
+ if (ctx.str("instructions")) body.instructions = ctx.str("instructions") === "@-" ? "(from stdin)" : ctx.str("instructions");
1693
+ if (ctx.str("iconEmoji")) body.iconEmoji = ctx.str("iconEmoji");
1694
+ if (ctx.str("iconColor")) body.iconColor = ctx.str("iconColor");
1695
+ return {
1696
+ method: "POST",
1697
+ url: `${BASE_PATH5}/upload`,
1698
+ body
1699
+ };
1700
+ },
1701
+ execute: async (ctx) => {
1702
+ const filePath = ctx.str("file");
1703
+ const resolved = resolve(filePath);
1704
+ const buffer = readFileSync(resolved);
1705
+ const fileName = basename(resolved);
1706
+ const fd = new FormData();
1707
+ const blob = new Blob([new Uint8Array(buffer)], { type: "application/zip" });
1708
+ fd.append("file", blob, fileName);
1709
+ const scope = ctx.str("scope") || "personal";
1710
+ fd.append("scope", scope);
1711
+ if (ctx.bool("autoRename")) fd.append("autoRename", "true");
1712
+ if (ctx.str("replaceSkillId")) fd.append("replaceSkillId", ctx.str("replaceSkillId"));
1713
+ if (ctx.str("category")) fd.append("category", ctx.str("category"));
1714
+ if (ctx.str("name")) fd.append("name", ctx.str("name"));
1715
+ if (ctx.str("displayName")) fd.append("displayName", ctx.str("displayName"));
1716
+ if (ctx.str("description")) fd.append("description", ctx.str("description"));
1717
+ if (ctx.str("instructions")) {
1718
+ const instructions = await resolveInstructions3(ctx.str("instructions"));
1719
+ fd.append("instructions", instructions);
1720
+ }
1721
+ if (ctx.str("iconEmoji")) fd.append("iconEmoji", ctx.str("iconEmoji"));
1722
+ if (ctx.str("iconColor")) fd.append("iconColor", ctx.str("iconColor"));
1723
+ return uploadToMainApp(`${BASE_PATH5}/upload`, fd);
1724
+ }
1725
+ };
1726
+ var rescanSkills = {
1727
+ service: "agent",
1728
+ command: "+rescan-skills",
1729
+ description: "Rescan Skill files and sync to database (root only)",
1730
+ flags: [],
1731
+ risk: "write",
1732
+ dryRun: () => ({
1733
+ method: "POST",
1734
+ url: `${BASE_PATH5}/rescan`
1735
+ }),
1736
+ execute: async () => {
1737
+ return postToMainApp(`${BASE_PATH5}/rescan`, {});
1738
+ }
1739
+ };
1740
+
705
1741
  // src/commands/te-agent/skill-approvals.ts
706
- var BASE = "/api/skills";
1742
+ var BASE = "/api/sandbox/agent/skills";
707
1743
  var submitSkill = {
708
1744
  service: "agent",
709
1745
  command: "+submit-skill",
@@ -843,7 +1879,7 @@ var rejectSkill = {
843
1879
  };
844
1880
 
845
1881
  // src/commands/te-agent/skill-shares.ts
846
- var BASE2 = "/api/skills";
1882
+ var BASE2 = "/api/sandbox/agent/skills";
847
1883
  var shareSkill = {
848
1884
  service: "agent",
849
1885
  command: "+share-skill",
@@ -955,12 +1991,13 @@ var rejectSkillShare = {
955
1991
  };
956
1992
 
957
1993
  // src/commands/te-agent/attachments.ts
958
- import { readFileSync, existsSync } from "fs";
959
- import { resolve, basename, extname } from "path";
960
- var LIST_PATH2 = "/api/sandbox/agent/attachments";
1994
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
1995
+ import { resolve as resolve2, basename as basename2, extname as extname2 } from "path";
1996
+ var LIST_PATH = "/api/sandbox/agent/attachments";
961
1997
  var UPLOAD_PATH = "/api/sandbox/agent/attachments/upload";
962
- function guessMimeType(filePath) {
963
- const ext = extname(filePath).toLowerCase();
1998
+ var STATS_PATH2 = "/api/sandbox/agent/attachments/stats";
1999
+ function guessMimeType2(filePath) {
2000
+ const ext = extname2(filePath).toLowerCase();
964
2001
  const map = {
965
2002
  ".png": "image/png",
966
2003
  ".jpg": "image/jpeg",
@@ -1009,14 +2046,14 @@ function resolveFilePaths(ctx) {
1009
2046
  async function uploadFiles(filePaths) {
1010
2047
  const formData = new FormData();
1011
2048
  for (const filePath of filePaths) {
1012
- const resolved = resolve(filePath);
1013
- if (!existsSync(resolved)) {
2049
+ const resolved = resolve2(filePath);
2050
+ if (!existsSync2(resolved)) {
1014
2051
  throw new Error(`File not found: ${resolved}`);
1015
2052
  }
1016
- const buffer = readFileSync(resolved);
1017
- const mimeType = guessMimeType(resolved);
2053
+ const buffer = readFileSync2(resolved);
2054
+ const mimeType = guessMimeType2(resolved);
1018
2055
  const blob = new Blob([buffer], { type: mimeType });
1019
- formData.append("file", blob, basename(resolved));
2056
+ formData.append("file", blob, basename2(resolved));
1020
2057
  }
1021
2058
  return uploadToMainApp(UPLOAD_PATH, formData);
1022
2059
  }
@@ -1044,7 +2081,7 @@ var listAttachments = {
1044
2081
  if (ctx.num("page")) params.set("page", String(ctx.num("page")));
1045
2082
  if (ctx.num("pageSize")) params.set("pageSize", String(ctx.num("pageSize")));
1046
2083
  const qs = params.toString();
1047
- return { method: "GET", url: `${LIST_PATH2}${qs ? "?" + qs : ""}` };
2084
+ return { method: "GET", url: `${LIST_PATH}${qs ? "?" + qs : ""}` };
1048
2085
  },
1049
2086
  execute: async (ctx) => {
1050
2087
  const params = new URLSearchParams();
@@ -1053,7 +2090,7 @@ var listAttachments = {
1053
2090
  if (ctx.num("page")) params.set("page", String(ctx.num("page")));
1054
2091
  if (ctx.num("pageSize")) params.set("pageSize", String(ctx.num("pageSize")));
1055
2092
  const qs = params.toString();
1056
- return getFromMainApp(`${LIST_PATH2}${qs ? "?" + qs : ""}`);
2093
+ return getFromMainApp(`${LIST_PATH}${qs ? "?" + qs : ""}`);
1057
2094
  }
1058
2095
  };
1059
2096
  var addAttachment = {
@@ -1087,15 +2124,29 @@ var delAttachment = {
1087
2124
  risk: "write",
1088
2125
  dryRun: (ctx) => ({
1089
2126
  method: "DELETE",
1090
- url: `${LIST_PATH2}?id=${encodeURIComponent(ctx.str("id"))}`
2127
+ url: `${LIST_PATH}?id=${encodeURIComponent(ctx.str("id"))}`
1091
2128
  }),
1092
2129
  execute: async (ctx) => {
1093
- return deleteFromMainApp(`${LIST_PATH2}?id=${encodeURIComponent(ctx.str("id"))}`);
2130
+ return deleteFromMainApp(`${LIST_PATH}?id=${encodeURIComponent(ctx.str("id"))}`);
2131
+ }
2132
+ };
2133
+ var attachmentStats = {
2134
+ service: "agent",
2135
+ command: "+attachment-stats",
2136
+ description: "Show attachment library statistics (total files, size, images, documents)",
2137
+ flags: [],
2138
+ risk: "read",
2139
+ dryRun: () => ({
2140
+ method: "GET",
2141
+ url: STATS_PATH2
2142
+ }),
2143
+ execute: async () => {
2144
+ return getFromMainApp(STATS_PATH2);
1094
2145
  }
1095
2146
  };
1096
2147
 
1097
2148
  // src/commands/te-agent/automations.ts
1098
- var BASE_PATH5 = "/api/sandbox/agent/automations";
2149
+ var BASE_PATH6 = "/api/sandbox/agent/automations";
1099
2150
  var SCHEDULE_KINDS = ["hourly", "daily", "weekly", "monthly"];
1100
2151
  var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)$/;
1101
2152
  var AUTOMATION_STATUSES = ["active", "paused"];
@@ -1208,7 +2259,7 @@ function buildListPath(ctx) {
1208
2259
  if (status) params.set("status", status);
1209
2260
  if (limit) params.set("limit", String(ctx.num("limit")));
1210
2261
  const query = params.toString();
1211
- return query ? `${BASE_PATH5}?${query}` : BASE_PATH5;
2262
+ return query ? `${BASE_PATH6}?${query}` : BASE_PATH6;
1212
2263
  }
1213
2264
  function validateList(ctx) {
1214
2265
  const status = optional(ctx.str("status"));
@@ -1222,7 +2273,7 @@ function validateList(ctx) {
1222
2273
  }
1223
2274
  }
1224
2275
  }
1225
- function buildUpdateBody(ctx) {
2276
+ function buildUpdateBody2(ctx) {
1226
2277
  const enabled = readEnabledOptional(ctx);
1227
2278
  const body = {};
1228
2279
  const name = optional(ctx.str("name"));
@@ -1238,7 +2289,7 @@ function buildUpdateBody(ctx) {
1238
2289
  }
1239
2290
  function validateUpdate(ctx) {
1240
2291
  validateSchedule(ctx, false);
1241
- if (!Object.keys(buildUpdateBody(ctx)).length) {
2292
+ if (!Object.keys(buildUpdateBody2(ctx)).length) {
1242
2293
  throw new Error("\u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u66F4\u65B0\u5B57\u6BB5");
1243
2294
  }
1244
2295
  }
@@ -1370,10 +2421,10 @@ var createAutomation = {
1370
2421
  },
1371
2422
  dryRun: (ctx) => ({
1372
2423
  method: "POST",
1373
- url: BASE_PATH5,
2424
+ url: BASE_PATH6,
1374
2425
  body: buildCreateBody(ctx)
1375
2426
  }),
1376
- execute: async (ctx) => postToMainApp(BASE_PATH5, buildCreateBody(ctx))
2427
+ execute: async (ctx) => postToMainApp(BASE_PATH6, buildCreateBody(ctx))
1377
2428
  };
1378
2429
  var updateAutomation = {
1379
2430
  service: "agent",
@@ -1410,31 +2461,47 @@ var updateAutomation = {
1410
2461
  validate: validateUpdate,
1411
2462
  dryRun: (ctx) => ({
1412
2463
  method: "PATCH",
1413
- url: `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}`,
1414
- body: buildUpdateBody(ctx)
2464
+ url: `${BASE_PATH6}/${encodeURIComponent(ctx.str("id"))}`,
2465
+ body: buildUpdateBody2(ctx)
1415
2466
  }),
1416
2467
  execute: async (ctx) => patchToMainApp(
1417
- `${BASE_PATH5}/${encodeURIComponent(ctx.str("id"))}`,
1418
- buildUpdateBody(ctx)
2468
+ `${BASE_PATH6}/${encodeURIComponent(ctx.str("id"))}`,
2469
+ buildUpdateBody2(ctx)
1419
2470
  )
1420
2471
  };
1421
2472
 
1422
2473
  // src/commands/te-agent/index.ts
1423
2474
  var commands = [
1424
- // Agent query
2475
+ // Agent CRUD
1425
2476
  listAgents,
1426
- // Model management
2477
+ createAgent,
2478
+ updateAgent,
2479
+ delAgent,
2480
+ getAgent,
2481
+ // Model management + test
1427
2482
  listModels,
1428
2483
  addModel,
1429
2484
  delModel,
1430
2485
  toggleModel,
1431
- // MCP server management + market
2486
+ updateModel,
2487
+ testModel,
2488
+ // MCP server management + market + OAuth + credentials
1432
2489
  listMcps,
1433
2490
  addMcp,
1434
2491
  delMcp,
1435
2492
  toggleMcp,
1436
2493
  listMcpMarket,
1437
2494
  setMcpMeta,
2495
+ updateMcp,
2496
+ mcpTools,
2497
+ mcpAuthStart,
2498
+ mcpAuthStatus,
2499
+ mcpAuthDisconnect,
2500
+ listMcpCredentials,
2501
+ setMcpCredential,
2502
+ autoProvisionMcpCredentials,
2503
+ mcpToken,
2504
+ mcpStats,
1438
2505
  // Skill management + market + copy
1439
2506
  listSkills,
1440
2507
  addSkill,
@@ -1443,6 +2510,23 @@ var commands = [
1443
2510
  listSkillMarket,
1444
2511
  setSkillMeta,
1445
2512
  copySkill,
2513
+ // Skill content + assets (references / assets / scripts)
2514
+ editSkill,
2515
+ getSkillContent,
2516
+ listSkillAssets,
2517
+ uploadSkillAsset,
2518
+ readSkillAsset,
2519
+ delSkillAsset,
2520
+ listSkillReferences,
2521
+ uploadSkillReference,
2522
+ readSkillReference,
2523
+ delSkillReference,
2524
+ listSkillScripts,
2525
+ uploadSkillScript,
2526
+ readSkillScript,
2527
+ delSkillScript,
2528
+ uploadSkill,
2529
+ rescanSkills,
1446
2530
  // Skill approval (company-scope publish)
1447
2531
  submitSkill,
1448
2532
  listSkillSubmissions,
@@ -1458,6 +2542,7 @@ var commands = [
1458
2542
  listAttachments,
1459
2543
  addAttachment,
1460
2544
  delAttachment,
2545
+ attachmentStats,
1461
2546
  // Automate tasks
1462
2547
  listAutomations,
1463
2548
  createAutomation,