agentfootprint-lens 0.55.0 → 0.57.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 (46) hide show
  1. package/README.md +12 -5
  2. package/dist/{Lens-DKbZBkI8.d.ts → Lens-Bp0wQWPo.d.cts} +22 -110
  3. package/dist/{Lens-DHmINGvn.d.cts → Lens-CkZrAiF4.d.ts} +22 -110
  4. package/dist/{chunk-XCFEGRQD.js → chunk-7Z7PFATV.js} +497 -2
  5. package/dist/chunk-7Z7PFATV.js.map +1 -0
  6. package/dist/{chunk-AE7C4TPA.js → chunk-HYCITGO2.js} +4 -499
  7. package/dist/chunk-HYCITGO2.js.map +1 -0
  8. package/dist/{chunk-ZPJAJQFD.js → chunk-OFRR6ME6.js} +35 -13
  9. package/dist/{chunk-ZPJAJQFD.js.map → chunk-OFRR6ME6.js.map} +1 -1
  10. package/dist/{chunk-UYL7DUOI.js → chunk-QEC564NQ.js} +21 -10
  11. package/dist/chunk-QEC564NQ.js.map +1 -0
  12. package/dist/{chunk-JQKBC34F.js → chunk-WKFDNOWV.js} +3 -3
  13. package/dist/{chunk-CUBFVNOW.js → chunk-YEO6H3JY.js} +2 -2
  14. package/dist/core.d.cts +6 -62
  15. package/dist/core.d.ts +6 -62
  16. package/dist/core.js +10 -10
  17. package/dist/index.cjs +63 -21
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +11 -22
  20. package/dist/index.d.ts +11 -22
  21. package/dist/index.js +35 -24
  22. package/dist/index.js.map +1 -1
  23. package/dist/lensCursorPort-DdIrlvGI.d.cts +261 -0
  24. package/dist/lensCursorPort-JFVFNf-6.d.ts +261 -0
  25. package/dist/skillgraph.cjs +621 -112
  26. package/dist/skillgraph.cjs.map +1 -1
  27. package/dist/skillgraph.d.cts +19 -2
  28. package/dist/skillgraph.d.ts +19 -2
  29. package/dist/skillgraph.js +3 -3
  30. package/dist/{tagAxis-Dh-lINvw.d.cts → tagAxis-T6KT8hQe.d.cts} +2 -136
  31. package/dist/{tagAxis-DuOMNXvq.d.ts → tagAxis-m8H-ewcU.d.ts} +2 -136
  32. package/dist/useSharedCursor-CR5vHgkL.d.ts +131 -0
  33. package/dist/useSharedCursor-u1vyTFkj.d.cts +131 -0
  34. package/dist/why.cjs +13 -2
  35. package/dist/why.cjs.map +1 -1
  36. package/dist/why.d.cts +6 -5
  37. package/dist/why.d.ts +6 -5
  38. package/dist/why.js +7 -7
  39. package/package.json +1 -1
  40. package/dist/chunk-AE7C4TPA.js.map +0 -1
  41. package/dist/chunk-UYL7DUOI.js.map +0 -1
  42. package/dist/chunk-XCFEGRQD.js.map +0 -1
  43. package/dist/stepForRuntimeStageId-Ctlldoq5.d.cts +0 -70
  44. package/dist/stepForRuntimeStageId-DsYG7lad.d.ts +0 -70
  45. /package/dist/{chunk-JQKBC34F.js.map → chunk-WKFDNOWV.js.map} +0 -0
  46. /package/dist/{chunk-CUBFVNOW.js.map → chunk-YEO6H3JY.js.map} +0 -0
package/README.md CHANGED
@@ -828,11 +828,18 @@ const shared = useSharedCursor(recorder);
828
828
  // Reads the address on the milestone axis; a click here moves the address.
829
829
  <ContextView runner={recording} cursor={shared.forAxis('group')} />
830
830
 
