@thinkingai/ae-cli 1.0.27 → 1.0.30
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.
- package/README.md +1 -16
- package/README.zh.md +1 -16
- package/dist/auth-H3GJD55A.js +457 -0
- package/dist/{auth-TXFJHPXU.js → auth-U25QJU5D.js} +3 -3
- package/dist/{chunk-B4UL2VIJ.js → chunk-CLJF7MQA.js} +1 -1
- package/dist/{chunk-6T7245YE.js → chunk-EGEIXA2Z.js} +90 -18
- package/dist/{chunk-2NGWYMLB.js → chunk-GLNZSDKO.js} +88 -50
- package/dist/chunk-GSJGPNKK.js +49 -0
- package/dist/{chunk-VT6VC4PA.js → chunk-I42JGQ2J.js} +26 -11
- package/dist/chunk-JM34JPCO.js +239 -0
- package/dist/chunk-NOO24N7W.js +11 -0
- package/dist/chunk-SF3KTPIC.js +98 -0
- package/dist/chunk-SRJIAOBN.js +244 -0
- package/dist/chunk-U6TKB3IV.js +171 -0
- package/dist/{chunk-TG64AQV4.js → chunk-VJFUB3H3.js} +99 -56
- package/dist/{client-IU2E5IOL.js → client-IN42F223.js} +4 -4
- package/dist/config-64G36TJL.js +130 -0
- package/dist/index.js +52 -25
- package/dist/{model-CC7U5XOJ.js → model-VZCYNIOG.js} +11 -10
- package/dist/{raw-TUHZQ4UB.js → raw-WJIWC6YP.js} +13 -7
- package/dist/{sync-EVEDS7YE.js → sync-NVASAISS.js} +146 -47
- package/dist/{te-agent-FLTDYV3L.js → te-agent-YV4DXEXK.js} +24 -23
- package/dist/{te-analysis-CMXADIJM.js → te-analysis-CB3DA5I5.js} +61 -13
- package/dist/{te-audience-LPZFFSXM.js → te-audience-W7SCQFC7.js} +7 -5
- package/dist/{te-common-BXQFKTB3.js → te-common-FBXVWBSI.js} +21 -9
- package/dist/{te-community-K5S3VOZY.js → te-community-LNVDZSGW.js} +6 -4
- package/dist/{te-dataops-567IMCQG.js → te-dataops-IPCSSWYH.js} +29 -27
- package/dist/{te-engage-TBUTGW5F.js → te-engage-KARARMIR.js} +6 -4
- package/dist/{te-kb-XHVBWP5E.js → te-kb-2Z2CARN3.js} +7 -5
- package/dist/{te-meta-NQ4U3VJW.js → te-meta-PDKLMWXN.js} +6 -4
- package/dist/{te-team-556APRIU.js → te-team-SW5B7DHO.js} +17 -12
- package/package.json +6 -2
- package/skills/ae-agent/SKILL.md +2 -1
- package/skills/ae-analysis/SKILL.md +1 -1
- package/skills/ae-analysis/references/list_clusters.md +4 -2
- package/skills/ae-analysis-global/SKILL.md +51 -0
- package/skills/ae-analysis-global/references/list_query_clusters.md +67 -0
- package/skills/ae-community/SKILL.md +2 -3
- package/skills/ae-dataops/SKILL.md +1 -2
- package/skills/ae-engage/SKILL.md +1 -0
- package/skills/ae-engage/references/add-approver.md +0 -1
- package/skills/ae-engage/references/add-channel.md +0 -1
- package/skills/ae-engage/references/approver-list.md +0 -1
- package/skills/ae-engage/references/cancel-query-by-request-id.md +0 -1
- package/skills/ae-engage/references/channel-detail.md +0 -1
- package/skills/ae-engage/references/channel-list.md +0 -1
- package/skills/ae-engage/references/config-channel-detail.md +0 -1
- package/skills/ae-engage/references/config-channel-list.md +0 -1
- package/skills/ae-engage/references/config-item-analysis-report.md +0 -1
- package/skills/ae-engage/references/config-item-detail.md +0 -1
- package/skills/ae-engage/references/config-item-list.md +0 -1
- package/skills/ae-engage/references/config-item-strategy-comparison.md +0 -1
- package/skills/ae-engage/references/config-item-trigger-report.md +0 -1
- package/skills/ae-engage/references/copy-config-template.md +0 -1
- package/skills/ae-engage/references/delete-channel.md +0 -1
- package/skills/ae-engage/references/delete-config-channel.md +0 -1
- package/skills/ae-engage/references/delete-config-item.md +0 -1
- package/skills/ae-engage/references/delete-flow.md +0 -1
- package/skills/ae-engage/references/flow-ab-split-node-report.md +0 -1
- package/skills/ae-engage/references/flow-detail.md +0 -1
- package/skills/ae-engage/references/flow-list.md +0 -1
- package/skills/ae-engage/references/flow-node-config-schema.md +0 -1
- package/skills/ae-engage/references/flow-node-detail-report.md +0 -1
- package/skills/ae-engage/references/flow-node-overview-report.md +0 -1
- package/skills/ae-engage/references/flow-process-report.md +0 -1
- package/skills/ae-engage/references/manage-flow.md +0 -1
- package/skills/ae-engage/references/manage-strategy.md +0 -1
- package/skills/ae-engage/references/manage-task.md +0 -1
- package/skills/ae-engage/references/modify-flow-base-info.md +0 -1
- package/skills/ae-engage/references/strategy-detail.md +0 -1
- package/skills/ae-engage/references/strategy-list.md +0 -1
- package/skills/ae-engage/references/task-data-detail.md +0 -1
- package/skills/ae-engage/references/task-data-overview.md +0 -1
- package/skills/ae-engage/references/task-detail.md +0 -1
- package/skills/ae-engage/references/task-experiment-report.md +0 -1
- package/skills/ae-engage/references/task-list.md +0 -1
- package/skills/ae-engage/references/task-metric-detail.md +0 -1
- package/skills/ae-engage/references/task-stats.md +0 -1
- package/skills/ae-engage/references/update-channel-status.md +0 -1
- package/skills/ae-engage/references/update-config-channel-status.md +0 -1
- package/skills/ae-engage/references/validate-flow-node-config.md +0 -1
- package/skills/ae-engage/references/whitelist-list.md +0 -1
- package/skills/ae-kb/SKILL.md +1 -0
- package/skills/ae-team/SKILL.md +1 -1
- package/dist/auth-W2JZ3DKA.js +0 -170
- package/dist/chunk-BI5ZVD6T.js +0 -186
- package/dist/chunk-MNHE6SSI.js +0 -79
- package/dist/chunk-MWWYGZ76.js +0 -130
- package/dist/chunk-SRRUNQIM.js +0 -312
- package/dist/config-WH3R3IRY.js +0 -258
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MultiselectCancelled,
|
|
3
3
|
SKILL_MANIFEST_FILE,
|
|
4
|
+
assertValidMcpName,
|
|
5
|
+
assertValidSkillSlug,
|
|
4
6
|
describeSource,
|
|
5
7
|
getCurrentWorkspace,
|
|
6
8
|
promptMultiselect,
|
|
@@ -8,19 +10,20 @@ import {
|
|
|
8
10
|
readSkillManifestEntries,
|
|
9
11
|
scanMcps,
|
|
10
12
|
scanSkills,
|
|
13
|
+
splitPushableMcps,
|
|
11
14
|
writeSkillManifestEntries
|
|
12
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-EGEIXA2Z.js";
|
|
13
16
|
import {
|
|
14
17
|
TeAgentApiError,
|
|
15
18
|
TeAgentCredentialsError,
|
|
16
19
|
getSandboxSyncPullCandidates,
|
|
17
20
|
postSandboxSyncPull,
|
|
18
21
|
postToMainApp
|
|
19
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-VJFUB3H3.js";
|
|
20
23
|
import {
|
|
21
24
|
printError
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-CLJF7MQA.js";
|
|
26
|
+
import "./chunk-SRJIAOBN.js";
|
|
24
27
|
|
|
25
28
|
// src/commands/sync/index.ts
|
|
26
29
|
import Table from "cli-table3";
|
|
@@ -30,19 +33,57 @@ import {
|
|
|
30
33
|
cpSync,
|
|
31
34
|
existsSync,
|
|
32
35
|
mkdirSync,
|
|
36
|
+
readFileSync,
|
|
33
37
|
realpathSync,
|
|
34
38
|
rmSync,
|
|
35
|
-
statSync
|
|
39
|
+
statSync,
|
|
40
|
+
writeFileSync
|
|
36
41
|
} from "fs";
|
|
37
42
|
import path from "path";
|
|
38
|
-
var
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
var MCP_MANIFEST_FILE = ".mcp-manifest.json";
|
|
44
|
+
function isMcpScope(value) {
|
|
45
|
+
return value === "personal" || value === "company" || value === "system";
|
|
46
|
+
}
|
|
47
|
+
function uniqueMcpEntries(entries) {
|
|
48
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
if (seen.has(entry.name)) continue;
|
|
52
|
+
seen.add(entry.name);
|
|
53
|
+
out.push(entry);
|
|
42
54
|
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function readMcpManifestEntries(manifestPath) {
|
|
58
|
+
if (!existsSync(manifestPath)) return [];
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
62
|
+
} catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
if (!Array.isArray(parsed)) return [];
|
|
66
|
+
const entries = [];
|
|
67
|
+
for (const item of parsed) {
|
|
68
|
+
if (!item || typeof item !== "object") continue;
|
|
69
|
+
const entry = item;
|
|
70
|
+
if (typeof entry.name !== "string" || !isMcpScope(entry.scope)) continue;
|
|
71
|
+
entries.push({ name: entry.name, scope: entry.scope });
|
|
72
|
+
}
|
|
73
|
+
return uniqueMcpEntries(entries);
|
|
74
|
+
}
|
|
75
|
+
function writeMcpManifestEntries(manifestPath, entries) {
|
|
76
|
+
writeFileSync(
|
|
77
|
+
manifestPath,
|
|
78
|
+
JSON.stringify(uniqueMcpEntries(entries), null, 2) + "\n",
|
|
79
|
+
"utf8"
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function updateSkillManifestForSource(sourceDir, slug) {
|
|
83
|
+
assertValidSkillSlug(slug);
|
|
43
84
|
const sourceAbs = path.resolve(sourceDir);
|
|
44
85
|
if (!statSync(sourceAbs).isDirectory()) {
|
|
45
|
-
throw new Error(`Skill
|
|
86
|
+
throw new Error(`Skill source path is not a directory: ${sourceDir}`);
|
|
46
87
|
}
|
|
47
88
|
const manifestPath = path.join(path.dirname(sourceAbs), SKILL_MANIFEST_FILE);
|
|
48
89
|
const manifest = readSkillManifestEntries(manifestPath);
|
|
@@ -60,16 +101,36 @@ function updateSkillManifestForSource(sourceDir, slug) {
|
|
|
60
101
|
writeSkillManifestEntries(manifestPath, nextManifest);
|
|
61
102
|
return { manifestPath, changed: true };
|
|
62
103
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
|
|
104
|
+
function updateMcpManifestForProjectSource(workspaceDir, name) {
|
|
105
|
+
assertValidMcpName(name);
|
|
106
|
+
const workspaceAbs = path.resolve(workspaceDir);
|
|
107
|
+
if (!statSync(workspaceAbs).isDirectory()) {
|
|
108
|
+
throw new Error(`MCP workspace path is not a directory: ${workspaceDir}`);
|
|
109
|
+
}
|
|
110
|
+
const manifestPath = path.join(workspaceAbs, MCP_MANIFEST_FILE);
|
|
111
|
+
const manifest = readMcpManifestEntries(manifestPath);
|
|
112
|
+
const nextEntry = { name, scope: "personal" };
|
|
113
|
+
const existingIndex = manifest.findIndex((entry) => entry.name === name);
|
|
114
|
+
if (existingIndex >= 0 && manifest[existingIndex].scope === nextEntry.scope) {
|
|
115
|
+
return { manifestPath, changed: false };
|
|
116
|
+
}
|
|
117
|
+
const nextManifest = manifest.slice();
|
|
118
|
+
if (existingIndex >= 0) {
|
|
119
|
+
nextManifest[existingIndex] = nextEntry;
|
|
120
|
+
} else {
|
|
121
|
+
nextManifest.push(nextEntry);
|
|
66
122
|
}
|
|
123
|
+
writeMcpManifestEntries(manifestPath, nextManifest);
|
|
124
|
+
return { manifestPath, changed: true };
|
|
125
|
+
}
|
|
126
|
+
function copySkillPackageToTarget(args) {
|
|
127
|
+
assertValidSkillSlug(args.slug);
|
|
67
128
|
if (!path.isAbsolute(args.targetRoot)) {
|
|
68
|
-
throw new Error(`skillTargetRoot
|
|
129
|
+
throw new Error(`skillTargetRoot must be an absolute path: ${args.targetRoot}`);
|
|
69
130
|
}
|
|
70
131
|
const sourceReal = realpathSync(args.sourceDir);
|
|
71
132
|
if (!statSync(sourceReal).isDirectory()) {
|
|
72
|
-
throw new Error(`Skill
|
|
133
|
+
throw new Error(`Skill source path is not a directory: ${args.sourceDir}`);
|
|
73
134
|
}
|
|
74
135
|
const targetDir = path.join(args.targetRoot, args.slug);
|
|
75
136
|
const targetAbs = path.resolve(targetDir);
|
|
@@ -101,6 +162,13 @@ function redactEnv(env) {
|
|
|
101
162
|
}
|
|
102
163
|
return out;
|
|
103
164
|
}
|
|
165
|
+
var SOURCE_ORDER = {
|
|
166
|
+
global: 0,
|
|
167
|
+
workspace: 1,
|
|
168
|
+
project: 0,
|
|
169
|
+
local: 1,
|
|
170
|
+
user: 2
|
|
171
|
+
};
|
|
104
172
|
function skillToItem(s) {
|
|
105
173
|
return {
|
|
106
174
|
kind: "skill",
|
|
@@ -122,6 +190,7 @@ function mcpToItem(m, includeSecrets) {
|
|
|
122
190
|
scope: "personal",
|
|
123
191
|
source: m.source,
|
|
124
192
|
workspacePath: m.workspacePath,
|
|
193
|
+
workspaceDir: m.workspaceDir,
|
|
125
194
|
event: "upsert",
|
|
126
195
|
transport: m.transport,
|
|
127
196
|
url: m.url,
|
|
@@ -134,11 +203,11 @@ function mcpToItem(m, includeSecrets) {
|
|
|
134
203
|
async function selectSkills() {
|
|
135
204
|
const all = scanSkills();
|
|
136
205
|
if (all.length === 0) {
|
|
137
|
-
process.stderr.write("
|
|
206
|
+
process.stderr.write("No Skills found (scanned current workspace .claude/skills)\n");
|
|
138
207
|
return [];
|
|
139
208
|
}
|
|
140
209
|
all.sort((a, b) => {
|
|
141
|
-
if (a.source !== b.source) return a.source
|
|
210
|
+
if (a.source !== b.source) return SOURCE_ORDER[a.source] - SOURCE_ORDER[b.source];
|
|
142
211
|
return a.slug.localeCompare(b.slug);
|
|
143
212
|
});
|
|
144
213
|
const items = all.map((s) => ({
|
|
@@ -147,26 +216,36 @@ async function selectSkills() {
|
|
|
147
216
|
group: describeSource(s),
|
|
148
217
|
hint: s.isSymlink ? "(symlink)" : void 0
|
|
149
218
|
}));
|
|
150
|
-
const picked = await promptMultiselect({ title: "
|
|
219
|
+
const picked = await promptMultiselect({ title: "Select Skills to push to the main app", items });
|
|
151
220
|
return picked.map(skillToItem);
|
|
152
221
|
}
|
|
153
222
|
async function selectMcps(includeSecrets) {
|
|
154
223
|
const all = scanMcps();
|
|
155
224
|
if (all.length === 0) {
|
|
156
|
-
process.stderr.write("
|
|
225
|
+
process.stderr.write("No MCPs found (scanned current workspace .mcp.json / .claude/.claude.json and global ~/.claude.json)\n");
|
|
157
226
|
return [];
|
|
158
227
|
}
|
|
159
|
-
|
|
160
|
-
|
|
228
|
+
const { supported, unsupportedStdio } = splitPushableMcps(all);
|
|
229
|
+
if (unsupportedStdio.length > 0) {
|
|
230
|
+
const names = unsupportedStdio.map((m) => m.slug).sort().join(", ");
|
|
231
|
+
process.stderr.write(`ae-cli sync push only supports http/sse MCPs; skipped stdio MCPs: ${names}
|
|
232
|
+
`);
|
|
233
|
+
}
|
|
234
|
+
if (supported.length === 0) {
|
|
235
|
+
process.stderr.write("No syncable MCPs found. ae-cli sync push only supports http/sse.\n");
|
|
236
|
+
return [];
|
|
237
|
+
}
|
|
238
|
+
supported.sort((a, b) => {
|
|
239
|
+
if (a.source !== b.source) return SOURCE_ORDER[a.source] - SOURCE_ORDER[b.source];
|
|
161
240
|
return a.slug.localeCompare(b.slug);
|
|
162
241
|
});
|
|
163
|
-
const items =
|
|
242
|
+
const items = supported.map((m) => ({
|
|
164
243
|
value: m,
|
|
165
244
|
label: m.slug,
|
|
166
245
|
group: describeSource(m),
|
|
167
|
-
hint: m.hasSecrets && !includeSecrets ? "(env
|
|
246
|
+
hint: m.hasSecrets && !includeSecrets ? "(env redacted)" : void 0
|
|
168
247
|
}));
|
|
169
|
-
const picked = await promptMultiselect({ title: "
|
|
248
|
+
const picked = await promptMultiselect({ title: "Select MCPs to push to the main app", items });
|
|
170
249
|
return picked.map((m) => mcpToItem(m, includeSecrets));
|
|
171
250
|
}
|
|
172
251
|
function renderResults(results) {
|
|
@@ -178,7 +257,7 @@ function renderResults(results) {
|
|
|
178
257
|
const failed = results.filter((r) => r.status === "failed").length;
|
|
179
258
|
if (failed > 0) {
|
|
180
259
|
process.stderr.write(`
|
|
181
|
-
\u2717
|
|
260
|
+
\u2717 ${failed} item(s) failed
|
|
182
261
|
`);
|
|
183
262
|
}
|
|
184
263
|
}
|
|
@@ -193,7 +272,7 @@ async function selectPullResources(args) {
|
|
|
193
272
|
return scopeDiff !== 0 ? scopeDiff : a.name.localeCompare(b.name);
|
|
194
273
|
});
|
|
195
274
|
if (all.length === 0) {
|
|
196
|
-
process.stderr.write(`${args.title}
|
|
275
|
+
process.stderr.write(`${args.title}: no candidates available to sync
|
|
197
276
|
`);
|
|
198
277
|
return [];
|
|
199
278
|
}
|
|
@@ -210,7 +289,7 @@ function toHttpItems(items) {
|
|
|
210
289
|
const { kind: _kind2, dirPath: _dirPath, ...rest2 } = item;
|
|
211
290
|
return rest2;
|
|
212
291
|
}
|
|
213
|
-
const { kind: _kind, ...rest } = item;
|
|
292
|
+
const { kind: _kind, workspaceDir: _workspaceDir, ...rest } = item;
|
|
214
293
|
return rest;
|
|
215
294
|
});
|
|
216
295
|
}
|
|
@@ -245,7 +324,7 @@ function copySyncedSkillPackages(skillItems, resp) {
|
|
|
245
324
|
if (!item) continue;
|
|
246
325
|
if (!resp.skillTargetRoot) {
|
|
247
326
|
result.status = "failed";
|
|
248
|
-
result.message = "
|
|
327
|
+
result.message = "Main app response is missing skillTargetRoot; cannot copy Skill package";
|
|
249
328
|
continue;
|
|
250
329
|
}
|
|
251
330
|
try {
|
|
@@ -256,34 +335,54 @@ function copySyncedSkillPackages(skillItems, resp) {
|
|
|
256
335
|
});
|
|
257
336
|
updateSkillManifestForSource(item.dirPath, item.slug);
|
|
258
337
|
if (copied.skipped) {
|
|
259
|
-
result.message = "
|
|
338
|
+
result.message = "Source directory is already the target directory; local copy skipped";
|
|
260
339
|
}
|
|
261
340
|
} catch (err) {
|
|
262
341
|
result.status = "failed";
|
|
263
|
-
result.message =
|
|
342
|
+
result.message = `Local copy failed: ${err?.message ?? String(err)}`;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function updateSyncedProjectMcpManifest(mcpItems, resp) {
|
|
347
|
+
if (mcpItems.length === 0) return;
|
|
348
|
+
const bySlug = new Map(mcpItems.map((item) => [item.slug, item]));
|
|
349
|
+
for (const result of resp.results) {
|
|
350
|
+
if (result.kind !== "mcp" || result.status !== "synced") continue;
|
|
351
|
+
const item = bySlug.get(result.slug);
|
|
352
|
+
if (!item || item.source !== "project") continue;
|
|
353
|
+
if (!item.workspaceDir) {
|
|
354
|
+
result.status = "failed";
|
|
355
|
+
result.message = "Main app synced the MCP, but local MCP manifest update failed: missing workspaceDir";
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
try {
|
|
359
|
+
updateMcpManifestForProjectSource(item.workspaceDir, item.slug);
|
|
360
|
+
} catch (err) {
|
|
361
|
+
result.status = "failed";
|
|
362
|
+
result.message = `Main app synced the MCP, but local MCP manifest update failed: ${err?.message ?? String(err)}`;
|
|
264
363
|
}
|
|
265
364
|
}
|
|
266
365
|
}
|
|
267
366
|
async function selectDirection(optsDirection) {
|
|
268
367
|
if (optsDirection === "push" || optsDirection === "pull") return optsDirection;
|
|
269
368
|
if (optsDirection) {
|
|
270
|
-
throw new Error("--direction
|
|
369
|
+
throw new Error("--direction must be push or pull");
|
|
271
370
|
}
|
|
272
371
|
return promptSingleSelect({
|
|
273
|
-
title: "
|
|
372
|
+
title: "Sync direction?",
|
|
274
373
|
items: [
|
|
275
|
-
{ value: "push", label: "
|
|
276
|
-
{ value: "pull", label: "
|
|
374
|
+
{ value: "push", label: "Workspace -> Main app" },
|
|
375
|
+
{ value: "pull", label: "Main app -> Workspace" }
|
|
277
376
|
]
|
|
278
377
|
});
|
|
279
378
|
}
|
|
280
379
|
async function selectKind(optsKind) {
|
|
281
380
|
if (optsKind === "skill" || optsKind === "mcp" || optsKind === "both") return optsKind;
|
|
282
381
|
if (optsKind) {
|
|
283
|
-
throw new Error("--kind
|
|
382
|
+
throw new Error("--kind must be skill, mcp, or both");
|
|
284
383
|
}
|
|
285
384
|
return promptSingleSelect({
|
|
286
|
-
title: "
|
|
385
|
+
title: "Which resource type to sync?",
|
|
287
386
|
items: [
|
|
288
387
|
{ value: "skill", label: "Skills" },
|
|
289
388
|
{ value: "mcp", label: "MCPs" },
|
|
@@ -295,10 +394,10 @@ async function runPush(kind, includeSecrets) {
|
|
|
295
394
|
const skillItems = kind !== "mcp" ? await selectSkills() : [];
|
|
296
395
|
const mcpItems = kind !== "skill" ? await selectMcps(includeSecrets) : [];
|
|
297
396
|
if (skillItems.length === 0 && mcpItems.length === 0) {
|
|
298
|
-
process.stderr.write("\
|
|
397
|
+
process.stderr.write("Nothing selected, exiting\n");
|
|
299
398
|
return;
|
|
300
399
|
}
|
|
301
|
-
process.stderr.write(
|
|
400
|
+
process.stderr.write(`Pushing ${skillItems.length} Skill(s) / ${mcpItems.length} MCP(s) ...
|
|
302
401
|
`);
|
|
303
402
|
const allResults = [];
|
|
304
403
|
if (skillItems.length > 0) {
|
|
@@ -308,6 +407,7 @@ async function runPush(kind, includeSecrets) {
|
|
|
308
407
|
}
|
|
309
408
|
if (mcpItems.length > 0) {
|
|
310
409
|
const mcpResp = await pushItems("mcp", mcpItems);
|
|
410
|
+
updateSyncedProjectMcpManifest(mcpItems, mcpResp);
|
|
311
411
|
allResults.push(...mcpResp.results);
|
|
312
412
|
}
|
|
313
413
|
renderResults(allResults);
|
|
@@ -323,32 +423,31 @@ function pullResultRows(resp) {
|
|
|
323
423
|
async function runPull(kind) {
|
|
324
424
|
const workspace = getCurrentWorkspace();
|
|
325
425
|
if (!workspace) {
|
|
326
|
-
throw new Error("
|
|
426
|
+
throw new Error("Current workspace not recognized; please run from within /home/ta/workspaces/<workspace>");
|
|
327
427
|
}
|
|
328
428
|
const candidates = await getSandboxSyncPullCandidates({
|
|
329
429
|
workspacePath: workspace.name,
|
|
330
430
|
kind
|
|
331
431
|
});
|
|
332
432
|
const skillItems = kind !== "mcp" ? await selectPullResources({
|
|
333
|
-
title: "
|
|
334
|
-
candidates: candidates.skills ?? []
|
|
433
|
+
title: "Select Skills to sync to workspace",
|
|
434
|
+
candidates: (candidates.skills ?? []).filter((candidate) => candidate.scope !== "system")
|
|
335
435
|
}) : [];
|
|
336
436
|
const mcpItems = kind !== "skill" ? await selectPullResources({
|
|
337
|
-
title: "
|
|
437
|
+
title: "Select MCPs to sync to workspace",
|
|
338
438
|
candidates: candidates.mcp ?? []
|
|
339
439
|
}) : [];
|
|
340
440
|
if (skillItems.length === 0 && mcpItems.length === 0) {
|
|
341
|
-
process.stderr.write("\
|
|
441
|
+
process.stderr.write("Nothing selected, exiting\n");
|
|
342
442
|
return;
|
|
343
443
|
}
|
|
344
|
-
process.stderr.write(
|
|
444
|
+
process.stderr.write(`Syncing to workspace: ${skillItems.length} Skill(s) / ${mcpItems.length} MCP(s) ...
|
|
345
445
|
`);
|
|
346
446
|
const resp = await postSandboxSyncPull({
|
|
347
447
|
workspacePath: workspace.name,
|
|
348
448
|
kind,
|
|
349
449
|
skills: skillItems.map((item) => item.id),
|
|
350
|
-
mcp: mcpItems.map((item) => item.id)
|
|
351
|
-
ifUnmodifiedSince: candidates.mtime
|
|
450
|
+
mcp: mcpItems.map((item) => item.id)
|
|
352
451
|
});
|
|
353
452
|
renderResults(pullResultRows(resp));
|
|
354
453
|
}
|
|
@@ -361,7 +460,7 @@ function registerSync(program) {
|
|
|
361
460
|
else await runPull(kind);
|
|
362
461
|
} catch (err) {
|
|
363
462
|
if (err instanceof MultiselectCancelled) {
|
|
364
|
-
process.stderr.write("\
|
|
463
|
+
process.stderr.write("Cancelled\n");
|
|
365
464
|
return;
|
|
366
465
|
}
|
|
367
466
|
if (err instanceof TeAgentCredentialsError) {
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
patchToMainApp,
|
|
5
5
|
postToMainApp,
|
|
6
6
|
uploadToMainApp
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VJFUB3H3.js";
|
|
8
|
+
import "./chunk-SRJIAOBN.js";
|
|
8
9
|
|
|
9
10
|
// src/commands/te-agent/models.ts
|
|
10
11
|
var BASE_PATH = "/api/sandbox/agent/models";
|
|
@@ -19,7 +20,7 @@ var listModels = {
|
|
|
19
20
|
validate: (ctx) => {
|
|
20
21
|
const scope = ctx.str("scope");
|
|
21
22
|
if (scope && !["personal", "company", "system"].includes(scope)) {
|
|
22
|
-
throw new Error("--scope
|
|
23
|
+
throw new Error("--scope must be personal, company, or system");
|
|
23
24
|
}
|
|
24
25
|
},
|
|
25
26
|
dryRun: (ctx) => {
|
|
@@ -52,7 +53,7 @@ var addModel = {
|
|
|
52
53
|
try {
|
|
53
54
|
new URL(baseUrl);
|
|
54
55
|
} catch {
|
|
55
|
-
throw new Error("--base-url
|
|
56
|
+
throw new Error("--base-url must be a valid URL");
|
|
56
57
|
}
|
|
57
58
|
},
|
|
58
59
|
dryRun: (ctx) => ({
|
|
@@ -131,7 +132,7 @@ var listMcps = {
|
|
|
131
132
|
validate: (ctx) => {
|
|
132
133
|
const scope = ctx.str("scope");
|
|
133
134
|
if (scope && !["personal", "company", "system"].includes(scope)) {
|
|
134
|
-
throw new Error("--scope
|
|
135
|
+
throw new Error("--scope must be personal, company, or system");
|
|
135
136
|
}
|
|
136
137
|
},
|
|
137
138
|
dryRun: (ctx) => {
|
|
@@ -161,22 +162,22 @@ var addMcp = {
|
|
|
161
162
|
validate: (ctx) => {
|
|
162
163
|
const name = ctx.str("name");
|
|
163
164
|
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {
|
|
164
|
-
throw new Error("--name
|
|
165
|
+
throw new Error("--name must start with a letter and contain only letters, digits, _, or -");
|
|
165
166
|
}
|
|
166
167
|
if (name.length < 2 || name.length > 64) {
|
|
167
|
-
throw new Error("--name
|
|
168
|
+
throw new Error("--name length must be between 2 and 64");
|
|
168
169
|
}
|
|
169
170
|
try {
|
|
170
171
|
new URL(ctx.str("url"));
|
|
171
172
|
} catch {
|
|
172
|
-
throw new Error("--url
|
|
173
|
+
throw new Error("--url must be a valid URL");
|
|
173
174
|
}
|
|
174
175
|
if (!/^https?:\/\//i.test(ctx.str("url"))) {
|
|
175
|
-
throw new Error("--url
|
|
176
|
+
throw new Error("--url only supports http:// or https:// protocols");
|
|
176
177
|
}
|
|
177
178
|
const transport = ctx.str("transport");
|
|
178
179
|
if (transport && !["sse", "http"].includes(transport)) {
|
|
179
|
-
throw new Error("--transport
|
|
180
|
+
throw new Error("--transport must be sse or http");
|
|
180
181
|
}
|
|
181
182
|
},
|
|
182
183
|
dryRun: (ctx) => ({
|
|
@@ -249,7 +250,7 @@ async function resolveInstructions(raw) {
|
|
|
249
250
|
chunks.push(chunk);
|
|
250
251
|
}
|
|
251
252
|
const text = Buffer.concat(chunks).toString("utf8").trim();
|
|
252
|
-
if (!text) throw new Error("stdin
|
|
253
|
+
if (!text) throw new Error("stdin is empty; cannot read instructions");
|
|
253
254
|
return text;
|
|
254
255
|
}
|
|
255
256
|
return raw;
|
|
@@ -265,7 +266,7 @@ var listSkills = {
|
|
|
265
266
|
validate: (ctx) => {
|
|
266
267
|
const scope = ctx.str("scope");
|
|
267
268
|
if (scope && !["personal", "company", "system"].includes(scope)) {
|
|
268
|
-
throw new Error("--scope
|
|
269
|
+
throw new Error("--scope must be personal, company, or system");
|
|
269
270
|
}
|
|
270
271
|
},
|
|
271
272
|
dryRun: (ctx) => {
|
|
@@ -293,7 +294,7 @@ var addSkill = {
|
|
|
293
294
|
validate: (ctx) => {
|
|
294
295
|
const name = ctx.str("name");
|
|
295
296
|
if (name.length < 1 || name.length > 80) {
|
|
296
|
-
throw new Error("--name
|
|
297
|
+
throw new Error("--name length must be between 1 and 80");
|
|
297
298
|
}
|
|
298
299
|
},
|
|
299
300
|
dryRun: (ctx) => ({
|
|
@@ -388,21 +389,21 @@ function resolveFilePaths(ctx) {
|
|
|
388
389
|
const file = ctx.str("file");
|
|
389
390
|
const files = ctx.str("files");
|
|
390
391
|
if (file && files) {
|
|
391
|
-
throw new Error("--file
|
|
392
|
+
throw new Error("--file and --files cannot be used together");
|
|
392
393
|
}
|
|
393
394
|
if (!file && !files) {
|
|
394
|
-
throw new Error("
|
|
395
|
+
throw new Error("Either --file or --files must be specified");
|
|
395
396
|
}
|
|
396
397
|
if (file) return [file];
|
|
397
398
|
try {
|
|
398
399
|
const parsed = JSON.parse(files);
|
|
399
|
-
if (!Array.isArray(parsed)) throw new Error("--files
|
|
400
|
+
if (!Array.isArray(parsed)) throw new Error("--files must be a JSON array");
|
|
400
401
|
return parsed.map((p) => {
|
|
401
|
-
if (typeof p !== "string") throw new Error("--files
|
|
402
|
+
if (typeof p !== "string") throw new Error("--files array elements must be strings");
|
|
402
403
|
return p;
|
|
403
404
|
});
|
|
404
405
|
} catch (err) {
|
|
405
|
-
if (err instanceof SyntaxError) throw new Error("--files
|
|
406
|
+
if (err instanceof SyntaxError) throw new Error("--files must be a valid JSON array");
|
|
406
407
|
throw err;
|
|
407
408
|
}
|
|
408
409
|
}
|
|
@@ -411,7 +412,7 @@ async function uploadFiles(filePaths) {
|
|
|
411
412
|
for (const filePath of filePaths) {
|
|
412
413
|
const resolved = resolve(filePath);
|
|
413
414
|
if (!existsSync(resolved)) {
|
|
414
|
-
throw new Error(
|
|
415
|
+
throw new Error(`File not found: ${resolved}`);
|
|
415
416
|
}
|
|
416
417
|
const buffer = readFileSync(resolved);
|
|
417
418
|
const mimeType = guessMimeType(resolved);
|
|
@@ -434,7 +435,7 @@ var listAttachments = {
|
|
|
434
435
|
validate: (ctx) => {
|
|
435
436
|
const type = ctx.str("type");
|
|
436
437
|
if (type && !["image", "document"].includes(type)) {
|
|
437
|
-
throw new Error("--type
|
|
438
|
+
throw new Error("--type must be image or document");
|
|
438
439
|
}
|
|
439
440
|
},
|
|
440
441
|
dryRun: (ctx) => {
|
|
@@ -496,22 +497,22 @@ var delAttachment = {
|
|
|
496
497
|
|
|
497
498
|
// src/commands/te-agent/index.ts
|
|
498
499
|
var commands = [
|
|
499
|
-
//
|
|
500
|
+
// Model management
|
|
500
501
|
listModels,
|
|
501
502
|
addModel,
|
|
502
503
|
delModel,
|
|
503
504
|
toggleModel,
|
|
504
|
-
// MCP
|
|
505
|
+
// MCP server management
|
|
505
506
|
listMcps,
|
|
506
507
|
addMcp,
|
|
507
508
|
delMcp,
|
|
508
509
|
toggleMcp,
|
|
509
|
-
// Skill
|
|
510
|
+
// Skill management
|
|
510
511
|
listSkills,
|
|
511
512
|
addSkill,
|
|
512
513
|
delSkill,
|
|
513
514
|
toggleSkill,
|
|
514
|
-
//
|
|
515
|
+
// Attachment library management
|
|
515
516
|
listAttachments,
|
|
516
517
|
addAttachment,
|
|
517
518
|
delAttachment
|