@zackbart/connecta 0.11.0 → 0.12.1
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/CHANGELOG.md +84 -0
- package/dist/apps-shell.d.ts +38 -0
- package/dist/apps-shell.d.ts.map +1 -0
- package/dist/apps-shell.js +175 -0
- package/dist/apps-shell.js.map +1 -0
- package/dist/execute.d.ts +36 -5
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +139 -23
- package/dist/execute.js.map +1 -1
- package/dist/executor-admission.d.ts +8 -0
- package/dist/executor-admission.d.ts.map +1 -1
- package/dist/executor-admission.js +11 -0
- package/dist/executor-admission.js.map +1 -1
- package/dist/executors/quickjs.d.ts.map +1 -1
- package/dist/executors/quickjs.js +2 -2
- package/dist/executors/quickjs.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +48 -0
- package/dist/routes/mcp.js.map +1 -1
- package/dist/skills.d.ts +1 -1
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +17 -13
- package/dist/skills.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/code-mode.md +121 -7
- package/documentation/mcp-2026-07-28.md +1 -1
- package/documentation/mcp-ui-design.md +382 -0
- package/ethos.md +8 -2
- package/package.json +1 -1
- package/src/apps-shell.ts +179 -0
- package/src/execute.ts +152 -22
- package/src/executor-admission.ts +12 -0
- package/src/executors/quickjs.ts +2 -1
- package/src/routes/mcp.ts +60 -0
- package/src/skills.ts +17 -13
- package/src/version.ts +1 -1
- package/templates/node/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,90 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this package are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.12.1 — 2026-08-01
|
|
6
|
+
|
|
7
|
+
Instructions, not behavior. Calling-side feedback and a first-hand run of the
|
|
8
|
+
render loop found the same gap twice: a program that renders a view has to guess
|
|
9
|
+
at shapes the text never showed it. Guessing `{ result }` for a batch entry
|
|
10
|
+
fails silently through optional chaining — the run succeeds, the view renders,
|
|
11
|
+
and it is confidently empty — so the entry envelope now rides the
|
|
12
|
+
`connecta.call`/`connecta.batch` capabilities bullet rather than prose three
|
|
13
|
+
paragraphs down. The `connecta.ui` bullet and a new `U12` state the other half:
|
|
14
|
+
the model reads the return value, not the view, so a program that renders one
|
|
15
|
+
also returns the summary built from the same variables the view renders. No
|
|
16
|
+
runtime path changed. The only deltas a deployment ships are the served
|
|
17
|
+
`execute_code` description, the served usage skill, and the docs — upgrade and
|
|
18
|
+
its agents simply read better instructions. Nothing breaks, and a deployment
|
|
19
|
+
whose agents never render a view can ignore all of it; for the ones that do,
|
|
20
|
+
the new text is the entire release (#282, PR #284).
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **The batch entry envelope is stated where it is read.**
|
|
25
|
+
`execute_code`'s `connecta.call`/`connecta.batch` bullet now carries
|
|
26
|
+
`{ address, ok: true, data }` / `{ address, ok: false, error, errorDetails }`
|
|
27
|
+
and says to destructure that, not a bare result. Hosts truncate long
|
|
28
|
+
descriptions, so the bullets are a fixed budget: the text moved weight
|
|
29
|
+
forward instead of adding it and came out net shorter, now under a
|
|
30
|
+
4,400-character ceiling test.
|
|
31
|
+
- **The return value is what the model reads.** The `connecta.ui` bullet and
|
|
32
|
+
the new normative `U12` in `documentation/code-mode.md` bind program authors
|
|
33
|
+
to returning the summary built from the same variables the view renders — a
|
|
34
|
+
view the return value does not mirror is a view nobody in the loop can check.
|
|
35
|
+
Connecta enforces nothing here; it never reads the HTML or diffs it against
|
|
36
|
+
the return, because a heuristic there would be the host-side projection the
|
|
37
|
+
ethos already refuses.
|
|
38
|
+
- **The usage skill has a guarded-render recipe.** A "Rendering a view" section
|
|
39
|
+
says to fetch first and check the shape in code, and on a surprise — empty
|
|
40
|
+
array, missing key — to return a trimmed first record instead of rendering.
|
|
41
|
+
The wrong view becomes the sample you needed.
|
|
42
|
+
- **Result sampling on the catalog surface is refused.** The `ethos.md`
|
|
43
|
+
decisions table records `sample` / `dryRun` as refused: sampling is execution
|
|
44
|
+
and cannot ride a catalog read, most tools carry required arguments no
|
|
45
|
+
sampler can invent, and a program that checks the shape before rendering
|
|
46
|
+
already hands back the first record inside the run it was going to make
|
|
47
|
+
anyway, at zero new surface.
|
|
48
|
+
|
|
49
|
+
## 0.12.0 — 2026-08-01
|
|
50
|
+
|
|
51
|
+
Programs gained a *view*. `execute_code` code can now call `connecta.ui(html)`
|
|
52
|
+
to hand the client one rendered MCP Apps view of the run — the thing
|
|
53
|
+
`connecta.emit` could not do, which is give a human something to look at while
|
|
54
|
+
the model keeps its cheap textual summary. Programs supply HTML content and
|
|
55
|
+
nothing else: the only `ui://` URI in the system is connecta's build-time shell,
|
|
56
|
+
so nothing a client could dereference is derived from anything a program said,
|
|
57
|
+
and the shell forwards no channel from the program's markup back to the host.
|
|
58
|
+
The channel is additive — a program that never calls `connecta.ui` produces the
|
|
59
|
+
byte-for-byte prior response, no executor changed to carry it, and there is no
|
|
60
|
+
new budget knob. Deployments do gain a `resources` capability and one extension
|
|
61
|
+
declaration, both of which the design requires before any host will render.
|
|
62
|
+
The design record is `documentation/mcp-ui-design.md` (#266); the contract is
|
|
63
|
+
`code-mode.md`'s "Rendered output" clauses (#277).
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- **`connecta.ui(html)` inside `execute_code`.** One non-empty HTML string, at
|
|
68
|
+
most one payload per run, delivered on success only in the tool result's
|
|
69
|
+
`_meta["connecta/ui"]` with `ui: true` on the JSON envelope. A failed program
|
|
70
|
+
discards it visibly (`uiDiscarded: true`), alongside `emittedDiscarded` when
|
|
71
|
+
one failure loses both. The payload spends the existing
|
|
72
|
+
`execute.maxEmittedBytes` aggregate, no block count, and no host calls.
|
|
73
|
+
- **The MCP Apps shell.** A static connecta-authored HTML5 template at
|
|
74
|
+
`ui://connecta/program-ui/v1` (`text/html;profile=mcp-app`), served by a
|
|
75
|
+
`resources/read` handler that answers exactly that URI; `resources/list` is
|
|
76
|
+
served and returns an empty list. `execute_code` declares it through
|
|
77
|
+
`_meta.ui.resourceUri` with `_meta.ui.visibility: ["model"]`, and the server
|
|
78
|
+
declares the `io.modelcontextprotocol/ui` extension — the one extension
|
|
79
|
+
connecta advertises, without which no host renders anything.
|
|
80
|
+
- **`diagnostics.ui`.** With `diagnostics: true`, the accepted payload's
|
|
81
|
+
serialized byte size, distinct from the `emitted` aggregate.
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
|
|
85
|
+
- **Visible output discarded during QuickJS shutdown.** Closing the executor
|
|
86
|
+
after a program starts now reports accepted blocks and UI as discarded on
|
|
87
|
+
both error paths; admission failures before execution remain unchanged. (#279)
|
|
88
|
+
|
|
5
89
|
## 0.11.0 — 2026-07-31
|
|
6
90
|
|
|
7
91
|
**This is a breaking deployment release.** Connecta no longer carries the old
|
|
@@ -0,0 +1,38 @@
|
|
|
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 `v1`.
|
|
13
|
+
*/
|
|
14
|
+
/** The only `ui://` URI in the system. No program input reaches it. */
|
|
15
|
+
export declare const PROGRAM_UI_RESOURCE_URI = "ui://connecta/program-ui/v1";
|
|
16
|
+
/** The mimeType the Apps spec requires of an HTML template. */
|
|
17
|
+
export declare 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 declare const PROGRAM_UI_META_KEY = "connecta/ui";
|
|
25
|
+
/** The one extension identifier connecta advertises (`U11`). */
|
|
26
|
+
export declare 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,
|
|
35
|
+
* and no network.
|
|
36
|
+
*/
|
|
37
|
+
export declare const PROGRAM_UI_SHELL_HTML = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>connecta program view</title>\n <style>\n html,\n body {\n margin: 0;\n padding: 0;\n background: transparent;\n }\n #program-view {\n display: block;\n width: 100%;\n min-height: 480px;\n border: 0;\n }\n </style>\n </head>\n <body>\n <iframe\n id=\"program-view\"\n title=\"Program-rendered view\"\n sandbox=\"allow-scripts\"\n srcdoc=\"\"\n ></iframe>\n <script>\n (function () {\n \"use strict\";\n // The host frame is the only peer this shell speaks to, in either\n // direction. The payload frame below is sandboxed to scripts alone,\n // with no same-origin escape, and is never handed a reply path:\n // anything it posts fails the source check and is dropped. There is\n // no bridge from program HTML to the host, by construction rather\n // than by validation.\n var host = window.parent;\n var view = document.getElementById(\"program-view\");\n var initializeId = \"connecta-ui-initialize\";\n var lastWidth = 0;\n var lastHeight = 0;\n\n function send(message) {\n if (!host || host === window) return;\n host.postMessage(message, \"*\");\n }\n\n function notify(method, params) {\n send({ jsonrpc: \"2.0\", method: method, params: params });\n }\n\n // Program views are fixed-height by construction. The shell has no\n // bridge to the payload frame \u2014 that is the security posture, not an\n // omission \u2014 so it can never learn the payload's content height, and\n // what it reports here is its own box: the min-height above, unless\n // the host has given it more. Taller content scrolls inside the inner\n // frame rather than growing the view. Raising the min-height is the\n // only lever; a content-height signal would cost the isolation.\n function reportSize() {\n var width = Math.ceil(document.documentElement.clientWidth);\n var height = Math.ceil(document.documentElement.scrollHeight);\n if (width === lastWidth && height === lastHeight) return;\n lastWidth = width;\n lastHeight = height;\n notify(\"ui/notifications/size-changed\", {\n width: width,\n height: height\n });\n }\n\n function payloadHtml(result) {\n if (!result || typeof result !== \"object\") return null;\n var meta = result._meta;\n if (!meta || typeof meta !== \"object\") return null;\n var payload = meta[\"connecta/ui\"];\n if (!payload || typeof payload !== \"object\") return null;\n var html = payload.html;\n return typeof html === \"string\" && html.length > 0 ? html : null;\n }\n\n function render(params) {\n var html =\n payloadHtml(params) ||\n payloadHtml(params && params.result) ||\n payloadHtml(params && params.toolResult);\n if (html === null) return;\n view.srcdoc = html;\n reportSize();\n }\n\n window.addEventListener(\"message\", function (event) {\n if (event.source !== host) return;\n var message = event.data;\n if (!message || message.jsonrpc !== \"2.0\") return;\n if (message.method === \"ui/notifications/tool-result\") {\n render(message.params);\n return;\n }\n if (message.method === \"ui/resource-teardown\") {\n // A host->view request, not a notification: the host waits for\n // this reply before it tears the view down. There is nothing to\n // release, so answer immediately rather than make it time out.\n if (message.id !== undefined && message.id !== null) {\n send({ jsonrpc: \"2.0\", id: message.id, result: {} });\n }\n return;\n }\n // Only a completed handshake earns \"initialized\". A JSON-RPC error\n // response carries the same id, and announcing initialization on one\n // would assert a handshake that never happened.\n if (message.id === initializeId && message.result !== undefined) {\n notify(\"ui/notifications/initialized\", {});\n }\n });\n\n window.addEventListener(\"resize\", reportSize);\n view.addEventListener(\"load\", reportSize);\n\n // Every field here is required by the Apps initialize schema, and a\n // conforming host rejects the request outright when one is missing \u2014\n // which would strand the shell before any tool result arrives.\n send({\n jsonrpc: \"2.0\",\n id: initializeId,\n method: \"ui/initialize\",\n params: {\n appInfo: { name: \"connecta program view\", version: \"1\" },\n appCapabilities: {},\n protocolVersion: \"2026-01-26\"\n }\n });\n reportSize();\n })();\n </script>\n </body>\n</html>\n";
|
|
38
|
+
//# sourceMappingURL=apps-shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps-shell.d.ts","sourceRoot":"","sources":["../src/apps-shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AAErE,+DAA+D;AAC/D,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,gEAAgE;AAChE,eAAO,MAAM,kBAAkB,+BAA+B,CAAC;AAE/D;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,ssKAyIjC,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
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 `v1`.
|
|
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/v1";
|
|
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,
|
|
35
|
+
* and 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
|
+
`;
|
|
175
|
+
//# sourceMappingURL=apps-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps-shell.js","sourceRoot":"","sources":["../src/apps-shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uEAAuE;AACvE,MAAM,CAAC,MAAM,uBAAuB,GAAG,6BAA6B,CAAC;AAErE,+DAA+D;AAC/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEjD,gEAAgE;AAChE,MAAM,CAAC,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AAE/D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyIpC,CAAC"}
|
package/dist/execute.d.ts
CHANGED
|
@@ -32,9 +32,16 @@ declare class ExecuteDiagnostics {
|
|
|
32
32
|
setupMs: number;
|
|
33
33
|
executorWallMs: number;
|
|
34
34
|
private emitted?;
|
|
35
|
+
private ui?;
|
|
35
36
|
/** Numbers only, per R8 — and only once something was emitted, so a
|
|
36
37
|
* non-emitting run's diagnostics stay byte-for-byte what they were. */
|
|
37
38
|
recordEmitted(count: number, bytes: number): void;
|
|
39
|
+
/**
|
|
40
|
+
* U9: the UI payload gets its own aggregate — one number, the payload's
|
|
41
|
+
* serialized size. Folding it into `emitted` would desync that aggregate's
|
|
42
|
+
* pair, which reports the bytes a specific block count cost.
|
|
43
|
+
*/
|
|
44
|
+
recordUi(bytes: number): void;
|
|
38
45
|
private stats;
|
|
39
46
|
recordCatalog(operation: "search" | "describe", durationMs: number, ok: boolean, result?: unknown): void;
|
|
40
47
|
recordCall(operation: "call" | "batch", outcome: {
|
|
@@ -61,6 +68,7 @@ declare class ExecuteDiagnostics {
|
|
|
61
68
|
count: number;
|
|
62
69
|
bytes: number;
|
|
63
70
|
};
|
|
71
|
+
ui?: number;
|
|
64
72
|
};
|
|
65
73
|
}
|
|
66
74
|
/**
|
|
@@ -81,20 +89,43 @@ export type EmittedBlock = {
|
|
|
81
89
|
mimeType: string;
|
|
82
90
|
};
|
|
83
91
|
/**
|
|
84
|
-
* Request-local collection for `connecta.emit`. Budgets fail
|
|
85
|
-
* crossing call —
|
|
86
|
-
* unaffected — so a program learns it is over budget while it can still
|
|
87
|
-
* choose differently (M5). Accepted
|
|
88
|
-
* handler that owns this collector
|
|
92
|
+
* Request-local collection for `connecta.emit` and `connecta.ui`. Budgets fail
|
|
93
|
+
* loudly at the crossing call — nothing is partially accepted and prior blocks
|
|
94
|
+
* are unaffected — so a program learns it is over budget while it can still
|
|
95
|
+
* choose differently (M5, U4). Accepted output never rides `ExecuteResult`; the
|
|
96
|
+
* handler that owns this collector delivers it on the final tool result.
|
|
97
|
+
*
|
|
98
|
+
* The two channels share the byte aggregate and nothing else: a UI payload is
|
|
99
|
+
* not a block, so it spends no block count, and at most one is ever accepted.
|
|
89
100
|
*/
|
|
90
101
|
export declare class EmitCollector {
|
|
91
102
|
private readonly maxBytes;
|
|
92
103
|
private readonly maxBlocks;
|
|
93
104
|
private readonly diagnostics?;
|
|
94
105
|
readonly blocks: EmittedBlock[];
|
|
106
|
+
/** The shared transport aggregate: emitted blocks plus the UI payload. */
|
|
95
107
|
bytes: number;
|
|
108
|
+
/** The one accepted UI payload (U2), delivered in result `_meta` on success. */
|
|
109
|
+
ui?: {
|
|
110
|
+
html: string;
|
|
111
|
+
};
|
|
112
|
+
/** What the blocks alone cost, so the `emitted` aggregate stays a true pair. */
|
|
113
|
+
private blockBytes;
|
|
96
114
|
constructor(maxBytes: number, maxBlocks: number, diagnostics?: ExecuteDiagnostics | undefined);
|
|
97
115
|
accept(raw: unknown): void;
|
|
116
|
+
/**
|
|
117
|
+
* U2 and U4: one payload per run, measured as the serialized bytes of
|
|
118
|
+
* `{ html }` against the same aggregate emit spends. A second call throws
|
|
119
|
+
* naming the constraint rather than replacing the first — one tool result
|
|
120
|
+
* renders one view, and last-wins would silently discard a payload the
|
|
121
|
+
* program deliberately supplied.
|
|
122
|
+
*
|
|
123
|
+
* Multiplicity is checked before shape, so the second call is told what it
|
|
124
|
+
* actually broke. A program whose second payload is also malformed has one
|
|
125
|
+
* problem worth naming — that there is a second payload at all — and a
|
|
126
|
+
* complaint about its type would send the author to fix the wrong thing.
|
|
127
|
+
*/
|
|
128
|
+
acceptUi(raw: unknown): void;
|
|
98
129
|
}
|
|
99
130
|
/** Convert a connector/tool name into a valid JS identifier. */
|
|
100
131
|
export declare function sanitizeIdentifier(name: string): string;
|
package/dist/execute.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"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"}
|