@lloyal-labs/ui 0.1.0-alpha.6

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 ADDED
@@ -0,0 +1,107 @@
1
+ # Functional Source License, Version 1.1, Apache 2.0 Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-Apache-2.0
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Lloyal Labs
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publish, and distribute the
28
+ Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A "Permitted Purpose" is any purpose other than a Competing Use. A
33
+ "Competing Use" means making the Software available to others in a
34
+ commercial product or service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a Licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives
65
+ of the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND,
74
+ INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE,
75
+ MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO
78
+ THE SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
79
+ DAMAGES, EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software
90
+ under the Apache License, Version 2.0 that is effective on the second
91
+ anniversary of the date we make the Software available. On or after that
92
+ date, you may use the Software under the Apache License, Version 2.0, in
93
+ which case the following will apply:
94
+
95
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
96
+ use this file except in compliance with the License.
97
+
98
+ You may obtain a copy of the License at
99
+
100
+ http://www.apache.org/licenses/LICENSE-2.0
101
+
102
+ Unless required by applicable law or agreed to in writing, software
103
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
104
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
105
+
106
+ See the License for the specific language governing permissions and
107
+ limitations under the License.
@@ -0,0 +1,18 @@
1
+ import type { DocumentMeta } from '@lloyal-labs/media';
2
+ export type Asset = {
3
+ kind: 'image';
4
+ } | {
5
+ kind: 'document';
6
+ meta: DocumentMeta; /** The ingest retained the original file. */
7
+ source: boolean;
8
+ };
9
+ export declare function resolveAsset(origin: string, digest: string): Promise<Asset>;
10
+ /** The kinds of the given roots, filled in as the content plane answers. */
11
+ export declare function useAssets(digests: readonly string[]): Record<string, Asset>;
12
+ /** "1, 2, 3, 7" with runs of three or more folded: "1–3, 7". */
13
+ export declare function pageList(pages: readonly number[]): string;
14
+ /** What of a document reached the model, page by page: which pages had no text
15
+ * to extract (scanned), which were extracted as text, and — when the thread
16
+ * holds their renders — which pages the model looked at. */
17
+ export declare function pageFacts(meta: DocumentMeta, viewedRenders?: ReadonlySet<string>): string[];
18
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC,CAAC,6CAA6C;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAI5G,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAcjF;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAoB3E;AAED,gEAAgE;AAChE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CASzD;AAED;;6DAE6D;AAC7D,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,aAAa,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,MAAM,EAAE,CAatG"}
package/dist/assets.js ADDED
@@ -0,0 +1,83 @@
1
+ /**
2
+ * What a root IS, learned from its manifest through the content plane: a
3
+ * picture, or a document with its sidecar. One resolution per digest for the
4
+ * page's lifetime — content is immutable under its address, so an answer never
5
+ * goes stale. A root whose manifest cannot be read is shown as an image, so
6
+ * the failure is visible (a broken picture) rather than silent.
7
+ *
8
+ * @category UI
9
+ */
10
+ import { useEffect, useState } from 'react';
11
+ import { asDocumentMeta, configUrl, DOCUMENT_CONFIG_TYPE, manifestUrl } from '@lloyal-labs/media';
12
+ import { useContentOrigin } from './provider.js';
13
+ const resolved = new Map();
14
+ export async function resolveAsset(origin, digest) {
15
+ try {
16
+ const manifest = (await (await fetch(manifestUrl(origin, digest))).json());
17
+ if (manifest.config?.mediaType !== DOCUMENT_CONFIG_TYPE)
18
+ return { kind: 'image' };
19
+ const meta = asDocumentMeta(await (await fetch(configUrl(origin, digest))).json());
20
+ if (!meta)
21
+ return { kind: 'image' };
22
+ const source = (manifest.layers ?? []).some((l) => l.annotations?.['ai.lloyal.role'] === 'source');
23
+ return { kind: 'document', meta, source };
24
+ }
25
+ catch {
26
+ return { kind: 'image' };
27
+ }
28
+ }
29
+ /** The kinds of the given roots, filled in as the content plane answers. */
30
+ export function useAssets(digests) {
31
+ const origin = useContentOrigin();
32
+ const [assets, setAssets] = useState({});
33
+ const key = digests.join(' ');
34
+ useEffect(() => {
35
+ if (origin === null)
36
+ return;
37
+ let live = true;
38
+ for (const digest of key ? key.split(' ') : []) {
39
+ let p = resolved.get(digest);
40
+ if (!p) {
41
+ p = resolveAsset(origin, digest);
42
+ resolved.set(digest, p);
43
+ }
44
+ void p.then((asset) => {
45
+ if (live)
46
+ setAssets((prev) => (prev[digest] ? prev : { ...prev, [digest]: asset }));
47
+ });
48
+ }
49
+ return () => { live = false; };
50
+ }, [origin, key]);
51
+ return assets;
52
+ }
53
+ /** "1, 2, 3, 7" with runs of three or more folded: "1–3, 7". */
54
+ export function pageList(pages) {
55
+ const out = [];
56
+ for (let i = 0; i < pages.length;) {
57
+ let j = i;
58
+ while (j + 1 < pages.length && pages[j + 1] === pages[j] + 1)
59
+ j++;
60
+ out.push(j - i >= 2 ? `${pages[i]}–${pages[j]}` : pages.slice(i, j + 1).join(', '));
61
+ i = j + 1;
62
+ }
63
+ return out.join(', ');
64
+ }
65
+ /** What of a document reached the model, page by page: which pages had no text
66
+ * to extract (scanned), which were extracted as text, and — when the thread
67
+ * holds their renders — which pages the model looked at. */
68
+ export function pageFacts(meta, viewedRenders = new Set()) {
69
+ const scanned = meta.pages.filter((p) => p.chars === 0).map((p) => p.page);
70
+ const viewed = meta.pages.filter((p) => p.render && viewedRenders.has(p.render.digest)).map((p) => p.page);
71
+ const n = meta.pageCount;
72
+ const lines = [
73
+ scanned.length === 0
74
+ ? `Extracted as text: all ${n} page${n === 1 ? '' : 's'}`
75
+ : scanned.length === n
76
+ ? `Scanned (image only): all ${n} page${n === 1 ? '' : 's'}`
77
+ : `Scanned: ${pageList(scanned)} · extracted as text: the rest`,
78
+ ];
79
+ if (viewed.length > 0)
80
+ lines.push(`Viewed as images: ${pageList(viewed)}`);
81
+ return lines;
82
+ }
83
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"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"}
package/dist/fold.d.ts ADDED
@@ -0,0 +1,194 @@
1
+ /**
2
+ * The generic agent fold: one agent's life on a view, folded from the bus
3
+ * events every pool emits. Framework-free — the Ink view, the desktop shell's
4
+ * own fold and the browser page all fold the same records — and it knows no
5
+ * product: which spawns get a timeline, and what an agent's task is called,
6
+ * are the application's decisions, handed in at `agent:spawn`.
7
+ *
8
+ * What it owns: the per-agent record ({@link AgentRuntime}), the `<think>`
9
+ * boundary machine (a live think block advances until the marker, then closes
10
+ * and seeds the content buffer with the tail), the timeline items — think,
11
+ * tool call, tool result, report — with their summaries, retry state, and the
12
+ * terminal transitions (`return`/`recovered` → done, `failed`, and the
13
+ * stall-break `done` that precedes a forced recovery).
14
+ *
15
+ * @packageDocumentation
16
+ * @category UI
17
+ */
18
+ /** One cited source, extracted CONSUMER-side from a tool result (the Ability
19
+ * Protocol prescribes no result schema). Web tools populate url/title/snippet;
20
+ * image and icon arrive when an ability emits them; a corpus ability fills
21
+ * whatever subset applies. */
22
+ export interface SourceMeta {
23
+ url?: string;
24
+ title?: string;
25
+ snippet?: string;
26
+ image?: string;
27
+ icon?: string;
28
+ /** Display host, derived from url when present. */
29
+ host?: string;
30
+ }
31
+ /** Per-agent chronological stream item — a renderer lays one component per
32
+ * kind. `live: true` on a think item means its body is currently streaming. */
33
+ export type TimelineItem = {
34
+ kind: 'think';
35
+ id: number;
36
+ title: string;
37
+ body: string;
38
+ live: boolean;
39
+ openedAt: number;
40
+ closedAt: number | null;
41
+ } | {
42
+ kind: 'tool_call';
43
+ id: number;
44
+ tool: string;
45
+ argsSummary: string;
46
+ } | {
47
+ kind: 'tool_result';
48
+ id: number;
49
+ tool: string;
50
+ /** The tool_call id this result pairs with, for a renderer that indents results under their call. */
51
+ callId: number | null;
52
+ byteLength: number;
53
+ preview: string | null;
54
+ hosts: string[];
55
+ resultCount: number | null;
56
+ /** Per-source citation metadata parsed from the tool's free-form result. */
57
+ sources?: SourceMeta[];
58
+ } | {
59
+ kind: 'report';
60
+ id: number;
61
+ body: string;
62
+ tokenCount: number;
63
+ };
64
+ export interface AgentRuntime {
65
+ id: number;
66
+ /** "A0", "A1", … in spawn order within the roster. */
67
+ label: string;
68
+ phase: 'idle' | 'thinking' | 'content' | 'tool' | 'done' | 'failed';
69
+ tokenCount: number;
70
+ toolCallCount: number;
71
+ /** Wall-clock spawn time (ms). */
72
+ startedAt: number;
73
+ /** Wall-clock completion time (ms), set when the agent reaches `done` or `failed`. */
74
+ endedAt: number | null;
75
+ /** The application's index for this agent's task. Null means the agent is tracked but keeps no timeline. */
76
+ taskIndex: number | null;
77
+ taskDescription: string | null;
78
+ /** A dependency hint for a chained task ("builds on Task 1"). */
79
+ dependencyHint: string | null;
80
+ /** Id of the currently-live think item in `timeline`, or null. */
81
+ currentThinkId: number | null;
82
+ /** Id of the most recent tool_call, paired with its tool_result when one lands. */
83
+ pendingToolCallId: number | null;
84
+ /** A parked tool call: the provider was rate-limited and the pool re-executes after the delay. */
85
+ retry: {
86
+ tool: string;
87
+ retryAt: number;
88
+ attempt: number;
89
+ } | null;
90
+ /** Live post-`</think>` token buffer: the model writing its tool-call JSON, or a forced recovery's prose. */
91
+ contentBuffer: string;
92
+ /** True while the agent is being force-recovered: `agent:done` fired without a report and the pool
93
+ * streams a forced one; produce tokens go to `contentBuffer`, not a think block. */
94
+ recovering: boolean;
95
+ /** Set when the agent ended without a result: the terminal failure's reason. */
96
+ failReason: string | null;
97
+ timeline: TimelineItem[];
98
+ }
99
+ /** What a roster holds beside its agents: the counters that keep timeline ids and labels stable. */
100
+ export interface AgentRoster {
101
+ agents: Map<number, AgentRuntime>;
102
+ nextTimelineId: number;
103
+ nextLabelIdx: number;
104
+ }
105
+ export declare const emptyRoster: () => AgentRoster;
106
+ /** The bus events the fold reads, structurally — the agents package's own
107
+ * vocabulary, versioned beside it; every field the fold touches is guarded. */
108
+ export type AgentEvent = {
109
+ type: 'agent:spawn';
110
+ agentId: number;
111
+ parentAgentId?: number;
112
+ key?: string;
113
+ after?: number[];
114
+ } | {
115
+ type: 'agent:produce';
116
+ agentId: number;
117
+ text: string;
118
+ tokenCount: number;
119
+ } | {
120
+ type: 'agent:tool_call';
121
+ agentId: number;
122
+ tool: string;
123
+ args: string;
124
+ } | {
125
+ type: 'agent:tool_retry';
126
+ agentId: number;
127
+ tool: string;
128
+ retryAfterMs: number;
129
+ attempt: number;
130
+ } | {
131
+ type: 'agent:tool_result';
132
+ agentId: number;
133
+ tool: string;
134
+ result: string;
135
+ } | {
136
+ type: 'agent:return';
137
+ agentId: number;
138
+ result: string;
139
+ } | {
140
+ type: 'agent:recovered';
141
+ agentId: number;
142
+ result: string;
143
+ } | {
144
+ type: 'agent:failed';
145
+ agentId: number;
146
+ reason: string;
147
+ } | {
148
+ type: 'agent:done';
149
+ agentId: number;
150
+ };
151
+ /** What the application decides at a spawn: the agent's task, or nothing (tracked, no timeline). */
152
+ export interface SpawnDecision {
153
+ taskIndex: number | null;
154
+ taskDescription?: string | null;
155
+ dependencyHint?: string | null;
156
+ }
157
+ export interface FoldAgentsOptions {
158
+ /** The application's decision at `agent:spawn`. Default: every agent is tracked with no timeline. */
159
+ spawn?: (ev: Extract<AgentEvent, {
160
+ type: 'agent:spawn';
161
+ }>) => SpawnDecision;
162
+ /** The tool whose call ends the turn. Its call is not a timeline row: the report streamed live and
163
+ * `agent:return` files it. */
164
+ terminal?: string;
165
+ /** The clock, for tests. */
166
+ now?: () => number;
167
+ }
168
+ /** Live report markdown from a raw Hermes terminal-tool buffer
169
+ * (`…<parameter=result>\n<markdown>\n</parameter>…`). Null until the open
170
+ * marker arrives, so a half-written tool call never flashes as prose. A forced
171
+ * recovery streams raw prose with no envelope — callers branch on `recovering` first. */
172
+ export declare function extractStreamingReport(buffer: string): string | null;
173
+ /** First meaningful line of a think-block body, cleaned up for a title. */
174
+ export declare function extractTitle(body: string): string;
175
+ export declare function hostOf(url: string): string;
176
+ /** A one-line summary of a tool call's arguments: the query, pattern, url or filename it named. */
177
+ export declare function formatArgSummary(_tool: string, rawArgs: string): string;
178
+ export interface ResultSummary {
179
+ summary: string;
180
+ hosts: string[];
181
+ resultCount: number | null;
182
+ preview: string | null;
183
+ sources?: SourceMeta[];
184
+ }
185
+ /** A per-tool summary of a result, parsed from the stock abilities' result
186
+ * shapes (web search and fetch, corpus search, grep and read); anything else
187
+ * falls back to the URLs it carries, else its size. */
188
+ export declare function summarizeResult(tool: string, raw: string): ResultSummary;
189
+ /**
190
+ * Fold one agent event into the roster. Returns the same roster when the event
191
+ * changed nothing. An event for an unknown agent is dropped.
192
+ */
193
+ export declare function foldAgents(r: AgentRoster, ev: AgentEvent, opts?: FoldAgentsOptions): AgentRoster;
194
+ //# sourceMappingURL=fold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
package/dist/fold.js ADDED
@@ -0,0 +1,295 @@
1
+ /**
2
+ * The generic agent fold: one agent's life on a view, folded from the bus
3
+ * events every pool emits. Framework-free — the Ink view, the desktop shell's
4
+ * own fold and the browser page all fold the same records — and it knows no
5
+ * product: which spawns get a timeline, and what an agent's task is called,
6
+ * are the application's decisions, handed in at `agent:spawn`.
7
+ *
8
+ * What it owns: the per-agent record ({@link AgentRuntime}), the `<think>`
9
+ * boundary machine (a live think block advances until the marker, then closes
10
+ * and seeds the content buffer with the tail), the timeline items — think,
11
+ * tool call, tool result, report — with their summaries, retry state, and the
12
+ * terminal transitions (`return`/`recovered` → done, `failed`, and the
13
+ * stall-break `done` that precedes a forced recovery).
14
+ *
15
+ * @packageDocumentation
16
+ * @category UI
17
+ */
18
+ export const emptyRoster = () => ({ agents: new Map(), nextTimelineId: 0, nextLabelIdx: 0 });
19
+ /** Live report markdown from a raw Hermes terminal-tool buffer
20
+ * (`…<parameter=result>\n<markdown>\n</parameter>…`). Null until the open
21
+ * marker arrives, so a half-written tool call never flashes as prose. A forced
22
+ * recovery streams raw prose with no envelope — callers branch on `recovering` first. */
23
+ export function extractStreamingReport(buffer) {
24
+ const OPEN = '<parameter=result>';
25
+ const i = buffer.indexOf(OPEN);
26
+ if (i === -1)
27
+ return null;
28
+ let body = buffer.slice(i + OPEN.length);
29
+ const c = body.indexOf('</parameter>');
30
+ if (c !== -1)
31
+ body = body.slice(0, c);
32
+ return body.replace(/^\n/, '');
33
+ }
34
+ const THINK_CLOSE = '</think>';
35
+ /** First meaningful line of a think-block body, cleaned up for a title. */
36
+ export function extractTitle(body) {
37
+ const text = body.replace(/^\s*\n/, '').replace(/\*\*/g, '').replace(/^#+\s*/, '').trim();
38
+ if (!text)
39
+ return 'Thinking…';
40
+ const firstLine = text.split('\n')[0].trim();
41
+ return firstLine.length > 72 ? firstLine.slice(0, 72).trimEnd() + '…' : firstLine;
42
+ }
43
+ export function hostOf(url) {
44
+ try {
45
+ return new URL(url).hostname.replace(/^www\./, '');
46
+ }
47
+ catch {
48
+ return url;
49
+ }
50
+ }
51
+ /** A one-line summary of a tool call's arguments: the query, pattern, url or filename it named. */
52
+ export function formatArgSummary(_tool, rawArgs) {
53
+ let parsed;
54
+ try {
55
+ parsed = JSON.parse(rawArgs);
56
+ }
57
+ catch {
58
+ parsed = {};
59
+ }
60
+ const q = typeof parsed.query === 'string' ? parsed.query
61
+ : typeof parsed.pattern === 'string' ? parsed.pattern
62
+ : typeof parsed.url === 'string' ? parsed.url
63
+ : typeof parsed.filename === 'string' ? parsed.filename
64
+ : '';
65
+ return q ? `"${q.length > 48 ? q.slice(0, 48) + '…' : q}"` : '';
66
+ }
67
+ /** A per-tool summary of a result, parsed from the stock abilities' result
68
+ * shapes (web search and fetch, corpus search, grep and read); anything else
69
+ * falls back to the URLs it carries, else its size. */
70
+ export function summarizeResult(tool, raw) {
71
+ try {
72
+ const parsed = JSON.parse(raw);
73
+ if (tool === 'web_search' && Array.isArray(parsed)) {
74
+ const items = parsed;
75
+ const hosts = Array.from(new Set(items.map((i) => (i.url ? hostOf(i.url) : '')).filter(Boolean))).slice(0, 3);
76
+ const sources = items
77
+ .filter((i) => i.url || i.title)
78
+ .slice(0, 8)
79
+ .map((i) => ({ url: i.url, title: i.title, snippet: i.snippet, image: i.image, icon: i.icon, host: i.url ? hostOf(i.url) : undefined }));
80
+ return { summary: `${items.length} results`, hosts, resultCount: items.length, preview: items[0]?.title ?? null, sources: sources.length ? sources : undefined };
81
+ }
82
+ if (tool === 'search' && typeof parsed === 'object' && parsed !== null && Array.isArray(parsed.hits)) {
83
+ const hits = parsed.hits;
84
+ const sources = hits.slice(0, 8).map((h) => ({ title: h.heading || h.file, host: h.file })).filter((s) => s.title || s.host);
85
+ return { summary: `${hits.length} results`, hosts: [], resultCount: hits.length, preview: hits[0]?.heading ?? hits[0]?.file ?? null, sources: sources.length ? sources : undefined };
86
+ }
87
+ if (tool === 'grep' && typeof parsed === 'object' && parsed !== null) {
88
+ const r = parsed;
89
+ const matches = r.matches ?? [];
90
+ const sources = matches.slice(0, 8)
91
+ .map((m) => ({ title: m.file, host: m.line != null ? `line ${m.line}` : undefined, snippet: m.text }))
92
+ .filter((s) => s.title);
93
+ return { summary: `${r.totalMatches ?? 0} matches`, hosts: [], resultCount: r.totalMatches ?? null, preview: matches[0]?.file ?? null, sources: sources.length ? sources : undefined };
94
+ }
95
+ if (tool === 'read_file' && typeof parsed === 'object' && parsed !== null) {
96
+ const r = parsed;
97
+ if (r.error)
98
+ return { summary: r.error, hosts: [], resultCount: null, preview: null };
99
+ const sources = r.file ? [{ title: r.file }] : [];
100
+ return { summary: `${raw.length}b`, hosts: [], resultCount: null, preview: r.file ?? null, sources: sources.length ? sources : undefined };
101
+ }
102
+ if ((tool === 'fetch_page' || tool === 'web_fetch') && typeof parsed === 'object' && parsed !== null) {
103
+ const r = parsed;
104
+ if (r.error)
105
+ return { summary: r.error, hosts: [], resultCount: null, preview: null };
106
+ const hosts = r.url ? [hostOf(r.url)] : [];
107
+ const sources = r.url || r.title
108
+ ? [{ url: r.url, title: r.title, snippet: r.excerpt, image: r.image, icon: r.icon, host: r.url ? hostOf(r.url) : undefined }]
109
+ : undefined;
110
+ return { summary: `${raw.length}b`, hosts, resultCount: null, preview: r.title ?? null, sources };
111
+ }
112
+ }
113
+ catch {
114
+ /* fall through to the URL scan */
115
+ }
116
+ const urls = Array.from(raw.matchAll(/https?:\/\/[^\s\])>"]+/g)).map((m) => m[0]);
117
+ if (urls.length > 0) {
118
+ return { summary: `${urls.length} links`, hosts: Array.from(new Set(urls.map(hostOf))).slice(0, 3), resultCount: urls.length, preview: null };
119
+ }
120
+ return { summary: `${raw.length}b`, hosts: [], resultCount: null, preview: null };
121
+ }
122
+ // ── immutable helpers over the roster ──────────────────────────────
123
+ function replaceAgent(r, id, patch) {
124
+ const existing = r.agents.get(id);
125
+ if (!existing)
126
+ return r;
127
+ const agents = new Map(r.agents);
128
+ agents.set(id, patch(existing));
129
+ return { ...r, agents };
130
+ }
131
+ function createAgent(r, id, now, patch) {
132
+ if (r.agents.has(id))
133
+ return r;
134
+ const base = {
135
+ id, label: `A${r.nextLabelIdx}`, phase: 'idle', startedAt: now, endedAt: null, tokenCount: 0, toolCallCount: 0,
136
+ taskIndex: null, taskDescription: null, dependencyHint: null, currentThinkId: null, pendingToolCallId: null,
137
+ retry: null, contentBuffer: '', recovering: false, failReason: null, timeline: [],
138
+ ...patch,
139
+ };
140
+ const agents = new Map(r.agents);
141
+ agents.set(id, base);
142
+ return { ...r, agents, nextLabelIdx: r.nextLabelIdx + 1 };
143
+ }
144
+ const pushTimeline = (a, item) => ({ ...a, timeline: [...a.timeline, item] });
145
+ const updateTimeline = (a, id, update) => ({ ...a, timeline: a.timeline.map((it) => (it.id === id ? update(it) : it)) });
146
+ /** Open a new live think block on this agent. */
147
+ function openThink(r, agentId, now) {
148
+ const id = r.nextTimelineId;
149
+ const next = replaceAgent(r, agentId, (a) => pushTimeline({ ...a, currentThinkId: id, phase: 'thinking' }, { kind: 'think', id, title: 'Thinking…', body: '', live: true, openedAt: now, closedAt: null }));
150
+ return { ...next, nextTimelineId: r.nextTimelineId + 1 };
151
+ }
152
+ /** Close the agent's live think block with `finalBody`. */
153
+ function closeThink(r, agentId, finalBody, now) {
154
+ const agent = r.agents.get(agentId);
155
+ if (!agent || agent.currentThinkId === null)
156
+ return r;
157
+ const thinkId = agent.currentThinkId;
158
+ const title = extractTitle(finalBody);
159
+ return replaceAgent(r, agentId, (a) => updateTimeline({ ...a, currentThinkId: null, phase: 'content' }, thinkId, (it) => it.kind === 'think' ? { ...it, body: finalBody, title, live: false, closedAt: now } : it));
160
+ }
161
+ /** Close any live think block, keeping whatever body it holds — the recovery and tool-call paths may reach here without a `</think>`. */
162
+ function closeLiveThink(r, agentId, now) {
163
+ const agent = r.agents.get(agentId);
164
+ if (!agent || agent.currentThinkId === null)
165
+ return r;
166
+ const item = agent.timeline.find((it) => it.id === agent.currentThinkId);
167
+ return closeThink(r, agentId, item && item.kind === 'think' ? item.body : '', now);
168
+ }
169
+ /** Advance the live think block: append until `</think>`, then close on the marker and seed the content buffer with the tail. */
170
+ function advanceThink(r, agentId, text, tokenCount, now) {
171
+ const agent = r.agents.get(agentId);
172
+ if (!agent || agent.currentThinkId === null)
173
+ return r;
174
+ const thinkId = agent.currentThinkId;
175
+ const item = agent.timeline.find((it) => it.id === thinkId);
176
+ if (!item || item.kind !== 'think')
177
+ return r;
178
+ const combined = item.body + text;
179
+ const markerIdx = combined.indexOf(THINK_CLOSE);
180
+ if (markerIdx === -1) {
181
+ return replaceAgent(r, agentId, (a) => updateTimeline({ ...a, tokenCount }, thinkId, (it) => (it.kind === 'think' ? { ...it, body: combined } : it)));
182
+ }
183
+ const finalBody = combined.slice(0, markerIdx);
184
+ const tail = combined.slice(markerIdx + THINK_CLOSE.length);
185
+ return replaceAgent(closeThink(r, agentId, finalBody, now), agentId, (a) => ({ ...a, tokenCount, contentBuffer: tail }));
186
+ }
187
+ /**
188
+ * Fold one agent event into the roster. Returns the same roster when the event
189
+ * changed nothing. An event for an unknown agent is dropped.
190
+ */
191
+ export function foldAgents(r, ev, opts = {}) {
192
+ const now = (opts.now ?? Date.now)();
193
+ switch (ev.type) {
194
+ case 'agent:spawn': {
195
+ const decision = opts.spawn?.(ev) ?? { taskIndex: null };
196
+ const next = createAgent(r, ev.agentId, now, {
197
+ phase: decision.taskIndex !== null ? 'thinking' : 'idle',
198
+ taskIndex: decision.taskIndex,
199
+ taskDescription: decision.taskDescription ?? null,
200
+ dependencyHint: decision.dependencyHint ?? null,
201
+ });
202
+ return decision.taskIndex !== null ? openThink(next, ev.agentId, now) : next;
203
+ }
204
+ case 'agent:produce': {
205
+ const agent = r.agents.get(ev.agentId);
206
+ if (!agent)
207
+ return r;
208
+ if (agent.taskIndex === null)
209
+ return replaceAgent(r, ev.agentId, (a) => ({ ...a, tokenCount: ev.tokenCount }));
210
+ // Content-phase tokens (post-</think>, pre-tool_call): the model writing its tool-call JSON — the
211
+ // terminal tool's body lives inside it, so it streams into the buffer a renderer can read live.
212
+ if (agent.phase === 'content' || agent.recovering) {
213
+ return replaceAgent(r, ev.agentId, (a) => ({ ...a, tokenCount: ev.tokenCount, contentBuffer: a.contentBuffer + ev.text }));
214
+ }
215
+ let working = r;
216
+ if (agent.phase !== 'thinking' || agent.currentThinkId === null) {
217
+ if (agent.phase === 'tool' || agent.phase === 'idle')
218
+ working = openThink(working, ev.agentId, now);
219
+ else
220
+ return replaceAgent(working, ev.agentId, (a) => ({ ...a, tokenCount: ev.tokenCount })); // done or failed: count only
221
+ }
222
+ return advanceThink(working, ev.agentId, ev.text, ev.tokenCount, now);
223
+ }
224
+ case 'agent:tool_call': {
225
+ const agent = r.agents.get(ev.agentId);
226
+ if (!agent)
227
+ return r;
228
+ const working = closeLiveThink(r, ev.agentId, now);
229
+ if (agent.taskIndex === null) {
230
+ return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'tool', toolCallCount: a.toolCallCount + 1 }));
231
+ }
232
+ // The terminal tool fires at the stop token, but its report already streamed as content: no timeline row,
233
+ // the buffer clears, and `agent:return` files the report next.
234
+ const acting = working.agents.get(ev.agentId);
235
+ const wasReporting = ev.tool === opts.terminal || (acting?.contentBuffer.includes('<parameter=result>') ?? false);
236
+ if (wasReporting) {
237
+ return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'tool', toolCallCount: a.toolCallCount + 1, contentBuffer: '' }));
238
+ }
239
+ const id = working.nextTimelineId;
240
+ const next = replaceAgent(working, ev.agentId, (a) => pushTimeline({ ...a, phase: 'tool', toolCallCount: a.toolCallCount + 1, pendingToolCallId: id, contentBuffer: '' }, { kind: 'tool_call', id, tool: ev.tool, argsSummary: formatArgSummary(ev.tool, ev.args) }));
241
+ return { ...next, nextTimelineId: working.nextTimelineId + 1 };
242
+ }
243
+ case 'agent:tool_retry': {
244
+ if (!r.agents.has(ev.agentId))
245
+ return r;
246
+ return replaceAgent(r, ev.agentId, (a) => ({ ...a, retry: { tool: ev.tool, retryAt: now + ev.retryAfterMs, attempt: ev.attempt } }));
247
+ }
248
+ case 'agent:tool_result': {
249
+ const agent = r.agents.get(ev.agentId);
250
+ if (!agent)
251
+ return r;
252
+ if (agent.taskIndex === null)
253
+ return replaceAgent(r, ev.agentId, (a) => ({ ...a, phase: 'idle', retry: null }));
254
+ const summary = summarizeResult(ev.tool, ev.result);
255
+ const id = r.nextTimelineId;
256
+ const next = replaceAgent(r, ev.agentId, (a) => pushTimeline({ ...a, phase: 'idle', pendingToolCallId: null, retry: null }, {
257
+ kind: 'tool_result', id, tool: ev.tool, callId: agent.pendingToolCallId, byteLength: ev.result.length,
258
+ preview: summary.preview, hosts: Array.from(new Set(summary.hosts)), resultCount: summary.resultCount, sources: summary.sources,
259
+ }));
260
+ return { ...next, nextTimelineId: r.nextTimelineId + 1 };
261
+ }
262
+ case 'agent:return':
263
+ case 'agent:recovered': {
264
+ const agent = r.agents.get(ev.agentId);
265
+ if (!agent)
266
+ return r;
267
+ const working = closeLiveThink(r, ev.agentId, now);
268
+ if (agent.taskIndex === null) {
269
+ return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'done', endedAt: now, contentBuffer: '', recovering: false }));
270
+ }
271
+ const id = working.nextTimelineId;
272
+ const next = replaceAgent(working, ev.agentId, (a) => pushTimeline({ ...a, phase: 'done', endedAt: now, contentBuffer: '', recovering: false }, { kind: 'report', id, body: ev.result, tokenCount: a.tokenCount }));
273
+ return { ...next, nextTimelineId: working.nextTimelineId + 1 };
274
+ }
275
+ case 'agent:failed': {
276
+ const agent = r.agents.get(ev.agentId);
277
+ if (!agent || agent.phase === 'done' || agent.phase === 'failed')
278
+ return r;
279
+ const working = closeLiveThink(r, ev.agentId, now);
280
+ return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'failed', endedAt: now, contentBuffer: '', recovering: false, failReason: ev.reason }));
281
+ }
282
+ case 'agent:done': {
283
+ // Not `done` yet: in the stall-break path this precedes the forced recovery's produce stream and
284
+ // `agent:recovered`. Close any live think, step back to idle, and route what follows into the buffer.
285
+ const agent = r.agents.get(ev.agentId);
286
+ if (!agent || agent.phase === 'done' || agent.phase === 'failed')
287
+ return r; // terminal either way
288
+ const working = closeLiveThink(r, ev.agentId, now);
289
+ return replaceAgent(working, ev.agentId, (a) => ({ ...a, phase: 'idle', contentBuffer: '', recovering: true }));
290
+ }
291
+ default:
292
+ return r;
293
+ }
294
+ }
295
+ //# sourceMappingURL=fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `@lloyal-labs/ui` — the view side of a harness, for React.
3
+ *
4
+ * The provider connects a bridge's projection once; the hooks read the fold,
5
+ * the wire's status, the command sink and the content plane's origin. The
6
+ * primitives are the pieces every harness view rebuilt: markdown with math,
7
+ * the one enlarged view of an asset, and what a root is. The generic agent
8
+ * fold is framework-free and lives at `@lloyal-labs/ui/fold`, so a fold that
9
+ * runs where React does not (a terminal, a desktop shell's own process) takes
10
+ * that entry alone.
11
+ *
12
+ * Browser-safe: nothing here imports a Node module.
13
+ *
14
+ * @packageDocumentation
15
+ * @category UI
16
+ */
17
+ export { HarnessProvider, projectionFor, useHarness, useProjection, useSend, useConnection, useAvailability, useRecover, useContentOrigin } from './provider.js';
18
+ export type { Harness } from './provider.js';
19
+ export { Markdown, admitAttachmentUrls } from './markdown.js';
20
+ export type { MarkdownComponents } from './markdown.js';
21
+ export { Lightbox } from './lightbox.js';
22
+ export type { LightboxProps } from './lightbox.js';
23
+ export { resolveAsset, useAssets, pageFacts, pageList } from './assets.js';
24
+ export type { Asset } from './assets.js';
25
+ export * from './fold.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjK,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,cAAc,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `@lloyal-labs/ui` — the view side of a harness, for React.
3
+ *
4
+ * The provider connects a bridge's projection once; the hooks read the fold,
5
+ * the wire's status, the command sink and the content plane's origin. The
6
+ * primitives are the pieces every harness view rebuilt: markdown with math,
7
+ * the one enlarged view of an asset, and what a root is. The generic agent
8
+ * fold is framework-free and lives at `@lloyal-labs/ui/fold`, so a fold that
9
+ * runs where React does not (a terminal, a desktop shell's own process) takes
10
+ * that entry alone.
11
+ *
12
+ * Browser-safe: nothing here imports a Node module.
13
+ *
14
+ * @packageDocumentation
15
+ * @category UI
16
+ */
17
+ export { HarnessProvider, projectionFor, useHarness, useProjection, useSend, useConnection, useAvailability, useRecover, useContentOrigin } from './provider.js';
18
+ export { Markdown, admitAttachmentUrls } from './markdown.js';
19
+ export { Lightbox } from './lightbox.js';
20
+ export { resolveAsset, useAssets, pageFacts, pageList } from './assets.js';
21
+ export * from './fold.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjK,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE3E,cAAc,WAAW,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { CSSProperties, ReactElement } from 'react';
2
+ export interface LightboxProps {
3
+ /** The root of a single image to show — a photo, a page render. */
4
+ digest?: string;
5
+ /** Or a PDF to open in the browser's own viewer: the URL the content plane serves the original at. */
6
+ pdf?: string;
7
+ /** The representation's true pixel size, when the caller read it off the loaded element. */
8
+ dims?: string;
9
+ /** What is being shown, when it is not simply "the attached image". */
10
+ label?: string;
11
+ onClose: () => void;
12
+ /** The caller's register: the scrim, the image and the caption. */
13
+ styles?: {
14
+ scrim?: CSSProperties;
15
+ full?: CSSProperties;
16
+ pdf?: CSSProperties;
17
+ caption?: CSSProperties;
18
+ };
19
+ }
20
+ export declare function Lightbox({ digest, pdf, dims, label, onClose, styles }: LightboxProps): ReactElement | null;
21
+ //# sourceMappingURL=lightbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightbox.d.ts","sourceRoot":"","sources":["../src/lightbox.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAMzD,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,aAAa,CAAC;QAAC,GAAG,CAAC,EAAE,aAAa,CAAC;QAAC,OAAO,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC;CACxG;AAYD,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAW,EAAE,EAAE,aAAa,GAAG,YAAY,GAAG,IAAI,CA6B/G"}
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The full-size view of one asset: a single image by its root, or a PDF in
4
+ * the browser's own viewer. One enlarged view for a whole app — the figure
5
+ * strip, a run bar's marker and a cited page in the prose all open this one,
6
+ * so there is one that cannot drift. Escape and a click on the scrim close it.
7
+ *
8
+ * @category UI
9
+ */
10
+ import { useEffect } from 'react';
11
+ import { representationUrl } from '@lloyal-labs/media';
12
+ import { useContentOrigin } from './provider.js';
13
+ const short = (digest) => digest.replace(/^sha256:/, '').slice(0, 10);
14
+ const S = {
15
+ scrim: {
16
+ position: 'fixed', inset: 0, zIndex: 50, cursor: 'zoom-out', background: 'rgba(20,20,22,.82)',
17
+ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 12, padding: 32,
18
+ },
19
+ full: { maxWidth: '100%', maxHeight: 'calc(100vh - 110px)', objectFit: 'contain', borderRadius: 12, background: '#fff' },
20
+ pdf: { width: 'min(1100px, 94vw)', height: 'calc(100vh - 110px)', border: 0, borderRadius: 12, background: '#fff' },
21
+ caption: { font: '12px system-ui, sans-serif', color: '#D8D8D2', margin: 0 },
22
+ };
23
+ export function Lightbox({ digest, pdf, dims, label, onClose, styles = {} }) {
24
+ const origin = useContentOrigin();
25
+ useEffect(() => {
26
+ const onKey = (e) => {
27
+ if (e.key === 'Escape')
28
+ onClose();
29
+ };
30
+ window.addEventListener('keydown', onKey);
31
+ return () => window.removeEventListener('keydown', onKey);
32
+ }, [onClose]);
33
+ if (origin === null)
34
+ return null;
35
+ const s = { ...S, ...styles };
36
+ if (pdf !== undefined) {
37
+ return (_jsxs("div", { style: s.scrim, role: "dialog", "aria-modal": "true", "aria-label": label ?? 'Attached document', onClick: onClose, children: [_jsx("iframe", { src: pdf, title: label ?? 'Attached document', style: s.pdf, onClick: (e) => e.stopPropagation() }), _jsxs("p", { style: s.caption, children: [label ?? 'the attached document', " \u00B7 the file as attached"] })] }));
38
+ }
39
+ if (digest === undefined)
40
+ return null;
41
+ return (_jsxs("div", { style: s.scrim, role: "dialog", "aria-modal": "true", "aria-label": label ?? 'Attached image, full size', onClick: onClose, children: [_jsx("img", { src: representationUrl(origin, digest), alt: label ?? 'Attached image, as the model received it', style: s.full }), _jsxs("p", { style: s.caption, children: [label ?? 'what the model saw', dims ? ` · ${dims}` : '', " \u00B7 ", short(digest)] })] }));
42
+ }
43
+ //# sourceMappingURL=lightbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightbox.js","sourceRoot":"","sources":["../src/lightbox.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,KAAK,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAgBtF,MAAM,CAAC,GAAmD;IACxD,KAAK,EAAE;QACL,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB;QAC7F,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;KAC/G;IACD,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;IACxH,GAAG,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;IACnH,OAAO,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE;CAC7E,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAG,EAAE,EAAiB;IACxF,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAQ,EAAE;YACvC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,CACL,eAAK,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAC,QAAQ,gBAAY,MAAM,gBAAa,KAAK,IAAI,mBAAmB,EAAE,OAAO,EAAE,OAAO,aAC7G,iBAAQ,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,IAAI,mBAAmB,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,GAAI,EAC5G,aAAG,KAAK,EAAE,CAAC,CAAC,OAAO,aAAG,KAAK,IAAI,uBAAuB,oCAA4B,IAC9E,CACP,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,CACL,eAAK,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAC,QAAQ,gBAAY,MAAM,gBAAa,KAAK,IAAI,2BAA2B,EAAE,OAAO,EAAE,OAAO,aACrH,cAAK,GAAG,EAAE,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,IAAI,0CAA0C,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,GAAI,EACxH,aAAG,KAAK,EAAE,CAAC,CAAC,OAAO,aAChB,KAAK,IAAI,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,cAAK,KAAK,CAAC,MAAM,CAAC,IACxE,IACA,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { CSSProperties } from 'react';
2
+ import type { Components } from 'react-markdown';
3
+ import 'katex/dist/katex.min.css';
4
+ export type { Components as MarkdownComponents } from 'react-markdown';
5
+ /** The content plane's scheme is admitted; every other unknown scheme is stripped, as react-markdown does. */
6
+ export declare const admitAttachmentUrls: (url: string) => string;
7
+ /** Memoized on its props: a settled block keeps its parse while a sibling streams. */
8
+ export declare const Markdown: import("react").NamedExoticComponent<{
9
+ markdown: string;
10
+ /** The caller's renderers — links with citation chips, headings with anchors, the prose's own type. */
11
+ components?: Components;
12
+ style?: CSSProperties;
13
+ }>;
14
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,OAAO,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD,OAAO,0BAA0B,CAAC;AAElC,YAAY,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAUvE,8GAA8G;AAC9G,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,MACgB,CAAC;AAEnE,sFAAsF;AACtF,eAAO,MAAM,QAAQ;cACT,MAAM;IAChB,uGAAuG;iBAC1F,UAAU;YACf,aAAa;EAerB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Markdown in a harness view: GitHub-flavoured, with math set by KaTeX, links
4
+ * left to the caller's renderers, and the content plane's own scheme admitted
5
+ * through the URL transform so a cited page (`attachment://…/page/n`) reaches
6
+ * the caller's link component instead of being stripped as unknown.
7
+ *
8
+ * Math takes the document's own face where that is safe: inline runs inherit
9
+ * the surrounding font, while stacked constructs (fractions, radicals,
10
+ * accents, sized operators and delimiters) keep KaTeX's fonts — its metrics
11
+ * position them, and an inherited face's taller numerals crash into the bar.
12
+ *
13
+ * @category UI
14
+ */
15
+ import { memo } from 'react';
16
+ import ReactMarkdown, { defaultUrlTransform } from 'react-markdown';
17
+ import remarkGfm from 'remark-gfm';
18
+ import remarkMath from 'remark-math';
19
+ import rehypeKatex from 'rehype-katex';
20
+ import 'katex/dist/katex.min.css';
21
+ const MATH = `
22
+ .katex { font-size: 1em !important; }
23
+ .katex, .katex *:not(.delimsizing, .op-symbol) { font-family: inherit !important; }
24
+ .katex :is(.mfrac, .sqrt, .root, .accent) * {
25
+ font-family: KaTeX_Main, "Times New Roman", serif !important;
26
+ }
27
+ `;
28
+ /** The content plane's scheme is admitted; every other unknown scheme is stripped, as react-markdown does. */
29
+ export const admitAttachmentUrls = (url) => url.startsWith('attachment://') ? url : defaultUrlTransform(url);
30
+ /** Memoized on its props: a settled block keeps its parse while a sibling streams. */
31
+ export const Markdown = memo(function Markdown({ markdown, components, style }) {
32
+ return (_jsxs("div", { style: style, children: [_jsx("style", { children: MATH }), _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm, remarkMath], rehypePlugins: [[rehypeKatex, { throwOnError: false }]], urlTransform: admitAttachmentUrls, components: components, children: markdown })] }));
33
+ });
34
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B,OAAO,aAAa,EAAE,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,0BAA0B,CAAC;AAIlC,MAAM,IAAI,GAAG;;;;;;CAMZ,CAAC;AAEF,8GAA8G;AAC9G,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAU,EAAE,CACzD,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAEnE,sFAAsF;AACtF,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAK3E;IACC,OAAO,CACL,eAAK,KAAK,EAAE,KAAK,aACf,0BAAQ,IAAI,GAAS,EACrB,KAAC,aAAa,IACZ,aAAa,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,EACtC,aAAa,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EACvD,YAAY,EAAE,mBAAmB,EACjC,UAAU,EAAE,UAAU,YAErB,QAAQ,GACK,IACZ,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ import type { Availability, Bridge, Projection, WireStatus } from '@lloyal-labs/binding';
3
+ export interface Harness<E, C, S extends object> {
4
+ bridge: Bridge<E, C, S>;
5
+ projection: Projection<S>;
6
+ }
7
+ /** The one projection over a bridge — the provider's, shared with a consumer outside React (a history adapter). */
8
+ export declare function projectionFor<E, C, S extends object>(bridge: Bridge<E, C, S>, initialState: S, reduce: (state: S, ev: E) => S): Projection<S>;
9
+ export declare function HarnessProvider<E, C, S extends object>({ bridge, initialState, reduce, children }: {
10
+ bridge: Bridge<E, C, S>;
11
+ initialState: S;
12
+ reduce: (state: S, ev: E) => S;
13
+ children: ReactNode;
14
+ }): ReactElement;
15
+ /** The provider's bridge and projection, for a consumer outside the hooks (a history adapter). */
16
+ export declare function useHarness<E = unknown, C = unknown, S extends object = object>(): Harness<E, C, S>;
17
+ /** Read a derivation of the folded state, memoized per fold. */
18
+ export declare function useProjection<S extends object, T>(select: (state: S) => T): T;
19
+ /** Dispatch a command to the harness. */
20
+ export declare function useSend<C>(): (command: C) => void;
21
+ /** The wire's status. A bridge without `onStatus` (in-process) reads 'connected' forever. */
22
+ export declare function useConnection(): WireStatus;
23
+ /**
24
+ * Whether this harness can take work, and if not, why — the question a view actually asks.
25
+ *
26
+ * Derived from the transport's status and the host's session phase, because neither answers it
27
+ * alone: a queued reader's socket is healthy, and an ended session is followed by a close that
28
+ * reads as a network failure. Prefer this to {@link useConnection}, which is the transport fact
29
+ * on its own.
30
+ */
31
+ export declare function useAvailability(): Availability;
32
+ /**
33
+ * Ask the placement for a working harness — or null where this bridge cannot provide one.
34
+ *
35
+ * A view knows WHEN recovery is wanted and never what it costs: a browser opens a new connection
36
+ * because a served host cannot re-admit an existing one; a desktop shell starts a new engine while
37
+ * its renderer's IPC link stays up throughout. Same button, different price, and the view pays
38
+ * neither.
39
+ */
40
+ export declare function useRecover(): (() => void) | null;
41
+ /** The content plane's origin, or null on a bridge without one. */
42
+ export declare function useContentOrigin(): string | null;
43
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAgB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvG,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM;IAC7C,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAC3B;AASD,mHAAmH;AACnH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAO7I;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAClG,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxB,YAAY,EAAE,CAAC,CAAC;IAChB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,YAAY,CAGf;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAIlG;AAID,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAc7E;AAED,yCAAyC;AACzC,wBAAgB,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAGjD;AAqCD,6FAA6F;AAC7F,wBAAgB,aAAa,IAAI,UAAU,CAI1C;AA4CD;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAI9C;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAGhD;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAGhD"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * The projection, in React: a provider that connects a bridge once, and hooks
3
+ * that read the fold, the wire's status, the command sink and the content
4
+ * plane's origin. One projection per provider; a remount under the same bridge
5
+ * reattaches to the running fold, it never re-subscribes or resets.
6
+ *
7
+ * `useProjection(select)` memoizes per fold: the state is immutable between
8
+ * events, so a named selector returns the SAME reference until the next fold —
9
+ * what `useSyncExternalStore` needs. The contract: a selector with a stable
10
+ * identity may build objects; an inline selector must return a primitive.
11
+ *
12
+ * The folded state must be an OBJECT, and a new one on every event. Both halves
13
+ * are load-bearing and neither is a style preference: the memo is a `WeakMap`
14
+ * keyed by the snapshot, so a scalar or `null` state is not a legal key at all,
15
+ * and a state mutated in place keeps its identity and so keeps returning the
16
+ * selection cached against the previous fold. `S extends object` states the
17
+ * first half to the compiler. The second is a discipline the type system cannot
18
+ * carry, which is why it is written here.
19
+ *
20
+ * @category UI
21
+ */
22
+ import { createContext, createElement, useContext, useMemo, useSyncExternalStore } from 'react';
23
+ import { connectProjection, availabilityOf } from '@lloyal-labs/binding';
24
+ // `object`, not `unknown`, is what the erased context can say now that `S` is
25
+ // constrained — the hooks below cast back out of it exactly as before.
26
+ const HarnessContext = createContext(null);
27
+ /** One projection per bridge, for the life of the page: a React remount under the same bridge reattaches. */
28
+ const projections = new WeakMap();
29
+ /** The one projection over a bridge — the provider's, shared with a consumer outside React (a history adapter). */
30
+ export function projectionFor(bridge, initialState, reduce) {
31
+ let projection = projections.get(bridge);
32
+ if (!projection) {
33
+ projection = connectProjection(bridge, initialState, reduce);
34
+ projections.set(bridge, projection);
35
+ }
36
+ return projection;
37
+ }
38
+ export function HarnessProvider({ bridge, initialState, reduce, children }) {
39
+ const value = useMemo(() => ({ bridge, projection: projectionFor(bridge, initialState, reduce) }), [bridge]);
40
+ return createElement(HarnessContext.Provider, { value: value }, children);
41
+ }
42
+ /** The provider's bridge and projection, for a consumer outside the hooks (a history adapter). */
43
+ export function useHarness() {
44
+ const h = useContext(HarnessContext);
45
+ if (!h)
46
+ throw new Error('useHarness: no HarnessProvider above this component');
47
+ return h;
48
+ }
49
+ const derived = new WeakMap();
50
+ /** Read a derivation of the folded state, memoized per fold. */
51
+ export function useProjection(select) {
52
+ const { projection } = useHarness();
53
+ const read = () => {
54
+ const state = projection.getSnapshot();
55
+ let memo = derived.get(state);
56
+ if (!memo) {
57
+ memo = new Map();
58
+ derived.set(state, memo);
59
+ }
60
+ const key = select;
61
+ if (!memo.has(key))
62
+ memo.set(key, select(state));
63
+ return memo.get(key);
64
+ };
65
+ return useSyncExternalStore(projection.subscribe, read, read);
66
+ }
67
+ /** Dispatch a command to the harness. */
68
+ export function useSend() {
69
+ const { bridge } = useHarness();
70
+ return bridge.send;
71
+ }
72
+ /** One status per bridge, for the life of the page. React reads `getSnapshot`
73
+ * during render, so the status it reads must outlive the render that reads it:
74
+ * the bridge is told once, here, and every renderer of it shares that one
75
+ * answer. A bridge without `onStatus` (in-process) never leaves 'connected'. */
76
+ const statuses = new WeakMap();
77
+ function statusFor(bridge) {
78
+ let store = statuses.get(bridge);
79
+ if (!store) {
80
+ let status = 'connected';
81
+ const listeners = new Set();
82
+ bridge.onStatus?.((next) => {
83
+ status = next;
84
+ for (const notify of listeners)
85
+ notify();
86
+ });
87
+ store = {
88
+ subscribe(notify) {
89
+ listeners.add(notify);
90
+ return () => { listeners.delete(notify); };
91
+ },
92
+ getSnapshot: () => status,
93
+ };
94
+ statuses.set(bridge, store);
95
+ }
96
+ return store;
97
+ }
98
+ /** The status a server render reads: no wire has been asked yet. */
99
+ const connected = () => 'connected';
100
+ /** The wire's status. A bridge without `onStatus` (in-process) reads 'connected' forever. */
101
+ export function useConnection() {
102
+ const { bridge } = useHarness();
103
+ const wire = statusFor(bridge);
104
+ return useSyncExternalStore(wire.subscribe, wire.getSnapshot, connected);
105
+ }
106
+ /** One derivation per bridge, for the life of the page — the same reason the status has one. */
107
+ const availabilities = new WeakMap();
108
+ function availabilityFor(bridge) {
109
+ let store = availabilities.get(bridge);
110
+ if (!store) {
111
+ // A bridge with no droppable link is up, and one with no session plane has a single implicit
112
+ // session that is live: nothing queues it and nothing reaps it, so "waiting" and "ended" are not
113
+ // states it can be in. This is the ONE place a placement difference is stated; the derivation
114
+ // itself knows no placements.
115
+ let wire = 'connected';
116
+ let session = bridge.onSession ? null : { phase: 'live' };
117
+ let value = availabilityOf(session, wire);
118
+ const listeners = new Set();
119
+ const settle = () => {
120
+ const next = availabilityOf(session, wire);
121
+ if (next === value)
122
+ return;
123
+ value = next;
124
+ for (const notify of listeners)
125
+ notify();
126
+ };
127
+ bridge.onStatus?.((next) => { wire = next; settle(); });
128
+ bridge.onSession?.((next) => { session = next; settle(); });
129
+ store = {
130
+ subscribe(notify) {
131
+ listeners.add(notify);
132
+ return () => { listeners.delete(notify); };
133
+ },
134
+ getSnapshot: () => value,
135
+ };
136
+ availabilities.set(bridge, store);
137
+ }
138
+ return store;
139
+ }
140
+ /** What a server render reads: nothing has been asked of either plane yet. */
141
+ const starting = () => 'connecting';
142
+ /**
143
+ * Whether this harness can take work, and if not, why — the question a view actually asks.
144
+ *
145
+ * Derived from the transport's status and the host's session phase, because neither answers it
146
+ * alone: a queued reader's socket is healthy, and an ended session is followed by a close that
147
+ * reads as a network failure. Prefer this to {@link useConnection}, which is the transport fact
148
+ * on its own.
149
+ */
150
+ export function useAvailability() {
151
+ const { bridge } = useHarness();
152
+ const store = availabilityFor(bridge);
153
+ return useSyncExternalStore(store.subscribe, store.getSnapshot, starting);
154
+ }
155
+ /**
156
+ * Ask the placement for a working harness — or null where this bridge cannot provide one.
157
+ *
158
+ * A view knows WHEN recovery is wanted and never what it costs: a browser opens a new connection
159
+ * because a served host cannot re-admit an existing one; a desktop shell starts a new engine while
160
+ * its renderer's IPC link stays up throughout. Same button, different price, and the view pays
161
+ * neither.
162
+ */
163
+ export function useRecover() {
164
+ const { bridge } = useHarness();
165
+ return useMemo(() => (bridge.recover ? () => bridge.recover() : null), [bridge]);
166
+ }
167
+ /** The content plane's origin, or null on a bridge without one. */
168
+ export function useContentOrigin() {
169
+ const { bridge } = useHarness();
170
+ return bridge.contentOrigin?.() ?? null;
171
+ }
172
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAEhG,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQzE,8EAA8E;AAC9E,uEAAuE;AACvE,MAAM,cAAc,GAAG,aAAa,CAA2C,IAAI,CAAC,CAAC;AAErF,6GAA6G;AAC7G,MAAM,WAAW,GAAG,IAAI,OAAO,EAA+B,CAAC;AAE/D,mHAAmH;AACnH,MAAM,UAAU,aAAa,CAAyB,MAAuB,EAAE,YAAe,EAAE,MAA8B;IAC5H,IAAI,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAA8B,CAAC;IACtE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAC7D,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,eAAe,CAAyB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAK/F;IACC,MAAM,KAAK,GAAG,OAAO,CAAmB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/H,OAAO,aAAa,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAA0C,EAAE,EAAE,QAAQ,CAAC,CAAC;AACjH,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAC/E,OAAO,CAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAA+C,CAAC;AAE3E,gEAAgE;AAChE,MAAM,UAAU,aAAa,CAAsB,MAAuB;IACxE,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAuB,CAAC;IACzD,MAAM,IAAI,GAAG,GAAM,EAAE;QACnB,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,MAAM,GAAG,GAAG,MAA0C,CAAC;QACvD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAM,CAAC;IAC5B,CAAC,CAAC;IACF,OAAO,oBAAoB,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,OAAO;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAsB,CAAC;IACpD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAOD;;;iFAGiF;AACjF,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAqB,CAAC;AAElD,SAAS,SAAS,CAAC,MAAyC;IAC1D,IAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,MAAM,GAAe,WAAW,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;QACxC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE;YACzB,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,MAAM,MAAM,IAAI,SAAS;gBAAE,MAAM,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;QACH,KAAK,GAAG;YACN,SAAS,CAAC,MAAM;gBACd,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACtB,OAAO,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;YACD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM;SAC1B,CAAC;QACF,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,oEAAoE;AACpE,MAAM,SAAS,GAAG,GAAe,EAAE,CAAC,WAAW,CAAC;AAEhD,6FAA6F;AAC7F,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAC3E,CAAC;AAOD,gGAAgG;AAChG,MAAM,cAAc,GAAG,IAAI,OAAO,EAA6B,CAAC;AAEhE,SAAS,eAAe,CAAC,MAAyC;IAChE,IAAI,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,6FAA6F;QAC7F,iGAAiG;QACjG,8FAA8F;QAC9F,8BAA8B;QAC9B,IAAI,IAAI,GAAe,WAAW,CAAC;QACnC,IAAI,OAAO,GAAwB,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC/E,IAAI,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;QACxC,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC3C,IAAI,IAAI,KAAK,KAAK;gBAAE,OAAO;YAC3B,KAAK,GAAG,IAAI,CAAC;YACb,KAAK,MAAM,MAAM,IAAI,SAAS;gBAAE,MAAM,EAAE,CAAC;QAC3C,CAAC,CAAC;QACF,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,KAAK,GAAG;YACN,SAAS,CAAC,MAAM;gBACd,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACtB,OAAO,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;YACD,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK;SACzB,CAAC;QACF,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,MAAM,QAAQ,GAAG,GAAiB,EAAE,CAAC,YAAY,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IAChC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAS,EAAE,CAAC,MAAM,CAAC,OAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;IAChC,OAAO,MAAM,CAAC,aAAa,EAAE,EAAE,IAAI,IAAI,CAAC;AAC1C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@lloyal-labs/ui",
3
+ "version": "0.1.0-alpha.6",
4
+ "description": "The view side of a harness: the projection provider and hooks over a bridge, the generic agent fold, and the prose and figure primitives",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./fold": {
14
+ "types": "./dist/fold.d.ts",
15
+ "default": "./dist/fold.js"
16
+ }
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/lloyal-ai/hdk.git",
24
+ "directory": "packages/ui"
25
+ },
26
+ "homepage": "https://github.com/lloyal-ai/hdk/tree/main/packages/ui#readme",
27
+ "bugs": {
28
+ "url": "https://github.com/lloyal-ai/hdk/issues"
29
+ },
30
+ "keywords": [
31
+ "ui",
32
+ "react",
33
+ "harness",
34
+ "projection",
35
+ "markdown"
36
+ ],
37
+ "license": "SEE LICENSE IN LICENSE",
38
+ "files": [
39
+ "dist/",
40
+ "LICENSE"
41
+ ],
42
+ "scripts": {
43
+ "build": "tsc -p tsconfig.json"
44
+ },
45
+ "dependencies": {
46
+ "@lloyal-labs/binding": "0.2.0-alpha.6",
47
+ "@lloyal-labs/media": "0.2.0-alpha.6",
48
+ "katex": "^0.16.22",
49
+ "react-markdown": "^10.1.0",
50
+ "rehype-katex": "^7.0.1",
51
+ "remark-gfm": "^4.0.1",
52
+ "remark-math": "^6.0.0"
53
+ },
54
+ "peerDependencies": {
55
+ "react": "^18.3.0 || ^19.0.0"
56
+ }
57
+ }