skill-flow 1.3.1 → 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.md +3 -2
- package/README.zh.md +4 -3
- package/dist/bridge-command.js +406 -348
- 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,385 +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
|
-
message: warning.message,
|
|
20
|
-
})),
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
case "list": {
|
|
24
|
-
const result = await app.listWorkflows();
|
|
25
|
-
if (!result.ok) {
|
|
26
|
-
return toFailureResponse(request, result.errors, result.warnings);
|
|
27
|
-
}
|
|
28
|
-
return buildResponseWithRequest({
|
|
29
|
-
request,
|
|
30
|
-
ok: true,
|
|
31
|
-
data: sanitizeForJson(result.data),
|
|
32
|
-
warnings: result.warnings.map((warning) => ({
|
|
33
|
-
code: warning.code,
|
|
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
|
-
default:
|
|
228
|
-
return buildResponseWithRequest({
|
|
229
|
-
request,
|
|
230
|
-
ok: false,
|
|
231
|
-
errors: [
|
|
232
|
-
{
|
|
233
|
-
code: "UNSUPPORTED_COMMAND",
|
|
234
|
-
message: `Bridge command '${request.command}' is not supported.`,
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
});
|
|
238
|
-
}
|
|
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
|
+
});
|
|
239
39
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
+
});
|
|
247
54
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
+
});
|
|
72
|
+
}
|
|
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({
|
|
251
265
|
request,
|
|
252
266
|
ok: false,
|
|
253
267
|
errors: [
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
]
|
|
259
|
-
|
|
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
|
+
}
|
|
260
281
|
}
|
|
261
|
-
}
|
|
262
|
-
function toFailureResponse(request, errors, warnings) {
|
|
282
|
+
} catch (error) {
|
|
263
283
|
return buildResponseWithRequest({
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
284
|
+
request,
|
|
285
|
+
ok: false,
|
|
286
|
+
errors: [
|
|
287
|
+
{
|
|
288
|
+
code: "BRIDGE_REQUEST_INVALID",
|
|
289
|
+
message: error instanceof Error ? error.message : String(error)
|
|
290
|
+
}
|
|
291
|
+
]
|
|
268
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
|
+
});
|
|
269
302
|
}
|
|
270
303
|
function buildResponseWithRequest(args) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
+
});
|
|
279
312
|
}
|
|
280
313
|
function expectObjectPayload(payload, command) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
314
|
+
if (!isJsonObject(payload)) {
|
|
315
|
+
throw new Error(`Bridge command '${command}' requires an object payload.`);
|
|
316
|
+
}
|
|
317
|
+
return payload;
|
|
285
318
|
}
|
|
286
319
|
function expectOptionalObject(value, field) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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;
|
|
294
327
|
}
|
|
295
328
|
function expectString(value, field, command) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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;
|
|
300
333
|
}
|
|
301
334
|
function expectOptionalString(value, field, command) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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;
|
|
309
342
|
}
|
|
310
343
|
function parseRequiredStringArray(value, field) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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;
|
|
316
349
|
}
|
|
317
350
|
function parseOptionalStringArray(value, field) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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;
|
|
325
358
|
}
|
|
326
359
|
function expectDraftBinding(value) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
+
};
|
|
339
372
|
}
|
|
340
373
|
function expectOptionalImportDraft(value) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function expectCustomTargets(value) {
|
|
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.`);
|
|
350
397
|
}
|
|
351
|
-
const enabledTargets = parseOptionalStringArray(value.enabledTargets, "draft.enabledTargets") ?? [];
|
|
352
398
|
return {
|
|
353
|
-
|
|
354
|
-
|
|
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")
|
|
355
406
|
};
|
|
407
|
+
});
|
|
356
408
|
}
|
|
357
409
|
function expectProjectScope(value) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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 };
|
|
366
424
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
throw new Error("Field 'scope.projectId' must be a non-empty string when scope.kind is 'project'.");
|
|
372
|
-
}
|
|
373
|
-
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'.");
|
|
374
428
|
}
|
|
375
429
|
function sanitizeForJson(value) {
|
|
376
|
-
|
|
430
|
+
return JSON.parse(JSON.stringify(value));
|
|
377
431
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
432
|
+
function buildBridgeParseFailure(command, failure) {
|
|
433
|
+
return buildBridgeResponse({
|
|
434
|
+
command,
|
|
435
|
+
ok: false,
|
|
436
|
+
errors: [failure]
|
|
437
|
+
});
|
|
384
438
|
}
|
|
385
|
-
|
|
439
|
+
export {
|
|
440
|
+
buildBridgeParseFailure,
|
|
441
|
+
executeBridgeRequest
|
|
442
|
+
};
|
|
443
|
+
//# sourceMappingURL=bridge-command.js.map
|