@superblocksteam/gateway 2.0.161-next.0 → 2.0.162-next.0
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 +135 -39
- package/dist/capabilities/lifecycle.d.ts +46 -29
- package/dist/capabilities/lifecycle.js +1731 -843
- package/dist/capabilities/lifecycle.js.map +1 -1
- package/dist/capabilities/query-integration.d.ts +14 -0
- package/dist/capabilities/query-integration.js +172 -0
- package/dist/capabilities/query-integration.js.map +1 -0
- package/dist/capabilities/source-files-archive.d.ts +11 -0
- package/dist/capabilities/source-files-archive.js +54 -0
- package/dist/capabilities/source-files-archive.js.map +1 -0
- package/dist/capabilities/types.d.ts +197 -119
- package/dist/capabilities/types.js +45 -6
- package/dist/capabilities/types.js.map +1 -1
- package/dist/capture/browser-contract.d.ts +15 -5
- package/dist/capture/browser-contract.js +13 -3
- package/dist/capture/browser-contract.js.map +1 -1
- package/dist/capture/browser-instructions.d.ts +3 -2
- package/dist/capture/browser-instructions.js +3 -2
- package/dist/capture/browser-instructions.js.map +1 -1
- package/dist/capture/mode.d.ts +8 -1
- package/dist/capture/mode.js +22 -2
- package/dist/capture/mode.js.map +1 -1
- package/dist/config.d.ts +22 -23
- package/dist/config.js +13 -12
- package/dist/config.js.map +1 -1
- package/dist/deps.d.ts +7 -7
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/integrations/read-only-postgres-query.d.ts +2 -0
- package/dist/integrations/read-only-postgres-query.js +164 -0
- package/dist/integrations/read-only-postgres-query.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/playwright/ensure-chromium.d.ts +5 -7
- package/dist/playwright/ensure-chromium.js +13 -13
- package/dist/playwright/ensure-chromium.js.map +1 -1
- package/dist/preview/capture-screenshot.d.ts +30 -4
- package/dist/preview/capture-screenshot.js +67 -17
- package/dist/preview/capture-screenshot.js.map +1 -1
- package/dist/preview/viewer-url.js +3 -1
- package/dist/preview/viewer-url.js.map +1 -1
- package/dist/process/fault-barrier.js +1 -1
- package/dist/process/fault-barrier.js.map +1 -1
- package/dist/sabs/agent-facing-text.d.ts +2 -0
- package/dist/sabs/agent-facing-text.js +56 -2
- package/dist/sabs/agent-facing-text.js.map +1 -1
- package/dist/sabs/app-state.d.ts +126 -0
- package/dist/sabs/app-state.js +332 -0
- package/dist/sabs/app-state.js.map +1 -0
- package/dist/sabs/awaited-decision.d.ts +49 -0
- package/dist/sabs/awaited-decision.js +129 -0
- package/dist/sabs/awaited-decision.js.map +1 -0
- package/dist/sabs/editor-client-methods.d.ts +23 -5
- package/dist/sabs/editor-client-methods.js +45 -4
- package/dist/sabs/editor-client-methods.js.map +1 -1
- package/dist/sabs/editor-socket.d.ts +85 -0
- package/dist/sabs/editor-socket.js +67 -0
- package/dist/sabs/editor-socket.js.map +1 -0
- package/dist/sabs/session-peer.d.ts +119 -82
- package/dist/sabs/session-peer.js +10 -1
- package/dist/sabs/session-peer.js.map +1 -1
- package/dist/sabs/streamed-reply.d.ts +45 -0
- package/dist/sabs/streamed-reply.js +125 -0
- package/dist/sabs/streamed-reply.js.map +1 -0
- package/dist/sabs/turn-collector.d.ts +50 -35
- package/dist/sabs/turn-collector.js +110 -176
- package/dist/sabs/turn-collector.js.map +1 -1
- package/dist/sabs/websocket-session-peer.d.ts +104 -69
- package/dist/sabs/websocket-session-peer.js +1329 -475
- package/dist/sabs/websocket-session-peer.js.map +1 -1
- package/dist/server/client.d.ts +41 -9
- package/dist/server/client.js +126 -21
- package/dist/server/client.js.map +1 -1
- package/dist/start.d.ts +1 -1
- package/dist/start.js +30 -8
- package/dist/start.js.map +1 -1
- package/dist/stores/memory.d.ts +46 -0
- package/dist/stores/memory.js +163 -0
- package/dist/stores/memory.js.map +1 -0
- package/dist/stores/types.d.ts +92 -0
- package/dist/stores/types.js +11 -0
- package/dist/stores/types.js.map +1 -0
- package/dist/telemetry/mcp-client.d.ts +6 -1
- package/dist/telemetry/mcp-client.js +100 -4
- package/dist/telemetry/mcp-client.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +12 -3
- package/dist/telemetry/metrics.js +60 -14
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry/runtime.js +4 -6
- package/dist/telemetry/runtime.js.map +1 -1
- package/dist/transports/mcp/admin-tools.d.ts +8 -0
- package/dist/transports/mcp/admin-tools.js +115 -4
- package/dist/transports/mcp/admin-tools.js.map +1 -1
- package/dist/transports/mcp/app-status-html.d.ts +4 -8
- package/dist/transports/mcp/app-status-html.js +336 -128
- package/dist/transports/mcp/app-status-html.js.map +1 -1
- package/dist/transports/mcp/client-presentation.d.ts +16 -0
- package/dist/transports/mcp/client-presentation.js +13 -0
- package/dist/transports/mcp/client-presentation.js.map +1 -0
- package/dist/transports/mcp/cowork-editor-url.d.ts +6 -0
- package/dist/transports/mcp/cowork-editor-url.js +10 -0
- package/dist/transports/mcp/cowork-editor-url.js.map +1 -0
- package/dist/transports/mcp/decision-card-html.d.ts +26 -0
- package/dist/transports/mcp/decision-card-html.js +876 -0
- package/dist/transports/mcp/decision-card-html.js.map +1 -0
- package/dist/transports/mcp/decision-elicitation.d.ts +42 -0
- package/dist/transports/mcp/decision-elicitation.js +59 -0
- package/dist/transports/mcp/decision-elicitation.js.map +1 -1
- package/dist/transports/mcp/editor-document-probe.d.ts +4 -0
- package/dist/transports/mcp/editor-document-probe.js +35 -0
- package/dist/transports/mcp/editor-document-probe.js.map +1 -0
- package/dist/transports/mcp/editor-integration-setup-url.d.ts +14 -0
- package/dist/transports/mcp/editor-integration-setup-url.js +29 -0
- package/dist/transports/mcp/editor-integration-setup-url.js.map +1 -0
- package/dist/transports/mcp/format-tool-content.d.ts +13 -18
- package/dist/transports/mcp/format-tool-content.js +172 -13
- package/dist/transports/mcp/format-tool-content.js.map +1 -1
- package/dist/transports/mcp/instructions/index.d.ts +23 -0
- package/dist/transports/mcp/instructions/index.js +81 -0
- package/dist/transports/mcp/instructions/index.js.map +1 -0
- package/dist/transports/mcp/instructions/result.d.ts +18 -0
- package/dist/transports/mcp/instructions/result.js +58 -0
- package/dist/transports/mcp/instructions/result.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/ask-user.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/ask-user.js +20 -0
- package/dist/transports/mcp/instructions/tools/ask-user.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/build-app.d.ts +4 -0
- package/dist/transports/mcp/instructions/tools/build-app.js +54 -0
- package/dist/transports/mcp/instructions/tools/build-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/check-app-progress.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/check-app-progress.js +79 -0
- package/dist/transports/mcp/instructions/tools/check-app-progress.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/check-publish-progress.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/check-publish-progress.js +23 -0
- package/dist/transports/mcp/instructions/tools/check-publish-progress.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/copy.d.ts +18 -0
- package/dist/transports/mcp/instructions/tools/copy.js +49 -0
- package/dist/transports/mcp/instructions/tools/copy.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/create-integration.d.ts +4 -0
- package/dist/transports/mcp/instructions/tools/create-integration.js +41 -0
- package/dist/transports/mcp/instructions/tools/create-integration.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/edit-app.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/edit-app.js +18 -0
- package/dist/transports/mcp/instructions/tools/edit-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/get-app.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/get-app.js +49 -0
- package/dist/transports/mcp/instructions/tools/get-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/get-integration-metadata.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/get-integration-metadata.js +13 -0
- package/dist/transports/mcp/instructions/tools/get-integration-metadata.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/index.d.ts +7 -0
- package/dist/transports/mcp/instructions/tools/index.js +31 -0
- package/dist/transports/mcp/instructions/tools/index.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/publish-app.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/publish-app.js +23 -0
- package/dist/transports/mcp/instructions/tools/publish-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/start-app.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/start-app.js +22 -0
- package/dist/transports/mcp/instructions/tools/start-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/upload-artifact.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/upload-artifact.js +13 -0
- package/dist/transports/mcp/instructions/tools/upload-artifact.js.map +1 -0
- package/dist/transports/mcp/mcp-app-brand-css.d.ts +1 -0
- package/dist/transports/mcp/mcp-app-brand-css.js +180 -0
- package/dist/transports/mcp/mcp-app-brand-css.js.map +1 -0
- package/dist/transports/mcp/mount.d.ts +14 -1
- package/dist/transports/mcp/mount.js +729 -172
- package/dist/transports/mcp/mount.js.map +1 -1
- package/dist/transports/mcp/native-browser-presence.d.ts +45 -0
- package/dist/transports/mcp/native-browser-presence.js +158 -0
- package/dist/transports/mcp/native-browser-presence.js.map +1 -0
- package/dist/transports/mcp/plan-approval.d.ts +44 -0
- package/dist/transports/mcp/plan-approval.js +179 -0
- package/dist/transports/mcp/plan-approval.js.map +1 -0
- package/dist/transports/mcp/session-directory.d.ts +7 -0
- package/dist/transports/mcp/session-directory.js +18 -0
- package/dist/transports/mcp/session-directory.js.map +1 -0
- package/dist/transports/mcp/tool-names.d.ts +2 -0
- package/dist/transports/mcp/tool-names.js +2 -0
- package/dist/transports/mcp/tool-names.js.map +1 -0
- package/package.json +16 -7
- package/skills/superblocks-build/SKILL.md +59 -0
- package/skills/superblocks-import/SKILL.md +125 -0
- package/dist/capabilities/import-prompt.d.ts +0 -11
- package/dist/capabilities/import-prompt.js +0 -96
- package/dist/capabilities/import-prompt.js.map +0 -1
- package/dist/capabilities/persisted-progress.d.ts +0 -46
- package/dist/capabilities/persisted-progress.js +0 -246
- package/dist/capabilities/persisted-progress.js.map +0 -1
- package/dist/events/cursor.d.ts +0 -43
- package/dist/events/cursor.js +0 -78
- package/dist/events/cursor.js.map +0 -1
- package/dist/events/memory-event-store.d.ts +0 -34
- package/dist/events/memory-event-store.js +0 -110
- package/dist/events/memory-event-store.js.map +0 -1
- package/dist/events/merge.d.ts +0 -23
- package/dist/events/merge.js +0 -97
- package/dist/events/merge.js.map +0 -1
- package/dist/events/normalized-collector.d.ts +0 -62
- package/dist/events/normalized-collector.js +0 -156
- package/dist/events/normalized-collector.js.map +0 -1
- package/dist/events/schema.d.ts +0 -9
- package/dist/events/schema.js +0 -93
- package/dist/events/schema.js.map +0 -1
- package/dist/events/snapshot.d.ts +0 -32
- package/dist/events/snapshot.js +0 -57
- package/dist/events/snapshot.js.map +0 -1
- package/dist/events/stream-key.d.ts +0 -2
- package/dist/events/stream-key.js +0 -31
- package/dist/events/stream-key.js.map +0 -1
- package/dist/events/types.d.ts +0 -179
- package/dist/events/types.js +0 -66
- package/dist/events/types.js.map +0 -1
- package/dist/resume/memory-progress-store.d.ts +0 -39
- package/dist/resume/memory-progress-store.js +0 -82
- package/dist/resume/memory-progress-store.js.map +0 -1
- package/dist/resume/memory-recent-app-store.d.ts +0 -14
- package/dist/resume/memory-recent-app-store.js +0 -27
- package/dist/resume/memory-recent-app-store.js.map +0 -1
- package/dist/resume/memory-turn-store.d.ts +0 -18
- package/dist/resume/memory-turn-store.js +0 -73
- package/dist/resume/memory-turn-store.js.map +0 -1
- package/dist/resume/progress-key.d.ts +0 -21
- package/dist/resume/progress-key.js +0 -58
- package/dist/resume/progress-key.js.map +0 -1
- package/dist/resume/stores.d.ts +0 -14
- package/dist/resume/stores.js +0 -18
- package/dist/resume/stores.js.map +0 -1
- package/dist/resume/types.d.ts +0 -124
- package/dist/resume/types.js +0 -13
- package/dist/resume/types.js.map +0 -1
package/dist/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
console.error("This process speaks MCP over stdio as the Superblocks CLI user. Run: superblocks
|
|
2
|
+
console.error("This process speaks MCP over stdio as the Superblocks CLI user. Run: superblocks mcp serve");
|
|
3
3
|
process.exit(1);
|
|
4
4
|
export {};
|
|
5
5
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,CAAC,KAAK,CACX,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,CAAC,KAAK,CACX,4FAA4F,CAC7F,CAAC;AACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
export type EnsurePlaywrightChromiumOptions = {
|
|
2
2
|
/** Override for tests. Defaults to Playwright's Chromium executable path. */
|
|
3
3
|
chromiumExecutablePath?: string;
|
|
4
|
-
/** CLI invoked when Chromium is missing. Defaults to `pnpm`. */
|
|
5
|
-
playwrightCli?: string;
|
|
6
|
-
playwrightArgs?: string[];
|
|
7
4
|
};
|
|
8
5
|
export type EnsurePlaywrightChromiumResult = {
|
|
9
6
|
/** True when this call ran an install. */
|
|
@@ -11,16 +8,17 @@ export type EnsurePlaywrightChromiumResult = {
|
|
|
11
8
|
};
|
|
12
9
|
/**
|
|
13
10
|
* Probe only: true when Playwright Chromium is already on disk. Does not
|
|
14
|
-
* download anything. Used by `
|
|
11
|
+
* download anything. Used by `mcp setup` capture.mode and by capabilities
|
|
15
12
|
* that must fail closed instead of waiting on `chromium.launch()`.
|
|
16
13
|
*/
|
|
17
14
|
export declare function playwrightChromiumPresent(options?: Pick<EnsurePlaywrightChromiumOptions, "chromiumExecutablePath">): Promise<boolean>;
|
|
18
15
|
/**
|
|
19
|
-
* Ensures Playwright Chromium is on disk. Intended for
|
|
20
|
-
* every `
|
|
16
|
+
* Ensures Playwright Chromium is on disk. Intended for
|
|
17
|
+
* `mcp setup --with-screenshots`, not every `mcp serve` - corp laptops need a
|
|
18
|
+
* one-time download with network.
|
|
21
19
|
*/
|
|
22
20
|
export declare function ensurePlaywrightChromium(options?: EnsurePlaywrightChromiumOptions): Promise<EnsurePlaywrightChromiumResult>;
|
|
23
21
|
/**
|
|
24
|
-
* Clear error for `
|
|
22
|
+
* Clear error for `mcp serve` when setup was skipped.
|
|
25
23
|
*/
|
|
26
24
|
export declare function assertPlaywrightChromiumInstalled(options?: Pick<EnsurePlaywrightChromiumOptions, "chromiumExecutablePath">): Promise<void>;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { execFile as execFileCallback } from "node:child_process";
|
|
2
2
|
import { access } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
3
5
|
import { promisify } from "node:util";
|
|
4
6
|
import { chromium } from "playwright";
|
|
5
7
|
const execFile = promisify(execFileCallback);
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
6
9
|
async function pathExists(path) {
|
|
7
10
|
try {
|
|
8
11
|
await access(path);
|
|
@@ -14,7 +17,7 @@ async function pathExists(path) {
|
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Probe only: true when Playwright Chromium is already on disk. Does not
|
|
17
|
-
* download anything. Used by `
|
|
20
|
+
* download anything. Used by `mcp setup` capture.mode and by capabilities
|
|
18
21
|
* that must fail closed instead of waiting on `chromium.launch()`.
|
|
19
22
|
*/
|
|
20
23
|
export async function playwrightChromiumPresent(options = {}) {
|
|
@@ -22,39 +25,36 @@ export async function playwrightChromiumPresent(options = {}) {
|
|
|
22
25
|
return pathExists(executablePath);
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
25
|
-
* Ensures Playwright Chromium is on disk. Intended for
|
|
26
|
-
* every `
|
|
28
|
+
* Ensures Playwright Chromium is on disk. Intended for
|
|
29
|
+
* `mcp setup --with-screenshots`, not every `mcp serve` - corp laptops need a
|
|
30
|
+
* one-time download with network.
|
|
27
31
|
*/
|
|
28
32
|
export async function ensurePlaywrightChromium(options = {}) {
|
|
29
33
|
const executablePath = options.chromiumExecutablePath ?? chromium.executablePath();
|
|
30
34
|
if (await pathExists(executablePath)) {
|
|
31
35
|
return { installed: false };
|
|
32
36
|
}
|
|
33
|
-
const
|
|
34
|
-
const args = options.playwrightArgs ??
|
|
35
|
-
(options.playwrightCli
|
|
36
|
-
? ["install", "chromium"]
|
|
37
|
-
: ["exec", "playwright", "install", "chromium"]);
|
|
37
|
+
const playwrightCli = join(dirname(require.resolve("playwright")), "cli.js");
|
|
38
38
|
try {
|
|
39
|
-
await execFile(
|
|
39
|
+
await execFile(process.execPath, [playwrightCli, "install", "chromium"]);
|
|
40
40
|
}
|
|
41
41
|
catch (error) {
|
|
42
42
|
const detail = error instanceof Error ? error.message : String(error);
|
|
43
|
-
throw new Error(`Failed to install Playwright Chromium (needed for preview screenshots).
|
|
43
|
+
throw new Error(`Failed to install Playwright Chromium (needed for preview screenshots). The bundled playwright install chromium command failed. Re-run: superblocks mcp setup --with-screenshots. (${detail})`);
|
|
44
44
|
}
|
|
45
45
|
if (!(await pathExists(executablePath))) {
|
|
46
|
-
throw new Error(`Playwright Chromium is still missing after install at ${executablePath}. Run:
|
|
46
|
+
throw new Error(`Playwright Chromium is still missing after install at ${executablePath}. Run: superblocks mcp setup --with-screenshots`);
|
|
47
47
|
}
|
|
48
48
|
return { installed: true };
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* Clear error for `
|
|
51
|
+
* Clear error for `mcp serve` when setup was skipped.
|
|
52
52
|
*/
|
|
53
53
|
export async function assertPlaywrightChromiumInstalled(options = {}) {
|
|
54
54
|
const executablePath = options.chromiumExecutablePath ?? chromium.executablePath();
|
|
55
55
|
if (await pathExists(executablePath)) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
throw new Error(`Playwright Chromium is not installed (looked for ${executablePath}). Run: superblocks
|
|
58
|
+
throw new Error(`Playwright Chromium is not installed (looked for ${executablePath}). Run: superblocks mcp setup --with-screenshots`);
|
|
59
59
|
}
|
|
60
60
|
//# sourceMappingURL=ensure-chromium.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensure-chromium.js","sourceRoot":"","sources":["../../src/playwright/ensure-chromium.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ensure-chromium.js","sourceRoot":"","sources":["../../src/playwright/ensure-chromium.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;AAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAY/C,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,UAA2E,EAAE;IAE7E,MAAM,cAAc,GAClB,OAAO,CAAC,sBAAsB,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC9D,OAAO,UAAU,CAAC,cAAc,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,UAA2C,EAAE;IAE7C,MAAM,cAAc,GAClB,OAAO,CAAC,sBAAsB,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC9D,IAAI,MAAM,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAE7E,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,MAAM,IAAI,KAAK,CACb,sLAAsL,MAAM,GAAG,CAChM,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,yDAAyD,cAAc,iDAAiD,CACzH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,UAA2E,EAAE;IAE7E,MAAM,cAAc,GAClB,OAAO,CAAC,sBAAsB,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC9D,IAAI,MAAM,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACrC,OAAO;IACT,CAAC;IACD,MAAM,IAAI,KAAK,CACb,oDAAoD,cAAc,kDAAkD,CACrH,CAAC;AACJ,CAAC"}
|
|
@@ -10,15 +10,32 @@ export type PreviewScreenshot = {
|
|
|
10
10
|
};
|
|
11
11
|
/** Soft cap on decoded bytes before base64 (~256 KiB). */
|
|
12
12
|
export declare const PREVIEW_SCREENSHOT_MAX_BYTES: number;
|
|
13
|
+
export declare const CHECKPOINT_SCREENSHOT_MAX_BYTES: number;
|
|
13
14
|
export type CapturePreviewScreenshot = (input: {
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* App-scoped bearer handed to the embed shell. Without it the shell falls
|
|
17
|
+
* back to Auth0 silent login, which has no session to find headless.
|
|
17
18
|
*/
|
|
18
19
|
embedToken?: string;
|
|
19
|
-
|
|
20
|
+
maxBytes?: number;
|
|
20
21
|
timeoutMs?: number;
|
|
22
|
+
/**
|
|
23
|
+
* The origin {@link embedToken} belongs to - the control plane the session
|
|
24
|
+
* signed in to, which already receives this token on every API call. It is
|
|
25
|
+
* the only non-loopback origin allowed to be handed the token; unset means
|
|
26
|
+
* loopback only.
|
|
27
|
+
*/
|
|
28
|
+
trustedOrigin?: string;
|
|
29
|
+
url: string;
|
|
21
30
|
}) => Promise<PreviewScreenshot | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Whether a session bearer may be delivered to the page at `url`.
|
|
33
|
+
*
|
|
34
|
+
* Loopback is the user's own machine. The only remote origin allowed is the
|
|
35
|
+
* one the token was issued by, over https, so the token never reaches a host
|
|
36
|
+
* that does not already hold it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function isTrustedEmbedOrigin(url: string, trustedOrigin?: string): boolean;
|
|
22
39
|
/**
|
|
23
40
|
* Page source that hands the deployed shell its bearer, and the whole reason a
|
|
24
41
|
* headless capture can paint a real app.
|
|
@@ -43,10 +60,19 @@ export type CapturePreviewScreenshot = (input: {
|
|
|
43
60
|
* `JSON.stringify` is sufficient to contain the token. Putting it in a
|
|
44
61
|
* `<script>` element would not be — the token would need `</script>` escaped.
|
|
45
62
|
*/
|
|
46
|
-
export declare function buildEmbedHandshakeScript(token: string): string;
|
|
63
|
+
export declare function buildEmbedHandshakeScript(token: string, expectedOrigin: string): string;
|
|
47
64
|
/**
|
|
48
65
|
* Captures a JPEG screenshot via Playwright when available. Soft-fails when
|
|
49
66
|
* Chromium is missing or the page never becomes ready — callers must still
|
|
50
67
|
* return preview URLs when this returns undefined.
|
|
51
68
|
*/
|
|
52
69
|
export declare const capturePreviewScreenshotWithPlaywright: CapturePreviewScreenshot;
|
|
70
|
+
export declare function captureCheckpointScreenshotWithPlaywright(args: {
|
|
71
|
+
applicationId: string;
|
|
72
|
+
commitId: string;
|
|
73
|
+
deployedShellBaseUrl?: string;
|
|
74
|
+
previewToken?: string;
|
|
75
|
+
sessionToken: string;
|
|
76
|
+
trustedOrigin?: string;
|
|
77
|
+
uiBaseUrl: string;
|
|
78
|
+
}): Promise<string | undefined>;
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* Best-effort: callers must succeed with URLs alone when this returns
|
|
5
5
|
* undefined. Output is capped for Claude Desktop tool-result size limits.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { scrubSecrets } from "../sabs/agent-facing-text.js";
|
|
8
|
+
import { buildDeployedShellViewerUrl, buildEmbedShellPreviewUrl, isLoopbackUrl, } from "./viewer-url.js";
|
|
8
9
|
/** Soft cap on decoded bytes before base64 (~256 KiB). */
|
|
9
10
|
export const PREVIEW_SCREENSHOT_MAX_BYTES = 256 * 1024;
|
|
11
|
+
export const CHECKPOINT_SCREENSHOT_MAX_BYTES = 1024 * 1024;
|
|
10
12
|
/** How long to keep waiting for the shell to subscribe before handshaking anyway. */
|
|
11
13
|
const HANDSHAKE_FALLBACK_MS = 2_000;
|
|
12
14
|
/**
|
|
@@ -15,6 +17,27 @@ const HANDSHAKE_FALLBACK_MS = 2_000;
|
|
|
15
17
|
* no "finished rendering" signal an embedder could await.
|
|
16
18
|
*/
|
|
17
19
|
const APP_PAINT_SETTLE_MS = 2_500;
|
|
20
|
+
/**
|
|
21
|
+
* Whether a session bearer may be delivered to the page at `url`.
|
|
22
|
+
*
|
|
23
|
+
* Loopback is the user's own machine. The only remote origin allowed is the
|
|
24
|
+
* one the token was issued by, over https, so the token never reaches a host
|
|
25
|
+
* that does not already hold it.
|
|
26
|
+
*/
|
|
27
|
+
export function isTrustedEmbedOrigin(url, trustedOrigin) {
|
|
28
|
+
if (isLoopbackUrl(url))
|
|
29
|
+
return true;
|
|
30
|
+
if (!trustedOrigin)
|
|
31
|
+
return false;
|
|
32
|
+
try {
|
|
33
|
+
const target = new URL(url);
|
|
34
|
+
return (target.protocol === "https:" &&
|
|
35
|
+
target.origin === new URL(trustedOrigin).origin);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
18
41
|
/**
|
|
19
42
|
* Page source that hands the deployed shell its bearer, and the whole reason a
|
|
20
43
|
* headless capture can paint a real app.
|
|
@@ -39,8 +62,11 @@ const APP_PAINT_SETTLE_MS = 2_500;
|
|
|
39
62
|
* `JSON.stringify` is sufficient to contain the token. Putting it in a
|
|
40
63
|
* `<script>` element would not be — the token would need `</script>` escaped.
|
|
41
64
|
*/
|
|
42
|
-
export function buildEmbedHandshakeScript(token) {
|
|
65
|
+
export function buildEmbedHandshakeScript(token, expectedOrigin) {
|
|
43
66
|
return `(function () {
|
|
67
|
+
// Playwright re-runs init scripts after navigation. Never hand the bearer to
|
|
68
|
+
// a document outside the shell origin selected before Chromium launched.
|
|
69
|
+
if (window.location.origin !== ${JSON.stringify(expectedOrigin)}) return;
|
|
44
70
|
// The app iframe gets its own credentials from the shell; a handshake there
|
|
45
71
|
// would be rejected as not-from-parent anyway.
|
|
46
72
|
if (window.parent !== window) return;
|
|
@@ -74,6 +100,11 @@ export function buildEmbedHandshakeScript(token) {
|
|
|
74
100
|
* return preview URLs when this returns undefined.
|
|
75
101
|
*/
|
|
76
102
|
export const capturePreviewScreenshotWithPlaywright = async (input) => {
|
|
103
|
+
if (input.embedToken &&
|
|
104
|
+
!isTrustedEmbedOrigin(input.url, input.trustedOrigin)) {
|
|
105
|
+
console.warn("gateway preview screenshot: refusing token delivery to untrusted origin", { url: input.url });
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
77
108
|
let chromium;
|
|
78
109
|
try {
|
|
79
110
|
// Optional runtime dep — demos without browsers still return preview URLs.
|
|
@@ -94,17 +125,9 @@ export const capturePreviewScreenshotWithPlaywright = async (input) => {
|
|
|
94
125
|
browser = await chromium.launch({ headless: true });
|
|
95
126
|
const page = await browser.newPage();
|
|
96
127
|
if (input.embedToken) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (isLoopbackUrl(input.url)) {
|
|
101
|
-
await page.addInitScript({
|
|
102
|
-
content: buildEmbedHandshakeScript(input.embedToken),
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
console.warn("gateway preview screenshot: shell is not local, capturing unauthenticated", { url: input.url });
|
|
107
|
-
}
|
|
128
|
+
await page.addInitScript({
|
|
129
|
+
content: buildEmbedHandshakeScript(input.embedToken, new URL(input.url).origin),
|
|
130
|
+
});
|
|
108
131
|
}
|
|
109
132
|
await page.setViewportSize({ width: 1280, height: 800 });
|
|
110
133
|
// Not "networkidle": the shell holds a dev-server HMR socket open and
|
|
@@ -127,13 +150,14 @@ export const capturePreviewScreenshotWithPlaywright = async (input) => {
|
|
|
127
150
|
// page it captures is what tells the caller what went wrong.
|
|
128
151
|
.catch(() => undefined);
|
|
129
152
|
await page.waitForTimeout(APP_PAINT_SETTLE_MS);
|
|
153
|
+
const maxBytes = input.maxBytes ?? PREVIEW_SCREENSHOT_MAX_BYTES;
|
|
130
154
|
let quality = 80;
|
|
131
155
|
let buffer = await page.screenshot({ type: "jpeg", quality });
|
|
132
|
-
while (buffer.byteLength >
|
|
156
|
+
while (buffer.byteLength > maxBytes && quality > 30) {
|
|
133
157
|
quality -= 10;
|
|
134
158
|
buffer = await page.screenshot({ type: "jpeg", quality });
|
|
135
159
|
}
|
|
136
|
-
if (buffer.byteLength >
|
|
160
|
+
if (buffer.byteLength > maxBytes) {
|
|
137
161
|
console.warn("gateway preview screenshot exceeds size cap; skipping", {
|
|
138
162
|
bytes: buffer.byteLength,
|
|
139
163
|
});
|
|
@@ -146,8 +170,8 @@ export const capturePreviewScreenshotWithPlaywright = async (input) => {
|
|
|
146
170
|
}
|
|
147
171
|
catch (error) {
|
|
148
172
|
console.warn("gateway preview screenshot failed", {
|
|
149
|
-
message: error instanceof Error ? error.message : String(error),
|
|
150
|
-
url: input.url,
|
|
173
|
+
message: scrubSecrets(error instanceof Error ? error.message : String(error)),
|
|
174
|
+
url: scrubSecrets(input.url),
|
|
151
175
|
});
|
|
152
176
|
return undefined;
|
|
153
177
|
}
|
|
@@ -155,4 +179,30 @@ export const capturePreviewScreenshotWithPlaywright = async (input) => {
|
|
|
155
179
|
await browser?.close().catch(() => undefined);
|
|
156
180
|
}
|
|
157
181
|
};
|
|
182
|
+
export async function captureCheckpointScreenshotWithPlaywright(args) {
|
|
183
|
+
const { applicationId, commitId, deployedShellBaseUrl, previewToken, sessionToken, trustedOrigin, uiBaseUrl, } = args;
|
|
184
|
+
if (deployedShellBaseUrl && !previewToken)
|
|
185
|
+
return undefined;
|
|
186
|
+
const url = deployedShellBaseUrl && previewToken
|
|
187
|
+
? buildDeployedShellViewerUrl({
|
|
188
|
+
applicationId,
|
|
189
|
+
commitId,
|
|
190
|
+
deployedShellBaseUrl,
|
|
191
|
+
jwt: previewToken,
|
|
192
|
+
})
|
|
193
|
+
: buildEmbedShellPreviewUrl({
|
|
194
|
+
applicationId,
|
|
195
|
+
deployedShellBaseUrl,
|
|
196
|
+
uiBaseUrl,
|
|
197
|
+
});
|
|
198
|
+
const screenshot = await capturePreviewScreenshotWithPlaywright({
|
|
199
|
+
embedToken: deployedShellBaseUrl ? undefined : sessionToken,
|
|
200
|
+
maxBytes: CHECKPOINT_SCREENSHOT_MAX_BYTES,
|
|
201
|
+
trustedOrigin,
|
|
202
|
+
url,
|
|
203
|
+
});
|
|
204
|
+
return screenshot
|
|
205
|
+
? `data:${screenshot.mimeType};base64,${screenshot.dataBase64}`
|
|
206
|
+
: undefined;
|
|
207
|
+
}
|
|
158
208
|
//# sourceMappingURL=capture-screenshot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture-screenshot.js","sourceRoot":"","sources":["../../src/preview/capture-screenshot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"capture-screenshot.js","sourceRoot":"","sources":["../../src/preview/capture-screenshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,9 @@ export function isHttpsUrl(url) {
|
|
|
22
22
|
const LOOPBACK_HOSTNAMES = new Set(["127.0.0.1", "[::1]", "localhost"]);
|
|
23
23
|
export function isLoopbackUrl(url) {
|
|
24
24
|
try {
|
|
25
|
-
|
|
25
|
+
const parsed = new URL(url);
|
|
26
|
+
return ((parsed.protocol === "http:" || parsed.protocol === "https:") &&
|
|
27
|
+
LOOPBACK_HOSTNAMES.has(parsed.hostname));
|
|
26
28
|
}
|
|
27
29
|
catch {
|
|
28
30
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewer-url.js","sourceRoot":"","sources":["../../src/preview/viewer-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;AAExE,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,
|
|
1
|
+
{"version":3,"file":"viewer-url.js","sourceRoot":"","sources":["../../src/preview/viewer-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;AAExE,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,CACL,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;YAC7D,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CACxC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAIzC;IACC,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,GAAG,IAAI,yCAAyC,kBAAkB,CAC5E,KAAK,CAAC,aAAa,CACpB,EAAE,CAAC;IACJ,MAAM,OAAO,GAAG,KAAK,CAAC,oBAAoB,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,CAAC;IACb,CAAC;IACD,0EAA0E;IAC1E,wEAAwE;IACxE,OAAO,GAAG,GAAG,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,aAAiC;IAEjC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;QAC1C,wEAAwE;QACxE,oDAAoD;QACpD,OAAO,IAAI,GAAG,CACZ,GAAG,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,EACxD,UAAU,CACX,CAAC,QAAQ,EAAE,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAK3C;IACC,MAAM,IAAI,GAAG,KAAK,CAAC,oBAAoB;SACpC,IAAI,EAAE;SACN,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;SAClB,UAAU,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IACpE,gEAAgE;IAChE,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QACzC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC;IACrB,CAAC;IACD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACjD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAkBD;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAOxC;IACC,MAAM,SAAS,GACb,KAAK,CAAC,oBAAoB,IAAI,KAAK,CAAC,GAAG;QACrC,CAAC,CAAC,2BAA2B,CAAC;YAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;YAChD,GAAG,EAAE,KAAK,CAAC,GAAG;SACf,CAAC;QACJ,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IAEzB,IAAI,KAAK,CAAC,mBAAmB,IAAI,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACvE,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC1E,OAAO;YACL,gBAAgB,EAAE,UAAU,CAAC,UAAU,CAAC;YACxC,UAAU;YACV,SAAS;SACV,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,uEAAuE;IACvE,OAAO;QACL,gBAAgB,EAAE,UAAU,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,SAAS;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -43,7 +43,7 @@ export function installFaultBarrier(options) {
|
|
|
43
43
|
console.error(message, fault);
|
|
44
44
|
});
|
|
45
45
|
// Installed twice, one gateway would report every fault twice and race two
|
|
46
|
-
// exits. `
|
|
46
|
+
// exits. `mcp serve` boots through `startStdioGateway`, so this is
|
|
47
47
|
// reachable rather than theoretical. The MCP host owns process lifecycle;
|
|
48
48
|
// this barrier records the fault and exits instead of wrapping a grandchild.
|
|
49
49
|
//
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fault-barrier.js","sourceRoot":"","sources":["../../src/process/fault-barrier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAE1C,+EAA+E;AAC/E,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAwBxC,2EAA2E;AAC3E,MAAM,KAAK,GAAG,IAAI,OAAO,EAAoB,CAAC;AAa9C,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA4B;IAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,MAAM,GAAG,GACP,OAAO,CAAC,GAAG;QACX,CAAC,CAAC,OAAe,EAAE,KAAmB,EAAE,EAAE;YACxC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IAEL,2EAA2E;IAC3E,
|
|
1
|
+
{"version":3,"file":"fault-barrier.js","sourceRoot":"","sources":["../../src/process/fault-barrier.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,3 +31,5 @@ export declare function sanitizeAgentFacingText(text: string): string;
|
|
|
31
31
|
* needs without hiding a secret.
|
|
32
32
|
*/
|
|
33
33
|
export declare function sanitizeAgentFacingValue(value: unknown): unknown;
|
|
34
|
+
/** Deep-sanitize a configuration while omitting credential fields entirely. */
|
|
35
|
+
export declare function sanitizeAgentFacingConfiguration(value: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* characters, and prompt-injection wrappers. Strip those before any agent sees
|
|
6
6
|
* the string.
|
|
7
7
|
*/
|
|
8
|
+
import { containsCredentialMaterial } from "@superblocksteam/shared";
|
|
8
9
|
/** JWT / opaque bearer-ish tokens and common vendor API key shapes. */
|
|
9
10
|
const SECRET_PATTERNS = [
|
|
10
11
|
/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
|
|
@@ -22,10 +23,17 @@ const SECRET_FIELD_KEYS = new Set([
|
|
|
22
23
|
"api_key",
|
|
23
24
|
"apikey",
|
|
24
25
|
"authorization",
|
|
25
|
-
"
|
|
26
|
+
"ca",
|
|
27
|
+
"cert",
|
|
28
|
+
"connectionstring",
|
|
29
|
+
"dsn",
|
|
30
|
+
"googleserviceaccount",
|
|
31
|
+
"masterkey",
|
|
26
32
|
"passwd",
|
|
33
|
+
"password",
|
|
27
34
|
"secret",
|
|
28
35
|
"token",
|
|
36
|
+
"urlstring",
|
|
29
37
|
]);
|
|
30
38
|
/**
|
|
31
39
|
* Field names that end in a credential word but carry a cursor or a count.
|
|
@@ -85,9 +93,15 @@ function isSecretFieldKey(key) {
|
|
|
85
93
|
return (SECRET_FIELD_KEYS.has(key.toLowerCase()) ||
|
|
86
94
|
SECRET_FIELD_KEYS.has(normalized) ||
|
|
87
95
|
normalized.endsWith("password") ||
|
|
96
|
+
normalized.endsWith("passphrase") ||
|
|
88
97
|
normalized.endsWith("secret") ||
|
|
89
98
|
normalized.endsWith("token") ||
|
|
90
|
-
normalized.endsWith("apikey")
|
|
99
|
+
normalized.endsWith("apikey") ||
|
|
100
|
+
normalized.includes("accesskey") ||
|
|
101
|
+
normalized.includes("certificate") ||
|
|
102
|
+
normalized.includes("password") ||
|
|
103
|
+
normalized.includes("privatekey") ||
|
|
104
|
+
normalized.includes("secret"));
|
|
91
105
|
}
|
|
92
106
|
/**
|
|
93
107
|
* Deep-sanitize string leaves in tool results returned to Clark / MCP.
|
|
@@ -122,4 +136,44 @@ export function sanitizeAgentFacingValue(value) {
|
|
|
122
136
|
}
|
|
123
137
|
return value;
|
|
124
138
|
}
|
|
139
|
+
function isCredentialMaterial(value) {
|
|
140
|
+
if (typeof value !== "string") {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (/-----BEGIN [A-Z0-9 ]+-----/.test(value) ||
|
|
144
|
+
containsCredentialMaterial(value)) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const url = new URL(value, "https://example.invalid");
|
|
149
|
+
return Boolean(url.username || url.password);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Deep-sanitize a configuration while omitting credential fields entirely. */
|
|
156
|
+
export function sanitizeAgentFacingConfiguration(value) {
|
|
157
|
+
return sanitizeConfigurationValue(value);
|
|
158
|
+
}
|
|
159
|
+
function sanitizeConfigurationValue(value) {
|
|
160
|
+
if (Array.isArray(value)) {
|
|
161
|
+
return value
|
|
162
|
+
.filter((entry) => !isCredentialMaterial(entry))
|
|
163
|
+
.map(sanitizeConfigurationValue);
|
|
164
|
+
}
|
|
165
|
+
if (!value || typeof value !== "object") {
|
|
166
|
+
return sanitizeAgentFacingValue(value);
|
|
167
|
+
}
|
|
168
|
+
const out = {};
|
|
169
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
170
|
+
if (typeof entry !== "boolean" &&
|
|
171
|
+
entry != null &&
|
|
172
|
+
(isSecretFieldKey(key) || isCredentialMaterial(entry))) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
out[key] = sanitizeConfigurationValue(entry);
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
125
179
|
//# sourceMappingURL=agent-facing-text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-facing-text.js","sourceRoot":"","sources":["../../src/sabs/agent-facing-text.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,uEAAuE;AACvE,MAAM,eAAe,GAAa;IAChC,oEAAoE;IACpE,+EAA+E;IAC/E,0CAA0C;IAC1C,2BAA2B;IAC3B,uBAAuB;IACvB,wCAAwC;IACxC,iDAAiD;IACjD,sFAAsF;IACtF,0CAA0C;IAC1C,qFAAqF;CACtF,CAAC;AAEF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,SAAS;IACT,QAAQ;IACR,eAAe;IACf,
|
|
1
|
+
{"version":3,"file":"agent-facing-text.js","sourceRoot":"","sources":["../../src/sabs/agent-facing-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { RecentToolRun } from "../capabilities/types.js";
|
|
2
|
+
import type { FinishedTurn, RetryAction, TurnDecision } from "./session-peer.js";
|
|
3
|
+
/**
|
|
4
|
+
* How long a dead start stays the answer for an application.
|
|
5
|
+
*
|
|
6
|
+
* Long enough to outlive the poll that follows a failed prompt, short enough
|
|
7
|
+
* that an app abandoned after a failure is not still reporting it later.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_FAILED_START_TTL_MS: number;
|
|
10
|
+
/**
|
|
11
|
+
* Cap on remembered dead starts, because nothing else evicts: an app whose
|
|
12
|
+
* start failed and that is never retried would otherwise hold its entry for
|
|
13
|
+
* the life of the process.
|
|
14
|
+
*/
|
|
15
|
+
export declare const MAX_FAILED_STARTS = 256;
|
|
16
|
+
/**
|
|
17
|
+
* How long an acknowledged start may go without its live owner renewing it.
|
|
18
|
+
* Long enough for a cold sandbox boot, short enough that a background start
|
|
19
|
+
* killed without recording anything stops pinning the app at "building".
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_PENDING_START_TTL_MS: number;
|
|
22
|
+
/**
|
|
23
|
+
* Whose prompt died. Scoped to the caller because `connectLiveEdit` is where
|
|
24
|
+
* Superblocks authorizes them, per application - so a caller with no rights to
|
|
25
|
+
* this one still reaches that path, and a record keyed any wider becomes the
|
|
26
|
+
* status everyone who does have rights reads.
|
|
27
|
+
*/
|
|
28
|
+
export type FailedStartScope = {
|
|
29
|
+
applicationId: string;
|
|
30
|
+
branch?: string;
|
|
31
|
+
organizationId: string;
|
|
32
|
+
userId: string;
|
|
33
|
+
};
|
|
34
|
+
type FailedStart = FinishedTurn & {
|
|
35
|
+
branch?: string;
|
|
36
|
+
};
|
|
37
|
+
export type PendingPlan = {
|
|
38
|
+
branch?: string;
|
|
39
|
+
messageId?: string;
|
|
40
|
+
plan: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
};
|
|
43
|
+
export type PendingDecision = {
|
|
44
|
+
branch?: string;
|
|
45
|
+
decision: TurnDecision;
|
|
46
|
+
recentRuns?: RecentToolRun[];
|
|
47
|
+
reply: string;
|
|
48
|
+
};
|
|
49
|
+
export type AppStateOptions = {
|
|
50
|
+
failedStartTtlMs?: number;
|
|
51
|
+
maxFailedStarts?: number;
|
|
52
|
+
now?: () => number;
|
|
53
|
+
pendingStartTtlMs?: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* What Gateway remembers about an application between turns.
|
|
57
|
+
*
|
|
58
|
+
* None of this is transport state, and none of it can be pushed onto the
|
|
59
|
+
* caller. Each entry compensates for something the protocol does not carry:
|
|
60
|
+
*
|
|
61
|
+
* - The plan, because approving one means re-sending it as `planContext`, and
|
|
62
|
+
* a caller asked to echo markdown back paraphrases it - which silently
|
|
63
|
+
* changes what gets built.
|
|
64
|
+
* - The dead start, because the call that failed has already returned. It is
|
|
65
|
+
* the *next* call - a poll, or `get_app` - that would otherwise report
|
|
66
|
+
* `unknown` and preview the untouched starter template as a finished app.
|
|
67
|
+
*
|
|
68
|
+
* It lives here rather than on the session peer so a socket owns a socket. It
|
|
69
|
+
* is a concrete class with no optional members: a collaborator that is always
|
|
70
|
+
* present cannot be confused at a call site with a fact that is absent.
|
|
71
|
+
*/
|
|
72
|
+
export declare class AppState {
|
|
73
|
+
private readonly acceptedStarts;
|
|
74
|
+
private readonly plans;
|
|
75
|
+
private readonly decisions;
|
|
76
|
+
private readonly publishes;
|
|
77
|
+
private readonly failedStarts;
|
|
78
|
+
private readonly pendingStarts;
|
|
79
|
+
private readonly failedStartTtlMs;
|
|
80
|
+
private readonly maxFailedStarts;
|
|
81
|
+
private readonly now;
|
|
82
|
+
private readonly pendingStartTtlMs;
|
|
83
|
+
private revision;
|
|
84
|
+
constructor(options?: AppStateOptions);
|
|
85
|
+
pendingPlan(applicationId: string, requestedBranch?: string): PendingPlan | undefined;
|
|
86
|
+
setPendingPlan(applicationId: string, plan: PendingPlan): void;
|
|
87
|
+
pendingDecision(applicationId: string, requestedBranch?: string): PendingDecision | undefined;
|
|
88
|
+
setPendingDecision(applicationId: string, decision: PendingDecision): void;
|
|
89
|
+
/**
|
|
90
|
+
* The commit whose deploy `publish_app` handed back still running, so
|
|
91
|
+
* `check_publish_progress` can follow it without the caller carrying the id.
|
|
92
|
+
*/
|
|
93
|
+
publishInFlight(applicationId: string): string | undefined;
|
|
94
|
+
publishStartedAtMs(applicationId: string, commitId: string): number | undefined;
|
|
95
|
+
setPublishInFlight(applicationId: string, commitId: string, startedAtMs?: number): number;
|
|
96
|
+
claimPublishInFlight(applicationId: string, commitId: string, startedAtMs?: number): number;
|
|
97
|
+
noteMissingPublishStatus(applicationId: string, claim: number, atMs: number): number | undefined;
|
|
98
|
+
noteVisiblePublishStatus(applicationId: string, claim: number): void;
|
|
99
|
+
clearPublishInFlight(applicationId: string, claim: number): void;
|
|
100
|
+
/**
|
|
101
|
+
* Drop the plan alone, for a turn that ended on a decision that is not one.
|
|
102
|
+
* The decision it ended on is written separately and must survive this.
|
|
103
|
+
*/
|
|
104
|
+
clearPendingPlan(applicationId: string): void;
|
|
105
|
+
/** Both go together: a plan is one kind of decision Clark waits on. */
|
|
106
|
+
clearPending(applicationId: string): void;
|
|
107
|
+
markTurnStarted(): number;
|
|
108
|
+
failedStart(scope: FailedStartScope, newerThanRevision?: number): FailedStart | undefined;
|
|
109
|
+
recordFailedStart(scope: FailedStartScope, turn: FinishedTurn, revision?: number): void;
|
|
110
|
+
claimReplacementEntitlement(scope: Omit<FailedStartScope, "branch">, replyWhileClaimed: string): (() => void) | undefined;
|
|
111
|
+
/** Forget every caller's dead start for the accepted application branch. */
|
|
112
|
+
clearFailedStarts(applicationId: string, branch?: string, throughRevision?: number): void;
|
|
113
|
+
pendingStart(scope: FailedStartScope, idempotencyKey?: string, token?: number): {
|
|
114
|
+
idempotencyKey?: string;
|
|
115
|
+
retryAction?: RetryAction;
|
|
116
|
+
token: number;
|
|
117
|
+
} | undefined;
|
|
118
|
+
recordPendingStart(scope: FailedStartScope, value?: {
|
|
119
|
+
idempotencyKey?: string;
|
|
120
|
+
retryAction?: RetryAction;
|
|
121
|
+
}): number;
|
|
122
|
+
keepPendingStartAlive(scope: FailedStartScope, token: number): () => void;
|
|
123
|
+
clearPendingStart(scope: FailedStartScope, idempotencyKey?: string, throughRevision?: number, token?: number): boolean;
|
|
124
|
+
clearPendingStartsThrough(applicationId: string, revision: number): void;
|
|
125
|
+
}
|
|
126
|
+
export {};
|