@graview/react 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 (147) hide show
  1. package/LICENSE +96 -0
  2. package/README.md +20 -0
  3. package/dist/activity.d.ts +113 -0
  4. package/dist/activity.d.ts.map +1 -0
  5. package/dist/activity.js +207 -0
  6. package/dist/activity.js.map +1 -0
  7. package/dist/animation.d.ts +64 -0
  8. package/dist/animation.d.ts.map +1 -0
  9. package/dist/animation.js +245 -0
  10. package/dist/animation.js.map +1 -0
  11. package/dist/captions.d.ts +43 -0
  12. package/dist/captions.d.ts.map +1 -0
  13. package/dist/captions.js +61 -0
  14. package/dist/captions.js.map +1 -0
  15. package/dist/channels.d.ts +15 -0
  16. package/dist/channels.d.ts.map +1 -0
  17. package/dist/channels.js +114 -0
  18. package/dist/channels.js.map +1 -0
  19. package/dist/connectors.d.ts +176 -0
  20. package/dist/connectors.d.ts.map +1 -0
  21. package/dist/connectors.js +837 -0
  22. package/dist/connectors.js.map +1 -0
  23. package/dist/context.d.ts +348 -0
  24. package/dist/context.d.ts.map +1 -0
  25. package/dist/context.js +568 -0
  26. package/dist/context.js.map +1 -0
  27. package/dist/drawn.d.ts +60 -0
  28. package/dist/drawn.d.ts.map +1 -0
  29. package/dist/drawn.js +58 -0
  30. package/dist/drawn.js.map +1 -0
  31. package/dist/edge-signs.d.ts +13 -0
  32. package/dist/edge-signs.d.ts.map +1 -0
  33. package/dist/edge-signs.js +76 -0
  34. package/dist/edge-signs.js.map +1 -0
  35. package/dist/hooks.d.ts +160 -0
  36. package/dist/hooks.d.ts.map +1 -0
  37. package/dist/hooks.js +457 -0
  38. package/dist/hooks.js.map +1 -0
  39. package/dist/index.d.ts +37 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +22 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/keyboard.d.ts +5 -0
  44. package/dist/keyboard.d.ts.map +1 -0
  45. package/dist/keyboard.js +178 -0
  46. package/dist/keyboard.js.map +1 -0
  47. package/dist/kit.d.ts +10 -0
  48. package/dist/kit.d.ts.map +1 -0
  49. package/dist/kit.js +32 -0
  50. package/dist/kit.js.map +1 -0
  51. package/dist/local-intelligence.d.ts +31 -0
  52. package/dist/local-intelligence.d.ts.map +1 -0
  53. package/dist/local-intelligence.js +66 -0
  54. package/dist/local-intelligence.js.map +1 -0
  55. package/dist/motion.d.ts +17 -0
  56. package/dist/motion.d.ts.map +1 -0
  57. package/dist/motion.js +26 -0
  58. package/dist/motion.js.map +1 -0
  59. package/dist/occupants.d.ts +45 -0
  60. package/dist/occupants.d.ts.map +1 -0
  61. package/dist/occupants.js +57 -0
  62. package/dist/occupants.js.map +1 -0
  63. package/dist/parallel.d.ts +19 -0
  64. package/dist/parallel.d.ts.map +1 -0
  65. package/dist/parallel.js +30 -0
  66. package/dist/parallel.js.map +1 -0
  67. package/dist/picking.d.ts +30 -0
  68. package/dist/picking.d.ts.map +1 -0
  69. package/dist/picking.js +140 -0
  70. package/dist/picking.js.map +1 -0
  71. package/dist/plots.d.ts +106 -0
  72. package/dist/plots.d.ts.map +1 -0
  73. package/dist/plots.js +306 -0
  74. package/dist/plots.js.map +1 -0
  75. package/dist/pointer.d.ts +27 -0
  76. package/dist/pointer.d.ts.map +1 -0
  77. package/dist/pointer.js +39 -0
  78. package/dist/pointer.js.map +1 -0
  79. package/dist/presence.d.ts +110 -0
  80. package/dist/presence.d.ts.map +1 -0
  81. package/dist/presence.js +280 -0
  82. package/dist/presence.js.map +1 -0
  83. package/dist/rails.d.ts +11 -0
  84. package/dist/rails.d.ts.map +1 -0
  85. package/dist/rails.js +15 -0
  86. package/dist/rails.js.map +1 -0
  87. package/dist/resolved-view.d.ts +78 -0
  88. package/dist/resolved-view.d.ts.map +1 -0
  89. package/dist/resolved-view.js +365 -0
  90. package/dist/resolved-view.js.map +1 -0
  91. package/dist/robot.d.ts +114 -0
  92. package/dist/robot.d.ts.map +1 -0
  93. package/dist/robot.js +93 -0
  94. package/dist/robot.js.map +1 -0
  95. package/dist/routes.d.ts +50 -0
  96. package/dist/routes.d.ts.map +1 -0
  97. package/dist/routes.js +150 -0
  98. package/dist/routes.js.map +1 -0
  99. package/dist/scene-camera.d.ts +25 -0
  100. package/dist/scene-camera.d.ts.map +1 -0
  101. package/dist/scene-camera.js +130 -0
  102. package/dist/scene-camera.js.map +1 -0
  103. package/dist/scene-hand.d.ts +110 -0
  104. package/dist/scene-hand.d.ts.map +1 -0
  105. package/dist/scene-hand.js +317 -0
  106. package/dist/scene-hand.js.map +1 -0
  107. package/dist/scene-helpers.d.ts +46 -0
  108. package/dist/scene-helpers.d.ts.map +1 -0
  109. package/dist/scene-helpers.js +108 -0
  110. package/dist/scene-helpers.js.map +1 -0
  111. package/dist/scene-lines.d.ts +76 -0
  112. package/dist/scene-lines.d.ts.map +1 -0
  113. package/dist/scene-lines.js +578 -0
  114. package/dist/scene-lines.js.map +1 -0
  115. package/dist/scene-root.d.ts +71 -0
  116. package/dist/scene-root.d.ts.map +1 -0
  117. package/dist/scene-root.js +790 -0
  118. package/dist/scene-root.js.map +1 -0
  119. package/dist/scene.d.ts +17 -0
  120. package/dist/scene.d.ts.map +1 -0
  121. package/dist/scene.js +17 -0
  122. package/dist/scene.js.map +1 -0
  123. package/dist/seat-marks.d.ts +35 -0
  124. package/dist/seat-marks.d.ts.map +1 -0
  125. package/dist/seat-marks.js +43 -0
  126. package/dist/seat-marks.js.map +1 -0
  127. package/dist/settings.d.ts +30 -0
  128. package/dist/settings.d.ts.map +1 -0
  129. package/dist/settings.js +73 -0
  130. package/dist/settings.js.map +1 -0
  131. package/dist/view-boundary.d.ts +33 -0
  132. package/dist/view-boundary.d.ts.map +1 -0
  133. package/dist/view-boundary.js +53 -0
  134. package/dist/view-boundary.js.map +1 -0
  135. package/dist/view-host.d.ts +57 -0
  136. package/dist/view-host.d.ts.map +1 -0
  137. package/dist/view-host.js +474 -0
  138. package/dist/view-host.js.map +1 -0
  139. package/dist/view-registry.d.ts +122 -0
  140. package/dist/view-registry.d.ts.map +1 -0
  141. package/dist/view-registry.js +20 -0
  142. package/dist/view-registry.js.map +1 -0
  143. package/dist/where-drawn.d.ts +151 -0
  144. package/dist/where-drawn.d.ts.map +1 -0
  145. package/dist/where-drawn.js +231 -0
  146. package/dist/where-drawn.js.map +1 -0
  147. package/package.json +60 -0
