@insitue/sdk 0.1.13 → 0.2.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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  mountCaptureOnly
3
- } from "./chunk-RTIWK5P2.js";
4
- import "./chunk-MGEIT55T.js";
3
+ } from "./chunk-ZV3AVYBI.js";
4
+ import "./chunk-62N4L6RA.js";
5
5
  export {
6
6
  mountCaptureOnly
7
7
  };
@@ -583,7 +583,7 @@ function resolveTarget(el) {
583
583
  return source === void 0 ? { confidence, componentStack, selector } : { source, confidence, componentStack, selector };
584
584
  }
585
585
  var CAPTURE_SCHEMA_VERSION = 3;
586
- var PROTOCOL_VERSION = 4;
586
+ var PROTOCOL_VERSION = 5;
587
587
  function toIssueDraft(bundle) {
588
588
  const t3 = bundle.target;
589
589
  const where = t3?.source ? `\`${t3.source.file}:${t3.source.line}\` (${t3.confidence})` : t3 ? `\`${t3.selector}\` (selector-only \u2014 no source resolver)` : "(empty selection)";
@@ -1671,7 +1671,7 @@ async function renderViewportCrop(cropRect, pixelRatio) {
1671
1671
  out.width = Math.max(1, Math.round(cropRect.width * pixelRatio));
1672
1672
  out.height = Math.max(1, Math.round(cropRect.height * pixelRatio));
1673
1673
  const ctx = out.getContext("2d");
1674
- if (!ctx) return { dataUrl: null, failedImages };
1674
+ if (!ctx) return { dataUrl: null, looksBlank: false, failedImages };
1675
1675
  const fullCanvas = await toCanvas(document.documentElement, {
1676
1676
  pixelRatio,
1677
1677
  cacheBust: true,
@@ -1699,11 +1699,9 @@ async function renderViewportCrop(cropRect, pixelRatio) {
1699
1699
  failedImages
1700
1700
  );
1701
1701
  void drawnImgs;
1702
- if (looksBlankUniform(ctx, out.width, out.height)) {
1703
- return { dataUrl: null, failedImages };
1704
- }
1702
+ const looksBlank = looksBlankUniform(ctx, out.width, out.height);
1705
1703
  detectUnrenderedImages(ctx, cropRect, out, pixelRatio, failedImages);
1706
- return { dataUrl: out.toDataURL("image/png"), failedImages };
1704
+ return { dataUrl: out.toDataURL("image/png"), looksBlank, failedImages };
1707
1705
  }
1708
1706
  async function drawAbsoluteImagesOnto(ctx, cropRect, pixelRatio, failedImages) {
1709
1707
  const drawn = /* @__PURE__ */ new Set();
@@ -2133,13 +2131,15 @@ async function buildBundle(sel) {
2133
2131
  try {
2134
2132
  const skipLayer1 = settings.alwaysPixelPerfect;
2135
2133
  let layer1Result = null;
2134
+ let layer1LooksBlank = false;
2136
2135
  let quality = null;
2137
2136
  if (!skipLayer1) {
2138
2137
  const r3 = await renderViewportCrop(cropRect, Math.min(dpr, 1.5));
2139
2138
  layer1Result = r3.dataUrl;
2139
+ layer1LooksBlank = r3.looksBlank;
2140
2140
  quality = assessCaptureQuality(cropRect, r3.failedImages);
2141
2141
  }
2142
- const imperfect = !layer1Result || quality != null && (quality.unembeddableImages > 0 || quality.hasVideo || quality.hasCanvas);
2142
+ const imperfect = !layer1Result || layer1LooksBlank || quality != null && (quality.unembeddableImages > 0 || quality.hasVideo || quality.hasCanvas);
2143
2143
  const allowLayer2 = !settings.disableLayer2;
2144
2144
  if ((imperfect || skipLayer1) && allowLayer2) {
2145
2145
  const grab = await tryGrabViaDisplayMedia(
@@ -15,7 +15,7 @@ import {
15
15
  setCaptureSettings,
16
16
  stopDisplayMedia,
17
17
  y
18
- } from "./chunk-MGEIT55T.js";
18
+ } from "./chunk-62N4L6RA.js";
19
19
 
20
20
  // src/client.ts
21
21
  var CompanionClient = class {
@@ -84,6 +84,8 @@ var CompanionClient = class {
84
84
  this.events.onSessionCommitted?.(msg.commit, msg.files);
85
85
  } else if (msg.t === "capture-resolved") {
86
86
  this.events.onResolved?.(msg.id, msg.resolved, msg.note);
87
+ } else if (msg.t === "subscribers-attached") {
88
+ this.events.onSubscribersAttached?.(msg.count);
87
89
  } else if (msg.t === "error") {
88
90
  this.events.onState("error", `${msg.code}: ${msg.message}`);
89
91
  done();
@@ -127,6 +129,20 @@ var CompanionClient = class {
127
129
  );
128
130
  return true;
129
131
  }
132
+ /** #162: route the user's typed intent to a CLI/MCP subscriber
133
+ * (e.g. claude with `/insitue:connect` open) instead of the
134
+ * in-overlay headless agent. No reply arrives back through this
135
+ * client — the external claude shows its work in its own
136
+ * terminal. Callers should switch the panel UI to a "Sent to
137
+ * claude in your terminal" affordance after this returns. */
138
+ sendAsk(turnId, bundleId, text) {
139
+ const ws = this.ws;
140
+ if (!ws || ws.readyState !== WebSocket.OPEN) return false;
141
+ ws.send(
142
+ JSON.stringify({ t: "agent-ask-external", turnId, bundleId, text })
143
+ );
144
+ return true;
145
+ }
130
146
  cancelTurn(turnId) {
131
147
  this.ws?.send(JSON.stringify({ t: "agent-cancel", turnId }));
132
148
  }
@@ -267,6 +283,7 @@ function App(props) {
267
283
  const [commitMsg, setCommitMsg] = d("");
268
284
  const [sessionNote, setSessionNote] = d("");
269
285
  const [lastSel, setLastSel] = d(null);
286
+ const [externalCount, setExternalCount] = d(0);
270
287
  const [activeTurn, setActiveTurn] = d(null);
271
288
  const autoApplyRef = A(false);
272
289
  const changesRef = A([]);
@@ -417,7 +434,11 @@ function App(props) {
417
434
  )
418
435
  );
419
436
  setSessionNote(`committed as ${commit} (local only \u2014 not pushed)`);
420
- }
437
+ },
438
+ // #162: companion pushes this on every CLI/MCP subscriber
439
+ // connect/disconnect. Drives the "→ claude in terminal"
440
+ // badge and the Send-routing branch.
441
+ onSubscribersAttached: (count) => setExternalCount(count)
421
442
  });
422
443
  setClient(c);
423
444
  void c.connect();
@@ -523,9 +544,17 @@ function App(props) {
523
544
  }
524
545
  if (!bundle) return;
525
546
  const turnId = bundle.id;
526
- setActiveTurn({ turnId, prompt: text, sel: lastSel });
527
547
  setMessages((ms) => [...ms, { role: "user", text }]);
528
548
  setChatInput("");
549
+ if (externalCount > 0) {
550
+ client.sendAsk(turnId, bundle.id, text);
551
+ setMessages((ms) => [
552
+ ...ms,
553
+ { role: "agent", text: "\u2192 Sent to claude in your terminal." }
554
+ ]);
555
+ return;
556
+ }
557
+ setActiveTurn({ turnId, prompt: text, sel: lastSel });
529
558
  setChanges([]);
530
559
  setRevisitId("");
531
560
  setActivity("starting");
@@ -1114,6 +1143,25 @@ ${resolved.snippet}`
1114
1143
  ])
1115
1144
  ]
1116
1145
  ),
1146
+ // #162: external-claude attached badge. Lives at the top of
1147
+ // the panel body so the user always sees where their Send
1148
+ // will go before they type. Hidden when count = 0.
1149
+ externalCount > 0 ? k(
1150
+ "div",
1151
+ {
1152
+ style: "display:flex;align-items:center;gap:8px;margin:8px 0;padding:6px 10px;border-radius:4px;background:#0f1f15;border:1px solid #1f4030;color:#9fe7b8;font-size:11px"
1153
+ },
1154
+ [
1155
+ k("span", {
1156
+ style: "width:8px;height:8px;border-radius:50%;background:#2fd16b;box-shadow:0 0 6px #2fd16b;flex:none"
1157
+ }),
1158
+ k(
1159
+ "span",
1160
+ {},
1161
+ `\u2192 claude in terminal (${externalCount === 1 ? "1 session" : `${externalCount} sessions`})`
1162
+ )
1163
+ ]
1164
+ ) : null,
1117
1165
  settings,
1118
1166
  captureActivePill,
1119
1167
  captureDeniedNudge,
@@ -11,7 +11,7 @@ import {
11
11
  setCaptureSettings,
12
12
  stopDisplayMedia,
13
13
  y
14
- } from "./chunk-MGEIT55T.js";
14
+ } from "./chunk-62N4L6RA.js";
15
15
 
16
16
  // src/capture-only.ts
17
17
  var DEFAULT_INGEST = "https://www.insitue.com/api/v1/capture";
@@ -362,8 +362,8 @@ function CaptureOnlyApp(props) {
362
362
  k("span", {}, ""),
363
363
  k(
364
364
  "span",
365
- { title: `@insitue/sdk@${"0.1.13"}` },
366
- `InSitue \xB7 v${"0.1.13"}`
365
+ { title: `@insitue/sdk@${"0.2.0"}` },
366
+ `InSitue \xB7 v${"0.2.0"}`
367
367
  )
368
368
  ]
369
369
  )
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  mountCaptureOnly
3
- } from "./chunk-RTIWK5P2.js";
3
+ } from "./chunk-ZV3AVYBI.js";
4
4
  import {
5
5
  mountInSitue
6
- } from "./chunk-SXX75N6T.js";
7
- import "./chunk-MGEIT55T.js";
6
+ } from "./chunk-VRINS2SK.js";
7
+ import "./chunk-62N4L6RA.js";
8
8
 
9
9
  // src/InSitue.tsx
10
10
  import { useEffect } from "react";
@@ -52,7 +52,7 @@ function InSitueCapture({
52
52
  }
53
53
 
54
54
  // src/index.ts
55
- var SDK_VERSION = "0.1.13";
55
+ var SDK_VERSION = "0.2.0";
56
56
  export {
57
57
  InSitue,
58
58
  InSitueCapture,
package/dist/overlay.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  mountInSitue
3
- } from "./chunk-SXX75N6T.js";
4
- import "./chunk-MGEIT55T.js";
3
+ } from "./chunk-VRINS2SK.js";
4
+ import "./chunk-62N4L6RA.js";
5
5
  export {
6
6
  mountInSitue
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insitue/sdk",
3
- "version": "0.1.13",
3
+ "version": "0.2.0",
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",
@@ -56,7 +56,7 @@
56
56
  "tsup": "^8.3.5",
57
57
  "typescript": "^5.6.3",
58
58
  "vitest": "^3.2.4",
59
- "@insitue/capture-core": "0.0.0"
59
+ "@insitue/capture-core": "0.2.0"
60
60
  },
61
61
  "repository": {
62
62
  "type": "git",