@superblocksteam/gateway 2.0.0-SNAPSHOT.2161f9a02a4eb5d8
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/LICENSE.txt +87 -0
- package/README.md +284 -0
- package/dist/agents/resolve-orchestrator-url.d.ts +22 -0
- package/dist/agents/resolve-orchestrator-url.js +38 -0
- package/dist/agents/resolve-orchestrator-url.js.map +1 -0
- package/dist/capabilities/integration-metadata.d.ts +28 -0
- package/dist/capabilities/integration-metadata.js +174 -0
- package/dist/capabilities/integration-metadata.js.map +1 -0
- package/dist/capabilities/lifecycle.d.ts +93 -0
- package/dist/capabilities/lifecycle.js +3417 -0
- package/dist/capabilities/lifecycle.js.map +1 -0
- 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 +542 -0
- package/dist/capabilities/types.js +86 -0
- package/dist/capabilities/types.js.map +1 -0
- package/dist/capture/browser-contract.d.ts +46 -0
- package/dist/capture/browser-contract.js +34 -0
- package/dist/capture/browser-contract.js.map +1 -0
- package/dist/capture/browser-instructions.d.ts +10 -0
- package/dist/capture/browser-instructions.js +18 -0
- package/dist/capture/browser-instructions.js.map +1 -0
- package/dist/capture/capture-library-probe.d.ts +55 -0
- package/dist/capture/capture-library-probe.js +177 -0
- package/dist/capture/capture-library-probe.js.map +1 -0
- package/dist/capture/capture-library.d.ts +52 -0
- package/dist/capture/capture-library.js +249 -0
- package/dist/capture/capture-library.js.map +1 -0
- package/dist/capture/classify-library-paint.d.ts +21 -0
- package/dist/capture/classify-library-paint.js +13 -0
- package/dist/capture/classify-library-paint.js.map +1 -0
- package/dist/capture/host-mcp-scan.d.ts +16 -0
- package/dist/capture/host-mcp-scan.js +64 -0
- package/dist/capture/host-mcp-scan.js.map +1 -0
- package/dist/capture/library-parent-script.d.ts +35 -0
- package/dist/capture/library-parent-script.js +82 -0
- package/dist/capture/library-parent-script.js.map +1 -0
- package/dist/capture/mode.d.ts +29 -0
- package/dist/capture/mode.js +65 -0
- package/dist/capture/mode.js.map +1 -0
- package/dist/config.d.ts +148 -0
- package/dist/config.js +112 -0
- package/dist/config.js.map +1 -0
- package/dist/debug.d.ts +2 -0
- package/dist/debug.js +9 -0
- package/dist/debug.js.map +1 -0
- package/dist/deps.d.ts +38 -0
- package/dist/deps.js +2 -0
- package/dist/deps.js.map +1 -0
- package/dist/health/readiness.d.ts +99 -0
- package/dist/health/readiness.js +202 -0
- package/dist/health/readiness.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/filters.d.ts +8 -0
- package/dist/integrations/filters.js +40 -0
- package/dist/integrations/filters.js.map +1 -0
- package/dist/integrations/map.d.ts +27 -0
- package/dist/integrations/map.js +43 -0
- package/dist/integrations/map.js.map +1 -0
- package/dist/integrations/profile-key.d.ts +19 -0
- package/dist/integrations/profile-key.js +35 -0
- package/dist/integrations/profile-key.js.map +1 -0
- 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.d.ts +2 -0
- package/dist/main.js +5 -0
- package/dist/main.js.map +1 -0
- package/dist/orchestrator/client.d.ts +62 -0
- package/dist/orchestrator/client.js +160 -0
- package/dist/orchestrator/client.js.map +1 -0
- package/dist/playwright/ensure-chromium.d.ts +23 -0
- package/dist/playwright/ensure-chromium.js +59 -0
- package/dist/playwright/ensure-chromium.js.map +1 -0
- package/dist/preview/capture-screenshot.d.ts +67 -0
- package/dist/preview/capture-screenshot.js +179 -0
- package/dist/preview/capture-screenshot.js.map +1 -0
- package/dist/preview/viewer-url.d.ts +82 -0
- package/dist/preview/viewer-url.js +130 -0
- package/dist/preview/viewer-url.js.map +1 -0
- package/dist/process/fault-barrier.d.ts +55 -0
- package/dist/process/fault-barrier.js +113 -0
- package/dist/process/fault-barrier.js.map +1 -0
- package/dist/sabs/agent-facing-text.d.ts +35 -0
- package/dist/sabs/agent-facing-text.js +165 -0
- package/dist/sabs/agent-facing-text.js.map +1 -0
- package/dist/sabs/app-state.d.ts +133 -0
- package/dist/sabs/app-state.js +347 -0
- package/dist/sabs/app-state.js.map +1 -0
- package/dist/sabs/awaited-decision.d.ts +47 -0
- package/dist/sabs/awaited-decision.js +124 -0
- package/dist/sabs/awaited-decision.js.map +1 -0
- package/dist/sabs/browser-context.d.ts +53 -0
- package/dist/sabs/browser-context.js +92 -0
- package/dist/sabs/browser-context.js.map +1 -0
- package/dist/sabs/editor-client-methods.d.ts +164 -0
- package/dist/sabs/editor-client-methods.js +749 -0
- package/dist/sabs/editor-client-methods.js.map +1 -0
- package/dist/sabs/editor-socket.d.ts +84 -0
- package/dist/sabs/editor-socket.js +64 -0
- package/dist/sabs/editor-socket.js.map +1 -0
- package/dist/sabs/recent-tool-runs.d.ts +14 -0
- package/dist/sabs/recent-tool-runs.js +61 -0
- package/dist/sabs/recent-tool-runs.js.map +1 -0
- package/dist/sabs/session-peer.d.ts +386 -0
- package/dist/sabs/session-peer.js +11 -0
- package/dist/sabs/session-peer.js.map +1 -0
- package/dist/sabs/streamed-reply.d.ts +42 -0
- package/dist/sabs/streamed-reply.js +110 -0
- package/dist/sabs/streamed-reply.js.map +1 -0
- package/dist/sabs/turn-collector.d.ts +169 -0
- package/dist/sabs/turn-collector.js +512 -0
- package/dist/sabs/turn-collector.js.map +1 -0
- package/dist/sabs/websocket-session-peer.d.ts +533 -0
- package/dist/sabs/websocket-session-peer.js +3241 -0
- package/dist/sabs/websocket-session-peer.js.map +1 -0
- package/dist/security/constant-time.d.ts +9 -0
- package/dist/security/constant-time.js +13 -0
- package/dist/security/constant-time.js.map +1 -0
- package/dist/server/client.d.ts +400 -0
- package/dist/server/client.js +649 -0
- package/dist/server/client.js.map +1 -0
- package/dist/server/identity-reads.d.ts +76 -0
- package/dist/server/identity-reads.js +209 -0
- package/dist/server/identity-reads.js.map +1 -0
- package/dist/start.d.ts +24 -0
- package/dist/start.js +81 -0
- package/dist/start.js.map +1 -0
- package/dist/stores/memory.d.ts +42 -0
- package/dist/stores/memory.js +121 -0
- package/dist/stores/memory.js.map +1 -0
- package/dist/stores/types.d.ts +74 -0
- package/dist/stores/types.js +11 -0
- package/dist/stores/types.js.map +1 -0
- package/dist/telemetry/mcp-client.d.ts +22 -0
- package/dist/telemetry/mcp-client.js +140 -0
- package/dist/telemetry/mcp-client.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +41 -0
- package/dist/telemetry/metrics.js +103 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/runtime.d.ts +9 -0
- package/dist/telemetry/runtime.js +118 -0
- package/dist/telemetry/runtime.js.map +1 -0
- package/dist/transports/mcp/admin-tools.d.ts +51 -0
- package/dist/transports/mcp/admin-tools.js +211 -0
- package/dist/transports/mcp/admin-tools.js.map +1 -0
- package/dist/transports/mcp/app-status-html.d.ts +11 -0
- package/dist/transports/mcp/app-status-html.js +899 -0
- package/dist/transports/mcp/app-status-html.js.map +1 -0
- 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/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 +116 -0
- package/dist/transports/mcp/decision-elicitation.js +292 -0
- package/dist/transports/mcp/decision-elicitation.js.map +1 -0
- package/dist/transports/mcp/dispatch-probe.d.ts +24 -0
- package/dist/transports/mcp/dispatch-probe.js +48 -0
- package/dist/transports/mcp/dispatch-probe.js.map +1 -0
- package/dist/transports/mcp/format-tool-content.d.ts +20 -0
- package/dist/transports/mcp/format-tool-content.js +89 -0
- package/dist/transports/mcp/format-tool-content.js.map +1 -0
- 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 +17 -0
- package/dist/transports/mcp/instructions/tools/ask-user.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 +72 -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 +2 -0
- package/dist/transports/mcp/instructions/tools/check-publish-progress.js +14 -0
- package/dist/transports/mcp/instructions/tools/check-publish-progress.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/copy.d.ts +8 -0
- package/dist/transports/mcp/instructions/tools/copy.js +19 -0
- package/dist/transports/mcp/instructions/tools/copy.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/create-integration.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/create-integration.js +32 -0
- package/dist/transports/mcp/instructions/tools/create-integration.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/edit-app.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/edit-app.js +14 -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 +47 -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 +26 -0
- package/dist/transports/mcp/instructions/tools/index.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/preview-app.d.ts +3 -0
- package/dist/transports/mcp/instructions/tools/preview-app.js +14 -0
- package/dist/transports/mcp/instructions/tools/preview-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/publish-app.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/publish-app.js +11 -0
- package/dist/transports/mcp/instructions/tools/publish-app.js.map +1 -0
- package/dist/transports/mcp/instructions/tools/start-app.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/start-app.js +18 -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 +21 -0
- package/dist/transports/mcp/mount.js +968 -0
- package/dist/transports/mcp/mount.js.map +1 -0
- 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 +38 -0
- package/dist/transports/mcp/plan-approval.js +175 -0
- package/dist/transports/mcp/plan-approval.js.map +1 -0
- package/dist/transports/mcp/progress-notifier.d.ts +39 -0
- package/dist/transports/mcp/progress-notifier.js +52 -0
- package/dist/transports/mcp/progress-notifier.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 +78 -0
- package/skills/superblocks-build/SKILL.md +59 -0
- package/skills/superblocks-import/SKILL.md +87 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Superblocks Community Software License
|
|
2
|
+
|
|
3
|
+
This Superblocks Community License Agreement (the “Agreement”) sets forth the terms on which DayZero
|
|
4
|
+
Software, Inc. d/b/a Superblocks (“Superblocks”) makes available certain software made available by Superblocks
|
|
5
|
+
under this Agreement (the “Software”). BY INSTALLING, DOWNLOADING, ACCESSING, USING OR
|
|
6
|
+
DISTRIBUTING ANY OF THE SOFTWARE, YOU AGREE TO THE TERMS AND CONDITIONS OF THIS
|
|
7
|
+
AGREEMENT.IF YOU DO NOT AGREE TO SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE
|
|
8
|
+
SOFTWARE. IF YOU ARE RECEIVING THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU
|
|
9
|
+
REPRESENT AND WARRANT THAT YOU HAVE THE ACTUAL AUTHORITY TO AGREE TO THE
|
|
10
|
+
TERMS AND CONDITIONS OF THIS AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you,
|
|
11
|
+
an individual, or the entity on whose behalf you are receiving the Software.
|
|
12
|
+
|
|
13
|
+
1. LICENSE GRANT AND CONDITIONS.
|
|
14
|
+
|
|
15
|
+
1.1 License. Subject to the terms and conditions of this Agreement, Superblocks hereby grants to Licensee a
|
|
16
|
+
non-exclusive, royalty-free, worldwide, non-transferable, non-sublicenseable license during the term of this
|
|
17
|
+
Agreement to: (a) use the Software; (b) prepare modifications and derivative works of the Software; (c)
|
|
18
|
+
distribute the Software (including without limitation in source code or object code form); and (d) reproduce
|
|
19
|
+
copies of the Software (the “License”). Licensee is not granted the right to, and Licensee shall not, exercise the
|
|
20
|
+
License for an Excluded Purpose. For purposes of this Agreement, “Excluded Purpose” means making
|
|
21
|
+
available any software-as-a-service, platform-as-a-service, infrastructure-as-a-service or other similar online
|
|
22
|
+
service that competes with Superblocks’ products or services.
|
|
23
|
+
|
|
24
|
+
1.2 Conditions. In consideration of the License, Licensee’s distribution of the Software is subject to the
|
|
25
|
+
following conditions:
|
|
26
|
+
|
|
27
|
+
a. Licensee must cause any Software modified by Licensee to carry prominent notices stating that Licensee
|
|
28
|
+
modified the Software.
|
|
29
|
+
b. On each Software copy, Licensee shall reproduce and not remove or alter all Superblocks or third party
|
|
30
|
+
copyright or other proprietary notices contained in the Software, and Licensee must provide the notice
|
|
31
|
+
below with each copy.
|
|
32
|
+
|
|
33
|
+
“This software is made available by DayZero Software, Inc. d/b/a Superblocks, under the terms of the
|
|
34
|
+
Superblocks Community License Agreement. © 2022 DayZero Software, Inc.”
|
|
35
|
+
|
|
36
|
+
1.3 Licensee Modifications. Licensee may add its own copyright notices to modifications made by Licensee
|
|
37
|
+
and may provide additional or different license terms and conditions for use, reproduction, or distribution of
|
|
38
|
+
Licensee’s modifications. While redistributing the Software or modifications thereof, Licensee may choose to
|
|
39
|
+
offer, for a fee or free of charge, support, warranty, indemnity, or other obligations. Licensee, and not
|
|
40
|
+
Superblocks, will be responsible for any such obligations.
|
|
41
|
+
|
|
42
|
+
1.4 No Sublicensing. The License does not include the right to sublicense the Software, however, each recipient
|
|
43
|
+
to which Licensee provides the Software may exercise the Licenses so long as such recipient agrees to the terms
|
|
44
|
+
and conditions of this Agreement.
|
|
45
|
+
|
|
46
|
+
2. TERM AND TERMINATION. This Agreement will continue unless and until earlier terminated as set forth
|
|
47
|
+
herein. If Licensee breaches any of its conditions or obligations under this Agreement, this Agreement will
|
|
48
|
+
terminate automatically and the License will terminate automatically and permanently.
|
|
49
|
+
|
|
50
|
+
3. INTELLECTUAL PROPERTY. As between the parties, Superblocks will retain all right, title, and interest in
|
|
51
|
+
the Software, and all intellectual property rights therein. Superblocks hereby reserves all rights not expressly
|
|
52
|
+
granted to Licensee in this Agreement. Superblocks hereby reserves all rights in its trademarks and service
|
|
53
|
+
marks, and no licenses therein are granted in this Agreement.
|
|
54
|
+
|
|
55
|
+
4. DISCLAIMER. SUPERBLOCKS HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND
|
|
56
|
+
CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY
|
|
57
|
+
DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
|
|
58
|
+
PURPOSE, WITH RESPECT TO THE SOFTWARE.
|
|
59
|
+
|
|
60
|
+
5. LIMITATION OF LIABILITY. SUPERBLOCKS WILL NOT BE LIABLE FOR ANY DAMAGES OF
|
|
61
|
+
ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL,
|
|
62
|
+
SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY
|
|
63
|
+
THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL APPLY TO
|
|
64
|
+
THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
65
|
+
|
|
66
|
+
6. GENERAL.
|
|
67
|
+
|
|
68
|
+
6.1 Governing Law. This Agreement will be governed by and interpreted in accordance with the laws of the
|
|
69
|
+
state of California, without reference to its conflict of laws principles. If Licensee is located within the United
|
|
70
|
+
States, all disputes arising out of this Agreement are subject to the exclusive jurisdiction of courts located in San
|
|
71
|
+
Mateo County, California. USA. If Licensee is located outside of the United States, any dispute, controversy or
|
|
72
|
+
claim arising out of or relating to this Agreement will be referred to and finally determined by arbitration in
|
|
73
|
+
accordance with the JAMS International Arbitration Rules. The tribunal will consist of one neutral arbitrator.
|
|
74
|
+
The place of arbitration will be Palo Alto, California. The language to be used in the arbitral proceedings will be
|
|
75
|
+
English. Judgment upon the award rendered by the arbitrator may be entered in any court having jurisdiction
|
|
76
|
+
thereof.
|
|
77
|
+
|
|
78
|
+
6.2. Assignment. Licensee may not assign its rights under this Agreement to any third party. Superblocks may
|
|
79
|
+
freely assign its rights under this Agreement to any third party.
|
|
80
|
+
|
|
81
|
+
6.3. Other. This Agreement is the entire agreement between the parties regarding the subject matter hereof.
|
|
82
|
+
No amendment or modification of this Agreement will be valid or binding upon the parties unless made in
|
|
83
|
+
writing and signed by the duly authorized representatives of both parties. In the event that any provision,
|
|
84
|
+
including without limitation any condition, of this Agreement is held to be unenforceable, this Agreement and
|
|
85
|
+
all licenses and rights granted hereunder will immediately terminate. Waiver by Superblocks of a breach of any
|
|
86
|
+
provision of this Agreement or the failure by Superblocks to exercise any right hereunder will not be construed
|
|
87
|
+
as a waiver of any subsequent breach of that right or as a waiver of any other right.
|
package/README.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# Gateway v0
|
|
2
|
+
|
|
3
|
+
Standalone Superblocks entry point for a **single MCP connector** (Admin + Builder)
|
|
4
|
+
over **stdio**, running as the already-logged-in Superblocks CLI user.
|
|
5
|
+
|
|
6
|
+
Builder tools (`upload_artifact`, `start_app`, `edit_app`,
|
|
7
|
+
`check_app_progress`, `ask_user`, `get_app`, `get_integration_metadata`,
|
|
8
|
+
`query_integration`, `preview_app`, `publish_app`) plus customer Admin tools from
|
|
9
|
+
`@superblocksteam/mcp-server` share this process.
|
|
10
|
+
|
|
11
|
+
The MCP host owns process lifecycle: it spawns `superblocks gateway serve`.
|
|
12
|
+
There is no foreground HTTP `/mcp`, no OAuth resource server, and no linked-grant
|
|
13
|
+
exchange. Personal API keys here are the CLI session
|
|
14
|
+
(`~/.superblocks/auth.json` / `SUPERBLOCKS_AUTH_FILE` / `just worktree auth`).
|
|
15
|
+
|
|
16
|
+
Scope notes:
|
|
17
|
+
|
|
18
|
+
- In-memory stores only; no Redis (ENG-5594).
|
|
19
|
+
- CLI identity only. Linked MCP grants, static `GATEWAY_DEV_SUPERBLOCKS_API_KEY`,
|
|
20
|
+
and on-behalf-of exchange are not supported.
|
|
21
|
+
- Missing Playwright Chromium does not block start (ENG-5796). Screenshots fail
|
|
22
|
+
closed when Chromium is absent.
|
|
23
|
+
- No Slack wrapper (ENG-5596).
|
|
24
|
+
- Orchestrator URL is discovered from Server agent inventory, not configured here.
|
|
25
|
+
|
|
26
|
+
## Claude Code plugin
|
|
27
|
+
|
|
28
|
+
Add the Superblocks marketplace and install the plugin from inside Claude Code:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
/plugin marketplace add https://unpkg.com/@superblocksteam/cli@beta/.claude-plugin/marketplace.json
|
|
32
|
+
/plugin install superblocks@superblocks
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The plugin includes Gateway and the `superblocks-import` skill. When prompted,
|
|
36
|
+
enter a Superblocks personal API key and your Superblocks instance URL. Claude
|
|
37
|
+
stores the API key in secure storage. The npm-backed plugin requires Node.js 24
|
|
38
|
+
or newer and npm 10 or newer.
|
|
39
|
+
|
|
40
|
+
## Claude Cowork plugin
|
|
41
|
+
|
|
42
|
+
For a local desktop Cowork session:
|
|
43
|
+
|
|
44
|
+
1. Install Node.js 24 or newer and npm 10 or newer.
|
|
45
|
+
2. Download [the Cowork plugin](https://unpkg.com/@superblocksteam/cli@beta/dist/superblocks.plugin).
|
|
46
|
+
3. Open `Customize > Plugins`, choose upload, and select the plugin file.
|
|
47
|
+
4. Enter a Superblocks personal API key and your Superblocks instance URL.
|
|
48
|
+
|
|
49
|
+
The plugin starts Gateway on the desktop. It is unavailable in cloud Cowork
|
|
50
|
+
sessions, which cannot run local MCP servers.
|
|
51
|
+
|
|
52
|
+
### Organization-managed rollout
|
|
53
|
+
|
|
54
|
+
Owners and Primary Owners on Team and Enterprise plans can distribute the
|
|
55
|
+
plugin from `Organization settings > Plugins`:
|
|
56
|
+
|
|
57
|
+
1. Enable Cowork and Skills for the organization.
|
|
58
|
+
2. Save a copy of `superblocks.plugin` with a `.zip` suffix. Organization
|
|
59
|
+
uploads require a valid `.zip` smaller than 50 MB.
|
|
60
|
+
3. Choose `Add plugins > Upload a file`, then create a marketplace or add the
|
|
61
|
+
archive to an existing one.
|
|
62
|
+
4. Set the plugin to `Installed by default` or `Required` and confirm its
|
|
63
|
+
version in the marketplace.
|
|
64
|
+
|
|
65
|
+
Upload a new archive with the same plugin name to replace the current version.
|
|
66
|
+
Members receive it on their next session or plugin refresh. To deprecate it, set
|
|
67
|
+
it to `Not available`; to remove it, delete it from the marketplace. Rollback
|
|
68
|
+
behavior is not documented by Anthropic; validate re-uploading a retained older
|
|
69
|
+
archive in a test marketplace before relying on it.
|
|
70
|
+
|
|
71
|
+
Superblocks supplies the archive and Gateway runtime. Claude organization Owners
|
|
72
|
+
control marketplace distribution and installation policy. Each member supplies
|
|
73
|
+
their Superblocks credentials; each desktop still needs Node.js, npm, and
|
|
74
|
+
permission to run local MCP servers. See [Anthropic's organization plugin guide](https://support.claude.com/en/articles/13837433-manage-plugins-for-your-organization).
|
|
75
|
+
|
|
76
|
+
## Internal review
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Log in if needed (same CLI session the Gateway will use)
|
|
80
|
+
superblocks login
|
|
81
|
+
|
|
82
|
+
# Write a stdio MCP entry into the client config
|
|
83
|
+
superblocks gateway setup --client claude
|
|
84
|
+
# or: --client cursor / --client claude-desktop / --client generic
|
|
85
|
+
|
|
86
|
+
# Restart the MCP host. It spawns Gateway; do not run gateway serve yourself.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`--client claude` also copies `skills/superblocks-import/SKILL.md` to
|
|
90
|
+
`~/.claude/skills/superblocks-import/`. `--client cursor` copies it to
|
|
91
|
+
`~/.cursor/skills/superblocks-import/`. Claude Desktop and generic clients
|
|
92
|
+
have no Agent Skills dir; they rely on the short MCP migration fallback.
|
|
93
|
+
Restart the host after setup so skills reload.
|
|
94
|
+
|
|
95
|
+
`setup` writes an absolute spawn so the host does not depend on cwd.
|
|
96
|
+
Published `bin/run.js` is the MCP `command` (its `node` shebang applies).
|
|
97
|
+
Worktree `bin/dev.js` is launched with `tsx` and without `--watch`: the
|
|
98
|
+
dev shebang is a file-watcher, which would kill stdio on source edits and
|
|
99
|
+
corrupt JSON-RPC on stdout. When `SUPERBLOCKS_AUTH_FILE` is set (worktree
|
|
100
|
+
auth), it is copied into the MCP `env` block. Gateway derives both control
|
|
101
|
+
plane and remote UI URLs from `superblocksBaseUrl` in that auth file.
|
|
102
|
+
|
|
103
|
+
`gateway setup` downloads Playwright Chromium for preview captures when it is
|
|
104
|
+
missing.
|
|
105
|
+
|
|
106
|
+
## Local run
|
|
107
|
+
|
|
108
|
+
The MCP host spawns Gateway. Do not run `gateway serve` in a TTY.
|
|
109
|
+
|
|
110
|
+
Against a remote Superblocks domain (EE / SaaS IR):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cd packages/cli/packages/cli
|
|
114
|
+
./bin/dev.js config set domain <host>
|
|
115
|
+
./bin/dev.js login
|
|
116
|
+
./bin/dev.js gateway setup --client claude
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Against a local control plane, start the stack first (`just up <worktree>`),
|
|
120
|
+
then login and `gateway setup` the same way.
|
|
121
|
+
|
|
122
|
+
`superblocks mcp serve` (stdio Admin-only) is deprecated; prefer `gateway setup`.
|
|
123
|
+
|
|
124
|
+
## Worktree MCP (Cursor / Claude)
|
|
125
|
+
|
|
126
|
+
Until published packages are on PATH, point the MCP host at this checkout.
|
|
127
|
+
Log in and run setup from the worktree CLI (not a globally installed `superblocks`):
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cd packages/cli/packages/cli
|
|
131
|
+
./bin/dev.js config set domain <host>
|
|
132
|
+
./bin/dev.js login
|
|
133
|
+
./bin/dev.js gateway setup --client cursor
|
|
134
|
+
# or: --client claude
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`setup` writes an absolute stdio spawn into the host config (`~/.cursor/mcp.json`
|
|
138
|
+
for Cursor, `~/.claude.json` for Claude Code):
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"mcpServers": {
|
|
143
|
+
"superblocks": {
|
|
144
|
+
"command": "/absolute/path/to/tsx/cli.mjs",
|
|
145
|
+
"args": [
|
|
146
|
+
"/absolute/path/to/packages/cli/packages/cli/bin/dev.js",
|
|
147
|
+
"gateway",
|
|
148
|
+
"serve"
|
|
149
|
+
],
|
|
150
|
+
"env": {
|
|
151
|
+
"SUPERBLOCKS_AUTH_FILE": "/absolute/path/to/worktree/.superblocks/auth.json"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`command` is `tsx` without `--watch`: the `bin/dev.js` shebang is a file
|
|
159
|
+
watcher, which would kill stdio on source edits and corrupt JSON-RPC on
|
|
160
|
+
stdout. `env` only copies the worktree CLI session path
|
|
161
|
+
(`SUPERBLOCKS_AUTH_FILE`). Gateway reads `superblocksBaseUrl` from that file.
|
|
162
|
+
Do not add `SUPERBLOCKS_GATEWAY_FROM_SOURCE`.
|
|
163
|
+
Optional stderr tees (`2>> ~/.cursor/superblocks-gateway.err`) are host
|
|
164
|
+
specific; `setup` does not write them.
|
|
165
|
+
|
|
166
|
+
Restart the MCP host after `setup` and after every rebuild below.
|
|
167
|
+
|
|
168
|
+
### Rebuild after source changes
|
|
169
|
+
|
|
170
|
+
Cursor MCP still goes through oclif `dist/index.js`. CLI esbuild inlines
|
|
171
|
+
`@superblocksteam/gateway`, so a Gateway `tsc` alone does not update the
|
|
172
|
+
process the host spawns.
|
|
173
|
+
|
|
174
|
+
| You changed | Rebuild |
|
|
175
|
+
| --------------------------------------------------------------- | ---------------------------------------------- |
|
|
176
|
+
| `packages/shared` (types Gateway imports, e.g. SocketHeartbeat) | `pnpm --filter @superblocksteam/shared build` |
|
|
177
|
+
| `packages/gateway/src` | `pnpm --filter @superblocksteam/gateway build` |
|
|
178
|
+
| Gateway, CLI serve wiring, or anything oclif esbuild inlines | `pnpm --filter @superblocksteam/cli build` |
|
|
179
|
+
|
|
180
|
+
A typical Gateway capture change is shared (if types moved), then Gateway,
|
|
181
|
+
then CLI. Then restart Cursor.
|
|
182
|
+
|
|
183
|
+
Proof the new bundle is live: Gateway stderr logs
|
|
184
|
+
`gateway live canvas capture uses libraryBrowserContext (testingEnabled does not gate it)`
|
|
185
|
+
at boot. A crash that `@superblocksteam/shared` does not export
|
|
186
|
+
`SocketHeartbeat` means shared `dist/` is stale.
|
|
187
|
+
|
|
188
|
+
## Authentication
|
|
189
|
+
|
|
190
|
+
Gateway tools call the Superblocks control plane with the personal API key from
|
|
191
|
+
the CLI session. Log in first (`superblocks login`). There is no issuer env, no
|
|
192
|
+
consent page, and no second PAT.
|
|
193
|
+
|
|
194
|
+
## Cloud-Prem laptop agent
|
|
195
|
+
|
|
196
|
+
Set `GATEWAY_LOCAL_AGENT=true` for a single-user corp laptop process. Stores are
|
|
197
|
+
always in-memory; suspended turns and progress cursors do not survive a restart.
|
|
198
|
+
`SUPERBLOCKS_SERVER_URL` (or `GATEWAY_SERVER_URL`) points at the in-VPC control
|
|
199
|
+
plane. The CLI session supplies identity.
|
|
200
|
+
|
|
201
|
+
Set `GATEWAY_ADMIN_TOOLS_ONLY=true` alongside `GATEWAY_LOCAL_AGENT=true` to
|
|
202
|
+
package only the customer Admin surface. Builder tools are not registered.
|
|
203
|
+
|
|
204
|
+
## MCP tools
|
|
205
|
+
|
|
206
|
+
After `gateway setup`, restart Claude Code or Cursor and call `upload_artifact`,
|
|
207
|
+
`start_app`, `edit_app`, `check_app_progress`, `ask_user`, `get_app`,
|
|
208
|
+
`get_integration_metadata`, `query_integration`, `preview_app`, and `publish_app`.
|
|
209
|
+
|
|
210
|
+
`upload_artifact` accepts any file the gateway can read through `filePath` -
|
|
211
|
+
an archive, an image, a PDF, or a log - or source the MCP client is writing out
|
|
212
|
+
itself through `files: [{ path, content }]`. `files` is archived as text, so
|
|
213
|
+
binary belongs on the `filePath` route, where the bytes never pass through the
|
|
214
|
+
model. Pass its returned artifact to `start_app` or `edit_app`; retries reuse
|
|
215
|
+
the same artifact and application IDs.
|
|
216
|
+
|
|
217
|
+
`ask_user` is what a turn ending on a plan or a question goes through. Hosts
|
|
218
|
+
with form elicitation never need it - `check_app_progress` puts the decision as
|
|
219
|
+
a native picker and answers Superblocks itself. Hosts without one (Claude
|
|
220
|
+
Desktop) get an MCP App: the plan with Build it / Change something beside it, or
|
|
221
|
+
the question with a button per option. The answer is posted back as the user's
|
|
222
|
+
own message (`ui/message`), so the host's agent loop continues as if they had
|
|
223
|
+
typed it. The decision is in the tool result as data either way, and the server
|
|
224
|
+
instructions require the host to write it out in chat as well - a host that
|
|
225
|
+
renders the card shows it instead of the tool text, and one that renders nothing
|
|
226
|
+
shows only the text.
|
|
227
|
+
|
|
228
|
+
`get_integration_metadata` reads tables, columns, and types from a connected
|
|
229
|
+
integration; use `search`, `limit`, and `offset` for large results. It needs no
|
|
230
|
+
application: without one it mints an
|
|
231
|
+
`integrations:build` token scoped to that single integration. Pass
|
|
232
|
+
`applicationId` only for an integration owned by one application, such as a
|
|
233
|
+
Native DB, which is invisible without app context.
|
|
234
|
+
It resolves the integration through the RBAC-annotated superset list rather than
|
|
235
|
+
the org-wide lookup by id, so it answers `integration_not_permitted` without
|
|
236
|
+
build permission on that integration and `integration_not_supported` for a
|
|
237
|
+
plugin Clark cannot use as a tool.
|
|
238
|
+
`get_integration_config_schema` is the create-integration form, not live data.
|
|
239
|
+
|
|
240
|
+
`query_integration` answers one-off data questions directly without creating an
|
|
241
|
+
application or persistent API. It accepts one parser-constrained PostgreSQL
|
|
242
|
+
`SELECT`, read-only CTE, `SHOW`, or `EXPLAIN` statement and returns a sanitized,
|
|
243
|
+
bounded result. PostgreSQL functions are limited to `count`, `sum`, `avg`,
|
|
244
|
+
`min`, and `max`; explicit casts, all other functions, and all mutation, schema,
|
|
245
|
+
session, and row-locking statements are rejected before execution. The
|
|
246
|
+
operation uses the same integration-level build permission and scoped token as
|
|
247
|
+
metadata reads and has a 30-second execution ceiling within the host-call
|
|
248
|
+
deadline.
|
|
249
|
+
|
|
250
|
+
## Env
|
|
251
|
+
|
|
252
|
+
See `.env.example`. Stores are in-memory only. Identity comes from the CLI
|
|
253
|
+
session, not from these variables.
|
|
254
|
+
|
|
255
|
+
| Variable | Purpose |
|
|
256
|
+
| ---------------------------- | ---------------------------------------------------------- |
|
|
257
|
+
| `SUPERBLOCKS_SERVER_URL` | Control plane URL (default from `auth.json` or localhost). |
|
|
258
|
+
| `GATEWAY_PROFILE_KEY` | Integration profile key (default `default`). |
|
|
259
|
+
| `GATEWAY_LOCAL_AGENT` | Cloud-Prem laptop agent mode. |
|
|
260
|
+
| `GATEWAY_ADMIN_TOOLS_ONLY` | Admin tools only; skip Builder surface. |
|
|
261
|
+
| `GATEWAY_IMPORT_SEARCH_DIRS` | Directories `upload_artifact.filePath` may read. |
|
|
262
|
+
| `SUPERBLOCKS_AUTH_FILE` | Worktree-local CLI session (from `just worktree auth`). |
|
|
263
|
+
| `NODE_DEBUG=gateway` | Tool call stacks and conditional-flow logs on stderr. |
|
|
264
|
+
|
|
265
|
+
Gateway debug logs include tool names, result states, decision branches, and
|
|
266
|
+
entry-point stacks. They intentionally omit credentials, prompts, answers, and
|
|
267
|
+
result payloads. Run `superblocks gateway setup --client <client> --debug`, then
|
|
268
|
+
restart the MCP host. Re-run setup without `--debug` to turn them off.
|
|
269
|
+
|
|
270
|
+
## Remote traceability
|
|
271
|
+
|
|
272
|
+
Gateway exports one OpenTelemetry trace per MCP process through the authenticated
|
|
273
|
+
Server `/api/v1/traces` proxy. Each tool call is a child span with the MCP client
|
|
274
|
+
name and version, tool name, duration, outcome, organization ID, and application
|
|
275
|
+
ID when available.
|
|
276
|
+
|
|
277
|
+
Prompts, answers, result payloads, credentials, and raw error messages are never
|
|
278
|
+
added to these spans. Use the application ID to correlate a trace with the
|
|
279
|
+
existing server-side app and build records.
|
|
280
|
+
|
|
281
|
+
Cloud-Prem uses `SUPERBLOCKS_DEPLOYMENT_TYPE=cloud-prem` (or `GATEWAY_LOCAL_AGENT`)
|
|
282
|
+
so the stricter telemetry policy is selected. Laptop agents still drop client,
|
|
283
|
+
organization, and application attributes until the Tier 2 traces contract lists
|
|
284
|
+
them; tool name, duration, and outcome still export.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Picks an orchestrator (agent) base URL the way the browser does: from the
|
|
3
|
+
* Server's agent inventory for the org, filtered by org agent type, Active
|
|
4
|
+
* status, and profile tags. Operators never set this URL.
|
|
5
|
+
*/
|
|
6
|
+
export type OrchestratorAgentCandidate = {
|
|
7
|
+
status: string;
|
|
8
|
+
tags: Record<string, string[]>;
|
|
9
|
+
type: number;
|
|
10
|
+
url: string;
|
|
11
|
+
};
|
|
12
|
+
export type PickOrchestratorBaseUrlInput = {
|
|
13
|
+
agentType: number;
|
|
14
|
+
agents: OrchestratorAgentCandidate[];
|
|
15
|
+
profileKey: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Returns a single orchestrator base URL from Server-reported agents.
|
|
19
|
+
* Throws when none are eligible — same failure mode as the browser's
|
|
20
|
+
* "No active agent found".
|
|
21
|
+
*/
|
|
22
|
+
export declare function pickOrchestratorBaseUrl(input: PickOrchestratorBaseUrlInput): string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Picks an orchestrator (agent) base URL the way the browser does: from the
|
|
3
|
+
* Server's agent inventory for the org, filtered by org agent type, Active
|
|
4
|
+
* status, and profile tags. Operators never set this URL.
|
|
5
|
+
*/
|
|
6
|
+
const ACTIVE_STATUS = "Active";
|
|
7
|
+
function matchesProfile(tags, profileKey) {
|
|
8
|
+
const profiles = tags.profile;
|
|
9
|
+
if (!profiles || profiles.length === 0) {
|
|
10
|
+
// Cloud sentinel and untagged agents are eligible for any profile.
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
return profiles.includes("*") || profiles.includes(profileKey);
|
|
14
|
+
}
|
|
15
|
+
function withTrailingSlash(url) {
|
|
16
|
+
return url.endsWith("/") ? url : `${url}/`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns a single orchestrator base URL from Server-reported agents.
|
|
20
|
+
* Throws when none are eligible — same failure mode as the browser's
|
|
21
|
+
* "No active agent found".
|
|
22
|
+
*/
|
|
23
|
+
export function pickOrchestratorBaseUrl(input) {
|
|
24
|
+
const eligible = input.agents.filter((candidate) => candidate.type === input.agentType &&
|
|
25
|
+
candidate.status === ACTIVE_STATUS &&
|
|
26
|
+
Boolean(candidate.url) &&
|
|
27
|
+
matchesProfile(candidate.tags ?? {}, input.profileKey));
|
|
28
|
+
if (eligible.length === 0) {
|
|
29
|
+
throw new Error(`No active agent found for agentType=${input.agentType} profile=${input.profileKey}`);
|
|
30
|
+
}
|
|
31
|
+
// Browser picks randomly among matches; stable first is fine for gateway.
|
|
32
|
+
const chosen = eligible[0];
|
|
33
|
+
if (!chosen) {
|
|
34
|
+
throw new Error(`No active agent found for agentType=${input.agentType} profile=${input.profileKey}`);
|
|
35
|
+
}
|
|
36
|
+
return withTrailingSlash(chosen.url);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=resolve-orchestrator-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-orchestrator-url.js","sourceRoot":"","sources":["../../src/agents/resolve-orchestrator-url.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,MAAM,aAAa,GAAG,QAAQ,CAAC;AAE/B,SAAS,cAAc,CACrB,IAA8B,EAC9B,UAAkB;IAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,mEAAmE;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAmC;IAEnC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAClC,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,SAAS;QAClC,SAAS,CAAC,MAAM,KAAK,aAAa;QAClC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC;QACtB,cAAc,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,UAAU,CAAC,CACzD,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,SAAS,YAAY,KAAK,CAAC,UAAU,EAAE,CACrF,CAAC;IACJ,CAAC;IACD,0EAA0E;IAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,CAAC,SAAS,YAAY,KAAK,CAAC,UAAU,EAAE,CACrF,CAAC;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CapabilityContext } from "./lifecycle.js";
|
|
2
|
+
import type { CapabilityResult } from "./types.js";
|
|
3
|
+
export type GetIntegrationMetadataInput = {
|
|
4
|
+
applicationId?: string;
|
|
5
|
+
integrationId: string;
|
|
6
|
+
limit?: number;
|
|
7
|
+
offset?: number;
|
|
8
|
+
search?: string;
|
|
9
|
+
};
|
|
10
|
+
type MetadataEntry = {
|
|
11
|
+
path: string;
|
|
12
|
+
value: boolean | null | number | string;
|
|
13
|
+
};
|
|
14
|
+
export type GetIntegrationMetadataResult = {
|
|
15
|
+
/** Absent when the metadata was read through an integration-scoped token. */
|
|
16
|
+
applicationId?: string;
|
|
17
|
+
entries: MetadataEntry[];
|
|
18
|
+
hasMore: boolean;
|
|
19
|
+
integrationId: string;
|
|
20
|
+
integrationName: string;
|
|
21
|
+
nextOffset: number | null;
|
|
22
|
+
offset: number;
|
|
23
|
+
pluginId: string;
|
|
24
|
+
returnedCount: number;
|
|
25
|
+
totalCount: number;
|
|
26
|
+
};
|
|
27
|
+
export declare function getIntegrationMetadata(context: CapabilityContext, input: GetIntegrationMetadataInput): Promise<CapabilityResult<GetIntegrationMetadataResult>>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { pickOrchestratorBaseUrl } from "../agents/resolve-orchestrator-url.js";
|
|
2
|
+
import { integrationIsToolSupported } from "../integrations/filters.js";
|
|
3
|
+
import { hasBuildPermission } from "../integrations/map.js";
|
|
4
|
+
import { pickEditorProfileKey } from "../integrations/profile-key.js";
|
|
5
|
+
import { HttpOrchestratorClient } from "../orchestrator/client.js";
|
|
6
|
+
import { sanitizeAgentFacingText, sanitizeAgentFacingValue, } from "../sabs/agent-facing-text.js";
|
|
7
|
+
import { ensurePrincipal, resolveApplicationId, } from "./lifecycle.js";
|
|
8
|
+
const DEFAULT_LIMIT = 100;
|
|
9
|
+
function labelPart(value) {
|
|
10
|
+
return typeof value === "string"
|
|
11
|
+
? value.trim().replaceAll(/[.[\]]/g, "_")
|
|
12
|
+
: "";
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A table name alone is ambiguous: `public.users` and `analytics.users` are
|
|
16
|
+
* different tables, so qualify with the schema whenever the row carries one.
|
|
17
|
+
*/
|
|
18
|
+
function arrayEntryLabel(value, index) {
|
|
19
|
+
if (value && typeof value === "object") {
|
|
20
|
+
const row = value;
|
|
21
|
+
const name = labelPart(row.name);
|
|
22
|
+
if (name) {
|
|
23
|
+
const schema = labelPart(row.schema);
|
|
24
|
+
return schema ? `${schema}.${name}` : name;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return String(index);
|
|
28
|
+
}
|
|
29
|
+
function metadataEntries(value, path = "", entries = []) {
|
|
30
|
+
if (value === null ||
|
|
31
|
+
typeof value === "boolean" ||
|
|
32
|
+
typeof value === "number" ||
|
|
33
|
+
typeof value === "string") {
|
|
34
|
+
entries.push({ path, value });
|
|
35
|
+
return entries;
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
value.forEach((entry, index) => {
|
|
40
|
+
const label = arrayEntryLabel(entry, index);
|
|
41
|
+
// Two rows that still label identically would be indistinguishable, so
|
|
42
|
+
// fall back to the index for the later one.
|
|
43
|
+
const unique = seen.has(label) ? `${label}#${index}` : label;
|
|
44
|
+
seen.add(unique);
|
|
45
|
+
metadataEntries(entry, `${path}[${unique}]`, entries);
|
|
46
|
+
});
|
|
47
|
+
return entries;
|
|
48
|
+
}
|
|
49
|
+
if (value && typeof value === "object") {
|
|
50
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
51
|
+
metadataEntries(entry, path ? `${path}.${key}` : key, entries);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return entries;
|
|
55
|
+
}
|
|
56
|
+
export async function getIntegrationMetadata(context, input) {
|
|
57
|
+
const principal = await ensurePrincipal(context);
|
|
58
|
+
if (principal.kind !== "ok") {
|
|
59
|
+
return principal;
|
|
60
|
+
}
|
|
61
|
+
let applicationId;
|
|
62
|
+
// Named for the agent before the integration resolves, so a failure on the
|
|
63
|
+
// way to the metadata still reports which integration it was reaching for.
|
|
64
|
+
let label = sanitizeAgentFacingText(input.integrationId);
|
|
65
|
+
try {
|
|
66
|
+
// An app is preferred but not required. App-owned integrations (Native DB
|
|
67
|
+
// among them) are only visible through an app-scoped token, so use one
|
|
68
|
+
// whenever an app is in play and fall back to the integration-scoped token
|
|
69
|
+
// rather than making the caller invent an application.
|
|
70
|
+
const resolved = await resolveApplicationId(context, principal.value, input.applicationId);
|
|
71
|
+
applicationId = resolved.kind === "ok" ? resolved.value : undefined;
|
|
72
|
+
// The RBAC-annotated list, not the org-wide lookup by id: only this one
|
|
73
|
+
// carries the permissions that say whether the caller may build with the
|
|
74
|
+
// integration at all.
|
|
75
|
+
const rows = await context.server.getSupersetIntegrations({
|
|
76
|
+
apiKey: principal.value.apiKey,
|
|
77
|
+
...(applicationId && { applicationId }),
|
|
78
|
+
organizationId: principal.value.organizationId,
|
|
79
|
+
});
|
|
80
|
+
const integration = rows.find((row) => row.id === input.integrationId);
|
|
81
|
+
if (!integration) {
|
|
82
|
+
return {
|
|
83
|
+
...(applicationId && { applicationId }),
|
|
84
|
+
kind: "error",
|
|
85
|
+
code: "integration_not_accessible",
|
|
86
|
+
message: `Integration ${label} was not found or is not accessible.`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const integrationName = sanitizeAgentFacingText(integration.name);
|
|
90
|
+
const pluginId = sanitizeAgentFacingText(integration.pluginId);
|
|
91
|
+
label = integrationName;
|
|
92
|
+
if (!hasBuildPermission(integration)) {
|
|
93
|
+
return {
|
|
94
|
+
...(applicationId && { applicationId }),
|
|
95
|
+
kind: "error",
|
|
96
|
+
code: "integration_not_permitted",
|
|
97
|
+
message: `You do not have build permission on ${integrationName}.`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (!integrationIsToolSupported(integration.pluginId)) {
|
|
101
|
+
return {
|
|
102
|
+
...(applicationId && { applicationId }),
|
|
103
|
+
kind: "error",
|
|
104
|
+
code: "integration_not_supported",
|
|
105
|
+
message: `${integrationName} is a ${pluginId} integration, which this tool cannot inspect.`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const profiles = await context.server.getOrganizationProfiles({
|
|
109
|
+
apiKey: principal.value.apiKey,
|
|
110
|
+
organizationId: principal.value.organizationId,
|
|
111
|
+
});
|
|
112
|
+
const profileKey = pickEditorProfileKey(context.config.profileKey, profiles);
|
|
113
|
+
const inventory = await context.server.getAgentInventory({
|
|
114
|
+
apiKey: principal.value.apiKey,
|
|
115
|
+
organizationId: principal.value.organizationId,
|
|
116
|
+
});
|
|
117
|
+
const orchestratorUrl = pickOrchestratorBaseUrl({
|
|
118
|
+
agentType: inventory.agentType,
|
|
119
|
+
agents: inventory.agents,
|
|
120
|
+
profileKey,
|
|
121
|
+
});
|
|
122
|
+
const scopedToken = await context.server.issueScopedToken(applicationId
|
|
123
|
+
? {
|
|
124
|
+
apiKey: principal.value.apiKey,
|
|
125
|
+
applicationId,
|
|
126
|
+
scope: "apps:update",
|
|
127
|
+
}
|
|
128
|
+
: {
|
|
129
|
+
apiKey: principal.value.apiKey,
|
|
130
|
+
integrationId: input.integrationId,
|
|
131
|
+
scope: "integrations:build",
|
|
132
|
+
});
|
|
133
|
+
const metadata = await new HttpOrchestratorClient(orchestratorUrl).getMetadata({
|
|
134
|
+
apiKey: principal.value.apiKey,
|
|
135
|
+
integrationId: input.integrationId,
|
|
136
|
+
profileKey,
|
|
137
|
+
scopedToken,
|
|
138
|
+
});
|
|
139
|
+
const sanitized = sanitizeAgentFacingValue(metadata);
|
|
140
|
+
const search = input.search?.trim().toLowerCase();
|
|
141
|
+
const matched = metadataEntries(sanitized).filter((entry) => !search ||
|
|
142
|
+
entry.path.toLowerCase().includes(search) ||
|
|
143
|
+
String(entry.value).toLowerCase().includes(search));
|
|
144
|
+
const limit = input.limit ?? DEFAULT_LIMIT;
|
|
145
|
+
const offset = input.offset ?? 0;
|
|
146
|
+
const entries = matched.slice(offset, offset + limit);
|
|
147
|
+
const nextOffset = offset + entries.length < matched.length ? offset + entries.length : null;
|
|
148
|
+
return {
|
|
149
|
+
kind: "ok",
|
|
150
|
+
value: {
|
|
151
|
+
...(applicationId && { applicationId }),
|
|
152
|
+
entries,
|
|
153
|
+
hasMore: nextOffset !== null,
|
|
154
|
+
integrationId: integration.id,
|
|
155
|
+
integrationName,
|
|
156
|
+
nextOffset,
|
|
157
|
+
offset,
|
|
158
|
+
pluginId,
|
|
159
|
+
returnedCount: entries.length,
|
|
160
|
+
totalCount: matched.length,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
const detail = sanitizeAgentFacingText(error instanceof Error ? error.message : "Unknown metadata error").replaceAll("\u2014", "-");
|
|
166
|
+
return {
|
|
167
|
+
...(applicationId && { applicationId }),
|
|
168
|
+
kind: "error",
|
|
169
|
+
code: "integration_metadata_unavailable",
|
|
170
|
+
message: `Could not load metadata for ${label}: ${detail}`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=integration-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-metadata.js","sourceRoot":"","sources":["../../src/capabilities/integration-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EACL,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,eAAe,EACf,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,aAAa,GAAG,GAAG,CAAC;AA6B1B,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ;QAC9B,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC;QACzC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAc,EAAE,KAAa;IACpD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACrC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,eAAe,CACtB,KAAc,EACd,IAAI,GAAG,EAAE,EACT,UAA2B,EAAE;IAE7B,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,SAAS;QAC1B,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,QAAQ,EACzB,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC5C,uEAAuE;YACvE,4CAA4C;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;YAC7D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjB,eAAe,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAA0B,EAC1B,KAAkC;IAElC,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,aAAiC,CAAC;IACtC,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,KAAK,GAAG,uBAAuB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAEzD,IAAI,CAAC;QACH,0EAA0E;QAC1E,uEAAuE;QACvE,2EAA2E;QAC3E,uDAAuD;QACvD,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CACzC,OAAO,EACP,SAAS,CAAC,KAAK,EACf,KAAK,CAAC,aAAa,CACpB,CAAC;QACF,aAAa,GAAG,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAEpE,wEAAwE;QACxE,yEAAyE;QACzE,sBAAsB;QACtB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC;YACxD,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;YACvC,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;SAC/C,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC;QACvE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,eAAe,KAAK,sCAAsC;aACpE,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,uBAAuB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC/D,KAAK,GAAG,eAAe,CAAC;QAExB,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,uCAAuC,eAAe,GAAG;aACnE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,0BAA0B,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,GAAG,eAAe,SAAS,QAAQ,+CAA+C;aAC5F,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC;YAC5D,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;SAC/C,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,oBAAoB,CACrC,OAAO,CAAC,MAAM,CAAC,UAAU,EACzB,QAAQ,CACT,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC;YACvD,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;SAC/C,CAAC,CAAC;QACH,MAAM,eAAe,GAAG,uBAAuB,CAAC;YAC9C,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,UAAU;SACX,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,gBAAgB,CACvD,aAAa;YACX,CAAC,CAAC;gBACE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;gBAC9B,aAAa;gBACb,KAAK,EAAE,aAAa;aACrB;YACH,CAAC,CAAC;gBACE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;gBAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,KAAK,EAAE,oBAAoB;aAC5B,CACN,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,IAAI,sBAAsB,CAC/C,eAAe,CAChB,CAAC,WAAW,CAAC;YACZ,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,UAAU;YACV,WAAW;SACZ,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,MAAM,CAC/C,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,MAAM;YACP,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CACrD,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,aAAa,CAAC;QAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QACtD,MAAM,UAAU,GACd,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAE5E,OAAO;YACL,IAAI,EAAE,IAAI;YACV,KAAK,EAAE;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,OAAO;gBACP,OAAO,EAAE,UAAU,KAAK,IAAI;gBAC5B,aAAa,EAAE,WAAW,CAAC,EAAE;gBAC7B,eAAe;gBACf,UAAU;gBACV,MAAM;gBACN,QAAQ;gBACR,aAAa,EAAE,OAAO,CAAC,MAAM;gBAC7B,UAAU,EAAE,OAAO,CAAC,MAAM;aAC3B;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,uBAAuB,CACpC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAClE,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC5B,OAAO;YACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;YACvC,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,kCAAkC;YACxC,OAAO,EAAE,+BAA+B,KAAK,KAAK,MAAM,EAAE;SAC3D,CAAC;IACJ,CAAC;AACH,CAAC"}
|