@gmickel/gno 2.8.4 → 2.8.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.
package/README.md CHANGED
@@ -139,7 +139,7 @@ See the [guide](docs/COMPILED-CONTEXT.md).
139
139
 
140
140
  <!-- public-truth:current-version -->
141
141
 
142
- > Current source version: **v2.8.4**. See [CHANGELOG.md](./CHANGELOG.md).
142
+ > Current source version: **v2.8.5**. See [CHANGELOG.md](./CHANGELOG.md).
143
143
 
144
144
  <!-- /public-truth -->
145
145
 
Binary file
@@ -0,0 +1 @@
1
+ 347695588c724660218a91ae70cd7bd8420445d2f78dd293cf661626380db7f2 gno-browser-clipper-v2.8.5.zip
@@ -21,5 +21,5 @@
21
21
  "content_security_policy": {
22
22
  "extension_pages": "script-src 'self'; object-src 'none'; connect-src http://127.0.0.1:*"
23
23
  },
24
- "version": "2.8.4"
24
+ "version": "2.8.5"
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gmickel/gno",
3
- "version": "2.8.4",
3
+ "version": "2.8.5",
4
4
  "description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
5
5
  "keywords": [
6
6
  "embeddings",
package/spec/cli.md CHANGED
@@ -406,11 +406,19 @@ Passive callers report `semantic_not_checked` when vector runtime availability
406
406
  is unknown. `vector_unavailable` is reserved for a resident runtime that has
407
407
  positively reported vector search unavailable.
408
408
 
409
- `connectorProjection.total` counts every configured collection and connector
410
- target pair before projection bounds. `projected` equals `connectors.length`,
411
- and `truncated` is true exactly when `total > projected`. No result is claimed
412
- for omitted pairs, and human-readable health output must not report connector
413
- proof as healthy while the projection is truncated.
409
+ `connectorProjection.total` counts every non-empty collection and connector
410
+ target pair. Every pair is evaluated from cached receipts; the 64-pair cap
411
+ bounds only the listed `connectors`. `projected` equals `connectors.length`,
412
+ and `truncated` is true exactly when `total > projected`. When truncated,
413
+ `omitted` counts the unlisted pairs by outcome (`passed`, `failed`,
414
+ `incomplete`, `notApplicable`; the counts sum to `total - projected`). Connector
415
+ completeness, and so overall health, is decided from the listed pairs plus
416
+ these counts: a truncated projection whose pairs all passed or are not
417
+ applicable is healthy, and a failed or pending pair beyond the list keeps it
418
+ degraded. Human-readable output keeps the `N/M ... shown; K omitted` line and
419
+ summarizes the omitted outcomes, for example `(108 passed, 1 failed)`. A
420
+ truncated projection without `omitted` claims no result for the unlisted pairs
421
+ and is never reported healthy.
414
422
 
415
423
  **Exit Codes:**
416
424
 
@@ -164,7 +164,7 @@
164
164
  "total": {
165
165
  "type": "integer",
166
166
  "minimum": 0,
167
- "description": "All configured collection and connector target pairs before projection bounds."
167
+ "description": "All non-empty collection and connector target pairs; every pair is evaluated from cached receipts."
168
168
  },
169
169
  "projected": {
170
170
  "type": "integer",
@@ -174,7 +174,27 @@
174
174
  },
175
175
  "truncated": {
176
176
  "type": "boolean",
177
- "description": "True exactly when total is greater than projected; omitted pairs have no claimed result."
177
+ "description": "True exactly when total is greater than projected. Omitted pairs are still evaluated; their outcomes are counted in omitted."
178
+ },
179
+ "omitted": {
180
+ "type": "object",
181
+ "additionalProperties": false,
182
+ "required": ["passed", "failed", "incomplete", "notApplicable"],
183
+ "description": "Present when truncated: outcome counts for the evaluated pairs not listed in connectors. The counts sum to total - projected. Connector completeness is decided from connectors plus these counts.",
184
+ "properties": {
185
+ "passed": { "type": "integer", "minimum": 0 },
186
+ "failed": { "type": "integer", "minimum": 0 },
187
+ "incomplete": {
188
+ "type": "integer",
189
+ "minimum": 0,
190
+ "description": "Pending, or skipped for a runtime reason such as lexical retrieval not ready."
191
+ },
192
+ "notApplicable": {
193
+ "type": "integer",
194
+ "minimum": 0,
195
+ "description": "Connector not configured, or a skill runtime that cannot be verified."
196
+ }
197
+ }
178
198
  }
179
199
  }