831
- // The older step + report contract, bridged into the same address — so a
832
- // `<Lens>` or a Skill Graph transport keeps working while you migrate one
833
- // lens at a time.
834
- <Lens recorder={recorder} granularity="step"
835
- step={shared.forAxis('step').at.step} onStepChange={shared.onStepChange} />
831
+ // The Lens on the same owner (0.56.0): it derives its own step over
832
+ // whatever axis it draws — pick tags, drill, change granularity — and every
833
+ // mover in it moves the shared address.
834
+ <Lens recorder={recorder} granularity="step" shared={shared} />
835
+
836
+ // The Skill Graph on the same owner (0.57.0): it reads the address over the
837
+ // run's commit axis, moves it from its own transport, and finds its own
838
+ // snap stops — nothing else to hand it.
839
+ <SkillGraphDebugger recorder={recorder} shared={shared} />
840
+
841
+ // A view still on the older step + report contract is bridged into the same
842
+ // address with `shared.onStepChange`, so a host migrates one lens at a time.
836
843
  ```
837
844
 
838
845
  The law: a tab DERIVES its step from the address (the exact stage when its
@@ -3,10 +3,11 @@ import { ToolChoiceCall, ToolChoiceSummary } from 'agentfootprint/observe';
3
3
  import * as agentfootprint from 'agentfootprint';
4
4
  import { CommentaryTemplates } from 'agentfootprint';
5
5
  import React__default, { Ref } from 'react';
6
- import { a as LensCursorReading, C as CursorPosition, L as LensCursor, e as NavigationResult, h as LensRecorder } from './lensCursor-BQyMCkdo.js';
7
- import { C as ChartGroupHighlight, c as LensCursorPort, H as Humanizer, b as BookmarkStore } from './tagAxis-DuOMNXvq.js';
6
+ import { e as NavigationResult, C as CursorPosition, h as LensRecorder, L as LensCursor } from './lensCursor-BQyMCkdo.cjs';
7
+ import { C as ChartGroupHighlight, H as Humanizer, b as BookmarkStore } from './tagAxis-T6KT8hQe.cjs';
8
8
  import { NodeTypes } from '@xyflow/react';
9
9
  import { TraceGraph, TraceFlowLayout, RuntimeOverlay } from 'footprint-explainable-ui/flowchart';
10
+ import { L as LensCursorAt, S as SharedCursor } from './useSharedCursor-u1vyTFkj.cjs';
10
11
 
11
12
  /**
12
13
  * LensFlow — the canonical Lens chart renderer.
@@ -134,113 +135,6 @@ interface LensFlowProps {
134
135
  }
135
136
  declare const LensFlow: React__default.FC<LensFlowProps>;
136
137
 
137
- /**
138
- * useLensCursor — the ONE cursor, controlled or uncontrolled.
139
- *
140
- * `<Lens>` has always held its scrub position in local state. This hook is that
141
- * same state with one addition: when the host passes a value, the host owns it.
142
- * The standard controlled/uncontrolled pair, modelled on
143
- * `<TraceExplorerShell selectedRuntimeStageId / onSelectionChange>` in
144
- * `footprint-explainable-ui` so the family reads as one API.
145
- *
146
- * The law it exists to keep: **one cursor, never two owners.** Every mover
147
- * inside the lens — the step strip, the ◀ ▶ ⟳Live buttons, the arrow keys, a
148
- * chart node click, a "what happened" moment, a provenance jump, and the
149
- * auto-advance that follows a live run — goes through `moveTo`. A mover that
150
- * sets position without notifying would be a second cursor wearing the first
151
- * one's clothes.
152
- *
153
- * Omit `controlledStep` and nothing changes: the hook keeps today's internal
154
- * state and today's auto-advance, byte for byte.
155
- */
156
-
157
- /**
158
- * Where the cursor landed, in all three units the lens knows — handed to
159
- * `onStepChange` alongside the step so a host never has to reverse-engineer
160
- * the lens's axis.
161
- *
162
- * It is a `LensCursorReading` (`/core`) plus the one thing a MOVE REPORT needs
163
- * and a reading does not: `clamped`. One declaration of the reading's fields,
164
- * so the report and the `LensCursor` every view is handed cannot drift.
165
- */
166
- interface LensCursorAt extends LensCursorReading {
167
- /**
168
- * `true` when this call is Lens CORRECTING a step that is not a position on
169
- * the axis it is now read against, not a move someone made. That is an
170
- * out-of-range `step` you passed, one an internal jump produced, OR — when
171
- * you passed no `step` at all — the lens's own remembered step after the
172
- * axis shrank under it. Uncontrolled snaps are reported too, so this flag
173
- * means the same thing in both modes. Store the corrected value and the two
174
- * cursors agree again.
175
- */
176
- readonly clamped: boolean;
177
- }
178
- /** The cursor's address at one step — resolved by the caller, which owns the
179
- * position list. */
180
- interface LensCursorPlace {
181
- readonly runtimeStageId: string;
182
- readonly commitIdx: number;
183
- readonly label: string;
184
- readonly kind?: string;
185
- }
186
- interface UseLensCursorArgs {
187
- /** The host's value. `undefined` → uncontrolled (Lens owns the cursor). */
188
- readonly controlledStep: number | undefined;
189
- /** Fires on every cursor move, controlled or not. */
190
- readonly onStepChange?: ((step: number, at: LensCursorAt) => void) | undefined;
191
- /** Highest valid step (`totalSteps - 1`). */
192
- readonly maxStep: number;
193
- /** Resolve a step to its address. Called only when a move is reported. */
194
- readonly describe: (step: number) => LensCursorPlace;
195
- /**
196
- * The MOVEMENT port — footprintjs 9.17's reader cursor over the Lens's own
197
- * stops (`openLensCursor(positions)`). When present, every move this funnel
198
- * makes is decided by the library: where a step lands, what happens at the
199
- * ends of the axis, and what an out-of-range ask does. Omit it and the
200
- * funnel keeps its own arithmetic, unchanged — which is what the hook's own
201
- * tests drive, so the two readings can be compared.
202
- *
203
- * It is NOT a second cursor: the port is re-seated on the step this hook
204
- * owns before every question and remembers nothing between them.
205
- */
206
- readonly port?: LensCursorPort | undefined;
207
- /**
208
- * The ACTIVE scrub axis — the same list the lens draws its ruler from.
209
- *
210
- * Supplied only so this hook can also hand back the `LensCursor` every view
211
- * receives (`cursor` below), which needs the axis to answer an ADDRESS. It
212
- * is never consulted for movement: `maxStep`, `describe` and `port` decide
213
- * that, exactly as they did before 0.51.0.
214
- *
215
- * Omit it and `cursor` is a cursor over an EMPTY axis — `resolve` refuses
216
- * `'empty-axis'`, which is the honest answer for a caller that gave none.
217
- */
218
- readonly positions?: readonly CursorPosition[] | undefined;
219
- }
220
- interface UseLensCursorResult {
221
- /** The cursor to render. */
222
- readonly step: number;
223
- /** Pinned to the live edge (drives the ⟳Live affordance). */
224
- readonly isLive: boolean;
225
- /** The ONE way anything inside the lens moves the cursor. */
226
- readonly moveTo: (n: number) => void;
227
- /**
228
- * The same one cursor in the shape EVERY view is handed (0.51.0): a READING
229
- * (`at`), the honest address query (`resolve`) and this very `moveTo`.
230
- *
231
- * Added BESIDE the three fields above — nothing moved, nothing was removed.
232
- * It holds no position: it is rebuilt from (`positions`, `step`) on every
233
- * render, so a view cannot end up rendering a stale copy.
234
- */
235
- readonly cursor: LensCursor;
236
- }
237
- /**
238
- * Snap a host-supplied step onto the axis. Non-finite and fractional values
239
- * are not positions, so they clamp too — and the clamp is always reported.
240
- */
241
- declare function clampStep(n: number, maxStep: number): number;
242
- declare function useLensCursor({ controlledStep, onStepChange, maxStep, describe, port, positions, }: UseLensCursorArgs): UseLensCursorResult;
243
-
244
138
  /**
245
139
  * useLensNavigator — move the ONE cursor to a stage by its address.
246
140
  *
@@ -603,6 +497,24 @@ interface LensProps {
603
497
  * Memoize via `useCallback` to avoid downstream re-renders.
604
498
  */
605
499
  readonly onStepChange?: (step: number, at: LensCursorAt) => void;
500
+ /**
501
+ * The HOST's one cursor across every lens it mounts (0.56.0) — the owner
502
+ * `useSharedCursor(recorder)` hands back. Pass it and this lens derives its
503
+ * own step over whatever axis it is drawing (the commit axis, the milestone
504
+ * axis, a tag-filtered one, a drilled one) from the shared ADDRESS, and
505
+ * every mover here — the strip, ◀ ▶, a chart click, `navigatorRef` — moves
506
+ * that address. `step` is ignored while `shared` is given; `onStepChange`
507
+ * still fires as an observation hook. A correction the lens makes on its
508
+ * own (`at.clamped`, an address this axis cannot hold) never rewrites the
509
+ * address: a tab derives a step, only a mover changes the address.
510
+ *
511
+ * ```tsx
512
+ * const shared = useSharedCursor(recorder);
513
+ * <Lens recorder={recorder} shared={shared} granularity="group" />
514
+ * <ContextView runner={runner} cursor={shared.forAxis('group')} />
515
+ * ```
516
+ */
517
+ readonly shared?: SharedCursor;
606
518
  /**
607
519
  * Move the cursor to a STAGE, by its address — the pointing half of the
608
520
  * cursor API. `step` / `onStepChange` let a host OWN the cursor; this lets
@@ -759,4 +671,4 @@ interface LensDetailSlotProps {
759
671
  }
760
672
  declare const Lens: React__default.FC<LensProps>;
761
673
 
762
- export { type LensProps as L, type ToolChoiceSource as T, type UseLensCursorArgs as U, Lens as a, type LensCursorAt as b, type LensDetailSlotProps as c, type LensSlots as d, type LensTheme as e, type LensView as f, type LensCursorPlace as g, LensFlow as h, type LensFlowProps as i, type LensNavigator as j, type UseLensCursorResult as k, type UseLensNavigatorArgs as l, type UseToolChoiceResult as m, clampStep as n, useLensNavigator as o, useToolChoice as p, useLensCursor as u };
674
+ export { type LensProps as L, type ToolChoiceSource as T, type UseLensNavigatorArgs as U, Lens as a, type LensDetailSlotProps as b, type LensSlots as c, type LensTheme as d, type LensView as e, LensFlow as f, type LensFlowProps as g, type LensNavigator as h, type UseToolChoiceResult as i, useToolChoice as j, useLensNavigator as u };
@@ -3,10 +3,11 @@ import { ToolChoiceCall, ToolChoiceSummary } from 'agentfootprint/observe';
3
3
  import * as agentfootprint from 'agentfootprint';
4
4
  import { CommentaryTemplates } from 'agentfootprint';
5
5
  import React__default, { Ref } from 'react';
6
- import { a as LensCursorReading, C as CursorPosition, L as LensCursor, e as NavigationResult, h as LensRecorder } from './lensCursor-BQyMCkdo.cjs';
7
- import { C as ChartGroupHighlight, c as LensCursorPort, H as Humanizer, b as BookmarkStore } from './tagAxis-Dh-lINvw.cjs';
6
+ import { e as NavigationResult, C as CursorPosition, h as LensRecorder, L as LensCursor } from './lensCursor-BQyMCkdo.js';
7
+ import { C as ChartGroupHighlight, H as Humanizer, b as BookmarkStore } from './tagAxis-m8H-ewcU.js';
8
8
  import { NodeTypes } from '@xyflow/react';
9
9
  import { TraceGraph, TraceFlowLayout, RuntimeOverlay } from 'footprint-explainable-ui/flowchart';
10
+ import { L as LensCursorAt, S as SharedCursor } from './useSharedCursor-CR5vHgkL.js';
10
11
 
11
12
  /**
12
13
  * LensFlow — the canonical Lens chart renderer.
@@ -134,113 +135,6 @@ interface LensFlowProps {
134
135
  }
135
136
  declare const LensFlow: React__default.FC<LensFlowProps>;
136
137
 
137
- /**
138
- * useLensCursor — the ONE cursor, controlled or uncontrolled.
139
- *
140
- * `<Lens>` has always held its scrub position in local state. This hook is that
141
- * same state with one addition: when the host passes a value, the host owns it.
142
- * The standard controlled/uncontrolled pair, modelled on
143
- * `<TraceExplorerShell selectedRuntimeStageId / onSelectionChange>` in
144
- * `footprint-explainable-ui` so the family reads as one API.
145
- *
146
- * The law it exists to keep: **one cursor, never two owners.** Every mover
147
- * inside the lens — the step strip, the ◀ ▶ ⟳Live buttons, the arrow keys, a
148
- * chart node click, a "what happened" moment, a provenance jump, and the
149
- * auto-advance that follows a live run — goes through `moveTo`. A mover that
150
- * sets position without notifying would be a second cursor wearing the first
151
- * one's clothes.
152
- *
153
- * Omit `controlledStep` and nothing changes: the hook keeps today's internal
154
- * state and today's auto-advance, byte for byte.
155
- */
156
-
157
- /**
158
- * Where the cursor landed, in all three units the lens knows — handed to
159
- * `onStepChange` alongside the step so a host never has to reverse-engineer
160
- * the lens's axis.
161
- *
162
- * It is a `LensCursorReading` (`/core`) plus the one thing a MOVE REPORT needs
163
- * and a reading does not: `clamped`. One declaration of the reading's fields,
164
- * so the report and the `LensCursor` every view is handed cannot drift.
165
- */
166
- interface LensCursorAt extends LensCursorReading {
167
- /**
168
- * `true` when this call is Lens CORRECTING a step that is not a position on
169
- * the axis it is now read against, not a move someone made. That is an
170
- * out-of-range `step` you passed, one an internal jump produced, OR — when
171
- * you passed no `step` at all — the lens's own remembered step after the
172
- * axis shrank under it. Uncontrolled snaps are reported too, so this flag
173
- * means the same thing in both modes. Store the corrected value and the two
174
- * cursors agree again.
175
- */
176
- readonly clamped: boolean;
177
- }
178
- /** The cursor's address at one step — resolved by the caller, which owns the
179
- * position list. */
180
- interface LensCursorPlace {
181
- readonly runtimeStageId: string;
182
- readonly commitIdx: number;
183
- readonly label: string;
184
- readonly kind?: string;
185
- }
186
- interface UseLensCursorArgs {
187
- /** The host's value. `undefined` → uncontrolled (Lens owns the cursor). */
188
- readonly controlledStep: number | undefined;
189
- /** Fires on every cursor move, controlled or not. */
190
- readonly onStepChange?: ((step: number, at: LensCursorAt) => void) | undefined;
191
- /** Highest valid step (`totalSteps - 1`). */
192
- readonly maxStep: number;
193
- /** Resolve a step to its address. Called only when a move is reported. */
194
- readonly describe: (step: number) => LensCursorPlace;
195
- /**
196
- * The MOVEMENT port — footprintjs 9.17's reader cursor over the Lens's own
197
- * stops (`openLensCursor(positions)`). When present, every move this funnel
198
- * makes is decided by the library: where a step lands, what happens at the
199
- * ends of the axis, and what an out-of-range ask does. Omit it and the
200
- * funnel keeps its own arithmetic, unchanged — which is what the hook's own
201
- * tests drive, so the two readings can be compared.
202
- *
203
- * It is NOT a second cursor: the port is re-seated on the step this hook
204
- * owns before every question and remembers nothing between them.
205
- */
206
- readonly port?: LensCursorPort | undefined;
207
- /**
208
- * The ACTIVE scrub axis — the same list the lens draws its ruler from.
209
- *
210
- * Supplied only so this hook can also hand back the `LensCursor` every view
211
- * receives (`cursor` below), which needs the axis to answer an ADDRESS. It
212
- * is never consulted for movement: `maxStep`, `describe` and `port` decide
213
- * that, exactly as they did before 0.51.0.
214
- *
215
- * Omit it and `cursor` is a cursor over an EMPTY axis — `resolve` refuses
216
- * `'empty-axis'`, which is the honest answer for a caller that gave none.
217
- */
218
- readonly positions?: readonly CursorPosition[] | undefined;
219
- }
220
- interface UseLensCursorResult {
221
- /** The cursor to render. */
222
- readonly step: number;
223
- /** Pinned to the live edge (drives the ⟳Live affordance). */
224
- readonly isLive: boolean;
225
- /** The ONE way anything inside the lens moves the cursor. */
226
- readonly moveTo: (n: number) => void;
227
- /**
228
- * The same one cursor in the shape EVERY view is handed (0.51.0): a READING
229
- * (`at`), the honest address query (`resolve`) and this very `moveTo`.
230
- *
231
- * Added BESIDE the three fields above — nothing moved, nothing was removed.
232
- * It holds no position: it is rebuilt from (`positions`, `step`) on every
233
- * render, so a view cannot end up rendering a stale copy.
234
- */
235
- readonly cursor: LensCursor;
236
- }
237
- /**
238
- * Snap a host-supplied step onto the axis. Non-finite and fractional values
239
- * are not positions, so they clamp too — and the clamp is always reported.
240
- */
241
- declare function clampStep(n: number, maxStep: number): number;
242
- declare function useLensCursor({ controlledStep, onStepChange, maxStep, describe, port, positions, }: UseLensCursorArgs): UseLensCursorResult;
243
-
244
138
  /**
245
139
  * useLensNavigator — move the ONE cursor to a stage by its address.
246
140
  *
@@ -603,6 +497,24 @@ interface LensProps {
603
497
  * Memoize via `useCallback` to avoid downstream re-renders.
604
498
  */
605
499
  readonly onStepChange?: (step: number, at: LensCursorAt) => void;
500
+ /**
501
+ * The HOST's one cursor across every lens it mounts (0.56.0) — the owner
502
+ * `useSharedCursor(recorder)` hands back. Pass it and this lens derives its
503
+ * own step over whatever axis it is drawing (the commit axis, the milestone
504
+ * axis, a tag-filtered one, a drilled one) from the shared ADDRESS, and
505
+ * every mover here — the strip, ◀ ▶, a chart click, `navigatorRef` — moves
506
+ * that address. `step` is ignored while `shared` is given; `onStepChange`
507
+ * still fires as an observation hook. A correction the lens makes on its
508
+ * own (`at.clamped`, an address this axis cannot hold) never rewrites the
509
+ * address: a tab derives a step, only a mover changes the address.
510
+ *
511
+ * ```tsx
512
+ * const shared = useSharedCursor(recorder);
513
+ * <Lens recorder={recorder} shared={shared} granularity="group" />
514
+ * <ContextView runner={runner} cursor={shared.forAxis('group')} />
515
+ * ```
516
+ */
517
+ readonly shared?: SharedCursor;
606
518
  /**
607
519
  * Move the cursor to a STAGE, by its address — the pointing half of the
608
520
  * cursor API. `step` / `onStepChange` let a host OWN the cursor; this lets
@@ -759,4 +671,4 @@ interface LensDetailSlotProps {
759
671
  }
760
672
  declare const Lens: React__default.FC<LensProps>;
761
673
 
762
- export { type LensProps as L, type ToolChoiceSource as T, type UseLensCursorArgs as U, Lens as a, type LensCursorAt as b, type LensDetailSlotProps as c, type LensSlots as d, type LensTheme as e, type LensView as f, type LensCursorPlace as g, LensFlow as h, type LensFlowProps as i, type LensNavigator as j, type UseLensCursorResult as k, type UseLensNavigatorArgs as l, type UseToolChoiceResult as m, clampStep as n, useLensNavigator as o, useToolChoice as p, useLensCursor as u };
674
+ export { type LensProps as L, type ToolChoiceSource as T, type UseLensNavigatorArgs as U, Lens as a, type LensDetailSlotProps as b, type LensSlots as c, type LensTheme as d, type LensView as e, LensFlow as f, type LensFlowProps as g, type LensNavigator as h, type UseToolChoiceResult as i, useToolChoice as j, useLensNavigator as u };