@zackbart/connecta 0.22.3 → 0.24.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/AGENTS.md +5 -0
- package/CHANGELOG.md +82 -0
- package/README.md +19 -11
- package/dist/activity-friction.d.ts +3 -0
- package/dist/activity-friction.js +19 -0
- package/dist/activity.d.ts +11 -2
- package/dist/activity.js +15 -19
- package/dist/auth/downstream-oauth.d.ts +2 -1
- package/dist/auth/downstream-oauth.js +10 -1
- package/dist/branding.d.ts +67 -0
- package/dist/branding.js +176 -0
- package/dist/catalog-service.d.ts +1 -6
- package/dist/catalog-service.js +3 -53
- package/dist/connectors/remote-mcp.js +3 -5
- package/dist/credential-contract.d.ts +24 -0
- package/dist/credential-contract.js +1 -0
- package/dist/credential-rules.d.ts +85 -0
- package/dist/credential-rules.js +107 -0
- package/dist/credentials.d.ts +4 -100
- package/dist/credentials.js +3 -107
- package/dist/errors.d.ts +1 -1
- package/dist/execute.d.ts +5 -52
- package/dist/execute.js +40 -347
- package/dist/executors/quickjs-protocol.d.ts +0 -7
- package/dist/executors/quickjs-protocol.js +2 -10
- package/dist/executors/quickjs.js +1 -1
- package/dist/index.d.ts +23 -56
- package/dist/index.js +30 -58
- package/dist/invocation.d.ts +0 -33
- package/dist/invocation.js +56 -124
- package/dist/meta-tools.d.ts +7 -6
- package/dist/meta-tools.js +14 -21
- package/dist/module-contracts.d.ts +19 -0
- package/dist/module-contracts.js +1 -0
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/model.d.ts +6 -3
- package/dist/operator-ui/view.d.ts +2 -18
- package/dist/operator-ui/view.js +3 -20
- package/dist/registry.d.ts +4 -1
- package/dist/registry.js +8 -6
- package/dist/routes/activity.js +1 -1
- package/dist/routes/credentials.js +5 -2
- package/dist/routes/mcp.js +7 -51
- package/dist/routes/oauth-management.d.ts +2 -0
- package/dist/routes/oauth-management.js +108 -0
- package/dist/routes/oauth.d.ts +0 -1
- package/dist/routes/oauth.js +21 -121
- package/dist/routes/shared.d.ts +19 -17
- package/dist/routes/shared.js +48 -44
- package/dist/routes/ui.js +36 -33
- package/dist/server.d.ts +1 -2
- package/dist/server.js +7 -45
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +55 -19
- package/dist/types.d.ts +3 -15
- package/dist/ui.d.ts +15 -70
- package/dist/ui.js +176 -317
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/architecture.md +31 -26
- package/documentation/auth.md +65 -111
- package/documentation/call-admission.md +10 -11
- package/documentation/cloudflare.md +1 -1
- package/documentation/code-mode.md +65 -260
- package/documentation/connectors.md +8 -6
- package/documentation/linear.md +1 -1
- package/documentation/meta-tools.md +37 -18
- package/documentation/mixpanel.md +1 -1
- package/documentation/notion.md +2 -2
- package/documentation/operations.md +19 -23
- package/documentation/operator-ui.md +82 -104
- package/documentation/optional-modules-upgrade.md +243 -0
- package/documentation/provider-conventions.md +7 -5
- package/documentation/revenuecat.md +1 -1
- package/documentation/storage-and-credentials.md +59 -40
- package/documentation/stripe.md +1 -1
- package/documentation/upgrading.md +83 -8
- package/ethos.md +36 -43
- package/examples/worker/AGENTS.md +3 -1
- package/examples/worker/README.md +68 -84
- package/examples/worker/src/d1-activity.ts +1 -1
- package/examples/worker/src/index.ts +11 -6
- package/package.json +18 -2
- package/templates/node/AGENTS.md +8 -6
- package/templates/node/README.md +56 -67
- package/templates/node/package.json +1 -1
- package/templates/node/src/file-activity.ts +1 -1
- package/templates/node/src/index.ts +11 -12
- package/dist/access-tokens.d.ts +0 -31
- package/dist/access-tokens.js +0 -236
- package/dist/apps-shell.d.ts +0 -37
- package/dist/apps-shell.js +0 -174
- package/dist/routes/access-tokens.d.ts +0 -6
- package/dist/routes/access-tokens.js +0 -83
package/dist/apps-shell.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The one MCP Apps template connecta serves (`U5`, `U6`).
|
|
3
|
-
*
|
|
4
|
-
* A build-time string constant, not a file read at startup: the core is
|
|
5
|
-
* Web-API-only so it runs unchanged on Workers, and the same bytes have to
|
|
6
|
-
* serve everywhere. The shell is display-only: it renders whatever HTML a
|
|
7
|
-
* program handed `connecta.ui` inside a nested `srcdoc` frame and forwards no
|
|
8
|
-
* channel back from that frame to the host, so program-authored markup is
|
|
9
|
-
* inert beyond its own pixels.
|
|
10
|
-
*
|
|
11
|
-
* The address carries a version segment because hosts are permitted to
|
|
12
|
-
* prefetch and cache templates by URI: change these bytes, bump the version.
|
|
13
|
-
*/
|
|
14
|
-
/** The only `ui://` URI in the system. No program input reaches it. */
|
|
15
|
-
export const PROGRAM_UI_RESOURCE_URI = "ui://connecta/program-ui/v3";
|
|
16
|
-
/** The mimeType the Apps spec requires of an HTML template. */
|
|
17
|
-
export const PROGRAM_UI_MIME_TYPE = "text/html;profile=mcp-app";
|
|
18
|
-
/**
|
|
19
|
-
* The result `_meta` key carrying the payload (`U3`). A plain single-label
|
|
20
|
-
* prefix rather than the reverse-DNS form MCP's SHOULD prefers: connecta has
|
|
21
|
-
* no domain to reverse, and fabricating one to satisfy a SHOULD is a worse
|
|
22
|
-
* answer than the shape the key format's MUST already permits.
|
|
23
|
-
*/
|
|
24
|
-
export const PROGRAM_UI_META_KEY = "connecta/ui";
|
|
25
|
-
/** The one extension identifier connecta advertises (`U11`). */
|
|
26
|
-
export const MCP_APPS_EXTENSION = "io.modelcontextprotocol/ui";
|
|
27
|
-
/**
|
|
28
|
-
* The shell document. Dependency-free and deliberately small: it speaks the
|
|
29
|
-
* Apps postMessage dialect (`ui/initialize`, `ui/notifications/initialized`,
|
|
30
|
-
* `ui/notifications/tool-result`, `ui/notifications/size-changed`,
|
|
31
|
-
* `ui/resource-teardown`), lifts `_meta["connecta/ui"].html` out of the
|
|
32
|
-
* delivered tool result, and puts it in a frame. It declares no CSP domains,
|
|
33
|
-
* so the host applies its restrictive default and the `srcdoc` frame inherits
|
|
34
|
-
* `default-src 'none'`. The payload gets scripts and local interactivity, and
|
|
35
|
-
* no network.
|
|
36
|
-
*/
|
|
37
|
-
export const PROGRAM_UI_SHELL_HTML = `<!doctype html>
|
|
38
|
-
<html lang="en">
|
|
39
|
-
<head>
|
|
40
|
-
<meta charset="utf-8" />
|
|
41
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
42
|
-
<title>connecta program view</title>
|
|
43
|
-
<style>
|
|
44
|
-
html,
|
|
45
|
-
body {
|
|
46
|
-
margin: 0;
|
|
47
|
-
padding: 0;
|
|
48
|
-
background: transparent;
|
|
49
|
-
}
|
|
50
|
-
#program-view {
|
|
51
|
-
display: block;
|
|
52
|
-
width: 100%;
|
|
53
|
-
min-height: 480px;
|
|
54
|
-
border: 0;
|
|
55
|
-
}
|
|
56
|
-
</style>
|
|
57
|
-
</head>
|
|
58
|
-
<body>
|
|
59
|
-
<iframe
|
|
60
|
-
id="program-view"
|
|
61
|
-
title="Program-rendered view"
|
|
62
|
-
sandbox="allow-scripts"
|
|
63
|
-
srcdoc=""
|
|
64
|
-
></iframe>
|
|
65
|
-
<script>
|
|
66
|
-
(function () {
|
|
67
|
-
"use strict";
|
|
68
|
-
// The host frame is the only peer this shell speaks to, in either
|
|
69
|
-
// direction. The payload frame below is sandboxed to scripts alone,
|
|
70
|
-
// with no same-origin escape, and is never handed a reply path:
|
|
71
|
-
// anything it posts fails the source check and is dropped. There is
|
|
72
|
-
// no bridge from program HTML to the host, by construction rather
|
|
73
|
-
// than by validation.
|
|
74
|
-
var host = window.parent;
|
|
75
|
-
var view = document.getElementById("program-view");
|
|
76
|
-
var initializeId = "connecta-ui-initialize";
|
|
77
|
-
var lastWidth = 0;
|
|
78
|
-
var lastHeight = 0;
|
|
79
|
-
|
|
80
|
-
function send(message) {
|
|
81
|
-
if (!host || host === window) return;
|
|
82
|
-
host.postMessage(message, "*");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function notify(method, params) {
|
|
86
|
-
send({ jsonrpc: "2.0", method: method, params: params });
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Program views are fixed-height by construction. The shell has no
|
|
90
|
-
// bridge to the payload frame — that is the security posture, not an
|
|
91
|
-
// omission — so it can never learn the payload's content height, and
|
|
92
|
-
// what it reports here is its own box: the min-height above, unless
|
|
93
|
-
// the host has given it more. Taller content scrolls inside the inner
|
|
94
|
-
// frame rather than growing the view. Raising the min-height is the
|
|
95
|
-
// only lever; a content-height signal would cost the isolation.
|
|
96
|
-
function reportSize() {
|
|
97
|
-
var width = Math.ceil(document.documentElement.clientWidth);
|
|
98
|
-
var height = Math.ceil(document.documentElement.scrollHeight);
|
|
99
|
-
if (width === lastWidth && height === lastHeight) return;
|
|
100
|
-
lastWidth = width;
|
|
101
|
-
lastHeight = height;
|
|
102
|
-
notify("ui/notifications/size-changed", {
|
|
103
|
-
width: width,
|
|
104
|
-
height: height
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function payloadHtml(result) {
|
|
109
|
-
if (!result || typeof result !== "object") return null;
|
|
110
|
-
var meta = result._meta;
|
|
111
|
-
if (!meta || typeof meta !== "object") return null;
|
|
112
|
-
var payload = meta["connecta/ui"];
|
|
113
|
-
if (!payload || typeof payload !== "object") return null;
|
|
114
|
-
var html = payload.html;
|
|
115
|
-
return typeof html === "string" && html.length > 0 ? html : null;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function render(params) {
|
|
119
|
-
var html =
|
|
120
|
-
payloadHtml(params) ||
|
|
121
|
-
payloadHtml(params && params.result) ||
|
|
122
|
-
payloadHtml(params && params.toolResult);
|
|
123
|
-
if (html === null) return;
|
|
124
|
-
view.srcdoc = html;
|
|
125
|
-
reportSize();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
window.addEventListener("message", function (event) {
|
|
129
|
-
if (event.source !== host) return;
|
|
130
|
-
var message = event.data;
|
|
131
|
-
if (!message || message.jsonrpc !== "2.0") return;
|
|
132
|
-
if (message.method === "ui/notifications/tool-result") {
|
|
133
|
-
render(message.params);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
if (message.method === "ui/resource-teardown") {
|
|
137
|
-
// A host->view request, not a notification: the host waits for
|
|
138
|
-
// this reply before it tears the view down. There is nothing to
|
|
139
|
-
// release, so answer immediately rather than make it time out.
|
|
140
|
-
if (message.id !== undefined && message.id !== null) {
|
|
141
|
-
send({ jsonrpc: "2.0", id: message.id, result: {} });
|
|
142
|
-
}
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
// Only a completed handshake earns "initialized". A JSON-RPC error
|
|
146
|
-
// response carries the same id, and announcing initialization on one
|
|
147
|
-
// would assert a handshake that never happened.
|
|
148
|
-
if (message.id === initializeId && message.result !== undefined) {
|
|
149
|
-
notify("ui/notifications/initialized", {});
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
window.addEventListener("resize", reportSize);
|
|
154
|
-
view.addEventListener("load", reportSize);
|
|
155
|
-
|
|
156
|
-
// Every field here is required by the Apps initialize schema, and a
|
|
157
|
-
// conforming host rejects the request outright when one is missing —
|
|
158
|
-
// which would strand the shell before any tool result arrives.
|
|
159
|
-
send({
|
|
160
|
-
jsonrpc: "2.0",
|
|
161
|
-
id: initializeId,
|
|
162
|
-
method: "ui/initialize",
|
|
163
|
-
params: {
|
|
164
|
-
appInfo: { name: "connecta program view", version: "1" },
|
|
165
|
-
appCapabilities: {},
|
|
166
|
-
protocolVersion: "2026-01-26"
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
reportSize();
|
|
170
|
-
})();
|
|
171
|
-
</script>
|
|
172
|
-
</body>
|
|
173
|
-
</html>
|
|
174
|
-
`;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type RouteContext } from "./shared.js";
|
|
2
|
-
/**
|
|
3
|
-
* Interactive-operator lifecycle for deployment access tokens. The token itself
|
|
4
|
-
* is deliberately never an administrator credential and cannot reach here.
|
|
5
|
-
*/
|
|
6
|
-
export declare function routeAccessTokens(context: RouteContext): Promise<Response | null>;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { authorizeUiAdmin, isSameOrigin, msg, privateJson, } from "./shared.js";
|
|
2
|
-
async function readName(request) {
|
|
3
|
-
if (!request.headers
|
|
4
|
-
.get("content-type")
|
|
5
|
-
?.toLowerCase()
|
|
6
|
-
.startsWith("application/json")) {
|
|
7
|
-
return {
|
|
8
|
-
ok: false,
|
|
9
|
-
response: privateJson({ error: "Content-Type must be application/json" }, { status: 415 }),
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
const raw = await request.text();
|
|
13
|
-
if (raw.length > 1_000) {
|
|
14
|
-
return {
|
|
15
|
-
ok: false,
|
|
16
|
-
response: privateJson({ error: "request body is too large" }, { status: 413 }),
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
try {
|
|
20
|
-
const body = JSON.parse(raw);
|
|
21
|
-
return { ok: true, name: body.name };
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return {
|
|
25
|
-
ok: false,
|
|
26
|
-
response: privateJson({ error: "invalid JSON body" }, { status: 400 }),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Interactive-operator lifecycle for deployment access tokens. The token itself
|
|
32
|
-
* is deliberately never an administrator credential and cannot reach here.
|
|
33
|
-
*/
|
|
34
|
-
export async function routeAccessTokens(context) {
|
|
35
|
-
const match = /^\/ui\/access-tokens(?:\/([0-9a-f-]{36}))?$/.exec(context.path);
|
|
36
|
-
if (!match)
|
|
37
|
-
return null;
|
|
38
|
-
const { request, baseUrl, opts } = context;
|
|
39
|
-
if (request.method === "OPTIONS") {
|
|
40
|
-
return privateJson({ error: "CORS is not allowed" }, { status: 403 });
|
|
41
|
-
}
|
|
42
|
-
if (!opts.accessTokens) {
|
|
43
|
-
return privateJson({ error: "access token management is not configured" }, { status: 404 });
|
|
44
|
-
}
|
|
45
|
-
const mutating = request.method !== "GET";
|
|
46
|
-
if (mutating && !isSameOrigin(request, baseUrl)) {
|
|
47
|
-
return privateJson({ error: "same-origin request required" }, { status: 403 });
|
|
48
|
-
}
|
|
49
|
-
const admin = await authorizeUiAdmin(request, baseUrl, opts.auth, "access token management", context.runtimeContext, opts.identity);
|
|
50
|
-
if (!admin.ok)
|
|
51
|
-
return admin.response;
|
|
52
|
-
const id = match[1];
|
|
53
|
-
try {
|
|
54
|
-
if (!id && request.method === "GET") {
|
|
55
|
-
return privateJson({ accessTokens: await opts.accessTokens.list() });
|
|
56
|
-
}
|
|
57
|
-
if (!id && request.method === "POST") {
|
|
58
|
-
const input = await readName(request);
|
|
59
|
-
if (!input.ok)
|
|
60
|
-
return input.response;
|
|
61
|
-
return privateJson(await opts.accessTokens.create(input.name, admin.principal ?? admin.userId), { status: 201 });
|
|
62
|
-
}
|
|
63
|
-
if (id && request.method === "PUT") {
|
|
64
|
-
const input = await readName(request);
|
|
65
|
-
if (!input.ok)
|
|
66
|
-
return input.response;
|
|
67
|
-
const accessToken = await opts.accessTokens.rename(id, input.name);
|
|
68
|
-
return accessToken
|
|
69
|
-
? privateJson({ accessToken })
|
|
70
|
-
: privateJson({ error: "unknown access token" }, { status: 404 });
|
|
71
|
-
}
|
|
72
|
-
if (id && request.method === "DELETE") {
|
|
73
|
-
const accessToken = await opts.accessTokens.revoke(id, admin.userId);
|
|
74
|
-
return accessToken
|
|
75
|
-
? privateJson({ accessToken })
|
|
76
|
-
: privateJson({ error: "unknown access token" }, { status: 404 });
|
|
77
|
-
}
|
|
78
|
-
return privateJson({ error: "method not allowed" }, { status: 405 });
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
return privateJson({ error: msg(error) }, { status: 400 });
|
|
82
|
-
}
|
|
83
|
-
}
|