@superblocksteam/cli 2.0.157-next.5 → 2.0.157
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 -1
- package/bin/dev.js +0 -6
- package/bin/run.js +0 -6
- package/dist/{acorn-OZZ46WC6.js → acorn-WMA6L7P4.js} +3 -3
- package/dist/{angular-F3X4PU6H.js → angular-4M32OMPP.js} +3 -3
- package/dist/{api-LKM3KWDE.js → api-PWLWF2AO.js} +4 -4
- package/dist/{babel-P2KZ44V4.js → babel-6NS2YDUA.js} +3 -3
- package/dist/{chunk-PAGW2Y3I.js → chunk-2M6BYRVF.js} +4 -4
- package/dist/{chunk-O4SXABRB.js → chunk-3CHQLJTS.js} +3 -3
- package/dist/{chunk-DXUQTJ2E.js → chunk-5FZQ7GKI.js} +3 -3
- package/dist/{chunk-I4TBU2RS.js → chunk-72HOGMVP.js} +3 -3
- package/dist/{chunk-IYSPUQ7M.js → chunk-7G3SJRTY.js} +3 -3
- package/dist/{chunk-NHR7FAPE.js → chunk-AMN5CPNU.js} +3 -3
- package/dist/{chunk-B7DU3NCK.js → chunk-BIOZGKJI.js} +3 -3
- package/dist/{chunk-YBAGYCX4.js → chunk-DPDLTLGU.js} +2871 -4873
- package/dist/{chunk-YBAGYCX4.js.map → chunk-DPDLTLGU.js.map} +1 -1
- package/dist/{chunk-F5V42P6U.js → chunk-HK6JH3R3.js} +3 -3
- package/dist/{chunk-Q2BWW5QV.js → chunk-IUATCEZY.js} +3 -3
- package/dist/{chunk-VPLRE4U5.js → chunk-LQB4PWSW.js} +3 -3
- package/dist/{chunk-FIYNW3SU.js → chunk-MNVPTTZN.js} +4 -4
- package/dist/{chunk-LEBMSKJP.js → chunk-O74I62QF.js} +8 -8
- package/dist/{chunk-BOHZPNHE.js → chunk-OK32IXZD.js} +3 -3
- package/dist/{chunk-RH52ZSDO.js → chunk-PSOBYRL5.js} +5 -5
- package/dist/{chunk-LTWZXD76.js → chunk-Q6H6AYB3.js} +2 -2
- package/dist/{chunk-FJXQDKZ2.js → chunk-QMC3HPGT.js} +4 -4
- package/dist/{chunk-QVKSQHMA.js → chunk-U4R6POH4.js} +3 -3
- package/dist/{chunk-7FF5Q3TT.js → chunk-WQWBMBFH.js} +140 -3741
- package/dist/chunk-WQWBMBFH.js.map +1 -0
- package/dist/{chunk-ZOQPSDKJ.js → chunk-Y3RLIV4P.js} +4 -4
- package/dist/{cli-truncate-JE6KXDNY.js → cli-truncate-OWUAGIPO.js} +5 -5
- package/dist/commands/dev-parent.js +3 -3
- package/dist/{dd-trace-AQZGAF2E.js → dd-trace-EUCR6QVT.js} +6 -6
- package/dist/{dist-ONFSHJBQ.js → dist-BHLAUQQG.js} +15 -15
- package/dist/{dist-NJHWXUHQ.js → dist-LZ7TUGM6.js} +200 -839
- package/dist/dist-LZ7TUGM6.js.map +1 -0
- package/dist/{embedded-playwright-mcp-server-65RUBGLR.js → embedded-playwright-mcp-server-D4TETPXE.js} +3 -3
- package/dist/{enquirer-6C55IUPI.js → enquirer-UD7IHY44.js} +4 -4
- package/dist/{estree-OUX276MJ.js → estree-JZ3UIJHT.js} +3 -3
- package/dist/{flow-RNZL6EOQ.js → flow-GSPIY4XU.js} +3 -3
- package/dist/{getMachineId-bsd-SAYCT6BA.js → getMachineId-bsd-36VZS47Z.js} +5 -5
- package/dist/{getMachineId-darwin-2BIZIQZ6.js → getMachineId-darwin-7LZY45ZM.js} +5 -5
- package/dist/{getMachineId-linux-RTE4SKPS.js → getMachineId-linux-LX4NM644.js} +4 -4
- package/dist/{getMachineId-unsupported-4AJE3HZA.js → getMachineId-unsupported-7TJOPLYI.js} +4 -4
- package/dist/{getMachineId-win-WCR2ELI3.js → getMachineId-win-M22WJ3MM.js} +5 -5
- package/dist/{glimmer-ZSFJLGZS.js → glimmer-UVO3BIBM.js} +3 -3
- package/dist/{graphql-6XBYVCIJ.js → graphql-XLZ6JI47.js} +3 -3
- package/dist/{html-VEAJ3MIN.js → html-B4A6WYXT.js} +3 -3
- package/dist/{http-VGB6FR7N.js → http-ZUKAI3FV.js} +14 -14
- package/dist/index.js +23 -23
- package/dist/{jiti-NN2RRFEA.js → jiti-266YLMVX.js} +3 -3
- package/dist/{log-update-G37STD43.js → log-update-YQK5AUYG.js} +6 -6
- package/dist/{markdown-Y4YLMHL3.js → markdown-JEOFIXUQ.js} +3 -3
- package/dist/{meriyah-4GQGGWUO.js → meriyah-QGCQSGGS.js} +3 -3
- package/dist/{postcss-ZFUKCQTL.js → postcss-KSFJ6EQS.js} +3 -3
- package/dist/{read-pkg-Q3NL2F2P.js → read-pkg-CZ4YTNKI.js} +4 -4
- package/dist/{spans-XZD4N5LG.js → spans-3C4P2IQ3.js} +4 -4
- package/dist/{src-E7PNU35M.js → src-XPHA3RUC.js} +3 -3
- package/dist/{token-MQA7XSGS.js → token-BDGVUJER.js} +5 -5
- package/dist/{token-util-VDHZFUFG.js → token-util-5FML3764.js} +5 -5
- package/dist/{typescript-LKK6LNWR.js → typescript-22T2V3TY.js} +3 -3
- package/dist/{v4-SQGBAYYV.js → v4-IHD3EOAU.js} +4 -4
- package/dist/{wrap-ansi-XEURB6IQ.js → wrap-ansi-46TLWEUF.js} +5 -5
- package/dist/{yaml-GAKRLORX.js → yaml-TG67GZWZ.js} +3 -3
- package/oclif.manifest.json +1 -1
- package/package.json +7 -7
- package/dist/chunk-7FF5Q3TT.js.map +0 -1
- package/dist/dist-NJHWXUHQ.js.map +0 -1
- /package/dist/{acorn-OZZ46WC6.js.map → acorn-WMA6L7P4.js.map} +0 -0
- /package/dist/{angular-F3X4PU6H.js.map → angular-4M32OMPP.js.map} +0 -0
- /package/dist/{api-LKM3KWDE.js.map → api-PWLWF2AO.js.map} +0 -0
- /package/dist/{babel-P2KZ44V4.js.map → babel-6NS2YDUA.js.map} +0 -0
- /package/dist/{chunk-PAGW2Y3I.js.map → chunk-2M6BYRVF.js.map} +0 -0
- /package/dist/{chunk-O4SXABRB.js.map → chunk-3CHQLJTS.js.map} +0 -0
- /package/dist/{chunk-DXUQTJ2E.js.map → chunk-5FZQ7GKI.js.map} +0 -0
- /package/dist/{chunk-I4TBU2RS.js.map → chunk-72HOGMVP.js.map} +0 -0
- /package/dist/{chunk-IYSPUQ7M.js.map → chunk-7G3SJRTY.js.map} +0 -0
- /package/dist/{chunk-NHR7FAPE.js.map → chunk-AMN5CPNU.js.map} +0 -0
- /package/dist/{chunk-B7DU3NCK.js.map → chunk-BIOZGKJI.js.map} +0 -0
- /package/dist/{chunk-F5V42P6U.js.map → chunk-HK6JH3R3.js.map} +0 -0
- /package/dist/{chunk-Q2BWW5QV.js.map → chunk-IUATCEZY.js.map} +0 -0
- /package/dist/{chunk-VPLRE4U5.js.map → chunk-LQB4PWSW.js.map} +0 -0
- /package/dist/{chunk-FIYNW3SU.js.map → chunk-MNVPTTZN.js.map} +0 -0
- /package/dist/{chunk-LEBMSKJP.js.map → chunk-O74I62QF.js.map} +0 -0
- /package/dist/{chunk-BOHZPNHE.js.map → chunk-OK32IXZD.js.map} +0 -0
- /package/dist/{chunk-RH52ZSDO.js.map → chunk-PSOBYRL5.js.map} +0 -0
- /package/dist/{chunk-LTWZXD76.js.map → chunk-Q6H6AYB3.js.map} +0 -0
- /package/dist/{chunk-FJXQDKZ2.js.map → chunk-QMC3HPGT.js.map} +0 -0
- /package/dist/{chunk-QVKSQHMA.js.map → chunk-U4R6POH4.js.map} +0 -0
- /package/dist/{chunk-ZOQPSDKJ.js.map → chunk-Y3RLIV4P.js.map} +0 -0
- /package/dist/{cli-truncate-JE6KXDNY.js.map → cli-truncate-OWUAGIPO.js.map} +0 -0
- /package/dist/{dd-trace-AQZGAF2E.js.map → dd-trace-EUCR6QVT.js.map} +0 -0
- /package/dist/{dist-ONFSHJBQ.js.map → dist-BHLAUQQG.js.map} +0 -0
- /package/dist/{embedded-playwright-mcp-server-65RUBGLR.js.map → embedded-playwright-mcp-server-D4TETPXE.js.map} +0 -0
- /package/dist/{enquirer-6C55IUPI.js.map → enquirer-UD7IHY44.js.map} +0 -0
- /package/dist/{estree-OUX276MJ.js.map → estree-JZ3UIJHT.js.map} +0 -0
- /package/dist/{flow-RNZL6EOQ.js.map → flow-GSPIY4XU.js.map} +0 -0
- /package/dist/{getMachineId-bsd-SAYCT6BA.js.map → getMachineId-bsd-36VZS47Z.js.map} +0 -0
- /package/dist/{getMachineId-darwin-2BIZIQZ6.js.map → getMachineId-darwin-7LZY45ZM.js.map} +0 -0
- /package/dist/{getMachineId-linux-RTE4SKPS.js.map → getMachineId-linux-LX4NM644.js.map} +0 -0
- /package/dist/{getMachineId-unsupported-4AJE3HZA.js.map → getMachineId-unsupported-7TJOPLYI.js.map} +0 -0
- /package/dist/{getMachineId-win-WCR2ELI3.js.map → getMachineId-win-M22WJ3MM.js.map} +0 -0
- /package/dist/{glimmer-ZSFJLGZS.js.map → glimmer-UVO3BIBM.js.map} +0 -0
- /package/dist/{graphql-6XBYVCIJ.js.map → graphql-XLZ6JI47.js.map} +0 -0
- /package/dist/{html-VEAJ3MIN.js.map → html-B4A6WYXT.js.map} +0 -0
- /package/dist/{http-VGB6FR7N.js.map → http-ZUKAI3FV.js.map} +0 -0
- /package/dist/{jiti-NN2RRFEA.js.map → jiti-266YLMVX.js.map} +0 -0
- /package/dist/{log-update-G37STD43.js.map → log-update-YQK5AUYG.js.map} +0 -0
- /package/dist/{markdown-Y4YLMHL3.js.map → markdown-JEOFIXUQ.js.map} +0 -0
- /package/dist/{meriyah-4GQGGWUO.js.map → meriyah-QGCQSGGS.js.map} +0 -0
- /package/dist/{postcss-ZFUKCQTL.js.map → postcss-KSFJ6EQS.js.map} +0 -0
- /package/dist/{read-pkg-Q3NL2F2P.js.map → read-pkg-CZ4YTNKI.js.map} +0 -0
- /package/dist/{spans-XZD4N5LG.js.map → spans-3C4P2IQ3.js.map} +0 -0
- /package/dist/{src-E7PNU35M.js.map → src-XPHA3RUC.js.map} +0 -0
- /package/dist/{token-MQA7XSGS.js.map → token-BDGVUJER.js.map} +0 -0
- /package/dist/{token-util-VDHZFUFG.js.map → token-util-5FML3764.js.map} +0 -0
- /package/dist/{typescript-LKK6LNWR.js.map → typescript-22T2V3TY.js.map} +0 -0
- /package/dist/{v4-SQGBAYYV.js.map → v4-IHD3EOAU.js.map} +0 -0
- /package/dist/{wrap-ansi-XEURB6IQ.js.map → wrap-ansi-46TLWEUF.js.map} +0 -0
- /package/dist/{yaml-GAKRLORX.js.map → yaml-TG67GZWZ.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
if (typeof process === 'object' && process !== null &&
|
|
2
2
|
process.env !== null && typeof process.env === 'object') {
|
|
3
3
|
process.env.DD_GIT_REPOSITORY_URL = 'https://token@github.com/superblocksteam/superblocks.git';
|
|
4
|
-
process.env.DD_GIT_COMMIT_SHA = '
|
|
4
|
+
process.env.DD_GIT_COMMIT_SHA = 'b4017d1f7aca518ff00f7059ba25e73fc7ea4cb9';
|
|
5
5
|
}
|
|
6
6
|
import { createRequire as $dd_createRequire } from 'module';
|
|
7
7
|
import { fileURLToPath as $dd_fileURLToPath } from 'url';
|
|
@@ -13,7 +13,7 @@ globalThis.__dirname ??= $dd_dirname(globalThis.__filename);
|
|
|
13
13
|
import {
|
|
14
14
|
McpServer,
|
|
15
15
|
StdioServerTransport
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-O74I62QF.js";
|
|
17
17
|
import {
|
|
18
18
|
CallToolResultSchema,
|
|
19
19
|
ContentBlockSchema,
|
|
@@ -27,37 +27,30 @@ import {
|
|
|
27
27
|
executeToolCall,
|
|
28
28
|
runWithAuthContext,
|
|
29
29
|
toolDefinitions
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-WQWBMBFH.js";
|
|
31
31
|
import {
|
|
32
32
|
external_exports
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import "./chunk-
|
|
33
|
+
} from "./chunk-HK6JH3R3.js";
|
|
34
|
+
import "./chunk-2M6BYRVF.js";
|
|
35
35
|
import {
|
|
36
|
-
getDefaultPolicy,
|
|
37
|
-
import_shared,
|
|
38
36
|
import_websocket,
|
|
39
|
-
initNodeTelemetry,
|
|
40
|
-
parseDeploymentType,
|
|
41
37
|
require_dist
|
|
42
|
-
} from "./chunk-
|
|
43
|
-
import "./chunk-
|
|
44
|
-
import "./chunk-
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-
|
|
48
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-DPDLTLGU.js";
|
|
39
|
+
import "./chunk-U4R6POH4.js";
|
|
40
|
+
import "./chunk-72HOGMVP.js";
|
|
41
|
+
import "./chunk-PSOBYRL5.js";
|
|
42
|
+
import "./chunk-LQB4PWSW.js";
|
|
43
|
+
import "./chunk-3CHQLJTS.js";
|
|
44
|
+
import "./chunk-OK32IXZD.js";
|
|
49
45
|
import {
|
|
50
|
-
SpanStatusCode,
|
|
51
|
-
context,
|
|
52
46
|
init_esm,
|
|
53
|
-
metrics
|
|
54
|
-
|
|
55
|
-
} from "./chunk-NHR7FAPE.js";
|
|
47
|
+
metrics
|
|
48
|
+
} from "./chunk-AMN5CPNU.js";
|
|
56
49
|
import {
|
|
57
50
|
__require,
|
|
58
51
|
__toESM,
|
|
59
52
|
init_cjs_shims
|
|
60
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-Q6H6AYB3.js";
|
|
61
54
|
|
|
62
55
|
// ../../../gateway/dist/index.js
|
|
63
56
|
init_cjs_shims();
|
|
@@ -239,7 +232,7 @@ function formatCaptureModeSummary(input) {
|
|
|
239
232
|
|
|
240
233
|
// ../../../gateway/dist/capabilities/lifecycle.js
|
|
241
234
|
init_cjs_shims();
|
|
242
|
-
var
|
|
235
|
+
var import_shared2 = __toESM(require_dist());
|
|
243
236
|
import { randomUUID } from "node:crypto";
|
|
244
237
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
245
238
|
import path2 from "node:path";
|
|
@@ -444,7 +437,7 @@ function buildOpenablePreviewUrls(input) {
|
|
|
444
437
|
|
|
445
438
|
// ../../../gateway/dist/server/client.js
|
|
446
439
|
init_cjs_shims();
|
|
447
|
-
var
|
|
440
|
+
var import_shared = __toESM(require_dist());
|
|
448
441
|
|
|
449
442
|
// ../../../gateway/dist/telemetry/metrics.js
|
|
450
443
|
init_cjs_shims();
|
|
@@ -848,7 +841,7 @@ var HttpSuperblocksServerClient = class {
|
|
|
848
841
|
}
|
|
849
842
|
async uploadAttachment(input) {
|
|
850
843
|
const mimeType = input.mimeType ?? "application/zip";
|
|
851
|
-
const response = await (0,
|
|
844
|
+
const response = await (0, import_shared.uploadAttachmentToServerApi)({
|
|
852
845
|
applicationId: input.applicationId,
|
|
853
846
|
authorization: `Bearer ${input.apiKey}`,
|
|
854
847
|
baseUrl: this.baseUrl(),
|
|
@@ -895,18 +888,10 @@ var HttpSuperblocksServerClient = class {
|
|
|
895
888
|
*/
|
|
896
889
|
async issueScopedToken(input) {
|
|
897
890
|
const scope = input.scope ?? "apps:update";
|
|
898
|
-
const body = {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
}
|
|
903
|
-
body.integrationId = input.integrationId;
|
|
904
|
-
} else {
|
|
905
|
-
if (!input.applicationId?.trim()) {
|
|
906
|
-
throw new Error(`${scope} scoped tokens require an applicationId`);
|
|
907
|
-
}
|
|
908
|
-
body.applicationId = input.applicationId;
|
|
909
|
-
}
|
|
891
|
+
const body = {
|
|
892
|
+
applicationId: input.applicationId,
|
|
893
|
+
scope
|
|
894
|
+
};
|
|
910
895
|
if (scope === "apps:preview") {
|
|
911
896
|
if (!input.commitId?.trim()) {
|
|
912
897
|
throw new Error("apps:preview scoped tokens require a commitId so the viewer can load that commit");
|
|
@@ -1846,37 +1831,37 @@ async function captureModeOf(ctx) {
|
|
|
1846
1831
|
});
|
|
1847
1832
|
}
|
|
1848
1833
|
function libraryCaptureInput(ctx, applicationId) {
|
|
1849
|
-
const
|
|
1850
|
-
if (!
|
|
1834
|
+
const context = ctx.sessionPeer.libraryBrowserContext?.(applicationId);
|
|
1835
|
+
if (!context) {
|
|
1851
1836
|
return void 0;
|
|
1852
1837
|
}
|
|
1853
|
-
const auth =
|
|
1838
|
+
const auth = context.initData.devServerAuthorization;
|
|
1854
1839
|
if (!auth) {
|
|
1855
1840
|
console.error("gateway live canvas skipped: missing_dev_server_authorization", { applicationId });
|
|
1856
1841
|
return void 0;
|
|
1857
1842
|
}
|
|
1858
1843
|
return {
|
|
1859
1844
|
bootstrapData: {
|
|
1860
|
-
accessToken:
|
|
1861
|
-
agents:
|
|
1862
|
-
...
|
|
1863
|
-
appId:
|
|
1845
|
+
accessToken: context.bootstrapData.accessToken,
|
|
1846
|
+
agents: context.bootstrapData.agents ?? [],
|
|
1847
|
+
...context.bootstrapData.agentUrls ? { agentUrls: context.bootstrapData.agentUrls } : {},
|
|
1848
|
+
appId: context.bootstrapData.appId,
|
|
1864
1849
|
devServerAuthorization: auth,
|
|
1865
|
-
...
|
|
1866
|
-
...
|
|
1867
|
-
...
|
|
1868
|
-
token:
|
|
1869
|
-
...
|
|
1870
|
-
userId:
|
|
1871
|
-
...
|
|
1850
|
+
...context.bootstrapData.featureFlags ? { featureFlags: context.bootstrapData.featureFlags } : {},
|
|
1851
|
+
...context.bootstrapData.orgId ? { orgId: context.bootstrapData.orgId } : {},
|
|
1852
|
+
...context.bootstrapData.profiles ? { profiles: context.bootstrapData.profiles } : {},
|
|
1853
|
+
token: context.bootstrapData.token,
|
|
1854
|
+
...context.bootstrapData.userEmail ? { userEmail: context.bootstrapData.userEmail } : {},
|
|
1855
|
+
userId: context.bootstrapData.userId,
|
|
1856
|
+
...context.bootstrapData.windowOriginUrl ? { windowOriginUrl: context.bootstrapData.windowOriginUrl } : {}
|
|
1872
1857
|
},
|
|
1873
|
-
iframeBaseUrl:
|
|
1858
|
+
iframeBaseUrl: context.iframeBaseUrl,
|
|
1874
1859
|
initData: {
|
|
1875
|
-
appId:
|
|
1860
|
+
appId: context.initData.appId,
|
|
1876
1861
|
devServerAuthorization: auth,
|
|
1877
|
-
peerId:
|
|
1878
|
-
...
|
|
1879
|
-
...
|
|
1862
|
+
peerId: context.initData.peerId,
|
|
1863
|
+
...context.initData.userId ? { userId: context.initData.userId } : {},
|
|
1864
|
+
...context.initData.windowOriginUrl ? { windowOriginUrl: context.initData.windowOriginUrl } : {}
|
|
1880
1865
|
}
|
|
1881
1866
|
};
|
|
1882
1867
|
}
|
|
@@ -2000,15 +1985,13 @@ function defaultAppName(prompt) {
|
|
|
2000
1985
|
async function ensurePrincipal(ctx) {
|
|
2001
1986
|
const { principal } = ctx;
|
|
2002
1987
|
if (principal.organizationId && principal.userId) {
|
|
2003
|
-
const resolved2 = {
|
|
2004
|
-
...principal,
|
|
2005
|
-
organizationId: principal.organizationId,
|
|
2006
|
-
userId: principal.userId
|
|
2007
|
-
};
|
|
2008
|
-
ctx.onPrincipalResolved?.(resolved2);
|
|
2009
1988
|
return {
|
|
2010
1989
|
kind: "ok",
|
|
2011
|
-
value:
|
|
1990
|
+
value: {
|
|
1991
|
+
...principal,
|
|
1992
|
+
organizationId: principal.organizationId,
|
|
1993
|
+
userId: principal.userId
|
|
1994
|
+
}
|
|
2012
1995
|
};
|
|
2013
1996
|
}
|
|
2014
1997
|
let validated;
|
|
@@ -2038,16 +2021,14 @@ async function ensurePrincipal(ctx) {
|
|
|
2038
2021
|
message: "The Superblocks API rejected the credential issued for this caller."
|
|
2039
2022
|
};
|
|
2040
2023
|
}
|
|
2041
|
-
const resolved = {
|
|
2042
|
-
...principal,
|
|
2043
|
-
email: validated.email,
|
|
2044
|
-
organizationId: validated.organizationId,
|
|
2045
|
-
userId: validated.userId
|
|
2046
|
-
};
|
|
2047
|
-
ctx.onPrincipalResolved?.(resolved);
|
|
2048
2024
|
return {
|
|
2049
2025
|
kind: "ok",
|
|
2050
|
-
value:
|
|
2026
|
+
value: {
|
|
2027
|
+
...principal,
|
|
2028
|
+
email: validated.email,
|
|
2029
|
+
organizationId: validated.organizationId,
|
|
2030
|
+
userId: validated.userId
|
|
2031
|
+
}
|
|
2051
2032
|
};
|
|
2052
2033
|
}
|
|
2053
2034
|
async function nameWithClark(ctx, input) {
|
|
@@ -2240,7 +2221,7 @@ function turnSummary(turn) {
|
|
|
2240
2221
|
return "Superblocks is still working, but only the editor can show it \u2014 open the edit URL";
|
|
2241
2222
|
}
|
|
2242
2223
|
if (turn.generationStatus === "live_edit_terminated") {
|
|
2243
|
-
return
|
|
2224
|
+
return "The Superblocks live-edit session terminated before anything was built \u2014 send the prompt again with edit_app";
|
|
2244
2225
|
}
|
|
2245
2226
|
if (turn.checkpointCommitId) {
|
|
2246
2227
|
return `Application ready \u2014 checkpoint saved. ${NEXT_STEPS}`;
|
|
@@ -2366,7 +2347,6 @@ async function forwardClarkPrompt(ctx, input) {
|
|
|
2366
2347
|
generationStatus: forward.generationStatus,
|
|
2367
2348
|
...forward.liveEditId ? { liveEditId: forward.liveEditId } : {},
|
|
2368
2349
|
...forward.recentRuns && forward.recentRuns.length > 0 ? { recentRuns: forward.recentRuns } : {},
|
|
2369
|
-
...forward.retryAction ? { retryAction: forward.retryAction } : {},
|
|
2370
2350
|
viewStatus: forward.viewStatus
|
|
2371
2351
|
}
|
|
2372
2352
|
};
|
|
@@ -2412,7 +2392,7 @@ function namingCreatedApplication(applicationId, capability, result) {
|
|
|
2412
2392
|
return namingApplication(applicationId, result);
|
|
2413
2393
|
}
|
|
2414
2394
|
function retryIfReplayable(attachments) {
|
|
2415
|
-
return attachments && attachments.length > 0 ?
|
|
2395
|
+
return attachments && attachments.length > 0 ? void 0 : { pendingAction: "retry_build" };
|
|
2416
2396
|
}
|
|
2417
2397
|
function liveEditUnavailable(error, attachments) {
|
|
2418
2398
|
return {
|
|
@@ -2433,8 +2413,7 @@ function rememberFailedStart(ctx, input) {
|
|
|
2433
2413
|
organizationId: input.principal.organizationId,
|
|
2434
2414
|
// Reaches the caller as the dead start's reply on its next poll, so it
|
|
2435
2415
|
// has to stand on its own there rather than lean on this call's error.
|
|
2436
|
-
reason:
|
|
2437
|
-
...input.retryAction ? { retryAction: input.retryAction } : {},
|
|
2416
|
+
reason: `The Superblocks live-edit session for application ${input.applicationId} never opened, so the prompt never reached Superblocks and nothing was built. Nothing is running for that application; send the same instruction again to retry it. (${cause})`,
|
|
2438
2417
|
userId: input.principal.userId
|
|
2439
2418
|
});
|
|
2440
2419
|
} catch (error) {
|
|
@@ -2464,12 +2443,7 @@ async function promptNewApplication(ctx, args) {
|
|
|
2464
2443
|
organizationId: principal.organizationId
|
|
2465
2444
|
});
|
|
2466
2445
|
} catch (error) {
|
|
2467
|
-
rememberFailedStart(ctx, {
|
|
2468
|
-
applicationId,
|
|
2469
|
-
error,
|
|
2470
|
-
principal,
|
|
2471
|
-
...args.attachments?.length ? { retryAction: "retry_import" } : {}
|
|
2472
|
-
});
|
|
2446
|
+
rememberFailedStart(ctx, { applicationId, error, principal });
|
|
2473
2447
|
return liveEditUnavailable(error, args.attachments);
|
|
2474
2448
|
}
|
|
2475
2449
|
ctx.onProgress?.({
|
|
@@ -2664,7 +2638,7 @@ async function resolveImportArchive(input, searchDirs) {
|
|
|
2664
2638
|
if (bytes.byteLength > IMPORT_ZIP_MAX_BYTES) {
|
|
2665
2639
|
return tooLargeError(bytes.byteLength);
|
|
2666
2640
|
}
|
|
2667
|
-
const archiveType = (0,
|
|
2641
|
+
const archiveType = (0, import_shared2.detectAttachmentArchiveType)({ fileName });
|
|
2668
2642
|
if (archiveType === null) {
|
|
2669
2643
|
return {
|
|
2670
2644
|
kind: "error",
|
|
@@ -2706,15 +2680,14 @@ function normalizeImportSource(source) {
|
|
|
2706
2680
|
}
|
|
2707
2681
|
}
|
|
2708
2682
|
async function importApp(ctx, input) {
|
|
2709
|
-
const resumedApplicationId = input.applicationId?.trim();
|
|
2710
2683
|
const archiveResult = await resolveImportArchive(input, ctx.config.importSearchDirs);
|
|
2711
2684
|
if (archiveResult.kind !== "ok") {
|
|
2712
|
-
return
|
|
2685
|
+
return archiveResult;
|
|
2713
2686
|
}
|
|
2714
2687
|
const archive = archiveResult.value;
|
|
2715
2688
|
const principalResult = await ensurePrincipal(ctx);
|
|
2716
2689
|
if (principalResult.kind !== "ok") {
|
|
2717
|
-
return
|
|
2690
|
+
return principalResult;
|
|
2718
2691
|
}
|
|
2719
2692
|
const principal = principalResult.value;
|
|
2720
2693
|
const source = normalizeImportSource(input.source);
|
|
@@ -2725,26 +2698,23 @@ async function importApp(ctx, input) {
|
|
|
2725
2698
|
});
|
|
2726
2699
|
const explicitName = input.name?.trim();
|
|
2727
2700
|
const name = explicitName || defaultAppName(migrationPrompt);
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
if (created.kind !== "ok") {
|
|
2741
|
-
return created;
|
|
2742
|
-
}
|
|
2743
|
-
applicationId = created.value.id;
|
|
2701
|
+
ctx.onProgress?.({
|
|
2702
|
+
message: "Creating application for import",
|
|
2703
|
+
type: "progress"
|
|
2704
|
+
});
|
|
2705
|
+
const created = await createApplicationForPrompt(ctx, {
|
|
2706
|
+
apiKey: principal.apiKey,
|
|
2707
|
+
name,
|
|
2708
|
+
organizationId: principal.organizationId,
|
|
2709
|
+
templateName: "app-fullstack"
|
|
2710
|
+
});
|
|
2711
|
+
if (created.kind !== "ok") {
|
|
2712
|
+
return created;
|
|
2744
2713
|
}
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2714
|
+
const app = created.value;
|
|
2715
|
+
await rememberApplication(ctx, principal, app.id);
|
|
2716
|
+
return namingCreatedApplication(app.id, "import_app", await migrateArchiveIntoApplication(ctx, {
|
|
2717
|
+
applicationId: app.id,
|
|
2748
2718
|
archive,
|
|
2749
2719
|
explicitName,
|
|
2750
2720
|
input,
|
|
@@ -2752,8 +2722,7 @@ async function importApp(ctx, input) {
|
|
|
2752
2722
|
name,
|
|
2753
2723
|
principal,
|
|
2754
2724
|
source
|
|
2755
|
-
});
|
|
2756
|
-
return resumedApplicationId ? namingApplication(applicationId, result) : namingCreatedApplication(applicationId, "import_app", result);
|
|
2725
|
+
}));
|
|
2757
2726
|
}
|
|
2758
2727
|
async function migrateArchiveIntoApplication(ctx, args) {
|
|
2759
2728
|
const { applicationId, archive, principal } = args;
|
|
@@ -2772,18 +2741,10 @@ async function migrateArchiveIntoApplication(ctx, args) {
|
|
|
2772
2741
|
});
|
|
2773
2742
|
} catch (error) {
|
|
2774
2743
|
const message = error instanceof Error ? error.message : String(error);
|
|
2775
|
-
rememberFailedStart(ctx, {
|
|
2776
|
-
applicationId,
|
|
2777
|
-
error,
|
|
2778
|
-
principal,
|
|
2779
|
-
reason: `The archive for application ${applicationId} could not be uploaded, so the migration never started and nothing was built. Send the same archive again with import_app to retry it. (${message})`,
|
|
2780
|
-
retryAction: "retry_import"
|
|
2781
|
-
});
|
|
2782
2744
|
return {
|
|
2783
2745
|
kind: "error",
|
|
2784
2746
|
code: "import_upload_failed",
|
|
2785
|
-
message
|
|
2786
|
-
pendingAction: "retry_import"
|
|
2747
|
+
message
|
|
2787
2748
|
};
|
|
2788
2749
|
}
|
|
2789
2750
|
return promptNewApplication(ctx, {
|
|
@@ -2868,7 +2829,7 @@ async function checkAppProgress(ctx, input) {
|
|
|
2868
2829
|
}
|
|
2869
2830
|
const applicationId = resolved.value;
|
|
2870
2831
|
if (ctx.signal?.aborted) {
|
|
2871
|
-
return
|
|
2832
|
+
return cancelled("check_app_progress");
|
|
2872
2833
|
}
|
|
2873
2834
|
const cursorKey2 = cursorKeyFor(ctx, principal, applicationId);
|
|
2874
2835
|
const stored = cursorKey2 ? await ctx.progressCursors?.getCursor(cursorKey2) : void 0;
|
|
@@ -2880,7 +2841,7 @@ async function checkAppProgress(ctx, input) {
|
|
|
2880
2841
|
waitMs: hostCallBudgetMs(ctx, ctx.config.clarkProgressWaitMs)
|
|
2881
2842
|
});
|
|
2882
2843
|
if (ctx.signal?.aborted) {
|
|
2883
|
-
return
|
|
2844
|
+
return cancelled("check_app_progress");
|
|
2884
2845
|
}
|
|
2885
2846
|
const snapshot = await readSnapshot(ctx, {
|
|
2886
2847
|
applicationId,
|
|
@@ -2954,7 +2915,6 @@ async function checkAppProgress(ctx, input) {
|
|
|
2954
2915
|
reply: update.reply,
|
|
2955
2916
|
...update.decision ? { decision: update.decision } : {},
|
|
2956
2917
|
generationStatus: update.generationStatus,
|
|
2957
|
-
...update.retryAction && emptyTurnStatus(update.generationStatus) ? { pendingAction: update.retryAction } : {},
|
|
2958
2918
|
status,
|
|
2959
2919
|
viewStatus: update.viewStatus
|
|
2960
2920
|
}
|
|
@@ -3376,11 +3336,7 @@ function localUnbuiltReason(turn, pending) {
|
|
|
3376
3336
|
return void 0;
|
|
3377
3337
|
}
|
|
3378
3338
|
const status = emptyTurnStatus(turn.generationStatus);
|
|
3379
|
-
return status ? {
|
|
3380
|
-
kind: "empty_turn",
|
|
3381
|
-
retryAction: turn.retryAction ?? "retry_build",
|
|
3382
|
-
status
|
|
3383
|
-
} : void 0;
|
|
3339
|
+
return status ? { kind: "empty_turn", status } : void 0;
|
|
3384
3340
|
}
|
|
3385
3341
|
async function persistedUnbuiltReason(ctx, principal, applicationId) {
|
|
3386
3342
|
let snapshot;
|
|
@@ -3423,8 +3379,6 @@ function persistedTurnEnd(status) {
|
|
|
3423
3379
|
// plain question and cannot be approved.
|
|
3424
3380
|
case "needs_decision":
|
|
3425
3381
|
return { kind: "awaiting_decision" };
|
|
3426
|
-
// The stream never recorded whether the prompt carried an archive, so
|
|
3427
|
-
// this path cannot pick retry_build vs retry_import. Omit rather than guess.
|
|
3428
3382
|
case "live_edit_terminated":
|
|
3429
3383
|
return { kind: "empty_turn", status };
|
|
3430
3384
|
// A `cancelled` in the tail may still have a real app behind it: the
|
|
@@ -3483,11 +3437,7 @@ async function unbuiltApp(ctx, principal, applicationId) {
|
|
|
3483
3437
|
if (reason.kind === "empty_turn") {
|
|
3484
3438
|
return {
|
|
3485
3439
|
kind: "ok",
|
|
3486
|
-
value: {
|
|
3487
|
-
...app,
|
|
3488
|
-
...reason.retryAction ? { pendingAction: reason.retryAction } : {},
|
|
3489
|
-
status: reason.status
|
|
3490
|
-
}
|
|
3440
|
+
value: { ...app, pendingAction: "retry_build", status: reason.status }
|
|
3491
3441
|
};
|
|
3492
3442
|
}
|
|
3493
3443
|
return {
|
|
@@ -3589,7 +3539,7 @@ async function waitForBuild(ctx, input) {
|
|
|
3589
3539
|
let started = false;
|
|
3590
3540
|
for (; ; ) {
|
|
3591
3541
|
if (ctx.signal?.aborted) {
|
|
3592
|
-
return
|
|
3542
|
+
return cancelled("get_app");
|
|
3593
3543
|
}
|
|
3594
3544
|
if (nowMs(ctx) >= deadline) {
|
|
3595
3545
|
return { kind: "ok", value: { built: false } };
|
|
@@ -4243,7 +4193,7 @@ async function createStores() {
|
|
|
4243
4193
|
// ../../../gateway/dist/sabs/websocket-session-peer.js
|
|
4244
4194
|
init_cjs_shims();
|
|
4245
4195
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
4246
|
-
var
|
|
4196
|
+
var import_shared5 = __toESM(require_dist());
|
|
4247
4197
|
|
|
4248
4198
|
// ../../../gateway/dist/agents/resolve-orchestrator-url.js
|
|
4249
4199
|
init_cjs_shims();
|
|
@@ -4564,15 +4514,15 @@ var HttpOrchestratorClient = class {
|
|
|
4564
4514
|
|
|
4565
4515
|
// ../../../gateway/dist/sabs/browser-context.js
|
|
4566
4516
|
init_cjs_shims();
|
|
4567
|
-
var
|
|
4517
|
+
var import_shared3 = __toESM(require_dist());
|
|
4568
4518
|
function toProfile(row) {
|
|
4569
|
-
return new
|
|
4519
|
+
return new import_shared3.Profile({
|
|
4570
4520
|
allowedInEditor: row.allowedInEditor,
|
|
4571
4521
|
description: "",
|
|
4572
4522
|
displayName: row.displayName ?? row.key,
|
|
4573
4523
|
id: row.id ?? row.key,
|
|
4574
4524
|
key: row.key,
|
|
4575
|
-
type:
|
|
4525
|
+
type: import_shared3.ProfileType.RESERVED
|
|
4576
4526
|
});
|
|
4577
4527
|
}
|
|
4578
4528
|
function selectProfiles(input) {
|
|
@@ -4636,7 +4586,7 @@ function buildBrowserContext(input) {
|
|
|
4636
4586
|
|
|
4637
4587
|
// ../../../gateway/dist/sabs/editor-client-methods.js
|
|
4638
4588
|
init_cjs_shims();
|
|
4639
|
-
var
|
|
4589
|
+
var import_shared4 = __toESM(require_dist());
|
|
4640
4590
|
|
|
4641
4591
|
// ../../../gateway/dist/integrations/map.js
|
|
4642
4592
|
init_cjs_shims();
|
|
@@ -4791,7 +4741,7 @@ function sanitizeAgentFacingValue(value) {
|
|
|
4791
4741
|
}
|
|
4792
4742
|
|
|
4793
4743
|
// ../../../gateway/dist/sabs/editor-client-methods.js
|
|
4794
|
-
var ADMIN_MCP_SETUP_MESSAGE = "Integrations CRUD is available on this Superblocks MCP via
|
|
4744
|
+
var ADMIN_MCP_SETUP_MESSAGE = "Integrations CRUD is available on this Superblocks MCP via create_integration, update_integration, and list_integrations (same connector as start_app). Use those Admin tools, then continue with edit_app. The headless editor session cannot open the Integrations UI.";
|
|
4795
4745
|
var HEADLESS_AUTO_APPROVED_TOOLS = /* @__PURE__ */ new Set([
|
|
4796
4746
|
"build_deleteFile",
|
|
4797
4747
|
"build_installPackages",
|
|
@@ -4877,27 +4827,27 @@ function clarifySdkExecutionErrorMessage(message) {
|
|
|
4877
4827
|
}
|
|
4878
4828
|
return sanitizeAgentFacingText(clarified);
|
|
4879
4829
|
}
|
|
4880
|
-
async function executeRequestToIntegrationViaOrchestrator(
|
|
4830
|
+
async function executeRequestToIntegrationViaOrchestrator(context, payload) {
|
|
4881
4831
|
let pluginId = payload.integrationHint?.type;
|
|
4882
4832
|
let integrationName = payload.integrationHint?.displayName ?? payload.integrationHint?.name ?? "Integration";
|
|
4883
4833
|
if (!pluginId) {
|
|
4884
4834
|
let row;
|
|
4885
4835
|
try {
|
|
4886
|
-
row = await
|
|
4887
|
-
apiKey:
|
|
4836
|
+
row = await context.server.getIntegration({
|
|
4837
|
+
apiKey: context.apiKey,
|
|
4888
4838
|
integrationId: payload.integrationId
|
|
4889
4839
|
});
|
|
4890
4840
|
if (!row) {
|
|
4891
|
-
const rows = await
|
|
4892
|
-
apiKey:
|
|
4893
|
-
applicationId:
|
|
4894
|
-
organizationId:
|
|
4841
|
+
const rows = await context.server.getSupersetIntegrations({
|
|
4842
|
+
apiKey: context.apiKey,
|
|
4843
|
+
applicationId: context.applicationId,
|
|
4844
|
+
organizationId: context.organizationId
|
|
4895
4845
|
});
|
|
4896
4846
|
row = rows.find((candidate) => candidate.id === payload.integrationId);
|
|
4897
4847
|
}
|
|
4898
4848
|
} catch (error) {
|
|
4899
4849
|
console.warn("gateway failed to resolve integration for execute", {
|
|
4900
|
-
applicationId:
|
|
4850
|
+
applicationId: context.applicationId,
|
|
4901
4851
|
integrationId: payload.integrationId,
|
|
4902
4852
|
message: error instanceof Error ? error.message : String(error)
|
|
4903
4853
|
});
|
|
@@ -4910,7 +4860,7 @@ async function executeRequestToIntegrationViaOrchestrator(context2, payload) {
|
|
|
4910
4860
|
pluginId = row.pluginId;
|
|
4911
4861
|
integrationName = row.name || integrationName;
|
|
4912
4862
|
}
|
|
4913
|
-
const pluginIdForStep = (0,
|
|
4863
|
+
const pluginIdForStep = (0, import_shared4.getBasePluginId)(pluginId);
|
|
4914
4864
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4915
4865
|
const inlineApiId = `ai-inline-${payload.integrationId}-${Date.now()}`;
|
|
4916
4866
|
const definition = {
|
|
@@ -4926,14 +4876,14 @@ async function executeRequestToIntegrationViaOrchestrator(context2, payload) {
|
|
|
4926
4876
|
metadata: {
|
|
4927
4877
|
id: inlineApiId,
|
|
4928
4878
|
name: `${integrationName} AI Query`,
|
|
4929
|
-
organization:
|
|
4879
|
+
organization: context.organizationId,
|
|
4930
4880
|
timestamps: { created: now, updated: now }
|
|
4931
4881
|
},
|
|
4932
4882
|
trigger: { application: {} }
|
|
4933
4883
|
};
|
|
4934
4884
|
try {
|
|
4935
|
-
const result = await
|
|
4936
|
-
apiKey:
|
|
4885
|
+
const result = await context.orchestrator.executeV2Api({
|
|
4886
|
+
apiKey: context.apiKey,
|
|
4937
4887
|
body: {
|
|
4938
4888
|
definition: { api: definition },
|
|
4939
4889
|
inputs: {},
|
|
@@ -4944,10 +4894,10 @@ async function executeRequestToIntegrationViaOrchestrator(context2, payload) {
|
|
|
4944
4894
|
isAiTriggered: true,
|
|
4945
4895
|
suppressTracking: true
|
|
4946
4896
|
},
|
|
4947
|
-
...
|
|
4897
|
+
...context.profileKey ? { profile: { name: context.profileKey } } : {}
|
|
4948
4898
|
},
|
|
4949
|
-
profileKey:
|
|
4950
|
-
scopedToken:
|
|
4899
|
+
profileKey: context.profileKey,
|
|
4900
|
+
scopedToken: context.sessionToken
|
|
4951
4901
|
});
|
|
4952
4902
|
if (result && typeof result === "object" && "systemError" in result) {
|
|
4953
4903
|
const systemError = String(result.systemError ?? "Integration execution failed");
|
|
@@ -4983,11 +4933,11 @@ async function executeRequestToIntegrationViaOrchestrator(context2, payload) {
|
|
|
4983
4933
|
return { error: clarifySdkExecutionErrorMessage(message) };
|
|
4984
4934
|
}
|
|
4985
4935
|
}
|
|
4986
|
-
async function loadIntegrationsForPrompt(
|
|
4987
|
-
const rows = await
|
|
4988
|
-
apiKey:
|
|
4989
|
-
applicationId:
|
|
4990
|
-
organizationId:
|
|
4936
|
+
async function loadIntegrationsForPrompt(context) {
|
|
4937
|
+
const rows = await context.server.getSupersetIntegrations({
|
|
4938
|
+
apiKey: context.apiKey,
|
|
4939
|
+
applicationId: context.applicationId,
|
|
4940
|
+
organizationId: context.organizationId
|
|
4991
4941
|
});
|
|
4992
4942
|
return listIntegrationsForClark(rows);
|
|
4993
4943
|
}
|
|
@@ -5132,9 +5082,10 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5132
5082
|
],
|
|
5133
5083
|
updateApiInputs: ack,
|
|
5134
5084
|
updateScope: ack,
|
|
5135
|
-
// No browser tab means no viewport to photograph.
|
|
5136
|
-
//
|
|
5137
|
-
//
|
|
5085
|
+
// No browser tab means no viewport to photograph. The flag matters more
|
|
5086
|
+
// than the message: it tells the ai-service this was a refusal, not a
|
|
5087
|
+
// failed capture, so Clark can fall back to the sandbox's own browser
|
|
5088
|
+
// instead of reporting that it cannot see the app it just built.
|
|
5138
5089
|
aiCaptureScreenshot: [
|
|
5139
5090
|
async () => ({
|
|
5140
5091
|
error: "the headless gateway session has no browser viewport",
|
|
@@ -5146,13 +5097,13 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5146
5097
|
aiDeleteIntegration: setupUnavailable,
|
|
5147
5098
|
aiExecuteRequestToIntegration: [
|
|
5148
5099
|
async (payload) => {
|
|
5149
|
-
const
|
|
5150
|
-
if (!
|
|
5100
|
+
const context = deps?.getContext();
|
|
5101
|
+
if (!context) {
|
|
5151
5102
|
return {
|
|
5152
5103
|
error: "the headless gateway session cannot execute integration requests without an active prompt session"
|
|
5153
5104
|
};
|
|
5154
5105
|
}
|
|
5155
|
-
const result = await executeRequestToIntegrationViaOrchestrator(
|
|
5106
|
+
const result = await executeRequestToIntegrationViaOrchestrator(context, payload);
|
|
5156
5107
|
const name = payload.integrationHint?.name || payload.integrationId || "integration";
|
|
5157
5108
|
deps?.onToolRun?.({
|
|
5158
5109
|
detail: result,
|
|
@@ -5165,8 +5116,8 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5165
5116
|
],
|
|
5166
5117
|
aiExecuteSdkApi: [
|
|
5167
5118
|
async (payload) => {
|
|
5168
|
-
const
|
|
5169
|
-
if (!
|
|
5119
|
+
const context = deps?.getContext();
|
|
5120
|
+
if (!context) {
|
|
5170
5121
|
throw missingSessionError("execute SDK APIs");
|
|
5171
5122
|
}
|
|
5172
5123
|
if (!payload.entryPoint) {
|
|
@@ -5186,7 +5137,7 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5186
5137
|
return missing;
|
|
5187
5138
|
}
|
|
5188
5139
|
try {
|
|
5189
|
-
const inSync = await
|
|
5140
|
+
const inSync = await context.waitUntilFilesSynced();
|
|
5190
5141
|
if (!inSync) {
|
|
5191
5142
|
const syncing = {
|
|
5192
5143
|
success: false,
|
|
@@ -5203,15 +5154,15 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5203
5154
|
});
|
|
5204
5155
|
return syncing;
|
|
5205
5156
|
}
|
|
5206
|
-
const response = await
|
|
5207
|
-
apiKey:
|
|
5208
|
-
applicationId:
|
|
5209
|
-
branchName:
|
|
5157
|
+
const response = await context.orchestrator.executeSdkApiV3({
|
|
5158
|
+
apiKey: context.apiKey,
|
|
5159
|
+
applicationId: context.applicationId,
|
|
5160
|
+
branchName: context.branchName,
|
|
5210
5161
|
entryPoint: payload.entryPoint,
|
|
5211
5162
|
exportName: payload.exportName,
|
|
5212
5163
|
inputs: payload.input ?? {},
|
|
5213
|
-
profileKey:
|
|
5214
|
-
scopedToken:
|
|
5164
|
+
profileKey: context.profileKey,
|
|
5165
|
+
scopedToken: context.sessionToken
|
|
5215
5166
|
});
|
|
5216
5167
|
const mapped = mapSdkExecutionResponse(response);
|
|
5217
5168
|
deps?.onToolRun?.({
|
|
@@ -5241,8 +5192,8 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5241
5192
|
],
|
|
5242
5193
|
aiExecuteV2Api: [
|
|
5243
5194
|
async (payload) => {
|
|
5244
|
-
const
|
|
5245
|
-
if (!
|
|
5195
|
+
const context = deps?.getContext();
|
|
5196
|
+
if (!context) {
|
|
5246
5197
|
throw missingSessionError("execute V2 APIs");
|
|
5247
5198
|
}
|
|
5248
5199
|
if (payload.api.type === "fetch") {
|
|
@@ -5255,14 +5206,14 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5255
5206
|
...payload.api.definition,
|
|
5256
5207
|
metadata: {
|
|
5257
5208
|
...payload.api.definition.metadata ?? {},
|
|
5258
|
-
organization:
|
|
5209
|
+
organization: context.organizationId,
|
|
5259
5210
|
timestamps: { created: now, updated: now }
|
|
5260
5211
|
},
|
|
5261
5212
|
trigger: { application: {} }
|
|
5262
5213
|
};
|
|
5263
5214
|
try {
|
|
5264
|
-
const result = await
|
|
5265
|
-
apiKey:
|
|
5215
|
+
const result = await context.orchestrator.executeV2Api({
|
|
5216
|
+
apiKey: context.apiKey,
|
|
5266
5217
|
body: {
|
|
5267
5218
|
definition: { api: definition },
|
|
5268
5219
|
inputs: payload.inputs ?? {},
|
|
@@ -5273,10 +5224,10 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5273
5224
|
isAiTriggered: true,
|
|
5274
5225
|
suppressTracking: true
|
|
5275
5226
|
},
|
|
5276
|
-
...
|
|
5227
|
+
...context.profileKey ? { profile: { name: context.profileKey } } : {}
|
|
5277
5228
|
},
|
|
5278
|
-
profileKey:
|
|
5279
|
-
scopedToken:
|
|
5229
|
+
profileKey: context.profileKey,
|
|
5230
|
+
scopedToken: context.sessionToken
|
|
5280
5231
|
});
|
|
5281
5232
|
if (result && typeof result === "object" && "systemError" in result) {
|
|
5282
5233
|
return result;
|
|
@@ -5298,27 +5249,27 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5298
5249
|
],
|
|
5299
5250
|
aiGetIntegration: [
|
|
5300
5251
|
async (payload) => {
|
|
5301
|
-
const
|
|
5302
|
-
if (!
|
|
5252
|
+
const context = deps?.getContext();
|
|
5253
|
+
if (!context) {
|
|
5303
5254
|
throw missingSessionError("provide integration metadata");
|
|
5304
5255
|
}
|
|
5305
5256
|
let row;
|
|
5306
5257
|
try {
|
|
5307
|
-
row = await
|
|
5308
|
-
apiKey:
|
|
5258
|
+
row = await context.server.getIntegration({
|
|
5259
|
+
apiKey: context.apiKey,
|
|
5309
5260
|
integrationId: payload.integrationId
|
|
5310
5261
|
});
|
|
5311
5262
|
if (!row) {
|
|
5312
|
-
const rows = await
|
|
5313
|
-
apiKey:
|
|
5314
|
-
applicationId:
|
|
5315
|
-
organizationId:
|
|
5263
|
+
const rows = await context.server.getSupersetIntegrations({
|
|
5264
|
+
apiKey: context.apiKey,
|
|
5265
|
+
applicationId: context.applicationId,
|
|
5266
|
+
organizationId: context.organizationId
|
|
5316
5267
|
});
|
|
5317
5268
|
row = rows.find((candidate) => candidate.id === payload.integrationId);
|
|
5318
5269
|
}
|
|
5319
5270
|
} catch (error) {
|
|
5320
5271
|
console.warn("gateway failed to load integration for Clark", {
|
|
5321
|
-
applicationId:
|
|
5272
|
+
applicationId: context.applicationId,
|
|
5322
5273
|
integrationId: payload.integrationId,
|
|
5323
5274
|
message: error instanceof Error ? error.message : String(error)
|
|
5324
5275
|
});
|
|
@@ -5334,11 +5285,11 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5334
5285
|
}
|
|
5335
5286
|
let metadata = {};
|
|
5336
5287
|
try {
|
|
5337
|
-
metadata = await
|
|
5338
|
-
apiKey:
|
|
5288
|
+
metadata = await context.orchestrator.getMetadata({
|
|
5289
|
+
apiKey: context.apiKey,
|
|
5339
5290
|
integrationId: payload.integrationId,
|
|
5340
|
-
profileKey:
|
|
5341
|
-
scopedToken:
|
|
5291
|
+
profileKey: context.profileKey,
|
|
5292
|
+
scopedToken: context.sessionToken
|
|
5342
5293
|
});
|
|
5343
5294
|
} catch {
|
|
5344
5295
|
metadata = {};
|
|
@@ -5360,15 +5311,15 @@ function createEditorClientMethods(getListener, onInbound, deps) {
|
|
|
5360
5311
|
],
|
|
5361
5312
|
aiGetIntegrations: [
|
|
5362
5313
|
async () => {
|
|
5363
|
-
const
|
|
5364
|
-
if (!
|
|
5314
|
+
const context = deps?.getContext();
|
|
5315
|
+
if (!context) {
|
|
5365
5316
|
return [];
|
|
5366
5317
|
}
|
|
5367
5318
|
try {
|
|
5368
|
-
return await loadIntegrationsForPrompt(
|
|
5319
|
+
return await loadIntegrationsForPrompt(context);
|
|
5369
5320
|
} catch (error) {
|
|
5370
5321
|
console.warn("gateway failed to list integrations for Clark", {
|
|
5371
|
-
applicationId:
|
|
5322
|
+
applicationId: context.applicationId,
|
|
5372
5323
|
message: error instanceof Error ? error.message : String(error)
|
|
5373
5324
|
});
|
|
5374
5325
|
return [];
|
|
@@ -5469,7 +5420,6 @@ function truncate(text, max = RECENT_TOOL_RUN_SUMMARY_MAX) {
|
|
|
5469
5420
|
var GENERATE_METHOD = "editor.aiGenerateWithQueue";
|
|
5470
5421
|
var ACCEPT_DRAFT_METHOD = "editor.aiAcceptDraft";
|
|
5471
5422
|
var RELOAD_CHAT_METHOD = "editor.aiChatGetMessages";
|
|
5472
|
-
var RELEASE_TURN_LOCK_METHOD = "editor.releaseTurnLock";
|
|
5473
5423
|
var RESPOND_TOOL_PERMISSION_METHOD = "editor.aiRespondToToolPermission";
|
|
5474
5424
|
var PING_METHOD = "editor.ping";
|
|
5475
5425
|
var DEFAULT_TIMEOUT_MS3 = 12e4;
|
|
@@ -5811,7 +5761,6 @@ var WebSocketSessionPeer = class {
|
|
|
5811
5761
|
this.failedStarts.set(input, {
|
|
5812
5762
|
generationStatus: "live_edit_terminated",
|
|
5813
5763
|
reply: input.reason,
|
|
5814
|
-
...input.retryAction ? { retryAction: input.retryAction } : {},
|
|
5815
5764
|
// Nothing ran, so nothing is viewable. Reporting "ready" here is how a
|
|
5816
5765
|
// caller comes to show the untouched starter template as the app.
|
|
5817
5766
|
viewStatus: "unknown"
|
|
@@ -5844,11 +5793,7 @@ var WebSocketSessionPeer = class {
|
|
|
5844
5793
|
}
|
|
5845
5794
|
const failed = this.failedStarts.get(input);
|
|
5846
5795
|
if (failed) {
|
|
5847
|
-
return {
|
|
5848
|
-
generationStatus: failed.generationStatus,
|
|
5849
|
-
phase: "finished",
|
|
5850
|
-
...failed.retryAction ? { retryAction: failed.retryAction } : {}
|
|
5851
|
-
};
|
|
5796
|
+
return { generationStatus: failed.generationStatus, phase: "finished" };
|
|
5852
5797
|
}
|
|
5853
5798
|
if (!turn?.finished) {
|
|
5854
5799
|
return void 0;
|
|
@@ -5856,8 +5801,7 @@ var WebSocketSessionPeer = class {
|
|
|
5856
5801
|
return {
|
|
5857
5802
|
...turn.finished.checkpointCommitId ? { checkpointCommitId: turn.finished.checkpointCommitId } : {},
|
|
5858
5803
|
generationStatus: turn.finished.generationStatus,
|
|
5859
|
-
phase: "finished"
|
|
5860
|
-
...turn.retryAction ? { retryAction: turn.retryAction } : {}
|
|
5804
|
+
phase: "finished"
|
|
5861
5805
|
};
|
|
5862
5806
|
}
|
|
5863
5807
|
clearPendingPlan(applicationId) {
|
|
@@ -6003,7 +5947,6 @@ var WebSocketSessionPeer = class {
|
|
|
6003
5947
|
normalized: void 0,
|
|
6004
5948
|
recentRuns: [],
|
|
6005
5949
|
reconnects: 0,
|
|
6006
|
-
...input.attachments?.length ? { retryAction: "retry_import" } : {},
|
|
6007
5950
|
startedAt: Date.now(),
|
|
6008
5951
|
turnId: randomUUID3(),
|
|
6009
5952
|
unsubscribe: () => void 0,
|
|
@@ -6064,7 +6007,6 @@ var WebSocketSessionPeer = class {
|
|
|
6064
6007
|
jwt: input.sessionToken,
|
|
6065
6008
|
llmConfig: {
|
|
6066
6009
|
coreModel: this.options.coreModel ?? DEFAULT_LLM.coreModel,
|
|
6067
|
-
disabledTools: ["build_captureScreenshot", "build_navigatePreview"],
|
|
6068
6010
|
// The ai-service gates Clark's testing tools on this flag *and* a
|
|
6069
6011
|
// browser context, so the two travel together or not at all.
|
|
6070
6012
|
...browserContext ? { flags: { isTestingEnabled: true } } : {},
|
|
@@ -6170,7 +6112,6 @@ var WebSocketSessionPeer = class {
|
|
|
6170
6112
|
elapsedMs,
|
|
6171
6113
|
status: "finished",
|
|
6172
6114
|
...turn.finished,
|
|
6173
|
-
...turn.retryAction ? { retryAction: turn.retryAction } : {},
|
|
6174
6115
|
...recentRuns ? { recentRuns } : {}
|
|
6175
6116
|
};
|
|
6176
6117
|
}
|
|
@@ -6311,15 +6252,6 @@ var WebSocketSessionPeer = class {
|
|
|
6311
6252
|
collector.dispose();
|
|
6312
6253
|
const stillMapped = this.turns.get(input.applicationId) === turn;
|
|
6313
6254
|
if (stillMapped) {
|
|
6314
|
-
try {
|
|
6315
|
-
await turn.held.client.requestWithTracing(RELEASE_TURN_LOCK_METHOD, this.turnCorrelator(turn.turnId), {}, `Bearer ${input.sessionToken}`);
|
|
6316
|
-
} catch (error) {
|
|
6317
|
-
console.warn("gateway could not release the live-edit turn lock", {
|
|
6318
|
-
applicationId: input.applicationId,
|
|
6319
|
-
message: describeSocketError(error),
|
|
6320
|
-
turnId: turn.turnId
|
|
6321
|
-
});
|
|
6322
|
-
}
|
|
6323
6255
|
if (turn.finished?.generationStatus === "needs_decision") {
|
|
6324
6256
|
this.armIdle(turn.held);
|
|
6325
6257
|
} else {
|
|
@@ -6736,7 +6668,7 @@ var WebSocketSessionPeer = class {
|
|
|
6736
6668
|
const heldRef = {
|
|
6737
6669
|
current: void 0
|
|
6738
6670
|
};
|
|
6739
|
-
const socket = new
|
|
6671
|
+
const socket = new import_shared5.ISocket(ws, createEditorClientMethods(() => {
|
|
6740
6672
|
const listeners = heldRef.current?.listeners;
|
|
6741
6673
|
if (!listeners || listeners.size === 0) {
|
|
6742
6674
|
return void 0;
|
|
@@ -6813,7 +6745,7 @@ var WebSocketSessionPeer = class {
|
|
|
6813
6745
|
noResponseTimeoutInSeconds: (this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS3) / 1e3
|
|
6814
6746
|
}
|
|
6815
6747
|
});
|
|
6816
|
-
const client = (0,
|
|
6748
|
+
const client = (0, import_shared5.createISocketClient)(socket);
|
|
6817
6749
|
const heartbeat = this.buildHeartbeat(heldRef);
|
|
6818
6750
|
const held = {
|
|
6819
6751
|
applicationId: input.applicationId,
|
|
@@ -6849,7 +6781,7 @@ var WebSocketSessionPeer = class {
|
|
|
6849
6781
|
* who to tell.
|
|
6850
6782
|
*/
|
|
6851
6783
|
buildHeartbeat(heldRef) {
|
|
6852
|
-
return new
|
|
6784
|
+
return new import_shared5.SocketHeartbeat({
|
|
6853
6785
|
beat: async () => {
|
|
6854
6786
|
const held = heldRef.current;
|
|
6855
6787
|
if (!held?.sessionToken) {
|
|
@@ -7376,233 +7308,6 @@ var WebSocketSessionPeer = class {
|
|
|
7376
7308
|
}
|
|
7377
7309
|
};
|
|
7378
7310
|
|
|
7379
|
-
// ../../../gateway/dist/telemetry/runtime.js
|
|
7380
|
-
init_cjs_shims();
|
|
7381
|
-
|
|
7382
|
-
// ../../../gateway/dist/telemetry/mcp-client.js
|
|
7383
|
-
init_cjs_shims();
|
|
7384
|
-
init_esm();
|
|
7385
|
-
function bounded(value, maxLength) {
|
|
7386
|
-
return value.slice(0, maxLength);
|
|
7387
|
-
}
|
|
7388
|
-
function stringProperty(value, key2) {
|
|
7389
|
-
if (typeof value !== "object" || value === null || !(key2 in value)) {
|
|
7390
|
-
return void 0;
|
|
7391
|
-
}
|
|
7392
|
-
const property = Reflect.get(value, key2);
|
|
7393
|
-
return typeof property === "string" ? property : void 0;
|
|
7394
|
-
}
|
|
7395
|
-
var McpClientTelemetry = class {
|
|
7396
|
-
tracer;
|
|
7397
|
-
ended = false;
|
|
7398
|
-
hadError = false;
|
|
7399
|
-
organizationId;
|
|
7400
|
-
sessionContext;
|
|
7401
|
-
sessionSpan;
|
|
7402
|
-
constructor(tracer) {
|
|
7403
|
-
this.tracer = tracer;
|
|
7404
|
-
this.sessionSpan = tracer.startSpan("gen_ai.request", {
|
|
7405
|
-
attributes: {
|
|
7406
|
-
"gen_ai.operation.name": "invoke_agent"
|
|
7407
|
-
}
|
|
7408
|
-
});
|
|
7409
|
-
this.sessionContext = trace.setSpan(context.active(), this.sessionSpan);
|
|
7410
|
-
}
|
|
7411
|
-
setOrganizationId(organizationId) {
|
|
7412
|
-
this.organizationId = organizationId;
|
|
7413
|
-
this.sessionSpan.setAttribute("organization.id", organizationId);
|
|
7414
|
-
}
|
|
7415
|
-
async runTool(call, operation) {
|
|
7416
|
-
const attributes = {
|
|
7417
|
-
"gen_ai.operation.name": "execute_tool",
|
|
7418
|
-
...call.client ? {
|
|
7419
|
-
"mcp.client.name": bounded(call.client.name, 80),
|
|
7420
|
-
...call.client.version ? {
|
|
7421
|
-
"mcp.client.version": bounded(call.client.version, 40)
|
|
7422
|
-
} : {}
|
|
7423
|
-
} : {},
|
|
7424
|
-
...this.organizationId ? { "organization.id": this.organizationId } : {},
|
|
7425
|
-
"tool.name": bounded(call.toolName, 80)
|
|
7426
|
-
};
|
|
7427
|
-
if (call.client) {
|
|
7428
|
-
this.sessionSpan.setAttributes({
|
|
7429
|
-
"mcp.client.name": bounded(call.client.name, 80),
|
|
7430
|
-
...call.client.version ? { "mcp.client.version": bounded(call.client.version, 40) } : {}
|
|
7431
|
-
});
|
|
7432
|
-
}
|
|
7433
|
-
let span;
|
|
7434
|
-
try {
|
|
7435
|
-
span = this.tracer.startSpan("gen_ai.tool_call", { attributes }, this.sessionContext);
|
|
7436
|
-
} catch {
|
|
7437
|
-
return operation();
|
|
7438
|
-
}
|
|
7439
|
-
const startedAt = Date.now();
|
|
7440
|
-
try {
|
|
7441
|
-
const result = await context.with(trace.setSpan(this.sessionContext, span), operation);
|
|
7442
|
-
span.setAttribute("tool.duration_ms", Date.now() - startedAt);
|
|
7443
|
-
if (this.organizationId) {
|
|
7444
|
-
span.setAttribute("organization.id", this.organizationId);
|
|
7445
|
-
}
|
|
7446
|
-
if (result.kind === "error") {
|
|
7447
|
-
this.hadError = true;
|
|
7448
|
-
span.setAttributes({
|
|
7449
|
-
...result.applicationId ? { "application.id": result.applicationId } : {},
|
|
7450
|
-
"mcp.error.code": bounded(result.code, 80),
|
|
7451
|
-
"tool.error_category": result.code === "cancelled" ? "timeout" : "execution_error",
|
|
7452
|
-
"tool.status": "error"
|
|
7453
|
-
});
|
|
7454
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
7455
|
-
} else if (result.kind === "auth_required") {
|
|
7456
|
-
this.hadError = true;
|
|
7457
|
-
span.setAttributes({
|
|
7458
|
-
"mcp.result.status": "auth_required",
|
|
7459
|
-
"tool.error_category": "permission_denied",
|
|
7460
|
-
"tool.status": "error"
|
|
7461
|
-
});
|
|
7462
|
-
} else {
|
|
7463
|
-
const applicationId = stringProperty(result.value, "applicationId");
|
|
7464
|
-
const resultStatus = stringProperty(result.value, "status");
|
|
7465
|
-
span.setAttributes({
|
|
7466
|
-
...applicationId ? { "application.id": applicationId } : {},
|
|
7467
|
-
...resultStatus ? { "mcp.result.status": bounded(resultStatus, 80) } : {},
|
|
7468
|
-
"tool.error_category": "none",
|
|
7469
|
-
"tool.status": "success"
|
|
7470
|
-
});
|
|
7471
|
-
}
|
|
7472
|
-
return result;
|
|
7473
|
-
} catch (error) {
|
|
7474
|
-
this.hadError = true;
|
|
7475
|
-
span.setAttributes({
|
|
7476
|
-
"tool.duration_ms": Date.now() - startedAt,
|
|
7477
|
-
"tool.error_category": "execution_error",
|
|
7478
|
-
"tool.status": "error"
|
|
7479
|
-
});
|
|
7480
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
7481
|
-
throw error;
|
|
7482
|
-
} finally {
|
|
7483
|
-
span.end();
|
|
7484
|
-
}
|
|
7485
|
-
}
|
|
7486
|
-
endSession() {
|
|
7487
|
-
if (this.ended) {
|
|
7488
|
-
return;
|
|
7489
|
-
}
|
|
7490
|
-
this.ended = true;
|
|
7491
|
-
this.sessionSpan.setAttribute("gen_ai.request.status", this.hadError ? "error" : "success");
|
|
7492
|
-
this.sessionSpan.end();
|
|
7493
|
-
}
|
|
7494
|
-
};
|
|
7495
|
-
|
|
7496
|
-
// ../../../gateway/dist/telemetry/runtime.js
|
|
7497
|
-
var TELEMETRY_SHUTDOWN_MS = 2e3;
|
|
7498
|
-
function logToStderr(first, message) {
|
|
7499
|
-
if (message === void 0) {
|
|
7500
|
-
console.error(first);
|
|
7501
|
-
return;
|
|
7502
|
-
}
|
|
7503
|
-
console.error(first, message);
|
|
7504
|
-
}
|
|
7505
|
-
var stderrLogger = {
|
|
7506
|
-
error: logToStderr,
|
|
7507
|
-
info: logToStderr,
|
|
7508
|
-
warn: logToStderr
|
|
7509
|
-
};
|
|
7510
|
-
function telemetryBaseUrl(serverUrl) {
|
|
7511
|
-
try {
|
|
7512
|
-
const url = new URL(serverUrl);
|
|
7513
|
-
url.hash = "";
|
|
7514
|
-
url.pathname = `${url.pathname.replace(/\/$/u, "")}/api`;
|
|
7515
|
-
url.search = "";
|
|
7516
|
-
return url.toString().replace(/\/$/u, "");
|
|
7517
|
-
} catch {
|
|
7518
|
-
console.error("gateway telemetry skipped: server URL is not parseable");
|
|
7519
|
-
return void 0;
|
|
7520
|
-
}
|
|
7521
|
-
}
|
|
7522
|
-
function environmentName(config) {
|
|
7523
|
-
if (config.deploymentEnvironmentName !== "unknown") {
|
|
7524
|
-
return config.deploymentEnvironmentName;
|
|
7525
|
-
}
|
|
7526
|
-
try {
|
|
7527
|
-
return environmentFromHostname(new URL(config.serverUrl).hostname);
|
|
7528
|
-
} catch {
|
|
7529
|
-
return "unknown";
|
|
7530
|
-
}
|
|
7531
|
-
}
|
|
7532
|
-
function environmentFromHostname(hostname) {
|
|
7533
|
-
if (hostname.match(/^app\.superblocks(?:hq)?\.com$/u)) {
|
|
7534
|
-
return "prod";
|
|
7535
|
-
}
|
|
7536
|
-
if (hostname.match(/^eu\.superblocks(?:hq)?\.com$/u)) {
|
|
7537
|
-
return "prod-eu";
|
|
7538
|
-
}
|
|
7539
|
-
if (hostname.match(/^staging\.superblocks(?:hq)?\.com$/u)) {
|
|
7540
|
-
return "staging";
|
|
7541
|
-
}
|
|
7542
|
-
if (hostname.match(/^dev\.superblocks(?:hq)?\.com$/u)) {
|
|
7543
|
-
return "dev";
|
|
7544
|
-
}
|
|
7545
|
-
if (hostname.match(/^pr-[0-9]+\.superblocks(?:hq)?\.dev$/u)) {
|
|
7546
|
-
return "ephemeral";
|
|
7547
|
-
}
|
|
7548
|
-
if (hostname === "localhost" || hostname === "127.0.0.1") {
|
|
7549
|
-
return "local";
|
|
7550
|
-
}
|
|
7551
|
-
return "other";
|
|
7552
|
-
}
|
|
7553
|
-
function deploymentTypeFor(config) {
|
|
7554
|
-
if (config.localAgentMode) {
|
|
7555
|
-
return import_shared.DeploymentTypeEnum.CLOUD_PREM;
|
|
7556
|
-
}
|
|
7557
|
-
try {
|
|
7558
|
-
return parseDeploymentType(process.env.SUPERBLOCKS_DEPLOYMENT_TYPE);
|
|
7559
|
-
} catch {
|
|
7560
|
-
return import_shared.DeploymentTypeEnum.CLOUD;
|
|
7561
|
-
}
|
|
7562
|
-
}
|
|
7563
|
-
async function settleWithin(work, timeoutMs) {
|
|
7564
|
-
let timer;
|
|
7565
|
-
try {
|
|
7566
|
-
await Promise.race([
|
|
7567
|
-
work,
|
|
7568
|
-
new Promise((resolve) => {
|
|
7569
|
-
timer = setTimeout(resolve, timeoutMs);
|
|
7570
|
-
})
|
|
7571
|
-
]);
|
|
7572
|
-
} finally {
|
|
7573
|
-
if (timer !== void 0) {
|
|
7574
|
-
clearTimeout(timer);
|
|
7575
|
-
}
|
|
7576
|
-
}
|
|
7577
|
-
}
|
|
7578
|
-
function startGatewayTelemetry(input) {
|
|
7579
|
-
const otlpUrl = telemetryBaseUrl(input.config.serverUrl);
|
|
7580
|
-
const telemetry = initNodeTelemetry({
|
|
7581
|
-
environment: environmentName(input.config),
|
|
7582
|
-
logger: stderrLogger,
|
|
7583
|
-
logsEnabled: false,
|
|
7584
|
-
// Counters in metrics.ts are created at import time, before this SDK
|
|
7585
|
-
// starts, so they stay no-ops. Do not turn metrics on until those
|
|
7586
|
-
// instruments are created after init.
|
|
7587
|
-
metricsEnabled: false,
|
|
7588
|
-
otlpHeaders: { Authorization: `Bearer ${input.apiKey}` },
|
|
7589
|
-
...otlpUrl ? { otlpUrl } : {},
|
|
7590
|
-
serviceName: "gateway",
|
|
7591
|
-
serviceVersion: "0.0.1"
|
|
7592
|
-
}, getDefaultPolicy(deploymentTypeFor(input.config)));
|
|
7593
|
-
const mcpTelemetry = new McpClientTelemetry(telemetry.getTracer("gateway.mcp"));
|
|
7594
|
-
return {
|
|
7595
|
-
mcpTelemetry,
|
|
7596
|
-
shutdown: async () => {
|
|
7597
|
-
try {
|
|
7598
|
-
mcpTelemetry.endSession();
|
|
7599
|
-
} finally {
|
|
7600
|
-
await settleWithin(telemetry.shutdown(), TELEMETRY_SHUTDOWN_MS);
|
|
7601
|
-
}
|
|
7602
|
-
}
|
|
7603
|
-
};
|
|
7604
|
-
}
|
|
7605
|
-
|
|
7606
7311
|
// ../../../gateway/dist/transports/mcp/mount.js
|
|
7607
7312
|
init_cjs_shims();
|
|
7608
7313
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
@@ -7702,150 +7407,6 @@ function N3(Z, $, J, X, V) {
|
|
|
7702
7407
|
return Z.registerResource($, J, { mimeType: p, ...X }, V);
|
|
7703
7408
|
}
|
|
7704
7409
|
|
|
7705
|
-
// ../../../gateway/dist/capabilities/integration-metadata.js
|
|
7706
|
-
init_cjs_shims();
|
|
7707
|
-
var DEFAULT_LIMIT = 100;
|
|
7708
|
-
function labelPart(value) {
|
|
7709
|
-
return typeof value === "string" ? value.trim().replaceAll(/[.[\]]/g, "_") : "";
|
|
7710
|
-
}
|
|
7711
|
-
function arrayEntryLabel(value, index) {
|
|
7712
|
-
if (value && typeof value === "object") {
|
|
7713
|
-
const row = value;
|
|
7714
|
-
const name = labelPart(row.name);
|
|
7715
|
-
if (name) {
|
|
7716
|
-
const schema = labelPart(row.schema);
|
|
7717
|
-
return schema ? `${schema}.${name}` : name;
|
|
7718
|
-
}
|
|
7719
|
-
}
|
|
7720
|
-
return String(index);
|
|
7721
|
-
}
|
|
7722
|
-
function metadataEntries(value, path3 = "", entries = []) {
|
|
7723
|
-
if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
7724
|
-
entries.push({ path: path3, value });
|
|
7725
|
-
return entries;
|
|
7726
|
-
}
|
|
7727
|
-
if (Array.isArray(value)) {
|
|
7728
|
-
const seen = /* @__PURE__ */ new Set();
|
|
7729
|
-
value.forEach((entry, index) => {
|
|
7730
|
-
const label = arrayEntryLabel(entry, index);
|
|
7731
|
-
const unique = seen.has(label) ? `${label}#${index}` : label;
|
|
7732
|
-
seen.add(unique);
|
|
7733
|
-
metadataEntries(entry, `${path3}[${unique}]`, entries);
|
|
7734
|
-
});
|
|
7735
|
-
return entries;
|
|
7736
|
-
}
|
|
7737
|
-
if (value && typeof value === "object") {
|
|
7738
|
-
for (const [key2, entry] of Object.entries(value)) {
|
|
7739
|
-
metadataEntries(entry, path3 ? `${path3}.${key2}` : key2, entries);
|
|
7740
|
-
}
|
|
7741
|
-
}
|
|
7742
|
-
return entries;
|
|
7743
|
-
}
|
|
7744
|
-
async function getIntegrationMetadata(context2, input) {
|
|
7745
|
-
const principal = await ensurePrincipal(context2);
|
|
7746
|
-
if (principal.kind !== "ok") {
|
|
7747
|
-
return principal;
|
|
7748
|
-
}
|
|
7749
|
-
let applicationId;
|
|
7750
|
-
let label = sanitizeAgentFacingText(input.integrationId);
|
|
7751
|
-
try {
|
|
7752
|
-
const resolved = await resolveApplicationId(context2, principal.value, input.applicationId);
|
|
7753
|
-
applicationId = resolved.kind === "ok" ? resolved.value : void 0;
|
|
7754
|
-
const rows = await context2.server.getSupersetIntegrations({
|
|
7755
|
-
apiKey: principal.value.apiKey,
|
|
7756
|
-
...applicationId && { applicationId },
|
|
7757
|
-
organizationId: principal.value.organizationId
|
|
7758
|
-
});
|
|
7759
|
-
const integration = rows.find((row) => row.id === input.integrationId);
|
|
7760
|
-
if (!integration) {
|
|
7761
|
-
return {
|
|
7762
|
-
...applicationId && { applicationId },
|
|
7763
|
-
kind: "error",
|
|
7764
|
-
code: "integration_not_accessible",
|
|
7765
|
-
message: `Integration ${label} was not found or is not accessible.`
|
|
7766
|
-
};
|
|
7767
|
-
}
|
|
7768
|
-
const integrationName = sanitizeAgentFacingText(integration.name);
|
|
7769
|
-
const pluginId = sanitizeAgentFacingText(integration.pluginId);
|
|
7770
|
-
label = integrationName;
|
|
7771
|
-
if (!hasBuildPermission(integration)) {
|
|
7772
|
-
return {
|
|
7773
|
-
...applicationId && { applicationId },
|
|
7774
|
-
kind: "error",
|
|
7775
|
-
code: "integration_not_permitted",
|
|
7776
|
-
message: `You do not have build permission on ${integrationName}.`
|
|
7777
|
-
};
|
|
7778
|
-
}
|
|
7779
|
-
if (!integrationIsToolSupported(integration.pluginId)) {
|
|
7780
|
-
return {
|
|
7781
|
-
...applicationId && { applicationId },
|
|
7782
|
-
kind: "error",
|
|
7783
|
-
code: "integration_not_supported",
|
|
7784
|
-
message: `${integrationName} is a ${pluginId} integration, which this tool cannot inspect.`
|
|
7785
|
-
};
|
|
7786
|
-
}
|
|
7787
|
-
const profiles = await context2.server.getOrganizationProfiles({
|
|
7788
|
-
apiKey: principal.value.apiKey,
|
|
7789
|
-
organizationId: principal.value.organizationId
|
|
7790
|
-
});
|
|
7791
|
-
const profileKey = pickEditorProfileKey(context2.config.profileKey, profiles);
|
|
7792
|
-
const inventory = await context2.server.getAgentInventory({
|
|
7793
|
-
apiKey: principal.value.apiKey,
|
|
7794
|
-
organizationId: principal.value.organizationId
|
|
7795
|
-
});
|
|
7796
|
-
const orchestratorUrl = pickOrchestratorBaseUrl({
|
|
7797
|
-
agentType: inventory.agentType,
|
|
7798
|
-
agents: inventory.agents,
|
|
7799
|
-
profileKey
|
|
7800
|
-
});
|
|
7801
|
-
const scopedToken = await context2.server.issueScopedToken(applicationId ? {
|
|
7802
|
-
apiKey: principal.value.apiKey,
|
|
7803
|
-
applicationId,
|
|
7804
|
-
scope: "apps:update"
|
|
7805
|
-
} : {
|
|
7806
|
-
apiKey: principal.value.apiKey,
|
|
7807
|
-
integrationId: input.integrationId,
|
|
7808
|
-
scope: "integrations:build"
|
|
7809
|
-
});
|
|
7810
|
-
const metadata = await new HttpOrchestratorClient(orchestratorUrl).getMetadata({
|
|
7811
|
-
apiKey: principal.value.apiKey,
|
|
7812
|
-
integrationId: input.integrationId,
|
|
7813
|
-
profileKey,
|
|
7814
|
-
scopedToken
|
|
7815
|
-
});
|
|
7816
|
-
const sanitized = sanitizeAgentFacingValue(metadata);
|
|
7817
|
-
const search = input.search?.trim().toLowerCase();
|
|
7818
|
-
const matched = metadataEntries(sanitized).filter((entry) => !search || entry.path.toLowerCase().includes(search) || String(entry.value).toLowerCase().includes(search));
|
|
7819
|
-
const limit = input.limit ?? DEFAULT_LIMIT;
|
|
7820
|
-
const offset = input.offset ?? 0;
|
|
7821
|
-
const entries = matched.slice(offset, offset + limit);
|
|
7822
|
-
const nextOffset = offset + entries.length < matched.length ? offset + entries.length : null;
|
|
7823
|
-
return {
|
|
7824
|
-
kind: "ok",
|
|
7825
|
-
value: {
|
|
7826
|
-
...applicationId && { applicationId },
|
|
7827
|
-
entries,
|
|
7828
|
-
hasMore: nextOffset !== null,
|
|
7829
|
-
integrationId: integration.id,
|
|
7830
|
-
integrationName,
|
|
7831
|
-
nextOffset,
|
|
7832
|
-
offset,
|
|
7833
|
-
pluginId,
|
|
7834
|
-
returnedCount: entries.length,
|
|
7835
|
-
totalCount: matched.length
|
|
7836
|
-
}
|
|
7837
|
-
};
|
|
7838
|
-
} catch (error) {
|
|
7839
|
-
const detail = sanitizeAgentFacingText(error instanceof Error ? error.message : "Unknown metadata error").replaceAll("\u2014", "-");
|
|
7840
|
-
return {
|
|
7841
|
-
...applicationId && { applicationId },
|
|
7842
|
-
kind: "error",
|
|
7843
|
-
code: "integration_metadata_unavailable",
|
|
7844
|
-
message: `Could not load metadata for ${label}: ${detail}`
|
|
7845
|
-
};
|
|
7846
|
-
}
|
|
7847
|
-
}
|
|
7848
|
-
|
|
7849
7410
|
// ../../../gateway/dist/capture/browser-instructions.js
|
|
7850
7411
|
init_cjs_shims();
|
|
7851
7412
|
var BROWSER_DRIVER_INSTRUCTIONS = `Browser capture (MUST):
|
|
@@ -8507,16 +8068,6 @@ function resolveToken(options, auth) {
|
|
|
8507
8068
|
function superblocksProductCopy(text) {
|
|
8508
8069
|
return text.replaceAll(/\bClark AI Apps\b/g, "Superblocks AI Apps").replaceAll(/\bClark\b/g, "Superblocks");
|
|
8509
8070
|
}
|
|
8510
|
-
function completeToolAnnotations(annotations) {
|
|
8511
|
-
const readOnlyHint = annotations?.readOnlyHint ?? false;
|
|
8512
|
-
return {
|
|
8513
|
-
...annotations,
|
|
8514
|
-
destructiveHint: annotations?.destructiveHint ?? (readOnlyHint ? false : true),
|
|
8515
|
-
idempotentHint: annotations?.idempotentHint ?? readOnlyHint,
|
|
8516
|
-
openWorldHint: annotations?.openWorldHint ?? true,
|
|
8517
|
-
readOnlyHint
|
|
8518
|
-
};
|
|
8519
|
-
}
|
|
8520
8071
|
function registerAdminTools(server, options) {
|
|
8521
8072
|
const registry = buildToolRegistry(toolDefinitions, "customer", {
|
|
8522
8073
|
requireEntitledPlan: options.localAgentMode !== true
|
|
@@ -8527,7 +8078,7 @@ function registerAdminTools(server, options) {
|
|
|
8527
8078
|
}
|
|
8528
8079
|
const definition = toolDefinitions.find((d2) => d2.name === tool.name);
|
|
8529
8080
|
server.registerTool(tool.name, {
|
|
8530
|
-
annotations:
|
|
8081
|
+
annotations: tool.annotations,
|
|
8531
8082
|
description: superblocksProductCopy(tool.description ?? ""),
|
|
8532
8083
|
inputSchema: gatewayAdminInputShape(tool.inputSchema),
|
|
8533
8084
|
title: tool.title ?? definition?.title
|
|
@@ -8568,7 +8119,7 @@ function registerAdminTools(server, options) {
|
|
|
8568
8119
|
|
|
8569
8120
|
// ../../../gateway/dist/transports/mcp/app-status-html.js
|
|
8570
8121
|
init_cjs_shims();
|
|
8571
|
-
var APP_STATUS_RESOURCE_URI = "ui://gateway/app-status-
|
|
8122
|
+
var APP_STATUS_RESOURCE_URI = "ui://gateway/app-status-v6.html";
|
|
8572
8123
|
var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
8573
8124
|
<html lang="en">
|
|
8574
8125
|
<head>
|
|
@@ -8682,29 +8233,11 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8682
8233
|
<script>
|
|
8683
8234
|
(() => {
|
|
8684
8235
|
const PROTOCOL_VERSION = "2026-01-26";
|
|
8685
|
-
// Statuses get_app reports when the app is still the empty starter
|
|
8686
|
-
// template. "building" is deliberately absent: the card only hears a
|
|
8687
|
-
// build finished if a new result arrives, so a stale badge would strand
|
|
8688
|
-
// the button.
|
|
8689
|
-
const UNBUILT_STATUSES = [
|
|
8690
|
-
"cancelled",
|
|
8691
|
-
"live_edit_terminated",
|
|
8692
|
-
"needs_decision",
|
|
8693
|
-
"no_changes",
|
|
8694
|
-
"timeout",
|
|
8695
|
-
];
|
|
8696
|
-
const BLOCKED_ACTIONS = [
|
|
8697
|
-
"answer_question",
|
|
8698
|
-
"approve_plan",
|
|
8699
|
-
"retry_build",
|
|
8700
|
-
"retry_import",
|
|
8701
|
-
];
|
|
8702
8236
|
let nextId = 1;
|
|
8703
8237
|
const pending = new Map();
|
|
8704
8238
|
let applicationId = "";
|
|
8705
8239
|
let appName = "";
|
|
8706
8240
|
let commitId = "";
|
|
8707
|
-
let pendingAction = "";
|
|
8708
8241
|
let editUrl = "";
|
|
8709
8242
|
let previewUrl = "";
|
|
8710
8243
|
let publishUrl = "";
|
|
@@ -8712,13 +8245,6 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8712
8245
|
let canCallTools = false;
|
|
8713
8246
|
let publishing = false;
|
|
8714
8247
|
let lastHeight = 0;
|
|
8715
|
-
let refreshInFlight = false;
|
|
8716
|
-
let refreshTimer = 0;
|
|
8717
|
-
let refreshGeneration = 0;
|
|
8718
|
-
let refreshAttempts = 0;
|
|
8719
|
-
let pollAfterMs = 2000;
|
|
8720
|
-
const MIN_POLL_MS = 2000;
|
|
8721
|
-
const MAX_REFRESH_ATTEMPTS = 40;
|
|
8722
8248
|
|
|
8723
8249
|
function post(message) {
|
|
8724
8250
|
window.parent.postMessage(message, "*");
|
|
@@ -8808,31 +8334,6 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8808
8334
|
}
|
|
8809
8335
|
}
|
|
8810
8336
|
|
|
8811
|
-
/**
|
|
8812
|
-
* True when publishing would deploy the empty starter template.
|
|
8813
|
-
* pendingAction is the server's own "nothing to preview" signal;
|
|
8814
|
-
* wait_for_build is the building exception. Status is only a fallback
|
|
8815
|
-
* when the payload omitted pendingAction. loading/waiting with no
|
|
8816
|
-
* preview fail closed so Publish is not clickable before get_app
|
|
8817
|
-
* returns.
|
|
8818
|
-
*/
|
|
8819
|
-
function nothingToPublish() {
|
|
8820
|
-
if (previewUrl || publishUrl) {
|
|
8821
|
-
return false;
|
|
8822
|
-
}
|
|
8823
|
-
if (pendingAction === "wait_for_build") {
|
|
8824
|
-
return false;
|
|
8825
|
-
}
|
|
8826
|
-
if (BLOCKED_ACTIONS.indexOf(pendingAction) !== -1) {
|
|
8827
|
-
return true;
|
|
8828
|
-
}
|
|
8829
|
-
const badge = element("status").textContent;
|
|
8830
|
-
if (!badge || badge === "loading" || badge === "waiting") {
|
|
8831
|
-
return true;
|
|
8832
|
-
}
|
|
8833
|
-
return UNBUILT_STATUSES.indexOf(badge) !== -1;
|
|
8834
|
-
}
|
|
8835
|
-
|
|
8836
8337
|
/**
|
|
8837
8338
|
* Keep URLs in memory for openLink \u2014 never print them (preview JWTs are
|
|
8838
8339
|
* huge and ugly in the card).
|
|
@@ -8847,10 +8348,7 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8847
8348
|
: "Publish app";
|
|
8848
8349
|
element("publishApp").disabled = publishUrl
|
|
8849
8350
|
? !canOpenLinks
|
|
8850
|
-
: !applicationId ||
|
|
8851
|
-
!canCallTools ||
|
|
8852
|
-
publishing ||
|
|
8853
|
-
nothingToPublish();
|
|
8351
|
+
: !applicationId || !canCallTools || publishing;
|
|
8854
8352
|
// Only warn about what is actually broken. Hosts that do open links
|
|
8855
8353
|
// handle local http fine; if one refuses, refused() says so then.
|
|
8856
8354
|
if (!canOpenLinks && (editUrl || previewUrl) && !publishUrl) {
|
|
@@ -8922,11 +8420,6 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8922
8420
|
if (typeof value.commitId === "string") {
|
|
8923
8421
|
commitId = value.commitId;
|
|
8924
8422
|
}
|
|
8925
|
-
if (typeof value.pendingAction === "string") {
|
|
8926
|
-
pendingAction = value.pendingAction;
|
|
8927
|
-
} else if (typeof value.status === "string") {
|
|
8928
|
-
pendingAction = "";
|
|
8929
|
-
}
|
|
8930
8423
|
if (typeof value.screenshotBase64 === "string") {
|
|
8931
8424
|
showScreenshot(value.screenshotBase64, "image/jpeg");
|
|
8932
8425
|
}
|
|
@@ -8939,9 +8432,6 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8939
8432
|
if (typeof value.publishUrl === "string") {
|
|
8940
8433
|
publishUrl = webUrl(value.publishUrl);
|
|
8941
8434
|
}
|
|
8942
|
-
if (typeof value.nextPollAfterMs === "number") {
|
|
8943
|
-
pollAfterMs = value.nextPollAfterMs;
|
|
8944
|
-
}
|
|
8945
8435
|
// Hosts that deliver URLs without a status left the badge on the HTML
|
|
8946
8436
|
// default ("loading") even after the app was built.
|
|
8947
8437
|
const badge = element("status").textContent;
|
|
@@ -8956,91 +8446,29 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
8956
8446
|
}
|
|
8957
8447
|
|
|
8958
8448
|
/**
|
|
8959
|
-
*
|
|
8960
|
-
*
|
|
8961
|
-
*
|
|
8449
|
+
* When the host opened the card with tool input (applicationId) but never
|
|
8450
|
+
* pushed a tool result, refresh ourselves so the badge is not stuck on
|
|
8451
|
+
* "loading" after the build finished.
|
|
8962
8452
|
*/
|
|
8963
|
-
function clearRefreshTimer() {
|
|
8964
|
-
if (refreshTimer) {
|
|
8965
|
-
clearTimeout(refreshTimer);
|
|
8966
|
-
refreshTimer = 0;
|
|
8967
|
-
}
|
|
8968
|
-
}
|
|
8969
|
-
|
|
8970
|
-
function retryDelay() {
|
|
8971
|
-
return Math.max(MIN_POLL_MS, pollAfterMs || MIN_POLL_MS);
|
|
8972
|
-
}
|
|
8973
|
-
|
|
8974
|
-
function scheduleRefresh(delayMs) {
|
|
8975
|
-
clearRefreshTimer();
|
|
8976
|
-
if (refreshAttempts >= MAX_REFRESH_ATTEMPTS) {
|
|
8977
|
-
note("Stopped checking whether the app is still building.");
|
|
8978
|
-
return;
|
|
8979
|
-
}
|
|
8980
|
-
refreshTimer = setTimeout(() => {
|
|
8981
|
-
refreshTimer = 0;
|
|
8982
|
-
refreshFromServer();
|
|
8983
|
-
}, delayMs);
|
|
8984
|
-
}
|
|
8985
|
-
|
|
8986
8453
|
function refreshFromServer() {
|
|
8987
|
-
|
|
8988
|
-
if (!canCallTools || !applicationId || refreshInFlight) {
|
|
8989
|
-
return;
|
|
8990
|
-
}
|
|
8991
|
-
if (typeof document.hidden === "boolean" && document.hidden) {
|
|
8992
|
-
scheduleRefresh(retryDelay());
|
|
8993
|
-
return;
|
|
8994
|
-
}
|
|
8995
|
-
const badge = element("status").textContent;
|
|
8996
|
-
if (editUrl && badge !== "building") {
|
|
8997
|
-
return;
|
|
8998
|
-
}
|
|
8999
|
-
if (refreshAttempts >= MAX_REFRESH_ATTEMPTS) {
|
|
9000
|
-
note("Stopped checking whether the app is still building.");
|
|
8454
|
+
if (!canCallTools || !applicationId || editUrl) {
|
|
9001
8455
|
return;
|
|
9002
8456
|
}
|
|
9003
|
-
refreshAttempts += 1;
|
|
9004
|
-
const generation = refreshGeneration;
|
|
9005
|
-
refreshInFlight = true;
|
|
9006
8457
|
request("tools/call", {
|
|
9007
8458
|
name: "get_app",
|
|
9008
|
-
arguments: {
|
|
9009
|
-
applicationId,
|
|
9010
|
-
ensurePreview: false,
|
|
9011
|
-
wait: false,
|
|
9012
|
-
},
|
|
8459
|
+
arguments: { applicationId },
|
|
9013
8460
|
})
|
|
9014
8461
|
.then((result) => {
|
|
9015
|
-
refreshInFlight = false;
|
|
9016
|
-
if (generation !== refreshGeneration) {
|
|
9017
|
-
if (element("status").textContent === "building") {
|
|
9018
|
-
scheduleRefresh(retryDelay());
|
|
9019
|
-
}
|
|
9020
|
-
return;
|
|
9021
|
-
}
|
|
9022
8462
|
if (!result || result.isError) {
|
|
9023
|
-
scheduleRefresh(retryDelay());
|
|
9024
8463
|
return;
|
|
9025
8464
|
}
|
|
9026
8465
|
applyPayload(result);
|
|
9027
8466
|
if (result.structuredContent) {
|
|
9028
8467
|
applyPayload(result.structuredContent);
|
|
9029
8468
|
}
|
|
9030
|
-
if (element("status").textContent !== "building") {
|
|
9031
|
-
return;
|
|
9032
|
-
}
|
|
9033
|
-
if (pollAfterMs === 0) {
|
|
9034
|
-
return;
|
|
9035
|
-
}
|
|
9036
|
-
scheduleRefresh(retryDelay());
|
|
9037
8469
|
})
|
|
9038
8470
|
.catch(() => {
|
|
9039
|
-
|
|
9040
|
-
if (generation !== refreshGeneration) {
|
|
9041
|
-
return;
|
|
9042
|
-
}
|
|
9043
|
-
scheduleRefresh(retryDelay());
|
|
8471
|
+
// Host declined; stay on whatever we have.
|
|
9044
8472
|
});
|
|
9045
8473
|
}
|
|
9046
8474
|
|
|
@@ -9093,10 +8521,6 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
9093
8521
|
if (!applicationId || !canCallTools || publishing) {
|
|
9094
8522
|
return;
|
|
9095
8523
|
}
|
|
9096
|
-
if (nothingToPublish()) {
|
|
9097
|
-
note("Nothing to publish yet: this turn did not build the app.");
|
|
9098
|
-
return;
|
|
9099
|
-
}
|
|
9100
8524
|
publishing = true;
|
|
9101
8525
|
renderActions();
|
|
9102
8526
|
note("Publishing\u2026");
|
|
@@ -9180,10 +8604,6 @@ var APP_STATUS_HTML = `<!DOCTYPE html>
|
|
|
9180
8604
|
if (params.structuredContent) {
|
|
9181
8605
|
applyPayload(params.structuredContent);
|
|
9182
8606
|
}
|
|
9183
|
-
refreshGeneration += 1;
|
|
9184
|
-
if (element("status").textContent === "building") {
|
|
9185
|
-
refreshFromServer();
|
|
9186
|
-
}
|
|
9187
8607
|
}
|
|
9188
8608
|
if (method === "ui/notifications/tool-input" && params.arguments) {
|
|
9189
8609
|
applyPayload(params.arguments);
|
|
@@ -9513,24 +8933,6 @@ function createProgressNotifier(extra) {
|
|
|
9513
8933
|
}
|
|
9514
8934
|
|
|
9515
8935
|
// ../../../gateway/dist/transports/mcp/mount.js
|
|
9516
|
-
var DESTRUCTIVE_TOOL_ANNOTATIONS = {
|
|
9517
|
-
destructiveHint: true,
|
|
9518
|
-
idempotentHint: false,
|
|
9519
|
-
openWorldHint: true,
|
|
9520
|
-
readOnlyHint: false
|
|
9521
|
-
};
|
|
9522
|
-
var NON_DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS = {
|
|
9523
|
-
destructiveHint: false,
|
|
9524
|
-
idempotentHint: false,
|
|
9525
|
-
openWorldHint: true,
|
|
9526
|
-
readOnlyHint: false
|
|
9527
|
-
};
|
|
9528
|
-
var READ_ONLY_TOOL_ANNOTATIONS = {
|
|
9529
|
-
destructiveHint: false,
|
|
9530
|
-
idempotentHint: true,
|
|
9531
|
-
openWorldHint: true,
|
|
9532
|
-
readOnlyHint: true
|
|
9533
|
-
};
|
|
9534
8936
|
var eventCursorInputSchema = external_exports.object({
|
|
9535
8937
|
streams: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
9536
8938
|
version: external_exports.unknown().optional()
|
|
@@ -9551,11 +8953,10 @@ Name the builder "Superblocks" in every word you write. Users sometimes call it
|
|
|
9551
8953
|
Use these tools whenever the user asks to build, change, import, or ship an app, whichever of those names they reach for.
|
|
9552
8954
|
|
|
9553
8955
|
- start_app: create a new application and hand a prompt to Superblocks. Returns as soon as Superblocks accepts, with status "building". Superblocks names it unless a name is given.
|
|
9554
|
-
- import_app: import an existing app from a ZIP (or .tgz/.gz) into Superblocks and start a Superblocks migration. Pass the archive's file name as zipPath \u2014 the gateway opens the file on this machine itself. Archives larger than 1 MB are rejected \u2014 they almost certainly include node_modules; re-export without install artifacts. Optional prompt carries extra intent (e.g. "make it more secure"). Returns like start_app with status "building".
|
|
8956
|
+
- import_app: import an existing app from a ZIP (or .tgz/.gz) into Superblocks and start a Superblocks migration. Pass the archive's file name as zipPath \u2014 the gateway opens the file on this machine itself. Archives larger than 1 MB are rejected \u2014 they almost certainly include node_modules; re-export without install artifacts. Optional prompt carries extra intent (e.g. "make it more secure"). Returns like start_app with status "building".
|
|
9555
8957
|
- edit_app: send a follow-up prompt (including the answer when Superblocks asked a question) for an existing application. Also returns at status "building". Defaults to the most recent app, so an applicationId is only needed to target a different app.
|
|
9556
8958
|
- check_app_progress: wait for the next thing Superblocks does and return it. It returns the moment Superblocks says anything, and after ~10 seconds of silence at the latest. "activity" holds Superblocks' own words since the previous call, in order; a quiet poll still returns a short heartbeat with elapsedSeconds.
|
|
9557
|
-
- get_app: return editor and preview URLs for the recent or specified app (builds a private preview when needed). Prefer this after status "ready" so the user can open the live app. Hosts that support MCP Apps show the status card (Open editor / Open preview) on this call \u2014 not on check_app_progress or preview_app \u2014 so only one card opens. When Superblocks has written code the tool includes a screenshot: the live Vite canvas (library peer) if a held session exists, otherwise the signed-in preview. Never open canvas.doNotOpen (the edit URL) to take that screenshot. It refuses to build a preview of an app Superblocks has not written yet: while a plan or question is outstanding it returns status "needs_decision" with "pendingAction", while a turn is running it returns status "building", and when the last turn ended without writing anything it returns that turn's status ("timeout", "live_edit_terminated", "no_changes" or "cancelled") with pendingAction "retry_build"
|
|
9558
|
-
- get_integration_metadata: inspect the tables, columns, and types in a connected integration. It needs no application and never executes an integration action, so do not call start_app or hunt through list_applications to satisfy it. Pass applicationId only for an integration that belongs to one application, such as a Native DB. Use search, limit, and offset to page large results. get_integration_config_schema is the JSON form for create_integration; it does not inspect connected data.
|
|
8959
|
+
- get_app: return editor and preview URLs for the recent or specified app (builds a private preview when needed). Prefer this after status "ready" so the user can open the live app. Hosts that support MCP Apps show the status card (Open editor / Open preview) on this call \u2014 not on check_app_progress or preview_app \u2014 so only one card opens. When Superblocks has written code the tool includes a screenshot: the live Vite canvas (library peer) if a held session exists, otherwise the signed-in preview. Never open canvas.doNotOpen (the edit URL) to take that screenshot. It refuses to build a preview of an app Superblocks has not written yet: while a plan or question is outstanding it returns status "needs_decision" with "pendingAction", while a turn is running it returns status "building", and when the last turn ended without writing anything it returns that turn's status ("timeout", "live_edit_terminated", "no_changes" or "cancelled") with pendingAction "retry_build". In each case there are no preview URLs and no screenshot \u2014 do the pendingAction first rather than calling get_app again.
|
|
9559
8960
|
- preview_app: build the application's current work and return a URL that runs it, without deploying it \u2014 the editor's Preview button. Nobody else can reach a preview. Text/markdown only (no MCP Apps widget); use get_app instead when you want the status card.
|
|
9560
8961
|
- publish_app: deploy an application and wait until it is live. It commits the current work first, so a commitId is only needed to publish an earlier commit.
|
|
9561
8962
|
|
|
@@ -9563,25 +8964,21 @@ A build takes two to four minutes, and start_app/edit_app/import_app return with
|
|
|
9563
8964
|
|
|
9564
8965
|
The user sees nothing at all while a tool call is outstanding, so between two calls always write out the new "activity" lines as a short message in your own reply \u2014 quote or paraphrase them, oldest first, before calling check_app_progress again. Do not batch them up for a summary at the end, and do not go two calls in a row without writing something: the point of the loop is that the user watches the build happen. When a call comes back with only a heartbeat (no new Superblocks words), say Superblocks is still working and how long it has been going, then poll again.
|
|
9565
8966
|
|
|
9566
|
-
status "ready" means the turn finished: report the "reply" field, then call get_app (not preview_app as well \u2014 calling both used to open two widgets) so the user gets Open preview / an https link or a screenshot. status "needs_decision" means Superblocks is waiting \u2014 often with a plan \u2014 so stop polling and put the decision to the user. When "decision.kind" is "plan", show the plan markdown, then invite them to build it as written or say what to change \u2014 the same fork the editor's Build-it button offers. Ask that as an ordinary closing question in your own words; do not turn it into a numbered or bulleted menu, and do not wrap the choices in quotation marks. When they say "Build it", "approve", "looks good", or "go ahead", you MUST call edit_app with planAction "approve" and omit prompt (do not re-send the plan, and do not put "approve" or "Build it" in the prompt field \u2014 that is refine feedback to Superblocks, not the editor Build-it path). When they want changes, call edit_app with planAction "refine" and their feedback as prompt. When "decision.kind" is "multi_choice", relay the question and options and send their answer with edit_app. Do not claim the app is built while status is "needs_decision". status "no_changes" means the Superblocks job ended without building anything: relay reply, say no app was built, and do not present the edit URL as a finished app. status "live_edit_terminated" means the live-edit session that was to run the turn died before it built anything, or never opened at all \u2014 relay reply, tell the user the session did not survive, and
|
|
9567
|
-
|
|
9568
|
-
When get_app returns a screenshot, inspect it yourself before reporting that the app looks correct. If it shows skeletons, spinners, empty tables or charts, or "Loading...", call get_app again a few seconds later instead of treating that as a defect. If it shows a problem the user would plainly recognize as wrong, call edit_app once with a concrete correction, follow that turn to completion, and inspect the next get_app screenshot. Otherwise describe what you see and ask the user whether to fix it.
|
|
8967
|
+
status "ready" means the turn finished: report the "reply" field, then call get_app (not preview_app as well \u2014 calling both used to open two widgets) so the user gets Open preview / an https link or a screenshot. status "needs_decision" means Superblocks is waiting \u2014 often with a plan \u2014 so stop polling and put the decision to the user. When "decision.kind" is "plan", show the plan markdown, then invite them to build it as written or say what to change \u2014 the same fork the editor's Build-it button offers. Ask that as an ordinary closing question in your own words; do not turn it into a numbered or bulleted menu, and do not wrap the choices in quotation marks. When they say "Build it", "approve", "looks good", or "go ahead", you MUST call edit_app with planAction "approve" and omit prompt (do not re-send the plan, and do not put "approve" or "Build it" in the prompt field \u2014 that is refine feedback to Superblocks, not the editor Build-it path). When they want changes, call edit_app with planAction "refine" and their feedback as prompt. When "decision.kind" is "multi_choice", relay the question and options and send their answer with edit_app. Do not claim the app is built while status is "needs_decision". status "no_changes" means the Superblocks job ended without building anything: relay reply, say no app was built, and do not present the edit URL as a finished app. status "live_edit_terminated" means the live-edit session that was to run the turn died before it built anything, or never opened at all \u2014 the prompt was fine and nothing timed out, so relay reply, tell the user the session did not survive, and offer to send the same instruction again with edit_app. status "detached" means Superblocks is still working but the gateway can no longer see it \u2014 usually because the app is open in a browser editor, which takes over Superblocks updates. Stop polling, say so, and point the user at the edit URL. status "unknown" means nothing is in flight for that app. A checkpointCommitId means Superblocks work is saved and the edit URL opens the finished app; when viewStatus is unknown, say the app may still be finishing in the editor.
|
|
9569
8968
|
|
|
9570
8969
|
start_app, edit_app, and import_app default to Plan mode (Superblocks proposes a plan before writing). Pass mode "BUILD" only when the user asks to skip planning and build immediately. Approving a plan after start_app or import_app is always a follow-up edit_app with planAction "approve" \u2014 never a second start_app/import_app with prompt "approve". Once the app has run in Build mode, later edit_app calls stay in Build mode on their own: you do not need to re-send mode "BUILD", and a new instruction is not a fresh planning round. Send mode "PLAN" only when the user explicitly asks to plan again before building. Every start_app / edit_app / import_app result reports the "mode" the turn ran in, so you can tell the user whether Superblocks is planning or building rather than guessing \u2014 and if a result comes back "PLAN" after a long gap, the build session was recycled rather than the user asking to plan, so pass mode "BUILD" again to carry on building. editUrl / previewUrl / publishUrl may appear in structured JSON for openLink buttons \u2014 do not dump raw URLs (especially preview JWTs) into the chat. Prefer the MCP Apps Open editor / Open preview buttons from get_app. Claude Desktop can only openLink https URLs; when previewUrl is http, say so briefly and rely on any screenshot image the tool returned rather than pasting the URL.
|
|
9571
8970
|
|
|
9572
8971
|
Once a build reaches "ready", call get_app so the user can open the app, then offer publish_app to deploy for their organization when they ask. Prefer get_app over preview_app after a build \u2014 get_app already ensures a private preview and is the only tool that opens the MCP Apps status card. Only publish when the user asks. If preview_app or get_app comes back with status "building", the URL is already correct; tell the user it is still building and call again to check.
|
|
9573
8972
|
|
|
9574
|
-
There is nothing to preview until Superblocks has written code, so get_app is not the way out of a plan, a question, or a turn that failed. When it answers status "needs_decision" (pendingAction "approve_plan" or "answer_question"), the app is still the empty starter template: put the decision to the user, send their answer with edit_app, and only call get_app once a turn has finished. When it answers "timeout", "live_edit_terminated", "no_changes" or "cancelled" with pendingAction "retry_build", that turn built nothing: tell the user so plainly, and send the instruction again with edit_app if they want to retry.
|
|
8973
|
+
There is nothing to preview until Superblocks has written code, so get_app is not the way out of a plan, a question, or a turn that failed. When it answers status "needs_decision" (pendingAction "approve_plan" or "answer_question"), the app is still the empty starter template: put the decision to the user, send their answer with edit_app, and only call get_app once a turn has finished. When it answers "timeout", "live_edit_terminated", "no_changes" or "cancelled" with pendingAction "retry_build", that turn built nothing: tell the user so plainly, and send the instruction again with edit_app if they want to retry. Repeating get_app instead opens another status card and tells the user nothing new.
|
|
9575
8974
|
|
|
9576
8975
|
Superblocks tests what it builds: it opens the app in a browser and runs its APIs, and the test run arrives as ordinary "activity" lines ("Testing the orders page", "Test passed: \u2026", "Tests failed: \u2026"). Relay those lines like any other activity, and say which cases passed and which failed \u2014 a test run is the only evidence the user has that the app actually works. A failing test is a build signal, not an auth problem: it means the app has a bug Superblocks is about to work on, so keep polling and never tell the user to sign in again or re-enter credentials over one.
|
|
9577
8976
|
|
|
9578
|
-
A failed call still names the application it was working on. start_app and import_app create the application before the build can start, so an error from either one leaves an application that exists and belongs to this conversation, and the error says which: read the "applicationId" field, never a UUID out of the message text. Never take an error to mean nothing happened. Do not answer a failed start_app with a second start_app \u2014 that abandons the app you already have and creates a duplicate. When the error carries pendingAction "retry_build" \u2014 a "live_edit_unavailable" session that would not open, or a turn that ran out of budget \u2014 send the same prompt again with edit_app and that applicationId.
|
|
9579
|
-
|
|
9580
|
-
A cancelled call does not stop the build, and it is not permission to start over. Cancelling only ends the waiting \u2014 Superblocks carries on, and the "cancelled" error names the application it was driving in "applicationId". Read that id, call check_app_progress or get_app on it, and act on what comes back. When the user then asks to redo, retry, or resume an import, that is a request to finish the application you already have: never answer it with an import_app that omits applicationId, which builds a second app and strands the first. The same holds when no pendingAction is in front of you \u2014 after a cancel, or in a later session. If the app came from an import, the way back in is import_app with the same archive and that applicationId; if you cannot tell which application the user means, ask rather than create one.
|
|
8977
|
+
A failed call still names the application it was working on. start_app and import_app create the application before the build can start, so an error from either one leaves an application that exists and belongs to this conversation, and the error says which: read the "applicationId" field, never a UUID out of the message text. Never take an error to mean nothing happened. Do not answer a failed start_app with a second start_app \u2014 that abandons the app you already have and creates a duplicate. When the error carries pendingAction "retry_build" \u2014 a "live_edit_unavailable" session that would not open, or a turn that ran out of budget \u2014 send the same prompt again with edit_app and that applicationId. A failed import_app carries no such recovery, because edit_app cannot resupply the archive the migration prompt reads: that application is empty and nothing can continue it in place, so name it to the user and let them decide whether to import again. Every edit_app error names its applicationId too, which is the one place to see which app a call that omitted the id actually ran on.
|
|
9581
8978
|
|
|
9582
8979
|
Prompts are forwarded to Superblocks verbatim \u2014 pass the user's wording rather than a summary.
|
|
9583
8980
|
|
|
9584
|
-
This connector is the single Superblocks MCP: Builder tools (start_app, import_app, edit_app, check_app_progress, get_app,
|
|
8981
|
+
This connector is the single Superblocks MCP: Builder tools (start_app, import_app, edit_app, check_app_progress, get_app, preview_app, publish_app) and Admin tools (integrations, apps, users, folders, deploy_application, and the rest of the customer Admin surface) share this endpoint. Prefer create_integration / update_integration / list_integrations here when Superblocks needs a missing Postgres, REST, or other datasource \u2014 do not send the user to a second MCP. create_integration is Admin CRUD for org datasources; start_app creates a new application and hands a prompt to Superblocks. deploy_application is Admin deploy of an existing commit; publish_app is the Builder path that commits current work and waits until the app is live. Omit base_url on Admin tools unless targeting a different control plane \u2014 the gateway injects its configured Server URL. checkout_application is not exposed on this network surface (host filesystem writes); use the CLI/workspace checkout path instead.
|
|
9585
8982
|
|
|
9586
8983
|
This connection is already authenticated and already pointed at one Superblocks Server, so there is no setup, login, or auth-status call to make first. Call the tool that does the job \u2014 list_integrations to see the org's datasources, start_app to create an application \u2014 and read its error if something is genuinely wrong. Do not look for a tool that reports credentials or environments; there is none, and asking for one costs the user a turn.
|
|
9587
8984
|
|
|
@@ -9591,7 +8988,7 @@ For import_app, the archive never travels through you. A file the user attached
|
|
|
9591
8988
|
|
|
9592
8989
|
${BROWSER_DRIVER_INSTRUCTIONS}`;
|
|
9593
8990
|
function createMcpServer(deps) {
|
|
9594
|
-
const
|
|
8991
|
+
const context = async (progress, notify, signal) => ({
|
|
9595
8992
|
caller: callerFrom(),
|
|
9596
8993
|
captureLibraryScreenshot: captureLibraryScreenshotWithPlaywright,
|
|
9597
8994
|
capturePreviewScreenshot: capturePreviewScreenshotWithPlaywright,
|
|
@@ -9601,9 +8998,6 @@ function createMcpServer(deps) {
|
|
|
9601
8998
|
progress.push(event);
|
|
9602
8999
|
notify?.(event.message);
|
|
9603
9000
|
},
|
|
9604
|
-
onPrincipalResolved: (principal) => {
|
|
9605
|
-
deps.mcpTelemetry?.setOrganizationId(principal.organizationId);
|
|
9606
|
-
},
|
|
9607
9001
|
principal: principalFrom(deps),
|
|
9608
9002
|
progressCursors: deps.progressCursors,
|
|
9609
9003
|
recentApps: deps.recentApps,
|
|
@@ -9616,22 +9010,22 @@ function createMcpServer(deps) {
|
|
|
9616
9010
|
gatewayDebugStack("tool started", { "tool.name": toolName });
|
|
9617
9011
|
const progress = [];
|
|
9618
9012
|
const notify = createProgressNotifier(extra);
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9013
|
+
let result;
|
|
9014
|
+
if (!deps.cliApiKey) {
|
|
9015
|
+
gatewayDebug("tool short-circuited", {
|
|
9016
|
+
"tool.name": toolName,
|
|
9017
|
+
"tool.reason": "missing_cli_session"
|
|
9018
|
+
});
|
|
9019
|
+
result = {
|
|
9020
|
+
kind: "error",
|
|
9021
|
+
code: "unauthenticated",
|
|
9022
|
+
message: "This Gateway has no CLI session. Run: superblocks login"
|
|
9023
|
+
};
|
|
9024
|
+
} else {
|
|
9631
9025
|
try {
|
|
9632
9026
|
const signal = extra?.signal;
|
|
9633
|
-
const capabilityContext = await
|
|
9634
|
-
|
|
9027
|
+
const capabilityContext = await context(progress, notify, signal);
|
|
9028
|
+
result = await capability(capabilityContext, () => {
|
|
9635
9029
|
for (let index = progress.length - 1; index >= 0; index -= 1) {
|
|
9636
9030
|
if (progress[index]?.type === "completed") {
|
|
9637
9031
|
progress.splice(index, 1);
|
|
@@ -9640,23 +9034,13 @@ function createMcpServer(deps) {
|
|
|
9640
9034
|
});
|
|
9641
9035
|
} catch (error) {
|
|
9642
9036
|
console.error("gateway capability failed", error);
|
|
9643
|
-
|
|
9037
|
+
result = {
|
|
9644
9038
|
kind: "error",
|
|
9645
9039
|
code: "capability_failed",
|
|
9646
9040
|
message: error instanceof Error ? error.message : "The gateway failed for an unknown reason."
|
|
9647
9041
|
};
|
|
9648
9042
|
}
|
|
9649
|
-
}
|
|
9650
|
-
const client = server.server.getClientVersion();
|
|
9651
|
-
const result = deps.mcpTelemetry ? await deps.mcpTelemetry.runTool({
|
|
9652
|
-
...client ? {
|
|
9653
|
-
client: {
|
|
9654
|
-
name: client.name,
|
|
9655
|
-
version: client.version
|
|
9656
|
-
}
|
|
9657
|
-
} : {},
|
|
9658
|
-
toolName
|
|
9659
|
-
}, execute) : await execute();
|
|
9043
|
+
}
|
|
9660
9044
|
const resultStatus = result.kind === "ok" && result.value && typeof result.value === "object" && "status" in result.value && typeof result.value.status === "string" ? result.value.status : void 0;
|
|
9661
9045
|
gatewayDebug("tool finished", {
|
|
9662
9046
|
"progress.event_count": progress.length,
|
|
@@ -9682,12 +9066,12 @@ function createMcpServer(deps) {
|
|
|
9682
9066
|
title: "Superblocks",
|
|
9683
9067
|
version: "0.0.1"
|
|
9684
9068
|
}, { instructions: SERVER_INSTRUCTIONS });
|
|
9685
|
-
const progressWithDecisionForm = async (
|
|
9069
|
+
const progressWithDecisionForm = async (context2, input, extra, forgetFinishedTurn) => {
|
|
9686
9070
|
gatewayDebug("progress decision flow started", {
|
|
9687
9071
|
"application.id": input.applicationId,
|
|
9688
9072
|
"progress.cursor_provided": Boolean(input.cursor)
|
|
9689
9073
|
});
|
|
9690
|
-
const result = await checkAppProgress(
|
|
9074
|
+
const result = await checkAppProgress(context2, input);
|
|
9691
9075
|
const decision = pendingDecision(result);
|
|
9692
9076
|
if (!decision) {
|
|
9693
9077
|
gatewayDebug("progress decision flow finished", {
|
|
@@ -9707,7 +9091,7 @@ function createMcpServer(deps) {
|
|
|
9707
9091
|
const resolved = await resolveDecisionByElicitation({
|
|
9708
9092
|
apply: (answer) => {
|
|
9709
9093
|
forgetFinishedTurn();
|
|
9710
|
-
return editApp(
|
|
9094
|
+
return editApp(context2, {
|
|
9711
9095
|
applicationId: input.applicationId,
|
|
9712
9096
|
idempotencyKey: `mcp-decision:${randomUUID4()}`,
|
|
9713
9097
|
wait: "ack",
|
|
@@ -9739,20 +9123,7 @@ function createMcpServer(deps) {
|
|
|
9739
9123
|
});
|
|
9740
9124
|
}
|
|
9741
9125
|
function registerBuilderTools() {
|
|
9742
|
-
server.registerTool("get_integration_metadata", {
|
|
9743
|
-
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
9744
|
-
description: "Inspect the tables, columns, and types in a connected Superblocks integration. Needs no application and never executes an integration action. Pass integrationId, which list_integrations returns. A large result comes back paged: narrow it with search, take more or fewer entries with limit, and continue from nextOffset with offset. Requires build permission on the integration. Do not use this to learn how to create an integration; that is get_integration_config_schema.",
|
|
9745
|
-
inputSchema: {
|
|
9746
|
-
applicationId: external_exports.string().uuid().optional().describe("Only for an integration owned by a single application, such as a Native DB. Leave unset otherwise; do not go looking for an application to supply."),
|
|
9747
|
-
integrationId: external_exports.string().uuid(),
|
|
9748
|
-
limit: external_exports.number().int().min(1).max(200).optional(),
|
|
9749
|
-
offset: external_exports.number().int().min(0).optional(),
|
|
9750
|
-
search: external_exports.string().min(1).optional()
|
|
9751
|
-
},
|
|
9752
|
-
title: "Get Integration Metadata"
|
|
9753
|
-
}, async (input, extra) => run("get_integration_metadata", (context3) => getIntegrationMetadata(context3, input), extra));
|
|
9754
9126
|
server.registerTool("start_app", {
|
|
9755
|
-
annotations: NON_DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS,
|
|
9756
9127
|
description: 'Create a Superblocks application and hand a prompt to Superblocks in Plan mode by default. Returns as soon as Superblocks accepts, with status "building" and an edit URL; follow with check_app_progress until status is no longer "building". When Superblocks returns needs_decision with a plan and the user says "Build it", call edit_app with planAction "approve" (omit prompt) \u2014 do not call start_app again with prompt "approve". Pass mode "BUILD" to skip planning. Superblocks names the application unless name is given. An error from this tool does not mean nothing happened: the application is created before the build starts, so the error names it in "applicationId". Retry that app with edit_app rather than calling start_app another time, which would leave the first one abandoned.',
|
|
9757
9128
|
inputSchema: {
|
|
9758
9129
|
branch: external_exports.string().optional(),
|
|
@@ -9765,7 +9136,7 @@ function createMcpServer(deps) {
|
|
|
9765
9136
|
// the tool name: a host that ranks tools by title has to be able to find
|
|
9766
9137
|
// this one from the request.
|
|
9767
9138
|
title: "Create Superblocks App"
|
|
9768
|
-
}, async ({ branch, idempotencyKey, mode, name, prompt }, extra) => run("start_app", (
|
|
9139
|
+
}, async ({ branch, idempotencyKey, mode, name, prompt }, extra) => run("start_app", (context2) => startApp(context2, {
|
|
9769
9140
|
branch,
|
|
9770
9141
|
idempotencyKey: idempotencyKey ?? `mcp-start:${randomUUID4()}`,
|
|
9771
9142
|
mode,
|
|
@@ -9777,10 +9148,8 @@ function createMcpServer(deps) {
|
|
|
9777
9148
|
wait: "ack"
|
|
9778
9149
|
}), extra));
|
|
9779
9150
|
server.registerTool("import_app", {
|
|
9780
|
-
|
|
9781
|
-
description: `Import an existing app from a ZIP/.tgz/.gz archive into Superblocks and start a Superblocks migration. Pass the archive's file name (or its full path on this machine) as zipPath: the gateway reads the file itself, so a path from your own sandbox is fine as long as the name matches the file the user has. Never encode the archive as base64 \u2014 zipBase64 only carries test fixtures. Archives larger than 1 MB are rejected \u2014 exclude node_modules. Optional prompt adds intent such as hardening security. Returns status "building"; follow with check_app_progress. Defaults to Plan mode \u2014 when Superblocks returns a plan and the user says "Build it", call edit_app with planAction "approve" (omit prompt); do not call import_app again with prompt "approve". An error from this tool does not mean nothing happened: the application is created before the migration starts, so the error names it in "applicationId". When it returns pendingAction "retry_import", call import_app again with the same archive and applicationId to resume that application instead of creating another one.`,
|
|
9151
|
+
description: `Import an existing app from a ZIP/.tgz/.gz archive into Superblocks and start a Superblocks migration. Pass the archive's file name (or its full path on this machine) as zipPath: the gateway reads the file itself, so a path from your own sandbox is fine as long as the name matches the file the user has. Never encode the archive as base64 \u2014 zipBase64 only carries test fixtures. Archives larger than 1 MB are rejected \u2014 exclude node_modules. Optional prompt adds intent such as hardening security. Returns status "building"; follow with check_app_progress. Defaults to Plan mode \u2014 when Superblocks returns a plan and the user says "Build it", call edit_app with planAction "approve" (omit prompt); do not call import_app again with prompt "approve". An error from this tool does not mean nothing happened: the application is created before the migration starts, so the error names it in "applicationId". That application is empty \u2014 the migration never ran \u2014 and nothing can continue it in place, so say it exists and let the user decide whether to import again rather than silently retrying.`,
|
|
9782
9152
|
inputSchema: {
|
|
9783
|
-
applicationId: external_exports.string().uuid().optional(),
|
|
9784
9153
|
branch: external_exports.string().optional(),
|
|
9785
9154
|
idempotencyKey: external_exports.string().optional(),
|
|
9786
9155
|
mode: external_exports.enum(["BUILD", "PLAN"]).optional(),
|
|
@@ -9800,8 +9169,7 @@ function createMcpServer(deps) {
|
|
|
9800
9169
|
zipPath: external_exports.string().min(1).optional()
|
|
9801
9170
|
},
|
|
9802
9171
|
title: "Import App"
|
|
9803
|
-
}, async ({
|
|
9804
|
-
applicationId,
|
|
9172
|
+
}, async ({ branch, idempotencyKey, mode, name, prompt, source, zipBase64, zipPath }, extra) => run("import_app", (context2) => importApp(context2, {
|
|
9805
9173
|
branch,
|
|
9806
9174
|
idempotencyKey: idempotencyKey ?? `mcp-import:${randomUUID4()}`,
|
|
9807
9175
|
mode,
|
|
@@ -9813,7 +9181,6 @@ function createMcpServer(deps) {
|
|
|
9813
9181
|
zipPath
|
|
9814
9182
|
}), extra));
|
|
9815
9183
|
server.registerTool("edit_app", {
|
|
9816
|
-
annotations: DESTRUCTIVE_TOOL_ANNOTATIONS,
|
|
9817
9184
|
description: 'Forward a prompt to Superblocks for the recent or specified application. Defaults to Plan mode until the app has run in Build mode; after that later edits keep building directly \u2014 you do not need to pass mode again. Pass mode "PLAN" only when the user explicitly asks to plan before building. The result reports the "mode" the turn ran in; a "PLAN" result after a long gap means the build session was recycled, so pass mode "BUILD" again rather than treating it as a new planning round. When status was needs_decision with a plan and the user says "Build it" / approve / go ahead, call edit_app with planAction "approve" and omit prompt \u2014 do not put "approve" or "Build it" in prompt (that is refine feedback, not the Build-it path). Use planAction "refine" with their feedback as prompt to change the plan. Also use edit_app to answer multi_choice questions. Returns status "building"; follow with check_app_progress.',
|
|
9818
9185
|
inputSchema: {
|
|
9819
9186
|
applicationId: external_exports.string().uuid().optional(),
|
|
@@ -9824,7 +9191,7 @@ function createMcpServer(deps) {
|
|
|
9824
9191
|
prompt: external_exports.string().min(1).optional()
|
|
9825
9192
|
},
|
|
9826
9193
|
title: "Edit App"
|
|
9827
|
-
}, async ({ applicationId, branch, idempotencyKey, mode, planAction, prompt }, extra) => run("edit_app", (
|
|
9194
|
+
}, async ({ applicationId, branch, idempotencyKey, mode, planAction, prompt }, extra) => run("edit_app", (context2) => editApp(context2, {
|
|
9828
9195
|
applicationId,
|
|
9829
9196
|
branch,
|
|
9830
9197
|
idempotencyKey: idempotencyKey ?? `mcp-edit:${randomUUID4()}`,
|
|
@@ -9834,26 +9201,24 @@ function createMcpServer(deps) {
|
|
|
9834
9201
|
wait: "ack"
|
|
9835
9202
|
}), extra));
|
|
9836
9203
|
server.registerTool("check_app_progress", {
|
|
9837
|
-
annotations: NON_DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS,
|
|
9838
9204
|
description: `Wait for the next thing Superblocks does on the recent or specified application and return it: "activity" carries Superblocks' words since the previous call (or a short heartbeat when Superblocks is quiet), and status is "building" while the app is still being generated. Returns as soon as Superblocks says anything, and after ~10 seconds of silence at the latest. Call within about 10 seconds of start_app, import_app, or edit_app so a plan or question surfaces quickly. Once the plan is approved and Superblocks is building, space later polls about 30 seconds apart (honor "nextPollAfterMs" when present) until status is no longer "building" \u2014 a 10-second cadence on a multi-minute build burns through the host's tool-call budget. Relay each new activity line to the user between calls. When status becomes "needs_decision", stop polling and put the decision to the user \u2014 for a plan, show it and ask whether to build it or say what to change; for multi_choice, relay the question and options. Hosts that support form elicitation get a native picker instead, and this tool then returns the answered turn. When status becomes "ready", follow with get_app so the user can open the preview. Progress is text-only (no MCP Apps widget) so each poll does not reopen a blank card. Optional "cursor" from a prior result resumes from that composite position (per producer, no global sequence); omit it to use the gateway's stored place for this caller.`,
|
|
9839
9205
|
inputSchema: {
|
|
9840
9206
|
applicationId: external_exports.string().uuid().optional(),
|
|
9841
9207
|
cursor: eventCursorInputSchema.optional()
|
|
9842
9208
|
},
|
|
9843
9209
|
title: "Check App Progress"
|
|
9844
|
-
}, async ({ applicationId, cursor }, extra) => run("check_app_progress", (
|
|
9210
|
+
}, async ({ applicationId, cursor }, extra) => run("check_app_progress", (context2, forgetFinishedTurn) => {
|
|
9845
9211
|
const parsed = cursor === void 0 ? void 0 : parseEventCursor(cursor);
|
|
9846
9212
|
gatewayDebug("progress cursor parsed", {
|
|
9847
9213
|
"progress.cursor_provided": cursor !== void 0,
|
|
9848
9214
|
"progress.cursor_valid": Boolean(parsed)
|
|
9849
9215
|
});
|
|
9850
|
-
return progressWithDecisionForm(
|
|
9216
|
+
return progressWithDecisionForm(context2, {
|
|
9851
9217
|
applicationId,
|
|
9852
9218
|
...parsed ? { cursor: parsed } : {}
|
|
9853
9219
|
}, extra, forgetFinishedTurn);
|
|
9854
9220
|
}, extra));
|
|
9855
9221
|
K3(server, "get_app", {
|
|
9856
|
-
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
9857
9222
|
description: 'Return editor and preview URLs for the recent or specified Superblocks application. Ensures a private preview build by default (same as preview_app), but only once Superblocks has something to show: while a plan or question is outstanding it returns status "needs_decision" with the "decision" and a "pendingAction" of "approve_plan" or "answer_question", while a turn is running it returns status "building", and when the last turn ended without writing anything it returns "timeout", "live_edit_terminated", "no_changes" or "cancelled" with pendingAction "retry_build" \u2014 no preview URLs and no screenshot in any of those cases, because the app is still the empty starter template. Act on "pendingAction" through edit_app instead of calling this again. Prefer this after check_app_progress reaches status "ready". Also the right call when you do not know where a build stands \u2014 after a reconnect, when no turn of yours is running, or when the conversation moved to another channel: pass wait false and read "status" and "cursor" from the result rather than guessing. Hosts that support MCP Apps show Open editor / Open preview buttons. When Superblocks has written code the result includes a screenshot of the live Vite canvas if a held session exists, otherwise the signed-in preview \u2014 never the edit URL.',
|
|
9858
9223
|
inputSchema: {
|
|
9859
9224
|
applicationId: external_exports.string().uuid().optional(),
|
|
@@ -9865,16 +9230,15 @@ function createMcpServer(deps) {
|
|
|
9865
9230
|
_meta: {
|
|
9866
9231
|
ui: { resourceUri: APP_STATUS_RESOURCE_URI }
|
|
9867
9232
|
}
|
|
9868
|
-
}, async ({ applicationId, branch, ensurePreview, wait }, extra) => run("get_app", (
|
|
9233
|
+
}, async ({ applicationId, branch, ensurePreview, wait }, extra) => run("get_app", (context2) => getApp(context2, { applicationId, branch, ensurePreview, wait }), extra));
|
|
9869
9234
|
server.registerTool("preview_app", {
|
|
9870
|
-
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
9871
9235
|
description: `Build the recent or specified Superblocks application's current work and return a URL that runs it, without deploying it \u2014 the same thing the editor's Preview button does. Only the user can open it. Status "ready" means the URL works now; "building" means the build is still running and calling again resumes watching it. Prefer get_app when you want the MCP Apps status card (Open editor / Open preview); this tool returns the same URLs as text/markdown without opening a second widget.`,
|
|
9872
9236
|
inputSchema: {
|
|
9873
9237
|
applicationId: external_exports.string().uuid().optional(),
|
|
9874
9238
|
branch: external_exports.string().optional()
|
|
9875
9239
|
},
|
|
9876
9240
|
title: "Preview App"
|
|
9877
|
-
}, async ({ applicationId, branch }, extra) => run("preview_app", (
|
|
9241
|
+
}, async ({ applicationId, branch }, extra) => run("preview_app", (context2) => previewApp(context2, { applicationId, branch }), extra));
|
|
9878
9242
|
const uiCsp = { csp: { frameDomains: [] } };
|
|
9879
9243
|
N3(server, "Gateway app status", APP_STATUS_RESOURCE_URI, {
|
|
9880
9244
|
description: "Status card with Open editor / Open preview / Publish app",
|
|
@@ -9891,7 +9255,6 @@ function createMcpServer(deps) {
|
|
|
9891
9255
|
]
|
|
9892
9256
|
}));
|
|
9893
9257
|
server.registerTool("publish_app", {
|
|
9894
|
-
annotations: DESTRUCTIVE_TOOL_ANNOTATIONS,
|
|
9895
9258
|
description: "Publish/deploy the recent or specified Superblocks application and wait until it is live. Commits the application's current work first, so commitId is only needed to publish an earlier commit.",
|
|
9896
9259
|
inputSchema: {
|
|
9897
9260
|
applicationId: external_exports.string().uuid().optional(),
|
|
@@ -9901,7 +9264,7 @@ function createMcpServer(deps) {
|
|
|
9901
9264
|
prompt: external_exports.string().min(1)
|
|
9902
9265
|
},
|
|
9903
9266
|
title: "Publish App"
|
|
9904
|
-
}, async ({ applicationId, branch, commitId, idempotencyKey, prompt }, extra) => run("publish_app", (
|
|
9267
|
+
}, async ({ applicationId, branch, commitId, idempotencyKey, prompt }, extra) => run("publish_app", (context2) => publishApp(context2, {
|
|
9905
9268
|
applicationId,
|
|
9906
9269
|
branch,
|
|
9907
9270
|
commitId,
|
|
@@ -9921,7 +9284,6 @@ function createMcpServer(deps) {
|
|
|
9921
9284
|
async function createRuntime(apiKey) {
|
|
9922
9285
|
const config = loadConfig();
|
|
9923
9286
|
const stores = await createStores();
|
|
9924
|
-
const telemetry = startGatewayTelemetry({ apiKey, config });
|
|
9925
9287
|
const serverClient = new HttpSuperblocksServerClient(config.serverUrl);
|
|
9926
9288
|
const sessionPeer = new WebSocketSessionPeer({
|
|
9927
9289
|
beatLostGraceMs: config.beatLostGraceMs,
|
|
@@ -9939,7 +9301,6 @@ async function createRuntime(apiKey) {
|
|
|
9939
9301
|
cliApiKey: apiKey,
|
|
9940
9302
|
config,
|
|
9941
9303
|
events: stores.events,
|
|
9942
|
-
mcpTelemetry: telemetry.mcpTelemetry,
|
|
9943
9304
|
progressCursors: stores.progressCursors,
|
|
9944
9305
|
recentApps: stores.recentApps,
|
|
9945
9306
|
server: serverClient,
|
|
@@ -9951,7 +9312,7 @@ async function createRuntime(apiKey) {
|
|
|
9951
9312
|
deps,
|
|
9952
9313
|
close: async () => {
|
|
9953
9314
|
sessionPeer.closeAll();
|
|
9954
|
-
await
|
|
9315
|
+
await stores.close();
|
|
9955
9316
|
}
|
|
9956
9317
|
};
|
|
9957
9318
|
}
|
|
@@ -9997,4 +9358,4 @@ export {
|
|
|
9997
9358
|
startApp,
|
|
9998
9359
|
startStdioGateway
|
|
9999
9360
|
};
|
|
10000
|
-
//# sourceMappingURL=dist-
|
|
9361
|
+
//# sourceMappingURL=dist-LZ7TUGM6.js.map
|