180
200
  }
@@ -514,7 +514,7 @@
514
514
  "total": {
515
515
  "type": "integer",
516
516
  "minimum": 0,
517
- "description": "All configured collection and connector target pairs before projection bounds."
517
+ "description": "All non-empty collection and connector target pairs; every pair is evaluated from cached receipts."
518
518
  },
519
519
  "projected": {
520
520
  "type": "integer",
@@ -524,7 +524,27 @@
524
524
  },
525
525
  "truncated": {
526
526
  "type": "boolean",
527
- "description": "True exactly when total is greater than projected; omitted pairs have no claimed result."
527
+ "description": "True exactly when total is greater than projected. Omitted pairs are still evaluated; their outcomes are counted in omitted."
528
+ },
529
+ "omitted": {
530
+ "type": "object",
531
+ "additionalProperties": false,
532
+ "required": ["passed", "failed", "incomplete", "notApplicable"],
533
+ "description": "Present when truncated: outcome counts for the evaluated pairs not listed in connectors. The counts sum to total - projected. Connector completeness is decided from connectors plus these counts.",
534
+ "properties": {
535
+ "passed": { "type": "integer", "minimum": 0 },
536
+ "failed": { "type": "integer", "minimum": 0 },
537
+ "incomplete": {
538
+ "type": "integer",
539
+ "minimum": 0,
540
+ "description": "Pending, or skipped for a runtime reason such as lexical retrieval not ready."
541
+ },
542
+ "notApplicable": {
543
+ "type": "integer",
544
+ "minimum": 0,
545
+ "description": "Connector not configured, or a skill runtime that cannot be verified."
546
+ }
547
+ }
528
548
  }
529
549
  }
530
550
  }
@@ -6,6 +6,11 @@ import type { StorePort } from "../../store/types";
6
6
  import type { DoctorCheck } from "./doctor";
7
7
 
8
8
  import { getIndexDbPath, getModelsCachePath } from "../../app/constants";
9
+ import {
10
+ classifyConnectorProof,
11
+ describeOmittedConnectorPairs,
12
+ omittedConnectorSummary,
13
+ } from "../../core/activation-connector-health";
9
14
  import { isEmptyActivationCollection } from "../../core/activation-empty";
10
15
  import { buildActivationStatus } from "../../core/activation-status";
11
16
  import { ModelCache } from "../../llm/cache";