package/LICENSE ADDED
@@ -0,0 +1,96 @@
1
+ Elastic License 2.0
2
+
3
+ ## Acceptance
4
+
5
+ By using the software, you agree to all of the terms and conditions below.
6
+
7
+ ## Copyright License
8
+
9
+ The licensor grants you a non-exclusive, royalty-free, worldwide,
10
+ non-sublicensable, non-transferable license to use, copy, distribute, make
11
+ available, and prepare derivative works of the software, in each case subject
12
+ to the limitations and conditions below.
13
+
14
+ ## Limitations
15
+
16
+ You may not provide the software to third parties as a hosted or managed
17
+ service, where the service provides users with access to any substantial set
18
+ of the features or functionality of the software.
19
+
20
+ You may not move, change, disable, or circumvent the license key
21
+ functionality in the software, and you may not remove or obscure any
22
+ functionality in the software that is protected by the license key.
23
+
24
+ You may not alter, remove, or obscure any licensing, copyright, or other
25
+ notices of the licensor in the software. Any use of the licensor's trademarks
26
+ is subject to applicable law.
27
+
28
+ ## Patents
29
+
30
+ The licensor grants you a license, under any patent claims the licensor can
31
+ license, or becomes able to license, to make, have made, use, sell, offer for
32
+ sale, import and have imported the software, in each case subject to the
33
+ limitations and conditions in this license. This license does not cover any
34
+ patent claims that you cause to be infringed by modifications or additions to
35
+ the software. If you or your company make any written claim that the software
36
+ infringes or contributes to infringement of any patent, your patent license
37
+ for the software granted under these terms ends immediately. If your company
38
+ makes such a claim, your patent license ends immediately for work on behalf
39
+ of your company.
40
+
41
+ ## Notices
42
+
43
+ You must ensure that anyone who gets a copy of any part of the software from
44
+ you also gets a copy of these terms.
45
+
46
+ If you modify the software, you must include in any modified copies of the
47
+ software prominent notices stating that you have modified the software.
48
+
49
+ ## No Other Rights
50
+
51
+ These terms do not imply any licenses other than those expressly granted in
52
+ these terms.
53
+
54
+ ## Termination
55
+
56
+ If you use the software in violation of these terms, such use is not
57
+ licensed, and your licenses will automatically terminate. If the licensor
58
+ provides you with a notice of your violation, and you cease all violation of
59
+ this license no later than 30 days after you receive that notice, your
60
+ licenses will be reinstated retroactively. However, if you violate these
61
+ terms after such reinstatement, any additional violation of these terms will
62
+ cause your licenses to terminate automatically and permanently.
63
+
64
+ ## No Liability
65
+
66
+ *As far as the law allows, the software comes as is, without any warranty or
67
+ condition, and the licensor will not be liable to you for any damages arising
68
+ out of these terms or the use or nature of the software, under any kind of
69
+ legal claim.*
70
+
71
+ ## Definitions
72
+
73
+ The **licensor** is the entity offering these terms, and the **software** is
74
+ the software the licensor makes available under these terms, including any
75
+ portion of it.
76
+
77
+ **you** refers to the individual or entity agreeing to these terms.
78
+
79
+ **your company** is any legal entity, sole proprietorship, or other kind of
80
+ organization that you work for, plus all organizations that have control
81
+ over, are under the control of, or are under common control with that
82
+ organization. **control** means ownership of substantially all the assets of
83
+ an entity, or the power to direct its management and policies by vote,
84
+ contract, or otherwise. Control can be direct or indirect.
85
+
86
+ **your licenses** are all the licenses granted to you for the software under
87
+ these terms.
88
+
89
+ **use** means anything you do with the software requiring one of your
90
+ licenses.
91
+
92
+ **trademark** means trademarks, service marks, and similar rights.
93
+
94
+ ---
95
+
96
+ Copyright 2025-2026 En Dash Consulting
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @graview/react
2
+
3
+ The binding. A provider, a scene, and the hooks an app builds on.
4
+
5
+ A view is an ORDINARY React component. No scene API, no base class — that is
6
+ the whole authoring surface, and it is the reason the capture approach earns
7
+ its cost. Every view must render correctly in both modes: captured into the
8
+ scene, and lifted out as a full page.
9
+
10
+ ```tsx
11
+ <GraviewProvider store={store} views={views} brand={brand} principal={me}>
12
+ <Scene />
13
+ <JackedIn />
14
+ </GraviewProvider>
15
+ ```
16
+
17
+ The provider holds the store, the view registry, the current view, the
18
+ selection, the activity and the principal — together, so the scene, the chrome
19
+ and an agent seat are looking at the same thing rather than at three copies of
20
+ it.
@@ -0,0 +1,113 @@
1
+ import { type AnySchema, type Author, type Operation, type Store } from "@graview/core";
2
+ /**
3
+ * Who was moving, in the terms the op log already records.
4
+ *
5
+ * `directed` is a person; `autonomous` is an agent taking a turn of its own;
6
+ * `co-edited` is more than one participant on the same thing inside the
7
+ * window; `rule` is the invariant engine repairing something. Nothing new is
8
+ * invented to tell them apart — every op carries an author with a kind, an
9
+ * id and a session, and this is only a reading of it.
10
+ */
11
+ export type Manner = "directed" | "autonomous" | "co-edited" | "rule";
12
+ export interface ActivityMark {
13
+ /** When it happened, in `performance.now()`-comparable milliseconds. */
14
+ readonly at: number;
15
+ readonly manner: Manner;
16
+ /** What was MEANT, from the op. Not a description of what changed. */
17
+ readonly intent: string;
18
+ /** Something here was written. */
19
+ readonly wrote: boolean;
20
+ /**
21
+ * Something here was READ while deciding, and not written.
22
+ *
23
+ * This is the half a diff cannot show, and the half that makes an agent's
24
+ * turn legible: what it looked at before it moved says more about whether
25
+ * to trust the move than the move does.
26
+ */
27
+ readonly read: boolean;
28
+ /** A rule that implicates this began failing with this change. */
29
+ readonly broke: boolean;
30
+ /** Distinct participants, so a second one turns the mark into `co-edited`. */
31
+ readonly participants: readonly string[];
32
+ }
33
+ /**
34
+ * Folds one notification into the marks that are still current.
35
+ *
36
+ * Pure, and separate from the hook, because "what does the picture say after
37
+ * an agent turn" is a question worth being able to ask without a renderer.
38
+ */
39
+ export declare function markActivity(previous: ReadonlyMap<string, ActivityMark>, ops: readonly Operation[], broken: readonly BrokenRule[], at: number, holdMs: number): Map<string, ActivityMark>;
40
+ /** A violation that was not failing a moment ago. */
41
+ export interface BrokenRule {
42
+ readonly nodeIds: readonly string[];
43
+ readonly message: string;
44
+ }
45
+ /**
46
+ * What has just happened, per node, for a few seconds.
47
+ *
48
+ * The overview is the place to WATCH the system work — an edit landing, a
49
+ * rule starting to fail, an agent reading its way to a decision — and all of
50
+ * it is already in the op log. This turns the log into something a picture
51
+ * can read.
52
+ *
53
+ * The state lives in the provider rather than here for the same reason
54
+ * selection does: the scene, the chrome and an agent seat must all be
55
+ * looking at the same activity, or the picture and the list disagree about
56
+ * what just happened.
57
+ *
58
+ * It costs nothing on a quiet graph. There is no animation loop and no
59
+ * polling: a subscription that never fires schedules no timer, and the marks
60
+ * are cleared by a single timeout rather than by a frame callback checking
61
+ * whether they have expired.
62
+ */
63
+ export declare function useActivity<S extends AnySchema>(): ReadonlyMap<string, ActivityMark>;
64
+ /** How long a mark stays up. Long enough to notice, short enough to mean "just". */
65
+ export declare const ACTIVITY_HOLD_MS = 2600;
66
+ /**
67
+ * The activity state itself, owned by the provider.
68
+ *
69
+ * Returns the marks and the way to add attention that never became an op —
70
+ * an agent reading the graph changes nothing and produces no diff, which is
71
+ * exactly why it needs its own way in.
72
+ */
73
+ export declare function useActivityState<S extends AnySchema>(store: Store<S>, holdMs?: number): {
74
+ activity: ReadonlyMap<string, ActivityMark>;
75
+ noteAttention: (note: Attention) => void;
76
+ };
77
+ /**
78
+ * Something looked at, by someone, for a reason.
79
+ *
80
+ * A read leaves no diff and no operation, so there is nothing in the log to
81
+ * fold. This is the one thing the interface is told rather than derived —
82
+ * and it is told by the tool runtime, which is the only thing that knows.
83
+ */
84
+ export interface Attention {
85
+ readonly reads: readonly string[];
86
+ readonly author: Author;
87
+ readonly intent: string;
88
+ }
89
+ /**
90
+ * Pipes an agent seat's read-only tool calls into the picture.
91
+ *
92
+ * What an agent READ is the half a diff cannot show, and the half that says
93
+ * whether to trust what it then did. The runtime already announces every
94
+ * call with the nodes it looked at; this is the wire.
95
+ */
96
+ export declare function useAttention(runtime: {
97
+ readonly author?: Author;
98
+ onCall(listener: (call: ToolCallLike) => void): () => void;
99
+ }): void;
100
+ /**
101
+ * The shape of a settled tool call, structurally.
102
+ *
103
+ * Declared here rather than imported so that the react binding does not take
104
+ * a dependency on the tool runtime for the sake of one field: anything that
105
+ * announces calls in this shape can be watched.
106
+ */
107
+ export interface ToolCallLike {
108
+ readonly name: string;
109
+ readonly phase: "running" | "ok" | "failed";
110
+ readonly reads?: readonly string[];
111
+ readonly args?: Readonly<Record<string, unknown>>;
112
+ }
113
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,SAAS,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAItG;;;;;;;;GAQG;AACH,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,MAAM,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAeD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAC3C,GAAG,EAAE,SAAS,SAAS,EAAE,EACzB,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CA8D3B;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,KAAK,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAEpF;AAED,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAClD,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,MAAM,SAAmB,GACxB;IACD,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC5C,aAAa,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC1C,CA+DA;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAyBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC5D,GAAG,IAAI,CA2BP;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,QAAQ,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnD"}
@@ -0,0 +1,207 @@
1
+ import { violationKey } from "@graview/core";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { useGraview } from "./context.js";
4
+ /** One author's identity across a window. Session is what separates two agents. */
5
+ function participantOf(op) {
6
+ const { kind, id, session } = op.author;
7
+ return `${kind}:${id ?? ""}:${session ?? ""}`;
8
+ }
9
+ function mannerOf(participants, last) {
10
+ if (participants.length > 1)
11
+ return "co-edited";
12
+ if (last === "rule")
13
+ return "rule";
14
+ return last === "agent" ? "autonomous" : "directed";
15
+ }
16
+ /**
17
+ * Folds one notification into the marks that are still current.
18
+ *
19
+ * Pure, and separate from the hook, because "what does the picture say after
20
+ * an agent turn" is a question worth being able to ask without a renderer.
21
+ */
22
+ export function markActivity(previous, ops, broken, at, holdMs) {
23
+ const next = new Map();
24
+ // Anything still inside the window survives, so two changes a second apart
25
+ // read as two things happening rather than the second erasing the first.
26
+ for (const [id, mark] of previous) {
27
+ if (at - mark.at < holdMs)
28
+ next.set(id, mark);
29
+ }
30
+ const broke = new Set(broken.flatMap((violation) => violation.nodeIds));
31
+ const touch = (id, op, fields) => {
32
+ const existing = next.get(id);
33
+ const participants = existing?.participants.includes(participantOf(op))
34
+ ? existing.participants
35
+ : [...(existing?.participants ?? []), participantOf(op)];
36
+ next.set(id, {
37
+ at,
38
+ manner: mannerOf(participants, op.author.kind),
39
+ intent: op.intent,
40
+ wrote: (existing?.wrote ?? false) || (fields.wrote ?? false),
41
+ // A write outranks a read: once something was changed, saying it was
42
+ // also looked at adds nothing.
43
+ read: ((existing?.read ?? false) || (fields.read ?? false)),
44
+ broke: (existing?.broke ?? false) || broke.has(id),
45
+ participants,
46
+ });
47
+ };
48
+ for (const op of ops) {
49
+ for (const id of op.writes)
50
+ touch(id, op, { wrote: true });
51
+ for (const id of op.reads) {
52
+ if (op.writes.includes(id))
53
+ continue;
54
+ touch(id, op, { read: true });
55
+ }
56
+ }
57
+ /*
58
+ * A rule that has just begun to fail marks EVERY node it implicates, not
59
+ * only the one that was written.
60
+ *
61
+ * That is the whole point of watching from up here: the change lands on
62
+ * one card and the consequence appears on another, and seeing the second
63
+ * without having gone looking for it is the thing a list of diffs cannot
64
+ * do. The rule speaks in its own voice — its message is the intent.
65
+ */
66
+ for (const violation of broken) {
67
+ for (const id of violation.nodeIds) {
68
+ const existing = next.get(id);
69
+ next.set(id, {
70
+ at,
71
+ manner: existing?.manner ?? "rule",
72
+ intent: existing?.intent ?? violation.message,
73
+ wrote: existing?.wrote ?? false,
74
+ read: existing?.read ?? false,
75
+ broke: true,
76
+ participants: existing?.participants ?? ["rule::"],
77
+ });
78
+ }
79
+ }
80
+ return next;
81
+ }
82
+ /**
83
+ * What has just happened, per node, for a few seconds.
84
+ *
85
+ * The overview is the place to WATCH the system work — an edit landing, a
86
+ * rule starting to fail, an agent reading its way to a decision — and all of
87
+ * it is already in the op log. This turns the log into something a picture
88
+ * can read.
89
+ *
90
+ * The state lives in the provider rather than here for the same reason
91
+ * selection does: the scene, the chrome and an agent seat must all be
92
+ * looking at the same activity, or the picture and the list disagree about
93
+ * what just happened.
94
+ *
95
+ * It costs nothing on a quiet graph. There is no animation loop and no
96
+ * polling: a subscription that never fires schedules no timer, and the marks
97
+ * are cleared by a single timeout rather than by a frame callback checking
98
+ * whether they have expired.
99
+ */
100
+ export function useActivity() {
101
+ return useGraview().activity;
102
+ }
103
+ /** How long a mark stays up. Long enough to notice, short enough to mean "just". */
104
+ export const ACTIVITY_HOLD_MS = 2600;
105
+ /**
106
+ * The activity state itself, owned by the provider.
107
+ *
108
+ * Returns the marks and the way to add attention that never became an op —
109
+ * an agent reading the graph changes nothing and produces no diff, which is
110
+ * exactly why it needs its own way in.
111
+ */
112
+ export function useActivityState(store, holdMs = ACTIVITY_HOLD_MS) {
113
+ const [marks, setMarks] = useState(() => new Map());
114
+ const live = useRef(marks);
115
+ live.current = marks;
116
+ // One timer for the whole thing, reset by whatever happened last. A quiet
117
+ // graph holds no timer at all.
118
+ const timer = useRef(null);
119
+ const publish = useCallback((next) => {
120
+ live.current = next;
121
+ setMarks(next);
122
+ if (timer.current)
123
+ clearTimeout(timer.current);
124
+ timer.current = setTimeout(() => {
125
+ live.current = new Map();
126
+ setMarks(new Map());
127
+ }, holdMs);
128
+ }, [holdMs]);
129
+ useEffect(() => {
130
+ let failing = new Set(store.violations().map(violationKey));
131
+ const unsubscribe = store.subscribe((_diff, ops) => {
132
+ const after = store.violations();
133
+ const fresh = after.filter((violation) => !failing.has(violationKey(violation)));
134
+ failing = new Set(after.map(violationKey));
135
+ publish(markActivity(live.current, ops, fresh.map((violation) => ({
136
+ nodeIds: violation.nodeIds,
137
+ message: violation.message,
138
+ })), Date.now(), holdMs));
139
+ });
140
+ return () => {
141
+ unsubscribe();
142
+ if (timer.current)
143
+ clearTimeout(timer.current);
144
+ };
145
+ }, [store, holdMs, publish]);
146
+ const noteAttention = useCallback((note) => {
147
+ if (note.reads.length === 0)
148
+ return;
149
+ publish(markActivity(live.current, [attentionAsOp(note)], [], Date.now(), holdMs));
150
+ }, [holdMs, publish]);
151
+ return { activity: marks, noteAttention };
152
+ }
153
+ /**
154
+ * A read dressed as an operation, so it walks the same path a write does.
155
+ *
156
+ * Not appended to any log — the log is for things that happened to the
157
+ * graph, and looking at something did not. This exists only so `markActivity`
158
+ * has one shape to fold rather than two.
159
+ */
160
+ function attentionAsOp(note) {
161
+ return {
162
+ id: `attention:${note.intent}`,
163
+ seq: -1,
164
+ batch: "attention",
165
+ author: note.author,
166
+ intent: note.intent,
167
+ mutation: null,
168
+ primitives: [],
169
+ inverse: [],
170
+ reads: note.reads,
171
+ writes: [],
172
+ at: new Date().toISOString(),
173
+ };
174
+ }
175
+ /**
176
+ * Pipes an agent seat's read-only tool calls into the picture.
177
+ *
178
+ * What an agent READ is the half a diff cannot show, and the half that says
179
+ * whether to trust what it then did. The runtime already announces every
180
+ * call with the nodes it looked at; this is the wire.
181
+ */
182
+ export function useAttention(runtime) {
183
+ const { noteAttention, noteSeat } = useGraview();
184
+ useEffect(() => runtime.onCall((call) => {
185
+ const author = runtime.author ?? { kind: "agent" };
186
+ /*
187
+ * WHAT A CALL SAYS reaches the body: a run's stop reason, a loop's
188
+ * sentence — announced as a `stop` call carrying `said` — is said
189
+ * from the robot, not only written to the rail.
190
+ */
191
+ const said = call.args?.["said"];
192
+ if (call.phase === "ok" && typeof said === "string" && said.length > 0) {
193
+ noteSeat({ type: "said", author, say: said });
194
+ }
195
+ if (call.phase !== "ok" || !call.reads || call.reads.length === 0)
196
+ return;
197
+ noteAttention({
198
+ reads: call.reads,
199
+ // The seat's OWN author, not a generic agent: attributing a read to
200
+ // a different participant than the writes makes one agent looking
201
+ // and then moving read as two people editing at once.
202
+ author,
203
+ intent: `read ${call.name}`,
204
+ });
205
+ }), [runtime, noteAttention, noteSeat]);
206
+ }
207
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { type InterpolatedLayout, type Layout } from "@graview/layout";
2
+ import type { AnySchema } from "@graview/core";
3
+ export interface TransitionOptions {
4
+ /** Milliseconds. Long enough to follow, short enough not to wait for. */
5
+ readonly duration?: number;
6
+ /** Skip animation entirely — tests, SSR, reduced-motion. */
7
+ readonly enabled?: boolean;
8
+ }
9
+ /**
10
+ * Tweens between two layouts whenever the view changes.
11
+ *
12
+ * This is the pay-off for layout being a pure function: there is no list of
13
+ * known transitions and no per-navigation animation code. ANY two view states
14
+ * interpolate, so a kind of navigation nobody anticipated animates the same
15
+ * as the ones that were designed — and a node entering the scene grows out of
16
+ * whatever group stood in for it, because the interpolation knows where it
17
+ * came from.
18
+ *
19
+ * Motion is the one thing that makes depth legible. Without it, a plane
20
+ * change is a cut and the viewer has to re-find everything; with it, the eye
21
+ * follows and spatial memory survives the move.
22
+ */
23
+ export declare function useAnimatedLayout(target: Layout, options?: TransitionOptions): InterpolatedLayout;
24
+ /**
25
+ * The nodes implicated by the most recent change, for about a second.
26
+ *
27
+ * Human and agent edits arrive through the same subscription carrying the
28
+ * same diff, so the interface cannot render one differently from the other
29
+ * even by accident — which is the point. The renderer highlights an agent's
30
+ * work with exactly the code that highlights yours.
31
+ */
32
+ export declare function useTouched<S extends AnySchema>(holdMs?: number): ReadonlySet<string>;
33
+ /** One thing the seat did, and what it touched. */
34
+ export interface SeatAct {
35
+ readonly batch: string;
36
+ /** The agent's own name, from the op's author. */
37
+ readonly who: string;
38
+ readonly intent: string;
39
+ readonly at: string;
40
+ readonly wrote: readonly string[];
41
+ }
42
+ export interface SeatWork {
43
+ /** Node id → the seat that wrote it, while the mark stands. */
44
+ readonly marks: ReadonlyMap<string, string>;
45
+ /** What the seat has done this session, newest first — the companion's log. */
46
+ readonly acts: readonly SeatAct[];
47
+ }
48
+ /**
49
+ * WHERE THE SEAT WORKED, MARKED ON THE THINGS THEMSELVES.
50
+ *
51
+ * The robot used to walk to what it wrote and stand there, which is the
52
+ * one thing the body was genuinely good for: attribution in space. The
53
+ * walk is gone; the attribution is not. Every op the log attributes to an
54
+ * agent marks what it wrote for a hold, and the acts stay in a list the
55
+ * companion can offer to fly you to.
56
+ *
57
+ * Read from the OP LOG rather than from the seat's own reports, so it is
58
+ * the same on both render paths, inside a lens, and for a turn that
59
+ * arrived from somewhere else entirely. An undo takes its marks with it:
60
+ * an op that undoes another says so, and what it took back stops being
61
+ * something the seat just did.
62
+ */
63
+ export declare function useSeatWork<S extends AnySchema>(holdMs?: number): SeatWork;
64
+ //# sourceMappingURL=animation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,MAAM,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,iBAAsB,GAC9B,kBAAkB,CA4HpB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,SAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAkBlF;AAED,mDAAmD;AACnD,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,QAAQ;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;CACnC;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,SAAO,GAAG,QAAQ,CAuDxE"}