@knpkv/rly 0.14.0 → 0.16.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 (58) hide show
  1. package/README.md +90 -3
  2. package/dist/{Dialog-B9Ub_gMT.js → Dialog-CU66FqWD.js} +325 -257
  3. package/dist/Dialog-CU66FqWD.js.map +1 -0
  4. package/dist/{PortalProvider-CN_81Fy3.js → PortalProvider-op07u8na.js} +20 -18
  5. package/dist/PortalProvider-op07u8na.js.map +1 -0
  6. package/dist/components.css +2 -2
  7. package/dist/diff/bounded/index.js.map +1 -1
  8. package/dist/diff/index.js.map +1 -1
  9. package/dist/diff/patch/index.js.map +1 -1
  10. package/dist/dts/foundations/Icon.d.ts +1 -1
  11. package/dist/dts/foundations/Icon.d.ts.map +1 -1
  12. package/dist/dts/internal/composedFocus.d.ts +11 -0
  13. package/dist/dts/internal/composedFocus.d.ts.map +1 -0
  14. package/dist/dts/internal/relaySummon.d.ts +50 -0
  15. package/dist/dts/internal/relaySummon.d.ts.map +1 -0
  16. package/dist/dts/patterns/RelayComposer.d.ts +65 -0
  17. package/dist/dts/patterns/RelayComposer.d.ts.map +1 -0
  18. package/dist/dts/patterns/RelayDecision.d.ts +75 -0
  19. package/dist/dts/patterns/RelayDecision.d.ts.map +1 -0
  20. package/dist/dts/patterns/RelayDock.d.ts.map +1 -1
  21. package/dist/dts/patterns/RelayFindings.d.ts +83 -0
  22. package/dist/dts/patterns/RelayFindings.d.ts.map +1 -0
  23. package/dist/dts/patterns/RelayLauncher.d.ts +32 -1
  24. package/dist/dts/patterns/RelayLauncher.d.ts.map +1 -1
  25. package/dist/dts/patterns/RelayPanel.d.ts +91 -0
  26. package/dist/dts/patterns/RelayPanel.d.ts.map +1 -0
  27. package/dist/dts/patterns/RelaySetup.d.ts +58 -0
  28. package/dist/dts/patterns/RelaySetup.d.ts.map +1 -0
  29. package/dist/dts/patterns/RelayTranscript.d.ts +68 -0
  30. package/dist/dts/patterns/RelayTranscript.d.ts.map +1 -0
  31. package/dist/dts/patterns/index.d.ts +14 -2
  32. package/dist/dts/patterns/index.d.ts.map +1 -1
  33. package/dist/dts/tokens/fonts.d.ts +13 -0
  34. package/dist/dts/tokens/fonts.d.ts.map +1 -0
  35. package/dist/dts/tokens/index.d.ts +2 -0
  36. package/dist/dts/tokens/index.d.ts.map +1 -1
  37. package/dist/fonts.css +7 -2
  38. package/dist/foundations/index.js +1 -1
  39. package/dist/index.js +6 -6
  40. package/dist/patterns/index.js +2 -2
  41. package/dist/patterns-B3WbiVEp.js +4981 -0
  42. package/dist/patterns-B3WbiVEp.js.map +1 -0
  43. package/dist/primitives/index.js +3 -3
  44. package/dist/{primitives-Bd6WhE78.js → primitives-DgQybTyq.js} +254 -322
  45. package/dist/primitives-DgQybTyq.js.map +1 -0
  46. package/dist/tokens/index.js +2 -2
  47. package/dist/{tokens-B075JP3Z.js → tokens-Cf0jXIRg.js} +14 -8
  48. package/dist/tokens-Cf0jXIRg.js.map +1 -0
  49. package/dist/workbench-CHCnYW3G.js.map +1 -1
  50. package/package.json +1 -1
  51. package/registry/components.json +558 -1
  52. package/registry/search.json +162 -0
  53. package/dist/Dialog-B9Ub_gMT.js.map +0 -1
  54. package/dist/PortalProvider-CN_81Fy3.js.map +0 -1
  55. package/dist/patterns-ChmGSFqO.js +0 -3768
  56. package/dist/patterns-ChmGSFqO.js.map +0 -1
  57. package/dist/primitives-Bd6WhE78.js.map +0 -1
  58. package/dist/tokens-B075JP3Z.js.map +0 -1