@@ -149,13 +154,14 @@ export function checkConnectorActivation(
149
154
  activation: ActivationStatus
150
155
  ): DoctorCheck | null {
151
156
  const { projected, total, truncated } = activation.connectorProjection;
152
- const omitted = total - projected;
157
+ const omitted = omittedConnectorSummary(activation);
153
158
  const observed = activation.connectors.filter(
154
- ({ code }) =>
155
- code !== "connector_not_configured" &&
156
- code !== "target_runtime_unverifiable"
159
+ (connector) => classifyConnectorProof(connector) !== "notApplicable"
157
160
  );
158
- if (observed.length === 0 && !truncated) {
161
+ const omittedObserved = omitted
162
+ ? omitted.passed + omitted.failed + omitted.incomplete
163
+ : 0;
164
+ if (observed.length === 0 && omittedObserved === 0 && omitted) {
159
165
  return null;
160
166
  }
161
167
  const incomplete = observed.filter(({ status }) => status !== "passed");
@@ -163,20 +169,23 @@ export function checkConnectorActivation(
163
169
  ({ collection, target, status, code, remediation }) =>
164
170
  `${target}/${collection}: ${status}${code ? `/${code}` : ""}${remediation ? `. ${remediation}` : ""}`
165
171
  );
166
- if (truncated) {
167
- details.unshift(
168
- `${omitted} target/collection checks were omitted by the bounded status projection; no result is claimed for them.`
169
- );
172
+ const omittedDetail = describeOmittedConnectorPairs(activation);
173
+ if (omittedDetail) {
174
+ details.unshift(omittedDetail);
170
175
  }
176
+ const unresolved =
177
+ incomplete.length + (omitted ? omitted.failed + omitted.incomplete : 0);
178
+ const passed = observed.length - incomplete.length + (omitted?.passed ?? 0);
179
+ const listing = truncated ? ` (${projected} of ${total} checks listed)` : "";
171
180
  return {
172
181
  name: "connector-activation",
173
- status: incomplete.length > 0 || truncated ? "warn" : "ok",
182
+ status: unresolved > 0 || !omitted ? "warn" : "ok",
174
183
  message:
175
- incomplete.length > 0
176
- ? `${incomplete.length} connector proof${incomplete.length === 1 ? "" : "s"} pending or failed`
177
- : truncated
178
- ? `${projected} of ${total} connector target/collection checks projected`
179
- : `${observed.length} connector proof${observed.length === 1 ? "" : "s"} passed`,
184
+ unresolved > 0
185
+ ? `${unresolved} connector proof${unresolved === 1 ? "" : "s"} pending or failed${listing}`
186
+ : omitted
187
+ ? `${passed} connector proof${passed === 1 ? "" : "s"} passed${listing}`
188
+ : `${projected} of ${total} connector target/collection checks projected`,
180
189
  details,
181
190
  };
182
191
  }
@@ -18,7 +18,11 @@ import {
18
18
  isInitialized,
19
19
  loadConfig,
20
20
  } from "../../config";
21
- import { isConnectorActivationComplete } from "../../core/activation-connector-health";
21
+ import {
22
+ describeConnectorSummary,
23
+ isConnectorActivationComplete,
24
+ omittedConnectorSummary,
25
+ } from "../../core/activation-connector-health";
22
26
  import { isEmptyActivationCollection } from "../../core/activation-empty";
23
27
  import { buildActivationStatus } from "../../core/activation-status";
24
28
  import { formatChunkingStatus } from "../../core/chunking-status";
@@ -146,7 +150,8 @@ function connectorProjectionLine(activation: ActivationStatus): string | null {
146
150
  if (!truncated) {
147
151
  return null;
148
152
  }
149
- return `Connector projection: ${projected}/${total} target/collection checks shown; ${total - projected} omitted`;
153
+ const omitted = omittedConnectorSummary(activation);
154
+ return `Connector projection: ${projected}/${total} target/collection checks shown; ${total - projected} omitted${omitted ? ` (${describeConnectorSummary(omitted)})` : ", no result claimed"}`;
150
155
  }
151
156
 
152
157
  function isStatusHealthy(
@@ -1,19 +1,111 @@
1
- import type { ActivationStatus } from "./activation-status";
1
+ import type {
2
+ ActivationConnectorStatus,
3
+ ActivationStatus,
4
+ ConnectorOmittedSummary,
5
+ } from "./activation-status";
2
6
 
3
7
  const NON_RUNTIME_CODES = new Set([
4
8
  "connector_not_configured",
5
9
  "target_runtime_unverifiable",
6
10
  ]);
7
11
 
8
- /** True when every observable proof passed and no target/collection pair was omitted. */
12
+ export type ConnectorProofOutcome = keyof ConnectorOmittedSummary;
13
+
14
+ /** One shared reading of a connector pair, used for listed and unlisted pairs alike. */
15
+ export function classifyConnectorProof({
16
+ code,
17
+ status,
18
+ }: Pick<ActivationConnectorStatus, "code" | "status">): ConnectorProofOutcome {
19
+ if (code !== undefined && NON_RUNTIME_CODES.has(code)) {
20
+ return "notApplicable";
21
+ }
22
+ if (status === "passed" || status === "failed") {
23
+ return status;
24
+ }
25
+ return "incomplete";
26
+ }
27
+
28
+ export function summarizeConnectorProofs(
29
+ connectors: readonly Pick<ActivationConnectorStatus, "code" | "status">[]
30
+ ): ConnectorOmittedSummary {
31
+ const summary: ConnectorOmittedSummary = {
32
+ passed: 0,
33
+ failed: 0,
34
+ incomplete: 0,
35
+ notApplicable: 0,
36
+ };
37
+ for (const connector of connectors) {
38
+ summary[classifyConnectorProof(connector)] += 1;
39
+ }
40
+ return summary;
41
+ }
42
+
43
+ /**
44
+ * Summary of the pairs past the display cap, or null when some were omitted
45
+ * without an evaluated result (fail closed).
46
+ */
47
+ export function omittedConnectorSummary(
48
+ activation: ActivationStatus
49
+ ): ConnectorOmittedSummary | null {
50
+ const { omitted, projected, total, truncated } =
51
+ activation.connectorProjection;
52
+ if (!truncated) {
53
+ return { passed: 0, failed: 0, incomplete: 0, notApplicable: 0 };
54
+ }
55
+ if (!omitted) {
56
+ return null;
57
+ }
58
+ const counted =
59
+ omitted.passed +
60
+ omitted.failed +
61
+ omitted.incomplete +
62
+ omitted.notApplicable;
63
+ return counted === total - projected ? omitted : null;
64
+ }
65
+
66
+ /** Human summary of unlisted pairs, e.g. "108 passed, 1 failed". */
67
+ export function describeConnectorSummary(
68
+ summary: ConnectorOmittedSummary
69
+ ): string {
70
+ const parts = [
71
+ summary.passed > 0 ? `${summary.passed} passed` : null,
72
+ summary.failed > 0 ? `${summary.failed} failed` : null,
73
+ summary.incomplete > 0 ? `${summary.incomplete} pending` : null,
74
+ summary.notApplicable > 0
75
+ ? `${summary.notApplicable} not configured or not verifiable`
76
+ : null,
77
+ ].filter(Boolean);
78
+ return parts.length > 0 ? parts.join(", ") : "none";
79
+ }
80
+
81
+ /** Sentence describing the pairs past the display cap, or null when none were omitted. */
82
+ export function describeOmittedConnectorPairs(
83
+ activation: ActivationStatus
84
+ ): string | null {
85
+ const { projected, total, truncated } = activation.connectorProjection;
86
+ if (!truncated) {
87
+ return null;
88
+ }
89
+ const omitted = total - projected;
90
+ const summary = omittedConnectorSummary(activation);
91
+ return summary
92
+ ? `${omitted} more target/collection checks are not listed: ${describeConnectorSummary(summary)}.`
93
+ : `${omitted} target/collection checks were omitted by the bounded status projection; no result is claimed for them.`;
94
+ }
95
+
96
+ /**
97
+ * True when every collection/target pair, listed or not, passed or has a
98
+ * non-runtime code. Pairs omitted without an evaluated result fail closed.
99
+ */
9
100
  export function isConnectorActivationComplete(
10
101
  activation: ActivationStatus
11
102
  ): boolean {
12
- if (activation.connectorProjection.truncated) {
103
+ const omitted = omittedConnectorSummary(activation);
104
+ if (!omitted || omitted.failed > 0 || omitted.incomplete > 0) {
13
105
  return false;
14
106
  }
15
- return activation.connectors.every(
16
- ({ code, status }) =>
17
- (code !== undefined && NON_RUNTIME_CODES.has(code)) || status === "passed"
18
- );
107
+ return activation.connectors.every((connector) => {
108
+ const outcome = classifyConnectorProof(connector);
109
+ return outcome === "passed" || outcome === "notApplicable";
110
+ });
19
111
  }
@@ -14,6 +14,7 @@ import type {
14
14
  ConnectorVerificationTarget,
15
15
  } from "./connector-verifier";
16
16
 
17
+ import { summarizeConnectorProofs } from "./activation-connector-health";
17
18
  import { isEmptyActivationCollection } from "./activation-empty";
18
19
  import { createEphemeralActivationProbePlan } from "./activation-probe-plan";
19
20
  import { verifyLexicalActivation } from "./activation-verifier";
@@ -23,7 +24,7 @@ import {
23
24
  } from "./connector-verifier";
24
25
 
25
26
  const DEFAULT_CONCURRENCY = 4;
26
- const MAX_CONNECTOR_TARGETS = 16;
27
+ /** Bounds the listed pairs only; completeness is decided from every pair. */
27
28
  const MAX_CONNECTOR_PROJECTIONS = 64;
28
29
  const CONNECTOR_CODES = new Set<ActivationVerificationCode>([
29
30
  "connector_not_configured",
@@ -89,9 +90,21 @@ export interface ActivationStatus {
89
90
  total: number;
90
91
  projected: number;
91
92
  truncated: boolean;
93
+ /** Outcome counts for the evaluated pairs past the display cap; present when truncated. */
94
+ omitted?: ConnectorOmittedSummary;
92
95
  };
93
96
  }
94
97
 
98
+ /** Per-outcome counts of evaluated connector pairs that are not listed. */
99
+ export interface ConnectorOmittedSummary {
100
+ passed: number;
101
+ failed: number;
102
+ /** Pending, or skipped for a runtime reason (for example lexical not ready). */
103
+ incomplete: number;
104
+ /** Not configured, or a skill runtime that cannot be verified. */
105
+ notApplicable: number;
106
+ }
107
+
95
108
  export interface ActivationStatusOptions {
96
109
  concurrency?: number;
97
110
  semantic?: {
@@ -329,18 +342,22 @@ async function buildConnectorStatuses(
329
342
  store: StorePort,
330
343
  collections: VerifiedCollection[],
331
344
  targets: readonly ConnectorVerificationTarget[]
332
- ): Promise<{ items: ActivationConnectorStatus[]; total: number }> {
345
+ ): Promise<{
346
+ items: ActivationConnectorStatus[];
347
+ omitted: ConnectorOmittedSummary;
348
+ total: number;
349
+ }> {
333
350
  const sortedTargets = [...targets].sort((a, b) => a.id.localeCompare(b.id));
334
- const boundedTargets = sortedTargets.slice(0, MAX_CONNECTOR_TARGETS);
335
351
  // A collection with no documents gives a connector nothing to prove.
336
352
  const provable = collections.filter(
337
353
  ({ projected }) => !isEmptyActivationCollection(projected)
338
354
  );
339
355
  const allPairs = provable.flatMap((collection) =>
340
- boundedTargets.map((target) => ({ collection, target }))
356
+ sortedTargets.map((target) => ({ collection, target }))
341
357
  );
342
- const items = await mapBounded(
343
- allPairs.slice(0, MAX_CONNECTOR_PROJECTIONS),
358
+ // Every pair is read from cached receipts only; the cap bounds the listing.
359
+ const evaluated = await mapBounded(
360
+ allPairs,
344
361
  DEFAULT_CONCURRENCY,
345
362
  async ({ collection, target }) => {
346
363
  const fallback = connectorFallback(
@@ -377,7 +394,13 @@ async function buildConnectorStatuses(
377
394
  };
378
395
  }
379
396
  );
380
- return { items, total: provable.length * sortedTargets.length };
397
+ return {
398
+ items: evaluated.slice(0, MAX_CONNECTOR_PROJECTIONS),
399
+ omitted: summarizeConnectorProofs(
400
+ evaluated.slice(MAX_CONNECTOR_PROJECTIONS)
401
+ ),
402
+ total: evaluated.length,
403
+ };
381
404
  }
382
405
 
383
406
  async function verifyCoalesced(
@@ -526,6 +549,9 @@ export async function buildActivationStatus(
526
549
  total: connectorStatuses.total,
527
550
  projected: connectorStatuses.items.length,
528
551
  truncated: connectorStatuses.total > connectorStatuses.items.length,
552
+ ...(connectorStatuses.total > connectorStatuses.items.length
553
+ ? { omitted: connectorStatuses.omitted }
554
+ : {}),
529
555
  },
530
556
  };
531
557
  }
@@ -3,6 +3,11 @@
3
3
  import type { ActivationStatus } from "../core/activation-status";
4
4
  import type { HealthCheck } from "./status-model";
5
5
 
6
+ import {
7
+ classifyConnectorProof,
8
+ describeOmittedConnectorPairs,
9
+ omittedConnectorSummary,
10
+ } from "../core/activation-connector-health";
6
11
  import { isEmptyActivationCollection } from "../core/activation-empty";
7
12
 
8
13
  function countLabel(count: number, singular: string): string {
@@ -69,41 +74,46 @@ export function buildConnectorActivationCheck(
69
74
  activation: ActivationStatus
70
75
  ): HealthCheck | null {
71
76
  const { projected, total, truncated } = activation.connectorProjection;
72
- const omitted = total - projected;
77
+ const omitted = omittedConnectorSummary(activation);
73
78
  const observed = activation.connectors.filter(
74
- ({ code }) =>
75
- code !== "connector_not_configured" &&
76
- code !== "target_runtime_unverifiable"
79
+ (connector) => classifyConnectorProof(connector) !== "notApplicable"
77
80
  );
78
- if (observed.length === 0 && !truncated) {
81
+ const omittedObserved = omitted
82
+ ? omitted.passed + omitted.failed + omitted.incomplete
83
+ : 0;
84
+ if (observed.length === 0 && omittedObserved === 0 && omitted) {
79
85
  return null;
80
86
  }
81
87
  const failed = observed.filter(({ status }) => status === "failed");
82
88
  const incomplete = observed.filter(({ status }) => status !== "passed");
89
+ const failedCount = failed.length + (omitted?.failed ?? 0);
90
+ const incompleteCount =
91
+ incomplete.length + (omitted?.incomplete ?? 0) + (omitted?.failed ?? 0);
92
+ const passedCount =
93
+ observed.length - incomplete.length + (omitted?.passed ?? 0);
83
94
  const first = failed[0] ?? incomplete[0] ?? observed[0];
84
95
  const firstDetail = first
85
96
  ? `${first.target} / ${first.collection}: ${first.status}${first.code ? `/${first.code}` : ""}${first.remediation ? `. ${first.remediation}` : ""}`
86
97
  : null;
87
- const projectionDetail = truncated
88
- ? `${omitted} target/collection checks were omitted by the bounded status projection; no result is claimed for them.`
89
- : null;
98
+ const projectionDetail = describeOmittedConnectorPairs(activation);
99
+ const listing = truncated ? ` (${projected} of ${total} checks listed)` : "";
90
100
  return {
91
101
  id: "connector-activation",
92
102
  title: "Connector proof",
93
103
  status:
94
- failed.length > 0
104
+ failedCount > 0
95
105
  ? "error"
96
- : incomplete.length > 0 || truncated
106
+ : incompleteCount > 0 || !omitted
97
107
  ? "warn"
98
108
  : "ok",
99
109
  summary:
100
- failed.length > 0
101
- ? `${countLabel(failed.length, "connector proof")} failed`
102
- : incomplete.length > 0
103
- ? `${countLabel(incomplete.length, "connector proof")} incomplete`
104
- : truncated
105
- ? `${projected} of ${total} connector target/collection checks projected`
106
- : `${countLabel(observed.length, "connector proof")} passed`,
110
+ failedCount > 0
111
+ ? `${countLabel(failedCount, "connector proof")} failed${listing}`
112
+ : incompleteCount > 0
113
+ ? `${countLabel(incompleteCount, "connector proof")} incomplete${listing}`
114
+ : omitted
115
+ ? `${countLabel(passedCount, "connector proof")} passed${listing}`
116
+ : `${projected} of ${total} connector target/collection checks projected`,
107
117
  detail: [projectionDetail, firstDetail].filter(Boolean).join(" "),
108
118
  };
109
119
  }
@@ -9,6 +9,10 @@ import {
9
9
 
10
10
  import type { AppStatusResponse } from "../../status-model";
11
11
 
12
+ import {
13
+ describeConnectorSummary,
14
+ omittedConnectorSummary as summarizeOmittedConnectors,
15
+ } from "../../../core/activation-connector-health";
12
16
  import { isEmptyActivationCollection } from "../../../core/activation-empty";
13
17
  import { buildConnectorActivationCheck } from "../../activation-health";
14
18
  import { Button } from "./ui/button";
@@ -54,6 +58,7 @@ export function BootstrapStatus({
54
58
  const omittedConnectorCount =
55
59
  activation.connectorProjection.total -
56
60
  activation.connectorProjection.projected;
61
+ const omittedConnectorSummary = summarizeOmittedConnectors(activation);
57
62
  const connectorHealth = buildConnectorActivationCheck(activation);
58
63
  const connectorsHealthy =
59
64
  connectorHealth === null || connectorHealth.status === "ok";
@@ -221,6 +226,9 @@ export function BootstrapStatus({
221
226
  <p className="text-muted-foreground text-xs">
222
227
  {omittedConnectorCount} additional target/collection checks
223
228
  omitted from this bounded status view
229
+ {omittedConnectorSummary
230
+ ? ` (${describeConnectorSummary(omittedConnectorSummary)})`
231
+ : ""}
224
232
  </p>
225
233
  )}
226
234
  </div>
@@ -1 +0,0 @@
1
- 956ba0ce42d3b72635b61ca710d7adc8599fbdf08f3e32000d979158cac432c6 gno-browser-clipper-v2.8.4.zip