skill-flow 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.zh.md +1 -1
- package/dist/bridge-command.js +406 -385
- package/dist/bridge-command.js.map +7 -1
- package/dist/cli.js +11161 -237
- package/dist/cli.js.map +7 -1
- package/package.json +4 -10
package/dist/bridge-command.js
CHANGED
|
@@ -1,422 +1,443 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// ../../packages/shared-types/dist/protocol.js
|
|
2
|
+
var PROTOCOL_VERSION = "1.0";
|
|
3
|
+
function buildBridgeResponse(args) {
|
|
4
|
+
return {
|
|
5
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
6
|
+
command: args.command,
|
|
7
|
+
...args.requestId ? { requestId: args.requestId } : {},
|
|
8
|
+
ok: args.ok,
|
|
9
|
+
...args.data !== void 0 ? { data: args.data } : {},
|
|
10
|
+
warnings: args.warnings ?? [],
|
|
11
|
+
errors: args.errors ?? []
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function isJsonObject(value) {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/bridge-command.ts
|
|
19
|
+
async function executeBridgeRequest(app, request) {
|
|
20
|
+
try {
|
|
21
|
+
const previousCaller = process.env.SKILL_FLOW_CALLER;
|
|
22
|
+
process.env.SKILL_FLOW_CALLER = previousCaller?.trim() || "bridge";
|
|
3
23
|
try {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
message: warning.message,
|
|
35
|
-
})),
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
case "inspect": {
|
|
39
|
-
const payload = expectObjectPayload(request.payload, "inspect");
|
|
40
|
-
const sourceId = expectString(payload.sourceId, "sourceId", "inspect");
|
|
41
|
-
const scope = expectProjectScope(payload.scope);
|
|
42
|
-
const result = await app.inspectSource(sourceId, scope);
|
|
43
|
-
if (!result.ok) {
|
|
44
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
45
|
-
}
|
|
46
|
-
return buildResponseWithRequest({
|
|
47
|
-
request,
|
|
48
|
-
ok: true,
|
|
49
|
-
data: sanitizeForJson(result.data),
|
|
50
|
-
warnings: result.warnings.map((warning) => ({
|
|
51
|
-
code: warning.code,
|
|
52
|
-
message: warning.message,
|
|
53
|
-
})),
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
case "inspect-enrichment": {
|
|
57
|
-
const payload = expectObjectPayload(request.payload, "inspect-enrichment");
|
|
58
|
-
const sourceId = expectString(payload.sourceId, "sourceId", "inspect-enrichment");
|
|
59
|
-
const result = await app.inspectSourceEnrichment(sourceId);
|
|
60
|
-
if (!result.ok) {
|
|
61
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
62
|
-
}
|
|
63
|
-
return buildResponseWithRequest({
|
|
64
|
-
request,
|
|
65
|
-
ok: true,
|
|
66
|
-
data: sanitizeForJson(result.data),
|
|
67
|
-
warnings: result.warnings.map((warning) => ({
|
|
68
|
-
code: warning.code,
|
|
69
|
-
message: warning.message,
|
|
70
|
-
})),
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
case "search-import-groups": {
|
|
74
|
-
const payload = expectOptionalObject(request.payload, "search-import-groups");
|
|
75
|
-
const query = payload ? expectOptionalString(payload.query, "query", "search-import-groups") : undefined;
|
|
76
|
-
const result = await app.searchImportGroups(query ?? "");
|
|
77
|
-
if (!result.ok) {
|
|
78
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
79
|
-
}
|
|
80
|
-
return buildResponseWithRequest({
|
|
81
|
-
request,
|
|
82
|
-
ok: true,
|
|
83
|
-
data: sanitizeForJson(result.data),
|
|
84
|
-
warnings: result.warnings.map((warning) => ({
|
|
85
|
-
code: warning.code,
|
|
86
|
-
message: warning.message,
|
|
87
|
-
})),
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
case "preview-import-source": {
|
|
91
|
-
const payload = expectObjectPayload(request.payload, "preview-import-source");
|
|
92
|
-
const locator = expectString(payload.locator, "locator", "preview-import-source");
|
|
93
|
-
const result = await app.previewImportSource(locator);
|
|
94
|
-
if (!result.ok) {
|
|
95
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
96
|
-
}
|
|
97
|
-
return buildResponseWithRequest({
|
|
98
|
-
request,
|
|
99
|
-
ok: true,
|
|
100
|
-
data: sanitizeForJson(result.data),
|
|
101
|
-
warnings: result.warnings.map((warning) => ({
|
|
102
|
-
code: warning.code,
|
|
103
|
-
message: warning.message,
|
|
104
|
-
})),
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
case "import-source": {
|
|
108
|
-
const payload = expectObjectPayload(request.payload, "import-source");
|
|
109
|
-
const locator = expectString(payload.locator, "locator", "import-source");
|
|
110
|
-
const draft = expectOptionalImportDraft(payload.draft);
|
|
111
|
-
const result = await app.importSource(locator, draft);
|
|
112
|
-
if (!result.ok) {
|
|
113
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
114
|
-
}
|
|
115
|
-
return buildResponseWithRequest({
|
|
116
|
-
request,
|
|
117
|
-
ok: true,
|
|
118
|
-
data: sanitizeForJson(result.data),
|
|
119
|
-
warnings: result.warnings.map((warning) => ({
|
|
120
|
-
code: warning.code,
|
|
121
|
-
message: warning.message,
|
|
122
|
-
})),
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
case "toggle-pin": {
|
|
126
|
-
const payload = expectObjectPayload(request.payload, "toggle-pin");
|
|
127
|
-
const sourceId = expectString(payload.sourceId, "sourceId", "toggle-pin");
|
|
128
|
-
const result = await app.togglePinnedSource(sourceId);
|
|
129
|
-
if (!result.ok) {
|
|
130
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
131
|
-
}
|
|
132
|
-
return buildResponseWithRequest({
|
|
133
|
-
request,
|
|
134
|
-
ok: true,
|
|
135
|
-
data: sanitizeForJson(result.data),
|
|
136
|
-
warnings: result.warnings.map((warning) => ({
|
|
137
|
-
code: warning.code,
|
|
138
|
-
message: warning.message,
|
|
139
|
-
})),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
case "doctor": {
|
|
143
|
-
const result = await app.doctor();
|
|
144
|
-
if (!result.ok) {
|
|
145
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
146
|
-
}
|
|
147
|
-
return buildResponseWithRequest({
|
|
148
|
-
request,
|
|
149
|
-
ok: true,
|
|
150
|
-
data: sanitizeForJson(result.data),
|
|
151
|
-
warnings: result.warnings.map((warning) => ({
|
|
152
|
-
code: warning.code,
|
|
153
|
-
message: warning.message,
|
|
154
|
-
})),
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
case "add": {
|
|
158
|
-
const payload = expectObjectPayload(request.payload, "add");
|
|
159
|
-
const locator = expectString(payload.locator, "locator", "add");
|
|
160
|
-
const options = expectOptionalObject(payload.options, "add.options");
|
|
161
|
-
const applyNow = payload.applyNow === true;
|
|
162
|
-
const result = applyNow
|
|
163
|
-
? await app.addSource(locator, options)
|
|
164
|
-
: await app.prepareAddSource(locator, options);
|
|
165
|
-
if (!result.ok) {
|
|
166
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
167
|
-
}
|
|
168
|
-
return buildResponseWithRequest({
|
|
169
|
-
request,
|
|
170
|
-
ok: true,
|
|
171
|
-
data: sanitizeForJson(result.data),
|
|
172
|
-
warnings: result.warnings.map((warning) => ({
|
|
173
|
-
code: warning.code,
|
|
174
|
-
message: warning.message,
|
|
175
|
-
})),
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
case "apply": {
|
|
179
|
-
const payload = expectObjectPayload(request.payload, "apply");
|
|
180
|
-
const sourceId = expectString(payload.sourceId, "sourceId", "apply");
|
|
181
|
-
const draft = expectDraftBinding(payload.draft);
|
|
182
|
-
const scope = expectProjectScope(payload.scope);
|
|
183
|
-
const result = await app.applyDraft(sourceId, draft, scope);
|
|
184
|
-
if (!result.ok) {
|
|
185
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
186
|
-
}
|
|
187
|
-
return buildResponseWithRequest({
|
|
188
|
-
request,
|
|
189
|
-
ok: true,
|
|
190
|
-
data: sanitizeForJson(result.data),
|
|
191
|
-
warnings: result.warnings.map((warning) => ({
|
|
192
|
-
code: warning.code,
|
|
193
|
-
message: warning.message,
|
|
194
|
-
})),
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
case "update": {
|
|
198
|
-
const payload = expectOptionalObject(request.payload, "update");
|
|
199
|
-
const sourceIds = parseOptionalStringArray(payload?.sourceIds, "update.sourceIds");
|
|
200
|
-
const result = await app.updateSources(sourceIds);
|
|
201
|
-
if (!result.ok) {
|
|
202
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
203
|
-
}
|
|
204
|
-
return buildResponseWithRequest({
|
|
205
|
-
request,
|
|
206
|
-
ok: true,
|
|
207
|
-
data: sanitizeForJson(result.data),
|
|
208
|
-
warnings: result.warnings.map((warning) => ({
|
|
209
|
-
code: warning.code,
|
|
210
|
-
message: warning.message,
|
|
211
|
-
})),
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
case "uninstall": {
|
|
215
|
-
const payload = expectObjectPayload(request.payload, "uninstall");
|
|
216
|
-
const sourceIds = parseRequiredStringArray(payload.sourceIds, "uninstall.sourceIds");
|
|
217
|
-
const result = await app.uninstall(sourceIds);
|
|
218
|
-
if (!result.ok) {
|
|
219
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
220
|
-
}
|
|
221
|
-
return buildResponseWithRequest({
|
|
222
|
-
request,
|
|
223
|
-
ok: true,
|
|
224
|
-
data: sanitizeForJson(result.data),
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
case "save-settings": {
|
|
228
|
-
const payload = expectObjectPayload(request.payload, "save-settings");
|
|
229
|
-
const customTargets = expectCustomTargets(payload.customTargets);
|
|
230
|
-
const agentDisplayOrder = parseOptionalStringArray(payload.agentDisplayOrder, "save-settings.agentDisplayOrder") ?? [];
|
|
231
|
-
const result = await app.saveSettings({ customTargets, agentDisplayOrder });
|
|
232
|
-
if (!result.ok) {
|
|
233
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
234
|
-
}
|
|
235
|
-
return buildResponseWithRequest({
|
|
236
|
-
request,
|
|
237
|
-
ok: true,
|
|
238
|
-
data: sanitizeForJson(result.data),
|
|
239
|
-
warnings: result.warnings.map((warning) => ({
|
|
240
|
-
code: warning.code,
|
|
241
|
-
message: warning.message,
|
|
242
|
-
})),
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
default:
|
|
246
|
-
return buildResponseWithRequest({
|
|
247
|
-
request,
|
|
248
|
-
ok: false,
|
|
249
|
-
errors: [
|
|
250
|
-
{
|
|
251
|
-
code: "UNSUPPORTED_COMMAND",
|
|
252
|
-
message: `Bridge command '${request.command}' is not supported.`,
|
|
253
|
-
},
|
|
254
|
-
],
|
|
255
|
-
});
|
|
256
|
-
}
|
|
24
|
+
switch (request.command) {
|
|
25
|
+
case "bootstrap": {
|
|
26
|
+
const result = await app.bootstrapWorkspaceState();
|
|
27
|
+
if (!result.ok) {
|
|
28
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
29
|
+
}
|
|
30
|
+
return buildResponseWithRequest({
|
|
31
|
+
request,
|
|
32
|
+
ok: true,
|
|
33
|
+
data: sanitizeForJson(result.data),
|
|
34
|
+
warnings: result.warnings.map((warning) => ({
|
|
35
|
+
code: warning.code,
|
|
36
|
+
message: warning.message
|
|
37
|
+
}))
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
case "list": {
|
|
41
|
+
const result = await app.listWorkflows();
|
|
42
|
+
if (!result.ok) {
|
|
43
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
44
|
+
}
|
|
45
|
+
return buildResponseWithRequest({
|
|
46
|
+
request,
|
|
47
|
+
ok: true,
|
|
48
|
+
data: sanitizeForJson(result.data),
|
|
49
|
+
warnings: result.warnings.map((warning) => ({
|
|
50
|
+
code: warning.code,
|
|
51
|
+
message: warning.message
|
|
52
|
+
}))
|
|
53
|
+
});
|
|
257
54
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
55
|
+
case "inspect": {
|
|
56
|
+
const payload = expectObjectPayload(request.payload, "inspect");
|
|
57
|
+
const sourceId = expectString(payload.sourceId, "sourceId", "inspect");
|
|
58
|
+
const scope = expectProjectScope(payload.scope);
|
|
59
|
+
const result = await app.inspectSource(sourceId, scope);
|
|
60
|
+
if (!result.ok) {
|
|
61
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
62
|
+
}
|
|
63
|
+
return buildResponseWithRequest({
|
|
64
|
+
request,
|
|
65
|
+
ok: true,
|
|
66
|
+
data: sanitizeForJson(result.data),
|
|
67
|
+
warnings: result.warnings.map((warning) => ({
|
|
68
|
+
code: warning.code,
|
|
69
|
+
message: warning.message
|
|
70
|
+
}))
|
|
71
|
+
});
|
|
265
72
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
73
|
+
case "inspect-enrichment": {
|
|
74
|
+
const payload = expectObjectPayload(request.payload, "inspect-enrichment");
|
|
75
|
+
const sourceId = expectString(payload.sourceId, "sourceId", "inspect-enrichment");
|
|
76
|
+
const result = await app.inspectSourceEnrichment(sourceId);
|
|
77
|
+
if (!result.ok) {
|
|
78
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
79
|
+
}
|
|
80
|
+
return buildResponseWithRequest({
|
|
81
|
+
request,
|
|
82
|
+
ok: true,
|
|
83
|
+
data: sanitizeForJson(result.data),
|
|
84
|
+
warnings: result.warnings.map((warning) => ({
|
|
85
|
+
code: warning.code,
|
|
86
|
+
message: warning.message
|
|
87
|
+
}))
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
case "search-import-groups": {
|
|
91
|
+
const payload = expectOptionalObject(request.payload, "search-import-groups");
|
|
92
|
+
const query = payload ? expectOptionalString(payload.query, "query", "search-import-groups") : void 0;
|
|
93
|
+
const result = await app.searchImportGroups(query ?? "");
|
|
94
|
+
if (!result.ok) {
|
|
95
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
96
|
+
}
|
|
97
|
+
return buildResponseWithRequest({
|
|
98
|
+
request,
|
|
99
|
+
ok: true,
|
|
100
|
+
data: sanitizeForJson(result.data),
|
|
101
|
+
warnings: result.warnings.map((warning) => ({
|
|
102
|
+
code: warning.code,
|
|
103
|
+
message: warning.message
|
|
104
|
+
}))
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
case "preview-import-source": {
|
|
108
|
+
const payload = expectObjectPayload(request.payload, "preview-import-source");
|
|
109
|
+
const locator = expectString(payload.locator, "locator", "preview-import-source");
|
|
110
|
+
const result = await app.previewImportSource(locator);
|
|
111
|
+
if (!result.ok) {
|
|
112
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
113
|
+
}
|
|
114
|
+
return buildResponseWithRequest({
|
|
115
|
+
request,
|
|
116
|
+
ok: true,
|
|
117
|
+
data: sanitizeForJson(result.data),
|
|
118
|
+
warnings: result.warnings.map((warning) => ({
|
|
119
|
+
code: warning.code,
|
|
120
|
+
message: warning.message
|
|
121
|
+
}))
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
case "import-source": {
|
|
125
|
+
const payload = expectObjectPayload(request.payload, "import-source");
|
|
126
|
+
const locator = expectString(payload.locator, "locator", "import-source");
|
|
127
|
+
const draft = expectOptionalImportDraft(payload.draft);
|
|
128
|
+
const result = await app.importSource(locator, draft);
|
|
129
|
+
if (!result.ok) {
|
|
130
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
131
|
+
}
|
|
132
|
+
return buildResponseWithRequest({
|
|
133
|
+
request,
|
|
134
|
+
ok: true,
|
|
135
|
+
data: sanitizeForJson(result.data),
|
|
136
|
+
warnings: result.warnings.map((warning) => ({
|
|
137
|
+
code: warning.code,
|
|
138
|
+
message: warning.message
|
|
139
|
+
}))
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
case "toggle-pin": {
|
|
143
|
+
const payload = expectObjectPayload(request.payload, "toggle-pin");
|
|
144
|
+
const sourceId = expectString(payload.sourceId, "sourceId", "toggle-pin");
|
|
145
|
+
const result = await app.togglePinnedSource(sourceId);
|
|
146
|
+
if (!result.ok) {
|
|
147
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
148
|
+
}
|
|
149
|
+
return buildResponseWithRequest({
|
|
150
|
+
request,
|
|
151
|
+
ok: true,
|
|
152
|
+
data: sanitizeForJson(result.data),
|
|
153
|
+
warnings: result.warnings.map((warning) => ({
|
|
154
|
+
code: warning.code,
|
|
155
|
+
message: warning.message
|
|
156
|
+
}))
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
case "doctor": {
|
|
160
|
+
const result = await app.doctor();
|
|
161
|
+
if (!result.ok) {
|
|
162
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
163
|
+
}
|
|
164
|
+
return buildResponseWithRequest({
|
|
165
|
+
request,
|
|
166
|
+
ok: true,
|
|
167
|
+
data: sanitizeForJson(result.data),
|
|
168
|
+
warnings: result.warnings.map((warning) => ({
|
|
169
|
+
code: warning.code,
|
|
170
|
+
message: warning.message
|
|
171
|
+
}))
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
case "add": {
|
|
175
|
+
const payload = expectObjectPayload(request.payload, "add");
|
|
176
|
+
const locator = expectString(payload.locator, "locator", "add");
|
|
177
|
+
const options = expectOptionalObject(payload.options, "add.options");
|
|
178
|
+
const applyNow = payload.applyNow === true;
|
|
179
|
+
const result = applyNow ? await app.addSource(locator, options) : await app.prepareAddSource(locator, options);
|
|
180
|
+
if (!result.ok) {
|
|
181
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
182
|
+
}
|
|
183
|
+
return buildResponseWithRequest({
|
|
184
|
+
request,
|
|
185
|
+
ok: true,
|
|
186
|
+
data: sanitizeForJson(result.data),
|
|
187
|
+
warnings: result.warnings.map((warning) => ({
|
|
188
|
+
code: warning.code,
|
|
189
|
+
message: warning.message
|
|
190
|
+
}))
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
case "apply": {
|
|
194
|
+
const payload = expectObjectPayload(request.payload, "apply");
|
|
195
|
+
const sourceId = expectString(payload.sourceId, "sourceId", "apply");
|
|
196
|
+
const draft = expectDraftBinding(payload.draft);
|
|
197
|
+
const scope = expectProjectScope(payload.scope);
|
|
198
|
+
const result = await app.applyDraft(sourceId, draft, scope);
|
|
199
|
+
if (!result.ok) {
|
|
200
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
201
|
+
}
|
|
202
|
+
return buildResponseWithRequest({
|
|
203
|
+
request,
|
|
204
|
+
ok: true,
|
|
205
|
+
data: sanitizeForJson(result.data),
|
|
206
|
+
warnings: result.warnings.map((warning) => ({
|
|
207
|
+
code: warning.code,
|
|
208
|
+
message: warning.message
|
|
209
|
+
}))
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
case "update": {
|
|
213
|
+
const payload = expectOptionalObject(request.payload, "update");
|
|
214
|
+
const sourceIds = parseOptionalStringArray(payload?.sourceIds, "update.sourceIds");
|
|
215
|
+
const result = await app.updateSources(sourceIds);
|
|
216
|
+
if (!result.ok) {
|
|
217
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
218
|
+
}
|
|
219
|
+
return buildResponseWithRequest({
|
|
220
|
+
request,
|
|
221
|
+
ok: true,
|
|
222
|
+
data: sanitizeForJson(result.data),
|
|
223
|
+
warnings: result.warnings.map((warning) => ({
|
|
224
|
+
code: warning.code,
|
|
225
|
+
message: warning.message
|
|
226
|
+
}))
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
case "uninstall": {
|
|
230
|
+
const payload = expectObjectPayload(request.payload, "uninstall");
|
|
231
|
+
const sourceIds = parseRequiredStringArray(payload.sourceIds, "uninstall.sourceIds");
|
|
232
|
+
const result = await app.uninstall(sourceIds);
|
|
233
|
+
if (!result.ok) {
|
|
234
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
235
|
+
}
|
|
236
|
+
return buildResponseWithRequest({
|
|
237
|
+
request,
|
|
238
|
+
ok: true,
|
|
239
|
+
data: sanitizeForJson(result.data)
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
case "save-settings": {
|
|
243
|
+
const payload = expectObjectPayload(request.payload, "save-settings");
|
|
244
|
+
const customTargets = expectCustomTargets(payload.customTargets);
|
|
245
|
+
const agentDisplayOrder = parseOptionalStringArray(
|
|
246
|
+
payload.agentDisplayOrder,
|
|
247
|
+
"save-settings.agentDisplayOrder"
|
|
248
|
+
) ?? [];
|
|
249
|
+
const result = await app.saveSettings({ customTargets, agentDisplayOrder });
|
|
250
|
+
if (!result.ok) {
|
|
251
|
+
return toFailureResponse(request, result.errors, result.warnings);
|
|
252
|
+
}
|
|
253
|
+
return buildResponseWithRequest({
|
|
254
|
+
request,
|
|
255
|
+
ok: true,
|
|
256
|
+
data: sanitizeForJson(result.data),
|
|
257
|
+
warnings: result.warnings.map((warning) => ({
|
|
258
|
+
code: warning.code,
|
|
259
|
+
message: warning.message
|
|
260
|
+
}))
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
default:
|
|
264
|
+
return buildResponseWithRequest({
|
|
269
265
|
request,
|
|
270
266
|
ok: false,
|
|
271
267
|
errors: [
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
]
|
|
277
|
-
|
|
268
|
+
{
|
|
269
|
+
code: "UNSUPPORTED_COMMAND",
|
|
270
|
+
message: `Bridge command '${request.command}' is not supported.`
|
|
271
|
+
}
|
|
272
|
+
]
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
} finally {
|
|
276
|
+
if (previousCaller === void 0) {
|
|
277
|
+
delete process.env.SKILL_FLOW_CALLER;
|
|
278
|
+
} else {
|
|
279
|
+
process.env.SKILL_FLOW_CALLER = previousCaller;
|
|
280
|
+
}
|
|
278
281
|
}
|
|
279
|
-
}
|
|
280
|
-
function toFailureResponse(request, errors, warnings) {
|
|
282
|
+
} catch (error) {
|
|
281
283
|
return buildResponseWithRequest({
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
284
|
+
request,
|
|
285
|
+
ok: false,
|
|
286
|
+
errors: [
|
|
287
|
+
{
|
|
288
|
+
code: "BRIDGE_REQUEST_INVALID",
|
|
289
|
+
message: error instanceof Error ? error.message : String(error)
|
|
290
|
+
}
|
|
291
|
+
]
|
|
286
292
|
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function toFailureResponse(request, errors, warnings) {
|
|
296
|
+
return buildResponseWithRequest({
|
|
297
|
+
request,
|
|
298
|
+
ok: false,
|
|
299
|
+
warnings: warnings.map((warning) => ({ code: warning.code, message: warning.message })),
|
|
300
|
+
errors: errors.map((error) => ({ code: error.code, message: error.message }))
|
|
301
|
+
});
|
|
287
302
|
}
|
|
288
303
|
function buildResponseWithRequest(args) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
304
|
+
return buildBridgeResponse({
|
|
305
|
+
command: args.request.command,
|
|
306
|
+
...args.request.requestId ? { requestId: args.request.requestId } : {},
|
|
307
|
+
ok: args.ok,
|
|
308
|
+
...args.data !== void 0 ? { data: args.data } : {},
|
|
309
|
+
...args.warnings ? { warnings: args.warnings } : {},
|
|
310
|
+
...args.errors ? { errors: args.errors } : {}
|
|
311
|
+
});
|
|
297
312
|
}
|
|
298
313
|
function expectObjectPayload(payload, command) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
314
|
+
if (!isJsonObject(payload)) {
|
|
315
|
+
throw new Error(`Bridge command '${command}' requires an object payload.`);
|
|
316
|
+
}
|
|
317
|
+
return payload;
|
|
303
318
|
}
|
|
304
319
|
function expectOptionalObject(value, field) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
320
|
+
if (value === void 0) {
|
|
321
|
+
return void 0;
|
|
322
|
+
}
|
|
323
|
+
if (!isJsonObject(value)) {
|
|
324
|
+
throw new Error(`Field '${field}' must be a JSON object when provided.`);
|
|
325
|
+
}
|
|
326
|
+
return value;
|
|
312
327
|
}
|
|
313
328
|
function expectString(value, field, command) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
329
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
330
|
+
throw new Error(`Bridge command '${command}' requires a non-empty string field '${field}'.`);
|
|
331
|
+
}
|
|
332
|
+
return value;
|
|
318
333
|
}
|
|
319
334
|
function expectOptionalString(value, field, command) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
335
|
+
if (value === void 0) {
|
|
336
|
+
return void 0;
|
|
337
|
+
}
|
|
338
|
+
if (typeof value !== "string") {
|
|
339
|
+
throw new Error(`Bridge command '${command}' requires string field '${field}' when provided.`);
|
|
340
|
+
}
|
|
341
|
+
return value;
|
|
327
342
|
}
|
|
328
343
|
function parseRequiredStringArray(value, field) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
344
|
+
const parsed = parseOptionalStringArray(value, field);
|
|
345
|
+
if (!parsed || parsed.length === 0) {
|
|
346
|
+
throw new Error(`Field '${field}' must be a non-empty string array.`);
|
|
347
|
+
}
|
|
348
|
+
return parsed;
|
|
334
349
|
}
|
|
335
350
|
function parseOptionalStringArray(value, field) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
351
|
+
if (value === void 0) {
|
|
352
|
+
return void 0;
|
|
353
|
+
}
|
|
354
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item.length === 0)) {
|
|
355
|
+
throw new Error(`Field '${field}' must be a string array.`);
|
|
356
|
+
}
|
|
357
|
+
return value;
|
|
343
358
|
}
|
|
344
359
|
function expectDraftBinding(value) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
360
|
+
if (!isJsonObject(value)) {
|
|
361
|
+
throw new Error("Bridge command 'apply' requires object field 'draft'.");
|
|
362
|
+
}
|
|
363
|
+
const selectedLeafIds = parseOptionalStringArray(value.selectedLeafIds, "draft.selectedLeafIds");
|
|
364
|
+
if (!selectedLeafIds) {
|
|
365
|
+
throw new Error("Field 'draft.selectedLeafIds' must be a string array.");
|
|
366
|
+
}
|
|
367
|
+
const enabledTargets = parseOptionalStringArray(value.enabledTargets, "draft.enabledTargets") ?? [];
|
|
368
|
+
return {
|
|
369
|
+
selectedLeafIds,
|
|
370
|
+
enabledTargets
|
|
371
|
+
};
|
|
357
372
|
}
|
|
358
373
|
function expectOptionalImportDraft(value) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
+
if (value === void 0) {
|
|
375
|
+
return void 0;
|
|
376
|
+
}
|
|
377
|
+
if (!isJsonObject(value)) {
|
|
378
|
+
throw new Error("Field 'draft' must be a JSON object when provided.");
|
|
379
|
+
}
|
|
380
|
+
const selectedSkillIds = parseOptionalStringArray(value.selectedSkillIds, "draft.selectedSkillIds");
|
|
381
|
+
if (!selectedSkillIds) {
|
|
382
|
+
throw new Error("Field 'draft.selectedSkillIds' must be a string array.");
|
|
383
|
+
}
|
|
384
|
+
const enabledTargets = parseOptionalStringArray(value.enabledTargets, "draft.enabledTargets") ?? [];
|
|
385
|
+
return {
|
|
386
|
+
selectedSkillIds,
|
|
387
|
+
enabledTargets
|
|
388
|
+
};
|
|
374
389
|
}
|
|
375
390
|
function expectCustomTargets(value) {
|
|
376
|
-
|
|
377
|
-
|
|
391
|
+
if (!Array.isArray(value)) {
|
|
392
|
+
throw new Error("Field 'customTargets' must be an array.");
|
|
393
|
+
}
|
|
394
|
+
return value.map((entry, index) => {
|
|
395
|
+
if (!isJsonObject(entry)) {
|
|
396
|
+
throw new Error(`Field 'customTargets[${index}]' must be an object.`);
|
|
378
397
|
}
|
|
379
|
-
return
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
createdAt: expectString(entry.createdAt, `customTargets[${index}].createdAt`, "save-settings"),
|
|
390
|
-
updatedAt: expectString(entry.updatedAt, `customTargets[${index}].updatedAt`, "save-settings"),
|
|
391
|
-
};
|
|
392
|
-
});
|
|
398
|
+
return {
|
|
399
|
+
id: expectString(entry.id, `customTargets[${index}].id`, "save-settings"),
|
|
400
|
+
name: expectString(entry.name, `customTargets[${index}].name`, "save-settings"),
|
|
401
|
+
globalPath: expectString(entry.globalPath, `customTargets[${index}].globalPath`, "save-settings"),
|
|
402
|
+
projectPathTemplate: expectString(entry.projectPathTemplate, `customTargets[${index}].projectPathTemplate`, "save-settings"),
|
|
403
|
+
strategy: expectString(entry.strategy, `customTargets[${index}].strategy`, "save-settings"),
|
|
404
|
+
createdAt: expectString(entry.createdAt, `customTargets[${index}].createdAt`, "save-settings"),
|
|
405
|
+
updatedAt: expectString(entry.updatedAt, `customTargets[${index}].updatedAt`, "save-settings")
|
|
406
|
+
};
|
|
407
|
+
});
|
|
393
408
|
}
|
|
394
409
|
function expectProjectScope(value) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
410
|
+
if (value === void 0) {
|
|
411
|
+
return { kind: "global" };
|
|
412
|
+
}
|
|
413
|
+
if (!isJsonObject(value) || typeof value.kind !== "string") {
|
|
414
|
+
throw new Error(
|
|
415
|
+
"Field 'scope' must be a JSON object with kind 'global' or kind 'project' and a non-empty string 'projectId'."
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
if (value.kind === "global") {
|
|
419
|
+
return { kind: "global" };
|
|
420
|
+
}
|
|
421
|
+
if (value.kind === "project") {
|
|
422
|
+
if (typeof value.projectId === "string" && value.projectId.length > 0) {
|
|
423
|
+
return { kind: "project", projectId: value.projectId };
|
|
403
424
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
throw new Error("Field 'scope.projectId' must be a non-empty string when scope.kind is 'project'.");
|
|
409
|
-
}
|
|
410
|
-
throw new Error("Field 'scope.kind' must be either 'global' or 'project'.");
|
|
425
|
+
throw new Error("Field 'scope.projectId' must be a non-empty string when scope.kind is 'project'.");
|
|
426
|
+
}
|
|
427
|
+
throw new Error("Field 'scope.kind' must be either 'global' or 'project'.");
|
|
411
428
|
}
|
|
412
429
|
function sanitizeForJson(value) {
|
|
413
|
-
|
|
430
|
+
return JSON.parse(JSON.stringify(value));
|
|
414
431
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
432
|
+
function buildBridgeParseFailure(command, failure) {
|
|
433
|
+
return buildBridgeResponse({
|
|
434
|
+
command,
|
|
435
|
+
ok: false,
|
|
436
|
+
errors: [failure]
|
|
437
|
+
});
|
|
421
438
|
}
|
|
422
|
-
|
|
439
|
+
export {
|
|
440
|
+
buildBridgeParseFailure,
|
|
441
|
+
executeBridgeRequest
|
|
442
|
+
};
|
|
443
|
+
//# sourceMappingURL=bridge-command.js.map
|