package/README.md CHANGED
@@ -31,7 +31,10 @@ Import the global layers once at the application boundary:
31
31
  @import "@knpkv/rly/styles.css";
32
32
  ```
33
33
 
34
- The stylesheet contains self-hosted Geist and Geist Mono variable fonts,
34
+ The stylesheet contains self-hosted Geist and Geist Mono variable fonts (with
35
+ `font-display: optional`: preload each file in `RLY_FONT_FACES` from your own
36
+ origin with `crossorigin`, and Geist renders from first paint; a late face keeps
37
+ the metric-matched fallback for that page view rather than swapping),
35
38
  semantic `light-dark()` color pairs, typography, spacing, shape, motion, a
36
39
  scoped reset, and base styles. Set `data-theme="light|dark|system"` on the rly
37
40
  root; system is the default. Forced colors and reduced motion are handled
@@ -466,10 +469,94 @@ the platform) only when the host binds that key and prevents the browser's own C
466
469
  or `null` where it binds none, such as a live terminal that keeps its chords.
467
470
  The hint hides at 40rem and below, and the button is 32px tall, 44px for a coarse pointer.
468
471
 
472
+ `RelayTranscript` shows a Relay conversation: your turns as bubbles at the inline
473
+ end, Relay's turns as selectable prose whose code blocks scroll in place, each burst of
474
+ tool work as one collapsed row in reading order (each call's summary, a status word and
475
+ citations whose link text is the location), and how each run ended. One polite
476
+ announcer outside the content says when a run starts, finishes, stops or fails, never
477
+ per token; "Relay is writing…" is visible only. Inside `RelayPanel` it follows new
478
+ content only while you are at the end; reading earlier turns, "New messages" appears
479
+ instead, and jumps are instant under reduced motion.
480
+
481
+ `RelayComposer` is Relay's message box: it grows with its text up to 12 lines or 40%
482
+ of the viewport, Enter adds a line and Ctrl/⌘+Enter sends (said beside Send), and an
483
+ IME composition never sends. Context refs are removable chips. One `preset` slot holds
484
+ the run preset. Stop appears only when the host passes `onStop`. While `busyReason` is
485
+ set, Send stays focusable and announces why it is unavailable. `useRelayDraft(objectKey, { newRequestId })`
486
+ keeps the draft per object (the JSON ObjectRef) for the page, so closing, reopening or
487
+ resizing Relay keeps it and one object's draft never sends as another's; pass
488
+ `storage: () => sessionStorage` to survive a reload (never localStorage). Its
489
+ `submission()` reuses one request id until the text changes, so a retry after an
490
+ uncertain outcome is deduplicated; call `accepted(requestId)` once the server accepts
491
+ that request, which clears the draft unless the user has typed since.
492
+
493
+ `RelayDecision` asks before one Relay write: the question, exactly where the write
494
+ goes (only what the action pins: a PR comment names the PR, not a line), the exact
495
+ text in its own scroll, and Confirm or Don't for that one call, never "allow all". The
496
+ host writes the words (`copy`: ask, confirm, decline, working, done, and an optional
497
+ `reversible`), and `tone: "danger"` marks a destructive write. The first press is
498
+ latched until the host moves `state` on, so a double click cannot confirm twice.
499
+ Confirmed says "Posting…"; only Done, with its receipt, is past tense; Failed never
500
+ claims nothing was written. Pending, declined and expired are announced once per call
501
+ `id`, without moving focus; after an answer, focus moves to the outcome.
502
+
503
+ `RelaySetup` is Relay's in-panel first run: an agent, then a focus, then "Review this
504
+ pull request". Each backend shows the server's status, and only a Ready backend can be
505
+ chosen, so an installed CLI (a version on PATH) is never taken for a working one. Not
506
+ checked yet offers Check now; Unavailable names its cause (not installed, signed out,
507
+ needs setup, can't review here), the host's fix and Check again; Checking is the
508
+ client's own request state. rly never collects provider credentials: the fix tells the
509
+ user what to run on their machine. A finished check is announced politely, and Start
510
+ stays reachable while unavailable, saying what is missing.
511
+
512
+ `RelayFindings` reviews Relay's findings (the shape of codecommit's
513
+ `RelayReviewFinding`): grouped by location, the whole pull request first, most severe
514
+ first in each group, severity as an icon, a word and the P-number (Blocking, Should fix,
515
+ Consider, Nit). Accept and Dismiss are toggles (pressing again returns to pending);
516
+ Discuss attaches the set to the conversation. "Post accepted" hands the host the
517
+ accepted ids to post one confirmed call at a time, never a bulk write. When the head has
518
+ moved since `reviewedHead`, a banner says so with Re-run, and line findings wait for the
519
+ re-run instead of landing on the wrong line. A before-side line is shown as text with
520
+ its old revision and never opens a head line. Posting outcomes are announced once each;
521
+ a failed post offers Try again for that one finding.
522
+
523
+ `RelayPanel` is Relay's frame: header (mark, title, exact scope with the revision in
524
+ mono, an optional pin, options, close), tabs whose counts are part of their names, a
525
+ freshness line, a body, and a footer for the composer. Only the body scrolls, so the
526
+ composer never leaves the screen. `overlay` floats over the right of the page with
527
+ no backdrop and no focus trap; render it right after the launcher so Tab order
528
+ follows. `pinned` is a sticky column for the host's grid, and `fullscreen` is a modal
529
+ dialog with the page inert. Escape and the close button call `onClose` and return
530
+ focus to the launcher; closing hides Relay in every presentation, and whether it was
531
+ pinned stays the host's remembered preference. `useRelayPresentation({ pinned,
532
+ minHostWidth })` picks the presentation: full screen at 640 CSS px and narrower,
533
+ pinned only when the user pinned it at 1440 and up with the host's minimum beside the
534
+ 440px column, otherwise the overlay. Hosts set `--rly-relay-panel-offset` to their
535
+ sticky header's height and `--app-bottom-inset` to any bar docked at the bottom.
536
+ Full screen portals through `PortalProvider`, so render Relay inside one, and set
537
+ `interactive-widget=resizes-content` in the viewport meta so the full-screen footer
538
+ stays above a phone's on-screen keyboard.
539
+
540
+ `useRelaySummon` binds that shortcut. From the page it opens Relay and focuses the composer (or, if
541
+ Relay is already open, moves focus to the composer); from inside Relay it takes focus back to where it
542
+ came from, and Relay stays open. Full screen, it closes Relay. Escape closes Relay when focus is inside
543
+ it or Relay is full screen, and returns focus. Only the exact chord is handled and prevented, so Ctrl+K,
544
+ `?`, g-sequences and Alt keys reach the host. On a non-Latin layout the physical J key works; a Latin
545
+ layout uses the J the user sees. Escape is left to an IME composition and to a dialog, listbox or menu
546
+ open inside or opened from Relay, including inside shadow roots. When the element Relay came from is
547
+ gone, focus returns to the `launcher`; after a close, focus returns once Relay has actually closed.
548
+ Attach the returned `regionRef` to Relay's region and `composerRef` to the composer, which is focused
549
+ as soon as it mounts. The hook follows Relay into another document (an iframe portal). Pass the same
550
+ `shortcut` the launcher advertises, or `null` while the host's own surface owns the key; Escape inside
551
+ Relay works either way.
552
+
469
553
  ```tsx
470
- import { RelayLauncher, useRelayShortcut } from "@knpkv/rly/patterns"
554
+ import { RelayLauncher, useRelayShortcut, useRelaySummon } from "@knpkv/rly/patterns"
555
+
556
+ ;const shortcut = useRelayShortcut()
557
+ const { composerRef, regionRef } = useRelaySummon({ fullscreen: false, launcher, onOpenChange: setOpen, open, shortcut })
471
558
 
472
- ;<RelayLauncher expanded={open} onClick={() => setOpen((value) => !value)} shortcut={useRelayShortcut()} />
559
+ <RelayLauncher expanded={open} onClick={() => setOpen((value) => !value)} ref={launcher} shortcut={shortcut} />
473
560
  ```
474
561
 
475
562
  `RelayDock` is the shared product frame for one adapter-owned Relay thread. It