@elicitkit/renderers 0.1.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/dist/tui.js ADDED
@@ -0,0 +1,89 @@
1
+ /**
2
+ * `tui` tier — the universal sink the spec guarantees for every type
3
+ * (SPEC §4/§7). When no UI surface exists the agent reads this back and
4
+ * collects answers in conversation, then calls `elicit_submit`. Never
5
+ * hard-fails; this is why every type must define a text degradation.
6
+ */
7
+ export function renderTui(set, token) {
8
+ const lines = [
9
+ "Elicitkit needs input. Answer each item, then call",
10
+ `elicit_submit with token "${token}" and an answers array.`,
11
+ "",
12
+ ];
13
+ set.asks.forEach((ask, i) => {
14
+ lines.push(`[${i + 1}] (${ask.type}) ${ask.prompt}`);
15
+ if (ask.help)
16
+ lines.push(` ${ask.help}`);
17
+ lines.push(...detail(ask).map((l) => ` ${l}`));
18
+ lines.push(` -> answer: { "id": "${ask.id}", "type": "${ask.type}", "status": "answered", "value": ... }`);
19
+ lines.push("");
20
+ });
21
+ return { tier: "tui", text: lines.join("\n") };
22
+ }
23
+ function detail(ask) {
24
+ switch (ask.type) {
25
+ case "ask_text":
26
+ return [`free text${ask.spec.multiline ? " (multiline)" : ""}`];
27
+ case "ask_confirm":
28
+ return [
29
+ `${ask.spec.affirm ?? "Yes"} / ${ask.spec.deny ?? "No"}` +
30
+ (ask.spec.consequence ? ` - consequence: ${ask.spec.consequence}` : ""),
31
+ `value: boolean`,
32
+ ];
33
+ case "ask_select":
34
+ return [
35
+ ...ask.spec.options.map((o) => `- ${o.id}: ${o.label}${o.description ? ` - ${o.description}` : ""}`),
36
+ `value: ${ask.spec.multiple ? "string[] of ids" : "one id"}`,
37
+ ];
38
+ case "ask_code_diff":
39
+ return [
40
+ ...ask.spec.files.flatMap((f) => [
41
+ `file ${f.path}`,
42
+ ...f.hunks.map((h) => ` hunk ${h.id}${h.header ? `: ${h.header}` : ""}`),
43
+ ]),
44
+ `value: { "accepted": [hunkId...], "rejected": [hunkId...] }`,
45
+ ];
46
+ case "ask_number": {
47
+ const s = ask.spec ?? {};
48
+ const r = [
49
+ s.min != null ? `min ${s.min}` : null,
50
+ s.max != null ? `max ${s.max}` : null,
51
+ s.step != null ? `step ${s.step}` : null,
52
+ s.unit ? `unit ${s.unit}` : null,
53
+ s.integer ? "integer" : null,
54
+ ].filter(Boolean);
55
+ return [`number${r.length ? ` (${r.join(", ")})` : ""}`, `value: number`];
56
+ }
57
+ case "ask_slider":
58
+ return [
59
+ `slider ${ask.spec.min}..${ask.spec.max}${ask.spec.step ? ` step ${ask.spec.step}` : ""}${ask.spec.unit ? ` ${ask.spec.unit}` : ""}`,
60
+ `value: number in [${ask.spec.min}, ${ask.spec.max}]`,
61
+ ];
62
+ case "ask_rating": {
63
+ const max = ask.spec?.max ?? 5;
64
+ return [`rate 1..${max}`, `value: integer in [1, ${max}]`];
65
+ }
66
+ case "ask_date":
67
+ return [
68
+ ask.spec?.time ? "date + time" : "date",
69
+ `value: "${ask.spec?.time ? "YYYY-MM-DDTHH:MM" : "YYYY-MM-DD"}"`,
70
+ ];
71
+ case "ask_rank":
72
+ return [
73
+ ...ask.spec.items.map((i) => `- ${i.id}: ${i.label}`),
74
+ `value: [${ask.spec.items.map((i) => `"${i.id}"`).join(", ")}] in ranked order`,
75
+ ];
76
+ case "ask_color": {
77
+ const pal = ask.spec?.palette ?? [];
78
+ return [
79
+ pal.length
80
+ ? `palette: ${pal.join(", ")}${ask.spec?.allowCustom ? " (or a custom color)" : ""}`
81
+ : "any CSS color",
82
+ `value: a CSS color string (e.g. "#1d4ed8")`,
83
+ ];
84
+ }
85
+ default:
86
+ return [];
87
+ }
88
+ }
89
+ //# sourceMappingURL=tui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui.js","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
package/dist/url.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import type { AskSet } from "@elicitkit/core";
2
+ import type { RenderedPanel } from "./contract.js";
3
+ /**
4
+ * `url` tier — for hosts that open an external page rather than embed UI. It
5
+ * is the *same* panel as `apps`, delivered as an `externalUrl` the host loads
6
+ * in an iframe/browser; answers post back via the same mcp-ui `tool` message.
7
+ *
8
+ * Return channel: the page yields a copy-pasteable JSON payload the user
9
+ * hands back to the assistant (which forwards it verbatim to `elicit_submit`).
10
+ * It also attempts the mcp-ui `tool` postMessage, so it is *automatic* when a
11
+ * host embeds it and *still works* when opened standalone in a browser — no
12
+ * server or signed link required for v0.1.
13
+ *
14
+ * v0.1: the page is self-contained in a `data:` URL. Task #6 may add a hosted
15
+ * route and Task #7 a signed one-time link, but the copy-paste channel keeps
16
+ * this tier fully functional in the meantime — a contained change behind this
17
+ * one function.
18
+ */
19
+ export declare function renderUrl(set: AskSet, token: string): Promise<RenderedPanel>;
20
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAwBlF"}
package/dist/url.js ADDED
@@ -0,0 +1,40 @@
1
+ import { createUIResource } from "@mcp-ui/server";
2
+ import { buildPanelHtml } from "./panel.js";
3
+ /**
4
+ * `url` tier — for hosts that open an external page rather than embed UI. It
5
+ * is the *same* panel as `apps`, delivered as an `externalUrl` the host loads
6
+ * in an iframe/browser; answers post back via the same mcp-ui `tool` message.
7
+ *
8
+ * Return channel: the page yields a copy-pasteable JSON payload the user
9
+ * hands back to the assistant (which forwards it verbatim to `elicit_submit`).
10
+ * It also attempts the mcp-ui `tool` postMessage, so it is *automatic* when a
11
+ * host embeds it and *still works* when opened standalone in a browser — no
12
+ * server or signed link required for v0.1.
13
+ *
14
+ * v0.1: the page is self-contained in a `data:` URL. Task #6 may add a hosted
15
+ * route and Task #7 a signed one-time link, but the copy-paste channel keeps
16
+ * this tier fully functional in the meantime — a contained change behind this
17
+ * one function.
18
+ */
19
+ export async function renderUrl(set, token) {
20
+ const html = buildPanelHtml(set, token, "url");
21
+ const dataUrl = "data:text/html;base64," + Buffer.from(html, "utf8").toString("base64");
22
+ const ui = await createUIResource({
23
+ uri: `ui://elicitkit/round/${token}`,
24
+ encoding: "text",
25
+ content: { type: "externalUrl", iframeUrl: dataUrl },
26
+ metadata: { title: "Elicitkit", description: `${set.asks.length} question(s)` },
27
+ uiMetadata: {
28
+ "preferred-frame-size": ["720px", "640px"],
29
+ "initial-render-data": { token },
30
+ },
31
+ });
32
+ return {
33
+ tier: "url",
34
+ text: "Ask the user to open the linked panel and answer it. They will paste " +
35
+ "back a JSON payload — forward it verbatim to elicit_submit (it carries " +
36
+ "the round token). If the host embeds the panel, submission is automatic.",
37
+ ui,
38
+ };
39
+ }
40
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,KAAa;IACxD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/C,MAAM,OAAO,GACX,wBAAwB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE1E,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC;QAChC,GAAG,EAAE,wBAAwB,KAAK,EAAE;QACpC,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE;QACpD,QAAQ,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,cAAc,EAAE;QAC/E,UAAU,EAAE;YACV,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;YAC1C,qBAAqB,EAAE,EAAE,KAAK,EAAE;SACjC;KACF,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,KAAK;QACX,IAAI,EACF,uEAAuE;YACvE,yEAAyE;YACzE,0EAA0E;QAC5E,EAAE;KACH,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@elicitkit/renderers",
3
+ "version": "0.1.0",
4
+ "description": "Elicitkit progressive renderers — one AskSet, four tiers (apps · url · elicitation · tui). The reference rendering of the spec's 4-tier contract.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" } },
10
+ "files": ["dist"],
11
+ "scripts": { "build": "tsc -p tsconfig.json" },
12
+ "dependencies": {
13
+ "@elicitkit/core": "workspace:*",
14
+ "@mcp-ui/server": "^6.1.0"
15
+ },
16
+ "publishConfig": { "access": "public" }
17
+ }