@graview/primitives 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.
Files changed (207) hide show
  1. package/LICENSE +96 -0
  2. package/README.md +25 -0
  3. package/dist/arrange-bar.d.ts +49 -0
  4. package/dist/arrange-bar.d.ts.map +1 -0
  5. package/dist/arrange-bar.js +264 -0
  6. package/dist/arrange-bar.js.map +1 -0
  7. package/dist/chat.d.ts +46 -0
  8. package/dist/chat.d.ts.map +1 -0
  9. package/dist/chat.js +343 -0
  10. package/dist/chat.js.map +1 -0
  11. package/dist/companion.d.ts +58 -0
  12. package/dist/companion.d.ts.map +1 -0
  13. package/dist/companion.js +433 -0
  14. package/dist/companion.js.map +1 -0
  15. package/dist/connections.d.ts +23 -0
  16. package/dist/connections.d.ts.map +1 -0
  17. package/dist/connections.js +100 -0
  18. package/dist/connections.js.map +1 -0
  19. package/dist/default-views.d.ts +35 -0
  20. package/dist/default-views.d.ts.map +1 -0
  21. package/dist/default-views.js +605 -0
  22. package/dist/default-views.js.map +1 -0
  23. package/dist/editable.d.ts +71 -0
  24. package/dist/editable.d.ts.map +1 -0
  25. package/dist/editable.js +225 -0
  26. package/dist/editable.js.map +1 -0
  27. package/dist/figure.d.ts +30 -0
  28. package/dist/figure.d.ts.map +1 -0
  29. package/dist/figure.js +66 -0
  30. package/dist/figure.js.map +1 -0
  31. package/dist/find.d.ts +5 -0
  32. package/dist/find.d.ts.map +1 -0
  33. package/dist/find.js +252 -0
  34. package/dist/find.js.map +1 -0
  35. package/dist/index.d.ts +51 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +44 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/installation.d.ts +17 -0
  40. package/dist/installation.d.ts.map +1 -0
  41. package/dist/installation.js +37 -0
  42. package/dist/installation.js.map +1 -0
  43. package/dist/ladder.d.ts +2 -0
  44. package/dist/ladder.d.ts.map +1 -0
  45. package/dist/ladder.js +53 -0
  46. package/dist/ladder.js.map +1 -0
  47. package/dist/lens/arranging.d.ts +41 -0
  48. package/dist/lens/arranging.d.ts.map +1 -0
  49. package/dist/lens/arranging.js +38 -0
  50. package/dist/lens/arranging.js.map +1 -0
  51. package/dist/lens/board.d.ts +146 -0
  52. package/dist/lens/board.d.ts.map +1 -0
  53. package/dist/lens/board.js +658 -0
  54. package/dist/lens/board.js.map +1 -0
  55. package/dist/lens/calendar-dates.d.ts +19 -0
  56. package/dist/lens/calendar-dates.d.ts.map +1 -0
  57. package/dist/lens/calendar-dates.js +55 -0
  58. package/dist/lens/calendar-dates.js.map +1 -0
  59. package/dist/lens/calendar-drawing.d.ts +59 -0
  60. package/dist/lens/calendar-drawing.d.ts.map +1 -0
  61. package/dist/lens/calendar-drawing.js +229 -0
  62. package/dist/lens/calendar-drawing.js.map +1 -0
  63. package/dist/lens/calendar-options.d.ts +107 -0
  64. package/dist/lens/calendar-options.d.ts.map +1 -0
  65. package/dist/lens/calendar-options.js +19 -0
  66. package/dist/lens/calendar-options.js.map +1 -0
  67. package/dist/lens/calendar-placing.d.ts +35 -0
  68. package/dist/lens/calendar-placing.d.ts.map +1 -0
  69. package/dist/lens/calendar-placing.js +113 -0
  70. package/dist/lens/calendar-placing.js.map +1 -0
  71. package/dist/lens/calendar-spans.d.ts +48 -0
  72. package/dist/lens/calendar-spans.d.ts.map +1 -0
  73. package/dist/lens/calendar-spans.js +146 -0
  74. package/dist/lens/calendar-spans.js.map +1 -0
  75. package/dist/lens/calendar-view.d.ts +34 -0
  76. package/dist/lens/calendar-view.d.ts.map +1 -0
  77. package/dist/lens/calendar-view.js +228 -0
  78. package/dist/lens/calendar-view.js.map +1 -0
  79. package/dist/lens/calendar.d.ts +43 -0
  80. package/dist/lens/calendar.d.ts.map +1 -0
  81. package/dist/lens/calendar.js +43 -0
  82. package/dist/lens/calendar.js.map +1 -0
  83. package/dist/lens/coverage.d.ts +183 -0
  84. package/dist/lens/coverage.d.ts.map +1 -0
  85. package/dist/lens/coverage.js +732 -0
  86. package/dist/lens/coverage.js.map +1 -0
  87. package/dist/lens/horizon.d.ts +14 -0
  88. package/dist/lens/horizon.d.ts.map +1 -0
  89. package/dist/lens/horizon.js +20 -0
  90. package/dist/lens/horizon.js.map +1 -0
  91. package/dist/lens/more.d.ts +16 -0
  92. package/dist/lens/more.d.ts.map +1 -0
  93. package/dist/lens/more.js +17 -0
  94. package/dist/lens/more.js.map +1 -0
  95. package/dist/lens/plan-lens.d.ts +17 -0
  96. package/dist/lens/plan-lens.d.ts.map +1 -0
  97. package/dist/lens/plan-lens.js +24 -0
  98. package/dist/lens/plan-lens.js.map +1 -0
  99. package/dist/lens/plan-state.d.ts +122 -0
  100. package/dist/lens/plan-state.d.ts.map +1 -0
  101. package/dist/lens/plan-state.js +152 -0
  102. package/dist/lens/plan-state.js.map +1 -0
  103. package/dist/lens/plan-view.d.ts +10 -0
  104. package/dist/lens/plan-view.d.ts.map +1 -0
  105. package/dist/lens/plan-view.js +576 -0
  106. package/dist/lens/plan-view.js.map +1 -0
  107. package/dist/lens/plan.d.ts +25 -0
  108. package/dist/lens/plan.d.ts.map +1 -0
  109. package/dist/lens/plan.js +25 -0
  110. package/dist/lens/plan.js.map +1 -0
  111. package/dist/lens/reach.d.ts +47 -0
  112. package/dist/lens/reach.d.ts.map +1 -0
  113. package/dist/lens/reach.js +67 -0
  114. package/dist/lens/reach.js.map +1 -0
  115. package/dist/lens/timeline.d.ts +137 -0
  116. package/dist/lens/timeline.d.ts.map +1 -0
  117. package/dist/lens/timeline.js +426 -0
  118. package/dist/lens/timeline.js.map +1 -0
  119. package/dist/markup.d.ts +23 -0
  120. package/dist/markup.d.ts.map +1 -0
  121. package/dist/markup.js +24 -0
  122. package/dist/markup.js.map +1 -0
  123. package/dist/places.d.ts +24 -0
  124. package/dist/places.d.ts.map +1 -0
  125. package/dist/places.js +227 -0
  126. package/dist/places.js.map +1 -0
  127. package/dist/popover.d.ts +28 -0
  128. package/dist/popover.d.ts.map +1 -0
  129. package/dist/popover.js +59 -0
  130. package/dist/popover.js.map +1 -0
  131. package/dist/primitives/index.d.ts +214 -0
  132. package/dist/primitives/index.d.ts.map +1 -0
  133. package/dist/primitives/index.js +381 -0
  134. package/dist/primitives/index.js.map +1 -0
  135. package/dist/profile.d.ts +65 -0
  136. package/dist/profile.d.ts.map +1 -0
  137. package/dist/profile.js +233 -0
  138. package/dist/profile.js.map +1 -0
  139. package/dist/quick-relations.d.ts +16 -0
  140. package/dist/quick-relations.d.ts.map +1 -0
  141. package/dist/quick-relations.js +183 -0
  142. package/dist/quick-relations.js.map +1 -0
  143. package/dist/relation-key.d.ts +44 -0
  144. package/dist/relation-key.d.ts.map +1 -0
  145. package/dist/relation-key.js +196 -0
  146. package/dist/relation-key.js.map +1 -0
  147. package/dist/seat.d.ts +137 -0
  148. package/dist/seat.d.ts.map +1 -0
  149. package/dist/seat.js +162 -0
  150. package/dist/seat.js.map +1 -0
  151. package/dist/seats.d.ts +21 -0
  152. package/dist/seats.d.ts.map +1 -0
  153. package/dist/seats.js +62 -0
  154. package/dist/seats.js.map +1 -0
  155. package/dist/seeding.d.ts +150 -0
  156. package/dist/seeding.d.ts.map +1 -0
  157. package/dist/seeding.js +538 -0
  158. package/dist/seeding.js.map +1 -0
  159. package/dist/shell.d.ts +74 -0
  160. package/dist/shell.d.ts.map +1 -0
  161. package/dist/shell.js +86 -0
  162. package/dist/shell.js.map +1 -0
  163. package/dist/theme.d.ts +50 -0
  164. package/dist/theme.d.ts.map +1 -0
  165. package/dist/theme.js +1692 -0
  166. package/dist/theme.js.map +1 -0
  167. package/dist/wordmark.d.ts +15 -0
  168. package/dist/wordmark.d.ts.map +1 -0
  169. package/dist/wordmark.js +55 -0
  170. package/dist/wordmark.js.map +1 -0
  171. package/dist/workbench/activity.d.ts +75 -0
  172. package/dist/workbench/activity.d.ts.map +1 -0
  173. package/dist/workbench/activity.js +259 -0
  174. package/dist/workbench/activity.js.map +1 -0
  175. package/dist/workbench/agent-seat.d.ts +51 -0
  176. package/dist/workbench/agent-seat.d.ts.map +1 -0
  177. package/dist/workbench/agent-seat.js +112 -0
  178. package/dist/workbench/agent-seat.js.map +1 -0
  179. package/dist/workbench/answer-args.d.ts +31 -0
  180. package/dist/workbench/answer-args.d.ts.map +1 -0
  181. package/dist/workbench/answer-args.js +257 -0
  182. package/dist/workbench/answer-args.js.map +1 -0
  183. package/dist/workbench/back-out.d.ts +71 -0
  184. package/dist/workbench/back-out.d.ts.map +1 -0
  185. package/dist/workbench/back-out.js +238 -0
  186. package/dist/workbench/back-out.js.map +1 -0
  187. package/dist/workbench/following.d.ts +7 -0
  188. package/dist/workbench/following.d.ts.map +1 -0
  189. package/dist/workbench/following.js +26 -0
  190. package/dist/workbench/following.js.map +1 -0
  191. package/dist/workbench/index.d.ts +23 -0
  192. package/dist/workbench/index.d.ts.map +1 -0
  193. package/dist/workbench/index.js +23 -0
  194. package/dist/workbench/index.js.map +1 -0
  195. package/dist/workbench/inspector.d.ts +27 -0
  196. package/dist/workbench/inspector.d.ts.map +1 -0
  197. package/dist/workbench/inspector.js +745 -0
  198. package/dist/workbench/inspector.js.map +1 -0
  199. package/dist/workbench/standing.d.ts +16 -0
  200. package/dist/workbench/standing.d.ts.map +1 -0
  201. package/dist/workbench/standing.js +102 -0
  202. package/dist/workbench/standing.js.map +1 -0
  203. package/dist/workbench/trail.d.ts +35 -0
  204. package/dist/workbench/trail.d.ts.map +1 -0
  205. package/dist/workbench/trail.js +150 -0
  206. package/dist/workbench/trail.js.map +1 -0
  207. package/package.json +62 -0
