@insitue/sdk 0.4.3 → 0.4.5

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  mountCaptureOnly
3
- } from "./chunk-3XYBNSL6.js";
3
+ } from "./chunk-SI2PTZTD.js";
4
4
  export {
5
5
  mountCaptureOnly
6
6
  };
@@ -2106,14 +2106,30 @@ async function buildBundle(sel) {
2106
2106
  let screenshot;
2107
2107
  let screenshotUnavailable;
2108
2108
  if (el instanceof HTMLElement || el instanceof SVGElement) {
2109
+ const pickedRect = el.getBoundingClientRect();
2109
2110
  const context = findContextAncestor(el);
2110
- const cr = context.getBoundingClientRect();
2111
- const cropRect = new DOMRect(
2112
- Math.max(0, cr.x),
2113
- Math.max(0, cr.y),
2114
- Math.min(window.innerWidth, cr.right) - Math.max(0, cr.x),
2115
- Math.min(window.innerHeight, cr.bottom) - Math.max(0, cr.y)
2111
+ const ar = context.getBoundingClientRect();
2112
+ const MIN_W = 420;
2113
+ const MIN_H = 140;
2114
+ const cropW = Math.min(
2115
+ window.innerWidth,
2116
+ Math.max(MIN_W, ar.width, pickedRect.width)
2116
2117
  );
2118
+ const cropH = Math.min(
2119
+ window.innerHeight,
2120
+ Math.max(MIN_H, ar.height, pickedRect.height)
2121
+ );
2122
+ const pickedCx = pickedRect.x + pickedRect.width / 2;
2123
+ const pickedCy = pickedRect.y + pickedRect.height / 2;
2124
+ const cropX = Math.max(
2125
+ 0,
2126
+ Math.min(window.innerWidth - cropW, pickedCx - cropW / 2)
2127
+ );
2128
+ const cropY = Math.max(
2129
+ 0,
2130
+ Math.min(window.innerHeight - cropH, pickedCy - cropH / 2)
2131
+ );
2132
+ const cropRect = new DOMRect(cropX, cropY, cropW, cropH);
2117
2133
  const orig = {
2118
2134
  outline: el.style.outline,
2119
2135
  outlineOffset: el.style.outlineOffset
@@ -2466,6 +2482,106 @@ function defaultDeliver(draft) {
2466
2482
  } catch {
2467
2483
  }
2468
2484
  }
2485
+ function offlineHelpCard(reason, onClose) {
2486
+ const ink = "#ececef";
2487
+ const sub = "#a0a0aa";
2488
+ const faint = "#6b6b75";
2489
+ const line = "#26262d";
2490
+ const surface = "#13131a";
2491
+ const accent = "#5751e6";
2492
+ const mono = 'ui-monospace,"SF Mono",SFMono-Regular,Menlo,monospace';
2493
+ const sans = '-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,"Helvetica Neue",Arial,sans-serif';
2494
+ const title = reason === "companion" ? "Open claude to activate InSitue" : "Attach claude to start picking";
2495
+ const lead = reason === "companion" ? "The local companion isn't reachable yet. Open a terminal in this project and start claude." : "The companion is running, but no claude session is listening. Run the slash command below to attach.";
2496
+ const step1 = reason === "companion" ? "In your project directory, run:" : "In your existing claude session, run:";
2497
+ const cmd1 = reason === "companion" ? "claude" : "/insitue:connect";
2498
+ const step2 = reason === "companion" ? "Then inside claude, run:" : null;
2499
+ const cmd2 = reason === "companion" ? "/insitue:connect" : null;
2500
+ const code = (s3) => k(
2501
+ "code",
2502
+ {
2503
+ style: `display:inline-block;font:600 12.5px/1.4 ${mono};color:${ink};background:#0c0c11;border:1px solid ${line};padding:6px 10px;border-radius:6px`
2504
+ },
2505
+ s3
2506
+ );
2507
+ return k(
2508
+ "div",
2509
+ {
2510
+ style: `width:300px;font:13px/1.5 ${sans};color:${ink};background:${surface};border:1px solid ${line};border-radius:14px;box-shadow:0 14px 44px rgba(0,0,0,.55),0 2px 10px rgba(0,0,0,.35);overflow:hidden`
2511
+ },
2512
+ [
2513
+ k(
2514
+ "div",
2515
+ {
2516
+ style: `display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px 10px`
2517
+ },
2518
+ [
2519
+ k(
2520
+ "div",
2521
+ { style: "display:flex;align-items:center;gap:9px" },
2522
+ [
2523
+ k("span", {
2524
+ style: `width:9px;height:9px;border-radius:3px;background:${accent};box-shadow:0 1px 4px rgba(91,91,240,.4)`
2525
+ }),
2526
+ k(
2527
+ "span",
2528
+ {
2529
+ style: `font-weight:680;font-size:13.5px;letter-spacing:-.01em;color:${ink}`
2530
+ },
2531
+ title
2532
+ )
2533
+ ]
2534
+ ),
2535
+ k(
2536
+ "button",
2537
+ {
2538
+ onClick: onClose,
2539
+ style: `all:unset;cursor:pointer;color:${faint};font-size:18px;line-height:1;padding:2px 6px;border-radius:6px`,
2540
+ title: "Dismiss"
2541
+ },
2542
+ "\xD7"
2543
+ )
2544
+ ]
2545
+ ),
2546
+ k(
2547
+ "div",
2548
+ { style: `padding:0 16px 14px;color:${sub}` },
2549
+ [
2550
+ k("p", { style: "margin:0 0 12px" }, lead),
2551
+ k(
2552
+ "div",
2553
+ { style: "display:flex;flex-direction:column;gap:8px" },
2554
+ [
2555
+ k(
2556
+ "div",
2557
+ {
2558
+ style: `font-size:11.5px;color:${faint};letter-spacing:.04em;text-transform:uppercase;font-weight:600`
2559
+ },
2560
+ step1
2561
+ ),
2562
+ code(cmd1),
2563
+ step2 ? k(
2564
+ "div",
2565
+ {
2566
+ style: `margin-top:6px;font-size:11.5px;color:${faint};letter-spacing:.04em;text-transform:uppercase;font-weight:600`
2567
+ },
2568
+ step2
2569
+ ) : null,
2570
+ cmd2 ? code(cmd2) : null
2571
+ ]
2572
+ ),
2573
+ k(
2574
+ "p",
2575
+ {
2576
+ style: `margin:14px 0 0;font-size:12px;color:${faint}`
2577
+ },
2578
+ "Don't have the plugin? Run /plugin marketplace add InSitue/insitue in claude, then /plugin install insitue."
2579
+ )
2580
+ ]
2581
+ )
2582
+ ]
2583
+ );
2584
+ }
2469
2585
  function CaptureApp(props) {
2470
2586
  const isDev = props.sink.kind === "companion";
2471
2587
  const C3 = isDev ? DEV : CLOUD;
@@ -2478,6 +2594,8 @@ function CaptureApp(props) {
2478
2594
  isDev ? "connecting" : "idle"
2479
2595
  );
2480
2596
  const [companionDetail, setCompanionDetail] = d2("");
2597
+ const [subscriberCount, setSubscriberCount] = d2(0);
2598
+ const [showOfflineHelp, setShowOfflineHelp] = d2(false);
2481
2599
  const noteRef = A2(null);
2482
2600
  const companionRef = A2(null);
2483
2601
  y2(() => {
@@ -2491,12 +2609,14 @@ function CaptureApp(props) {
2491
2609
  onState: (s3, detail) => {
2492
2610
  setCompanionState(s3);
2493
2611
  if (detail) setCompanionDetail(detail);
2612
+ if (s3 !== "connected") setSubscriberCount(0);
2494
2613
  if (s3 === "error" || s3 === "idle") {
2495
2614
  if (!cancelled) {
2496
2615
  reconnectTimer = setTimeout(connect, 2500);
2497
2616
  }
2498
2617
  }
2499
- }
2618
+ },
2619
+ onSubscribersAttached: (count) => setSubscriberCount(count)
2500
2620
  });
2501
2621
  companionRef.current = c3;
2502
2622
  void c3.connect();
@@ -2633,29 +2753,44 @@ function CaptureApp(props) {
2633
2753
  };
2634
2754
  if (phase === "idle" || phase === "picking") {
2635
2755
  const picking = phase === "picking";
2636
- const offline = isDev && companionState !== "connected";
2756
+ const active = isDev && companionState === "connected" && subscriberCount > 0;
2757
+ const muted = isDev && !active;
2637
2758
  if (isDev) {
2638
- const containerBg = offline ? C3.surface : CLOUD.accentSolid;
2639
- const containerBorder = offline ? `1px solid ${C3.line}` : "1px solid transparent";
2640
- const containerShadow = offline ? C3.shadow : `0 0 0 4px rgba(91,91,240,.16),0 12px 30px rgba(60,55,200,.42)`;
2641
- const innerBg = offline ? "#9a9aa4" : "#ffffff";
2642
- const innerShadow = offline ? "none" : "0 1px 3px rgba(0,0,0,.20)";
2759
+ const containerBg = muted ? C3.surface : CLOUD.accentSolid;
2760
+ const containerBorder = muted ? `1px solid ${C3.line}` : "1px solid transparent";
2761
+ const containerShadow = muted ? C3.shadow : `0 0 0 4px rgba(91,91,240,.16),0 12px 30px rgba(60,55,200,.42)`;
2762
+ const innerBg = muted ? "#9a9aa4" : "#ffffff";
2763
+ const innerShadow = muted ? "none" : "0 1px 3px rgba(0,0,0,.20)";
2764
+ const onClickLauncher = picking ? void 0 : muted ? () => setShowOfflineHelp((v3) => !v3) : () => void startPick();
2765
+ const tooltip = picking ? "Click an element \xB7 Esc to cancel" : muted ? "InSitue is muted \u2014 click for setup" : "Pick an element to talk to claude about";
2643
2766
  return k(
2644
- "button",
2767
+ "div",
2645
2768
  {
2646
- onClick: picking ? void 0 : () => void startPick(),
2647
- style: `all:unset;position:fixed;bottom:20px;right:20px;z-index:2147483000;display:flex;align-items:center;justify-content:center;width:38px;height:38px;cursor:${picking ? "default" : "pointer"};background:${containerBg};border:${containerBorder};border-radius:50%;box-shadow:${containerShadow};transition:background .18s ease,box-shadow .18s ease`,
2648
- title: picking ? "Click an element \xB7 Esc to cancel" : offline ? "InSitue companion not running \u2014 start `claude` with /insitue:connect" : "Pick an element to talk to claude about"
2769
+ style: "position:fixed;bottom:20px;right:20px;z-index:2147483000;display:flex;flex-direction:column;align-items:flex-end;gap:12px"
2649
2770
  },
2650
2771
  [
2651
- k("span", {
2652
- style: `width:11px;height:11px;border-radius:3px;background:${innerBg};box-shadow:${innerShadow};${picking ? "animation:ipulse 1.1s ease-in-out infinite" : ""}`
2653
- }),
2654
- picking ? k(
2655
- "style",
2656
- {},
2657
- "@keyframes ipulse{0%,100%{opacity:.45}50%{opacity:1}}"
2658
- ) : null
2772
+ showOfflineHelp && muted ? offlineHelpCard(
2773
+ companionState === "connected" ? "subscriber" : "companion",
2774
+ () => setShowOfflineHelp(false)
2775
+ ) : null,
2776
+ k(
2777
+ "button",
2778
+ {
2779
+ onClick: onClickLauncher,
2780
+ style: `all:unset;display:flex;align-items:center;justify-content:center;width:38px;height:38px;cursor:${picking ? "default" : "pointer"};background:${containerBg};border:${containerBorder};border-radius:50%;box-shadow:${containerShadow};transition:background .18s ease,box-shadow .18s ease`,
2781
+ title: tooltip
2782
+ },
2783
+ [
2784
+ k("span", {
2785
+ style: `width:11px;height:11px;border-radius:3px;background:${innerBg};box-shadow:${innerShadow};${picking ? "animation:ipulse 1.1s ease-in-out infinite" : ""}`
2786
+ }),
2787
+ picking ? k(
2788
+ "style",
2789
+ {},
2790
+ "@keyframes ipulse{0%,100%{opacity:.45}50%{opacity:1}}"
2791
+ ) : null
2792
+ ]
2793
+ )
2659
2794
  ]
2660
2795
  );
2661
2796
  }
@@ -2920,8 +3055,8 @@ function CaptureApp(props) {
2920
3055
  k("span", {}, isDev ? "InSitue Dev \xB7 pick + describe \u2192 CLI" : ""),
2921
3056
  k(
2922
3057
  "span",
2923
- { title: `@insitue/sdk@${"0.4.3"}` },
2924
- `InSitue \xB7 v${"0.4.3"}`
3058
+ { title: `@insitue/sdk@${"0.4.5"}` },
3059
+ `InSitue \xB7 v${"0.4.5"}`
2925
3060
  )
2926
3061
  ]
2927
3062
  )
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  mountCaptureOnly
3
- } from "./chunk-3XYBNSL6.js";
3
+ } from "./chunk-SI2PTZTD.js";
4
4
 
5
5
  // src/InSitue.tsx
6
6
  import { useEffect } from "react";
@@ -54,7 +54,7 @@ function InSitue({ port }) {
54
54
  }
55
55
 
56
56
  // src/index.ts
57
- var SDK_VERSION = "0.4.3";
57
+ var SDK_VERSION = "0.4.5";
58
58
  export {
59
59
  InSitue,
60
60
  InSitueCapture,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insitue/sdk",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "InSitue capture SDK — drop one snippet into your deployed app; your users point at a bug, InSitue opens a verified pull request.",
5
5
  "license": "MIT",
6
6
  "type": "module",