@@ -0,0 +1,196 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { resolveKit } from "@graview/core";
3
+ import { kitConnector, useGraph, useGraview, useGraviewIfAny, useKit, useNavigation, useSelection } from "@graview/react";
4
+ import { CONNECTOR_DASH, connectorStroke, connectorWidth, } from "@graview/render";
5
+ import { useEffect, useMemo } from "react";
6
+ /**
7
+ * What the lines mean.
8
+ *
9
+ * From the Graview the relations ARE the content, drawn with a colour and a
10
+ * stroke pattern per edge kind — and nothing said which was which. A picture
11
+ * of a domain whose only legend is "these are different from each other"
12
+ * answers the shape of the question and not the question.
13
+ *
14
+ * Everything here is derived: the edge kinds come from the schema, the
15
+ * treatment from the same `connectorStyle` the scene draws with, the
16
+ * descriptions from the declarations, and the counts from the graph. Nothing
17
+ * is authored per app, and a new edge kind appears the day it is declared.
18
+ *
19
+ * Clicking one selects the kinds it joins, which is the same gesture as
20
+ * clicking a card: from up here, "show me what this touches" is the only thing
21
+ * selecting can mean.
22
+ */
23
+ export function RelationKey({ inside = false } = {}) {
24
+ const { store, view, emphasis, setEmphasis } = useGraview();
25
+ // The same kit the scene draws with: a swatch that ignored the brand's kit would be a key you cannot trust.
26
+ const kit = useKit();
27
+ const { selection, set } = useSelection();
28
+ const { show } = useNavigation();
29
+ // Recomputed when the graph changes, so a relation nobody uses yet does not
30
+ // sit in the key claiming to exist.
31
+ const nodes = useGraph();
32
+ /*
33
+ * One pass over the edges, not one per relation.
34
+ *
35
+ * `allEdges()` materialises a fresh array every call, and this component
36
+ * re-renders on every diff — so scanning once per edge kind, plus again for
37
+ * the counts, rebuilt the whole edge list six times per mutation while the
38
+ * Graview was open.
39
+ */
40
+ const relations = useMemo(() => {
41
+ const found = new Map();
42
+ for (const edge of store.graph.allEdges()) {
43
+ const entry = found.get(edge.kind) ?? { count: 0, ends: new Set() };
44
+ entry.count += 1;
45
+ for (const id of [edge.from, edge.to]) {
46
+ const node = store.graph.getNode(id);
47
+ if (node)
48
+ entry.ends.add(`kind:${node.kind}`);
49
+ }
50
+ found.set(edge.kind, entry);
51
+ }
52
+ return [...found.entries()]
53
+ .sort(([a], [b]) => a.localeCompare(b))
54
+ .map(([kind, entry]) => ({ kind, count: entry.count, ends: [...entry.ends] }));
55
+ }, [store, nodes]);
56
+ // A key that disappears mid-hover must not leave its question standing.
57
+ useEffect(() => () => setEmphasis(null), [setEmphasis]);
58
+ // Inside the companion it stands at every height: the rail is the one
59
+ // place the lines are explained, and they are drawn on the ground too.
60
+ if ((!view.overview && !inside) || relations.length === 0)
61
+ return null;
62
+ /*
63
+ * A relation is LIT when the selection reaches one of the kinds it joins.
64
+ *
65
+ * Resolved the same way the scene resolves a connector endpoint: the
66
+ * selection holds real node ids, and up here what is drawn is a kind card.
67
+ * Comparing them directly dimmed every row at once whenever an ordinary
68
+ * selection was carried into the Graview — a legend reading "nothing
69
+ * matches" when nothing was asked.
70
+ */
71
+ const chosen = new Set();
72
+ for (const id of selection) {
73
+ if (id.startsWith("kind:")) {
74
+ chosen.add(id);
75
+ continue;
76
+ }
77
+ const node = store.graph.getNode(id);
78
+ if (node)
79
+ chosen.add(`kind:${node.kind}`);
80
+ }
81
+ return (_jsxs("aside", { "aria-label": "What the lines mean", "data-testid": "relation-key", style: inside ? { display: "grid", gap: 1 } : {
82
+ position: "absolute",
83
+ /*
84
+ * The TOP-LEFT corner, mirroring the altitude control top-right.
85
+ *
86
+ * The bottom-left is ring ground now — the near-left districts land
87
+ * there, and the key was sitting on them. The upper corners are the
88
+ * one part of the ellipse that stays empty at every count.
89
+ */
90
+ left: 16,
91
+ top: 14,
92
+ zIndex: 5,
93
+ display: "grid",
94
+ gap: 1,
95
+ padding: "8px 10px",
96
+ borderRadius: 10,
97
+ border: "1px solid var(--graview-edge)",
98
+ background: "var(--graview-float)",
99
+ boxShadow: "var(--graview-lift-low)",
100
+ /*
101
+ * IT STAYS INSIDE ITS OWN RAIL.
102
+ *
103
+ * The scene reserves a left rail for this and the panes beside it —
104
+ * `min(264, width * 0.22)` — and the key was sized in fixed pixels,
105
+ * so the two agreed only on a wide screen. Below about 740px of
106
+ * scene the key is wider than the rail it was given, and whatever
107
+ * the layout drew at the left edge of the focus band was under it:
108
+ * a product in a 700x520 embed had a panel's title clipped to
109
+ * "…nds" by this card.
110
+ *
111
+ * The same formula, in CSS, minus its own 16px offset and a margin,
112
+ * so the cap cannot drift from the rail again. The 110px floor is
113
+ * where a key stops being readable at all — under about 590px of
114
+ * scene the floor wins, and at that width the scene is a desk view
115
+ * in a phone's clothing anyway (see the routed face).
116
+ */
117
+ maxWidth: "max(110px, calc(min(250px, 22%) - 32px))",
118
+ // Arrives after the cards have mostly flown, rather than popping at
119
+ // the cut.
120
+ animation: "graview-settle 380ms 280ms ease backwards",
121
+ }, children: [_jsx("span", { style: {
122
+ fontSize: "0.75rem",
123
+ letterSpacing: "0.16em",
124
+ textTransform: "uppercase",
125
+ color: "var(--graview-ink-faint)",
126
+ paddingBottom: 2,
127
+ }, children: relations.length === 1 ? "1 relation" : `${relations.length} relations` }), relations.map(({ kind: edgeKind, count, ends }) => {
128
+ const { connector, style } = kitConnector(kit, edgeKind);
129
+ const lit = emphasis !== null
130
+ ? emphasis === edgeKind
131
+ : chosen.size === 0 || ends.some((id) => chosen.has(id));
132
+ return (_jsxs("button", { type: "button",
133
+ // The schema's own accessor, which resolves first-declaration-wins
134
+ // exactly like the hand-rolled scan did, without a cast that would
135
+ // stop catching a shape change.
136
+ title: store.schema.edge(edgeKind)?.description ?? `${count} of these`,
137
+ /*
138
+ * Pointing at a row asks the picture the question: this relation's
139
+ * lines come forward and the rest recede. From up here the lines
140
+ * are the content, and a legend that cannot pick one line out of
141
+ * the picture is a caption, not a key.
142
+ */
143
+ onMouseEnter: () => setEmphasis(edgeKind), onMouseLeave: () => setEmphasis(null), onFocus: () => setEmphasis(edgeKind), onBlur: () => setEmphasis(null), onClick: () => {
144
+ // Same gesture as clicking a card: show me what this touches.
145
+ set(ends);
146
+ show(null);
147
+ }, style: {
148
+ all: "unset",
149
+ // `all: unset` resets `outline` too, and an inline declaration
150
+ // beats the stylesheet — so the theme's focus ring disappears
151
+ // from the only controls in here unless it is restored.
152
+ outline: "revert-layer",
153
+ cursor: "pointer",
154
+ display: "grid",
155
+ gridTemplateColumns: "30px 1fr auto",
156
+ alignItems: "center",
157
+ gap: 8,
158
+ minHeight: 23,
159
+ padding: "2px 4px",
160
+ borderRadius: 6,
161
+ opacity: lit ? 1 : 0.4,
162
+ }, children: [_jsx("svg", { width: "30", height: "8", "aria-hidden": "true", style: { display: "block", opacity: connector.visible ? 1 : 0.35 }, children: _jsx("path", { d: "M 1 4 L 29 4", fill: "none", stroke: connectorStroke(style), strokeWidth: connectorWidth(style, true), strokeDasharray: CONNECTOR_DASH[style.pattern], strokeLinecap: "round" }) }), _jsxs("span", { style: { display: "grid", minWidth: 0 }, "data-graview-relation-words": edgeKind, children: [_jsx("span", { style: { fontSize: "0.8125rem", color: "var(--graview-ink)" }, children: relationWords(store.schema, edgeKind).words }), _jsx("span", { style: { fontSize: "0.6875rem", color: "var(--graview-ink-faint)" }, children: relationWords(store.schema, edgeKind).ends })] }), connector.visible ? null : (_jsx("span", { "data-graview-quiet": edgeKind, style: { fontSize: "0.75rem", color: "var(--graview-ink-faint)", fontStyle: "italic" }, children: "not drawn" })), _jsx("span", { style: {
163
+ fontSize: "0.75rem",
164
+ color: "var(--graview-ink-faint)",
165
+ fontVariantNumeric: "tabular-nums",
166
+ }, children: count })] }, edgeKind));
167
+ })] }));
168
+ }
169
+ /**
170
+ * What a relation is called where a person reads it: the declaration's
171
+ * description, capitalised, and which kinds it runs between in their
172
+ * plurals — "The vehicle it is for", "Deals → Vehicles". The edge's name is
173
+ * the source's word for it and only stands in when nothing else was said.
174
+ */
175
+ export function relationWords(schema, edgeKind) {
176
+ const info = schema.edge(edgeKind);
177
+ const said = info?.description ?? edgeKind.replace(/[-_]+/g, " ");
178
+ const plural = (kind) => schema.tryDefinition(kind)?.plural ?? kind;
179
+ const from = (info?.from ?? []).map(plural).join(", ");
180
+ const to = info === undefined ? "" : info.to === "*" ? "anything" : info.to.map(plural).join(", ");
181
+ return { words: said.charAt(0).toUpperCase() + said.slice(1), ends: from && to ? `${from} → ${to}` : "" };
182
+ }
183
+ /**
184
+ * ONE RELATION'S MARK, on its own: the same stroke the scene draws and the
185
+ * key lists, for any surface that names an edge kind — the routed face's
186
+ * map of the kinds, a record's relation groups. Works with or without the
187
+ * scene's provider: outside one, the brand's kit is resolved from what the
188
+ * caller hands over, or the default kit stands.
189
+ */
190
+ export function RelationMark({ edgeKind, kit: given, width = 30 }) {
191
+ const context = useGraviewIfAny();
192
+ const kit = useMemo(() => resolveKit(given ?? context?.brand?.kit), [given, context?.brand?.kit]);
193
+ const { connector, style } = kitConnector(kit, edgeKind);
194
+ return (_jsx("svg", { width: width, height: "8", "aria-hidden": "true", "data-testid": "relation-mark", "data-graview-relation": edgeKind, style: { display: "inline-block", verticalAlign: "middle", opacity: connector.visible ? 1 : 0.35 }, children: _jsx("path", { d: `M 1 4 L ${width - 1} 4`, fill: "none", stroke: connectorStroke(style), strokeWidth: connectorWidth(style, true), strokeDasharray: CONNECTOR_DASH[style.pattern], strokeLinecap: "round" }) }));
195
+ }
196
+ //# sourceMappingURL=relation-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-key.js","sourceRoot":"","sources":["../src/relation-key.tsx"],"names":[],"mappings":"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"}
package/dist/seat.d.ts ADDED
@@ -0,0 +1,137 @@
1
+ import type { ChatContext, ChatReply, LocalStatus, OfferedQuestion, ProposedCall } from "@graview/tools";
2
+ import { type ReactNode } from "react";
3
+ /**
4
+ * ONE CONVERSATION WITH A SEAT, WHEREVER IT IS HELD.
5
+ *
6
+ * The app's chat and the studio's declaration seat were two conversations
7
+ * written twice, and they drifted the way copies do: one put the person in
8
+ * a bubble and the seat in prose, the other boxed both; one settled a
9
+ * proposal in place, the other wrote "Kept — … undo takes it back" under
10
+ * it; one told the model what had been applied, the other did not. A
11
+ * person moving from the app into its studio met a second assistant.
12
+ *
13
+ * What is shared is everything a conversation IS: the turns, what became of
14
+ * each proposal, what the model is told happened, the header that says
15
+ * which rung is answering, the thread and the field. What differs is only
16
+ * what a proposal is FOR — a change to the graph, applied; a change to the
17
+ * declaration, checked and kept — so a surface supplies how one proposal is
18
+ * drawn and nothing else.
19
+ */
20
+ export interface SeatTurn {
21
+ readonly role: "person" | "seat";
22
+ readonly text: string;
23
+ readonly proposals?: readonly ProposedCall[];
24
+ /** Questions the seat is asking back, each at the node it is about. */
25
+ readonly questions?: readonly OfferedQuestion[];
26
+ /** The rung could not read the sentence: a model would, one press away. */
27
+ readonly unsure?: boolean;
28
+ /** What the words found, when that was the answer: each a way to go there. */
29
+ readonly picks?: ChatReply["picks"];
30
+ }
31
+ /**
32
+ * WHAT BECAME OF A PROPOSAL, said where it was offered. Each settling used
33
+ * to post a message of its own, so one request read as five; the press
34
+ * becomes its own outcome instead, in place.
35
+ */
36
+ export type SeatOutcome = {
37
+ readonly state: "applied";
38
+ readonly said: string;
39
+ } | {
40
+ readonly state: "declined";
41
+ readonly said: string;
42
+ } | {
43
+ readonly state: "refused";
44
+ readonly error: string;
45
+ };
46
+ /** The key of a proposal in the thread: which turn, which of its proposals. */
47
+ export declare const proposalKey: (turn: number, at: number) => string;
48
+ export type SeatAnswer = (text: string, context: Pick<ChatContext, "history">) => Promise<ChatReply>;
49
+ /**
50
+ * The conversation's state and its one loop: ask, answer, record.
51
+ *
52
+ * WHAT WAS DONE is part of what was said. "Erin tends that plot" means the
53
+ * plot the last turn made, and the model only knows which if the history
54
+ * carries what landed, by name — so every surface sends it, not just one.
55
+ */
56
+ export declare function useSeatConversation({ answer, onReply, }: {
57
+ readonly answer: SeatAnswer;
58
+ /** Said from the body too, or refused at a gate: whatever the surface does with a reply besides showing it. */
59
+ readonly onReply?: (reply: ChatReply) => void;
60
+ }): {
61
+ turns: readonly SeatTurn[];
62
+ outcomes: ReadonlyMap<string, SeatOutcome>;
63
+ busy: boolean;
64
+ send: (text: string) => Promise<void>;
65
+ settle: (key: string, outcome: SeatOutcome) => void;
66
+ };
67
+ /** Where answers are coming from right now, for the header — the same words on every surface. */
68
+ export declare function describeSource(described: string, warmth: LocalStatus | null, floor?: string): string;
69
+ export declare function SeatHeader({ label, source, sourceTitle, testId, settings, onSettings, foot, }: {
70
+ /** What the seat talks about: "Seat" in the app, "Declaration" in the studio. */
71
+ readonly label: string;
72
+ readonly source: string;
73
+ readonly sourceTitle?: string;
74
+ readonly testId: string;
75
+ readonly settings?: boolean;
76
+ /** Under the composer rather than over the thread: a status line, not a title. */
77
+ readonly foot?: boolean;
78
+ /** Absent when the ladder is not the reader's to set — a host answers for them. */
79
+ readonly onSettings?: () => void;
80
+ }): import("react").JSX.Element;
81
+ /**
82
+ * The seat's trailing aside — "(from the graph)", "(the local model is
83
+ * warming …)" — is which rung answered, not the answer: kept, and set
84
+ * quieter than what was said.
85
+ */
86
+ export declare const splitAside: (text: string) => {
87
+ said: string;
88
+ aside?: string;
89
+ };
90
+ export declare function SeatThread({ turns, outcomes, busy, testId, empty, minHeight, maxHeight, renderProposal, renderAfter, ready, onApplyAll, applyAllLabel, onChooseModel, }: {
91
+ readonly turns: readonly SeatTurn[];
92
+ readonly outcomes: ReadonlyMap<string, SeatOutcome>;
93
+ readonly busy: boolean;
94
+ readonly testId: string;
95
+ /** What is said before anybody types. */
96
+ readonly empty: ReactNode;
97
+ readonly minHeight?: number;
98
+ readonly maxHeight?: string;
99
+ /** One open proposal, as this surface offers it. */
100
+ readonly renderProposal: (proposal: ProposedCall, at: {
101
+ readonly key: string;
102
+ readonly turn: number;
103
+ readonly at: number;
104
+ }) => ReactNode;
105
+ /** Whatever else a seat turn carries on this surface — questions at nodes, in the app. */
106
+ readonly renderAfter?: (turn: SeatTurn, index: number) => ReactNode;
107
+ /** Whether a proposal could be taken at all here; one that could not is not counted for "all". */
108
+ readonly ready?: (proposal: ProposedCall, key: string) => boolean;
109
+ /** One request, one press: take this turn's open proposals in order. */
110
+ readonly onApplyAll?: (turn: number, proposals: readonly ProposedCall[]) => void;
111
+ readonly applyAllLabel?: string;
112
+ /** Offered under a turn the rung could not read, when a model is one press away. */
113
+ readonly onChooseModel?: () => void;
114
+ }): import("react").JSX.Element;
115
+ /** A proposal that landed, was set aside, or was refused — in the place it was offered. */
116
+ export declare function Settled({ outcome, testId }: {
117
+ readonly outcome: SeatOutcome;
118
+ readonly testId: string;
119
+ }): import("react").JSX.Element;
120
+ export declare function SeatComposer({ busy, placeholder, ariaLabel, testId, onSend, }: {
121
+ readonly busy: boolean;
122
+ readonly placeholder: string;
123
+ readonly ariaLabel: string;
124
+ readonly testId: string;
125
+ readonly onSend: (text: string) => void;
126
+ }): import("react").JSX.Element;
127
+ /**
128
+ * WHAT ANSWERS, chosen where the seat is. The same one setting the profile
129
+ * holds — pills, and a key field only when a rung needs one — so a person
130
+ * pressing "Let a model read it" is shown the choice they would find in
131
+ * the profile, not a second form that could disagree with it.
132
+ */
133
+ export declare function SeatSettings({ testId, onDone }: {
134
+ readonly testId: string;
135
+ readonly onDone: () => void;
136
+ }): import("react").JSX.Element;
137
+ //# sourceMappingURL=seat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat.d.ts","sourceRoot":"","sources":["../src/seat.tsx"],"names":[],"mappings":"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"}
package/dist/seat.js ADDED
@@ -0,0 +1,162 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { LadderSetting } from "./ladder.js";
4
+ /** The key of a proposal in the thread: which turn, which of its proposals. */
5
+ export const proposalKey = (turn, at) => `${turn}:${at}`;
6
+ /**
7
+ * The conversation's state and its one loop: ask, answer, record.
8
+ *
9
+ * WHAT WAS DONE is part of what was said. "Erin tends that plot" means the
10
+ * plot the last turn made, and the model only knows which if the history
11
+ * carries what landed, by name — so every surface sends it, not just one.
12
+ */
13
+ export function useSeatConversation({ answer, onReply, }) {
14
+ const [turns, setTurns] = useState([]);
15
+ const [outcomes, setOutcomes] = useState(new Map());
16
+ const [busy, setBusy] = useState(false);
17
+ const settle = useCallback((key, outcome) => setOutcomes((current) => new Map(current).set(key, outcome)), []);
18
+ const send = async (text) => {
19
+ const asked = text.trim();
20
+ if (!asked || busy)
21
+ return;
22
+ setBusy(true);
23
+ setTurns((current) => [...current, { role: "person", text: asked }]);
24
+ const history = turns.map((turn, index) => {
25
+ const landed = (turn.proposals ?? []).flatMap((_, at) => {
26
+ const outcome = outcomes.get(proposalKey(index, at));
27
+ return outcome?.state === "applied" ? [outcome.said] : [];
28
+ });
29
+ return { role: turn.role, text: landed.length > 0 ? `${turn.text} [applied: ${landed.join("; ")}]` : turn.text };
30
+ });
31
+ let reply;
32
+ try {
33
+ reply = await answer(asked, { history });
34
+ }
35
+ catch (error) {
36
+ reply = { say: `The seat could not answer: ${error instanceof Error ? error.message : String(error)}`, proposals: [] };
37
+ }
38
+ setTurns((current) => [
39
+ ...current,
40
+ {
41
+ role: "seat",
42
+ text: reply.say,
43
+ proposals: reply.proposals,
44
+ ...(reply.questions ? { questions: reply.questions } : {}),
45
+ ...(reply.picks?.length ? { picks: reply.picks } : {}),
46
+ ...(reply.unsure ? { unsure: true } : {}),
47
+ },
48
+ ]);
49
+ onReply?.(reply);
50
+ setBusy(false);
51
+ };
52
+ return { turns, outcomes, busy, send, settle };
53
+ }
54
+ /** Where answers are coming from right now, for the header — the same words on every surface. */
55
+ export function describeSource(described, warmth, floor = "graph") {
56
+ if (warmth?.state === "warming") {
57
+ return `warming${warmth.progress !== undefined ? ` ${Math.round(warmth.progress * 100)}%` : "…"}`;
58
+ }
59
+ if (warmth?.state === "failed")
60
+ return `${floor} answering — ${warmth.detail ?? "the local model failed"}`;
61
+ return described;
62
+ }
63
+ export function SeatHeader({ label, source, sourceTitle, testId, settings, onSettings, foot = false, }) {
64
+ return (_jsxs("div", { style: {
65
+ display: "flex",
66
+ alignItems: "center",
67
+ gap: 8,
68
+ padding: foot ? "4px 4px 0 6px" : "6px 8px 6px 12px",
69
+ ...(foot ? {} : { borderBottom: "1px solid var(--graview-edge)" }),
70
+ }, children: [foot ? null : (_jsx("span", { style: { fontSize: "0.75rem", letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--graview-ink-faint)" }, children: label })), _jsx("span", { "data-testid": `${testId}-source`, title: sourceTitle, style: { fontSize: "0.75rem", color: "var(--graview-ink-muted)" }, children: source }), _jsx("span", { style: { flex: "1 1 auto" } }), onSettings ? (_jsx("button", { type: "button", "data-testid": `${testId}-settings`, "aria-expanded": settings ?? false, onClick: onSettings, title: "Choose what answers: the graph itself, a model in this browser, a decision provider, or your own key", style: { fontSize: "0.8125rem", padding: "2px 8px", minHeight: 24 }, children: "\u2699" })) : null] }));
71
+ }
72
+ /**
73
+ * The seat's trailing aside — "(from the graph)", "(the local model is
74
+ * warming …)" — is which rung answered, not the answer: kept, and set
75
+ * quieter than what was said.
76
+ */
77
+ export const splitAside = (text) => {
78
+ const match = /^([\s\S]*?)\s*(\((?:[^()]|\([^()]*\))*\))\s*$/.exec(text);
79
+ return match && match[1] ? { said: match[1], aside: match[2] } : { said: text };
80
+ };
81
+ export function SeatThread({ turns, outcomes, busy, testId, empty, minHeight = 64, maxHeight = "min(46cqh, 400px)", renderProposal, renderAfter, ready = () => true, onApplyAll, applyAllLabel = "Apply all", onChooseModel, }) {
82
+ const log = useRef(null);
83
+ useEffect(() => {
84
+ // A log that cannot be scrolled — jsdom, a print stylesheet — is not a reason to throw.
85
+ log.current?.scrollTo?.({ top: log.current.scrollHeight });
86
+ }, [turns]);
87
+ return (_jsxs("ol", { ref: log, style: {
88
+ margin: 0,
89
+ padding: 10,
90
+ listStyle: "none",
91
+ display: "grid",
92
+ gap: 8,
93
+ alignContent: "start",
94
+ maxHeight,
95
+ minHeight,
96
+ overflowY: "auto",
97
+ }, children: [turns.length === 0 ? (empty === null ? null : _jsx("li", { style: { fontSize: "0.8125rem", color: "var(--graview-ink-muted)", lineHeight: 1.5 }, children: empty })) : null, turns.map((turn, index) => {
98
+ const proposals = turn.proposals ?? [];
99
+ const open = proposals.filter((proposal, at) => {
100
+ const key = proposalKey(index, at);
101
+ const outcome = outcomes.get(key);
102
+ return outcome?.state !== "applied" && outcome?.state !== "declined" && ready(proposal, key);
103
+ });
104
+ const aside = splitAside(turn.text);
105
+ return (_jsxs("li", { style: { display: "grid", gap: 6, justifyItems: turn.role === "person" ? "end" : "start" }, children: [turn.role === "person" ? (_jsx("p", { style: {
106
+ margin: 0,
107
+ maxWidth: "85%",
108
+ padding: "6px 10px",
109
+ borderRadius: "12px 12px 4px 12px",
110
+ fontSize: "0.875rem",
111
+ lineHeight: 1.45,
112
+ background: "var(--graview-panel-muted)",
113
+ color: "var(--graview-ink)",
114
+ }, children: turn.text })) : (_jsxs("p", { style: { margin: 0, fontSize: "0.875rem", lineHeight: 1.5, color: "var(--graview-ink)" }, children: [aside.said, aside.aside ? (_jsx("span", { style: { display: "block", marginTop: 2, fontSize: "0.75rem", color: "var(--graview-ink-faint)" }, children: aside.aside })) : null] })), turn.unsure && onChooseModel ? (_jsx("button", { type: "button", "data-testid": `${testId}-offer-model`, onClick: onChooseModel, title: "A model reads a sentence however it is phrased, and proposes the acts it describes", style: { fontSize: "0.8125rem", justifySelf: "start" }, children: "Let a model read it \u2192" })) : null, renderAfter?.(turn, index), proposals.map((proposal, at) => {
115
+ const key = proposalKey(index, at);
116
+ const outcome = outcomes.get(key);
117
+ if (outcome?.state === "applied" || outcome?.state === "declined") {
118
+ return _jsx(Settled, { outcome: outcome, testId: testId }, key);
119
+ }
120
+ return (_jsxs("span", { style: { display: "grid", gap: 4, justifySelf: "stretch", justifyItems: "start" }, children: [renderProposal(proposal, { key, turn: index, at }), outcome ? _jsx(Settled, { outcome: outcome, testId: testId }) : null] }, key));
121
+ }), onApplyAll && open.length >= 2 ? (_jsxs("button", { type: "button", "data-testid": `${testId}-apply-all`, onClick: () => onApplyAll(index, proposals), title: "Take these in order; anything still missing is asked for", style: { fontSize: "0.8125rem", justifySelf: "start", fontWeight: 600 }, children: [applyAllLabel, " ", open.length] })) : null] }, index));
122
+ }), busy ? _jsx("li", { style: { fontSize: "0.8125rem", color: "var(--graview-ink-faint)" }, children: "thinking\u2026" }) : null] }));
123
+ }
124
+ /** A proposal that landed, was set aside, or was refused — in the place it was offered. */
125
+ export function Settled({ outcome, testId }) {
126
+ if (outcome.state === "refused") {
127
+ return (_jsxs("span", { "data-testid": `${testId}-refused`, style: { fontSize: "0.8125rem", color: "var(--graview-warn)" }, children: ["Refused: ", outcome.error] }));
128
+ }
129
+ const applied = outcome.state === "applied";
130
+ return (_jsxs("span", { "data-testid": `${testId}-${outcome.state}`, style: { fontSize: "0.8125rem", color: applied ? "var(--graview-ink-muted)" : "var(--graview-ink-faint)" }, children: [applied ? _jsx("span", { "aria-hidden": "true", style: { color: "var(--graview-accent)" }, children: "\u2713 " }) : null, applied ? outcome.said : _jsx("s", { children: outcome.said })] }));
131
+ }
132
+ export function SeatComposer({ busy, placeholder, ariaLabel, testId, onSend, }) {
133
+ const [draft, setDraft] = useState("");
134
+ return (_jsxs("form", { onSubmit: (event) => {
135
+ event.preventDefault();
136
+ if (busy || draft.trim().length === 0)
137
+ return;
138
+ onSend(draft);
139
+ setDraft("");
140
+ }, style: { display: "flex", gap: 6, padding: 8, borderTop: "1px solid var(--graview-edge)" }, children: [_jsx("input", { value: draft, onChange: (event) => setDraft(event.target.value), placeholder: placeholder, "aria-label": ariaLabel, "data-testid": `${testId}-draft`, style: {
141
+ flex: 1,
142
+ // An input's own minimum is about 180px; in a narrow pane it must give way.
143
+ minWidth: 0,
144
+ font: "inherit",
145
+ fontSize: "0.875rem",
146
+ padding: "6px 9px",
147
+ borderRadius: 8,
148
+ border: "1px solid var(--graview-edge)",
149
+ background: "var(--graview-panel)",
150
+ color: "var(--graview-ink)",
151
+ } }), _jsx("button", { type: "submit", "data-testid": `${testId}-send`, disabled: busy || draft.trim().length === 0, style: { fontSize: "0.875rem" }, children: "Send" })] }));
152
+ }
153
+ /**
154
+ * WHAT ANSWERS, chosen where the seat is. The same one setting the profile
155
+ * holds — pills, and a key field only when a rung needs one — so a person
156
+ * pressing "Let a model read it" is shown the choice they would find in
157
+ * the profile, not a second form that could disagree with it.
158
+ */
159
+ export function SeatSettings({ testId, onDone }) {
160
+ return (_jsxs("div", { "data-testid": `${testId}-ladder`, style: { display: "grid", gap: 10, padding: 12 }, children: [_jsx(LadderSetting, {}), _jsx("button", { type: "button", onClick: onDone, style: { justifySelf: "start", fontSize: "0.875rem" }, children: "Back to the conversation" })] }));
161
+ }
162
+ //# sourceMappingURL=seat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seat.js","sourceRoot":"","sources":["../src/seat.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { AnySchema } from "@graview/core";
2
+ /**
3
+ * WHO YOU ARE SITTING AS — on the bar, where a policy can be felt.
4
+ *
5
+ * A declared policy that nobody can stand on the other side of is a claim
6
+ * rather than a demonstration: a reader sees one set of acts and has to take
7
+ * it on faith that another seat would see a different one. Sitting down as
8
+ * somebody else re-derives everything from the one principal — what the
9
+ * strip offers and what it withholds with the policy's own sentence, which
10
+ * kinds are drawn at all, whether "Show the installation" is on the bar,
11
+ * what the routed face lists, and what the agent's tool list contains.
12
+ *
13
+ * The embed's strip has had this since it had a policy to feel. The demos
14
+ * people actually open are the apps, not the embeds, which is why it belongs
15
+ * here too and why it reads from the same context rather than from a prop.
16
+ *
17
+ * Nothing renders for an app that offers no seats, or offers only one:
18
+ * a control with one choice is furniture.
19
+ */
20
+ export declare function Seats<S extends AnySchema>(): import("react").JSX.Element | null;
21
+ //# sourceMappingURL=seats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seats.d.ts","sourceRoot":"","sources":["../src/seats.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,eAAe,CAAC;AAG1D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,SAAS,wCAsDxC"}
package/dist/seats.js ADDED
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useGraview } from "@graview/react";
3
+ /**
4
+ * WHO YOU ARE SITTING AS — on the bar, where a policy can be felt.
5
+ *
6
+ * A declared policy that nobody can stand on the other side of is a claim
7
+ * rather than a demonstration: a reader sees one set of acts and has to take
8
+ * it on faith that another seat would see a different one. Sitting down as
9
+ * somebody else re-derives everything from the one principal — what the
10
+ * strip offers and what it withholds with the policy's own sentence, which
11
+ * kinds are drawn at all, whether "Show the installation" is on the bar,
12
+ * what the routed face lists, and what the agent's tool list contains.
13
+ *
14
+ * The embed's strip has had this since it had a policy to feel. The demos
15
+ * people actually open are the apps, not the embeds, which is why it belongs
16
+ * here too and why it reads from the same context rather than from a prop.
17
+ *
18
+ * Nothing renders for an app that offers no seats, or offers only one:
19
+ * a control with one choice is furniture.
20
+ */
21
+ export function Seats() {
22
+ const { seats, principal, takeSeat } = useGraview();
23
+ if (seats.length < 2)
24
+ return null;
25
+ return (_jsxs("div", { role: "group", "aria-label": "Seat", "data-testid": "seats",
26
+ /*
27
+ * IT WRAPS. The switcher sits in the profile pane, which is 280
28
+ * wide: three seats in one unwrapping row ran straight off the edge,
29
+ * and the third was a chip with its name cut in half. A row of
30
+ * choices that cannot be read is not a choice.
31
+ */
32
+ style: { display: "flex", alignItems: "center", flexWrap: "wrap", gap: 6, rowGap: 4 }, children: [_jsx("span", { style: {
33
+ fontSize: "0.75rem",
34
+ letterSpacing: "0.12em",
35
+ textTransform: "uppercase",
36
+ color: "var(--graview-ink-faint)",
37
+ }, children: "As" }), seats.map((seat) => {
38
+ const here = sameSeat(principal, seat.principal);
39
+ return (_jsx("button", { type: "button", "aria-pressed": here, "data-testid": `seat-${seat.principal.id ?? seat.label}`, title: `Sit down as ${seat.label}: the acts, the kinds and the pages narrow to what this seat may do`, onClick: () => takeSeat(seat.principal), style: {
40
+ padding: "3px 11px",
41
+ borderRadius: 999,
42
+ fontSize: "0.875rem",
43
+ whiteSpace: "nowrap",
44
+ borderWidth: 1,
45
+ borderStyle: "solid",
46
+ borderColor: here ? "var(--graview-accent)" : "var(--graview-edge)",
47
+ color: here ? "var(--graview-accent)" : "var(--graview-ink-muted)",
48
+ background: here ? "var(--graview-panel)" : "transparent",
49
+ }, children: seat.label }, seat.principal.id ?? seat.label));
50
+ })] }));
51
+ }
52
+ /**
53
+ * Two principals are the same seat when they name the same person.
54
+ *
55
+ * By id, not by identity: the seated principal is the very object the seat
56
+ * carries today, and comparing references would be right by accident and
57
+ * wrong the first time a host rebuilt its seat list on a render.
58
+ */
59
+ function sameSeat(a, b) {
60
+ return a.kind === b.kind && a.id === b.id;
61
+ }
62
+ //# sourceMappingURL=seats.js.map