@integrity-labs/agt-cli 0.28.1083 → 0.28.1084

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.
@@ -24,7 +24,7 @@ import {
24
24
  rotateDailySession,
25
25
  sessionFileExists,
26
26
  todayLocalIso
27
- } from "./chunk-ELRALWJ7.js";
27
+ } from "./chunk-NEGFSB2W.js";
28
28
  import {
29
29
  classifyUnanswerablePane,
30
30
  findUsageLimitResetHint,
@@ -6113,4 +6113,4 @@ export {
6113
6113
  stopAllSessionsAndWait,
6114
6114
  getProjectDir
6115
6115
  };
6116
- //# sourceMappingURL=chunk-44254DEU.js.map
6116
+ //# sourceMappingURL=chunk-XJ4JK4C7.js.map
@@ -266,7 +266,7 @@ async function spawnPairSession(session) {
266
266
  return { ok: true };
267
267
  } catch {
268
268
  }
269
- const { resolveClaudeBinary } = await import("./persistent-session-UHSU52GZ.js");
269
+ const { resolveClaudeBinary } = await import("./persistent-session-35BXCGHB.js");
270
270
  const claudeBin = resolveClaudeBinary();
271
271
  const pairEnv = {
272
272
  ...process.env,
@@ -734,4 +734,4 @@ export {
734
734
  startClaudePair,
735
735
  submitClaudePairCode
736
736
  };
737
- //# sourceMappingURL=claude-pair-runtime-U6LVU5CI.js.map
737
+ //# sourceMappingURL=claude-pair-runtime-EUFDQGRU.js.map
@@ -67,7 +67,7 @@ import {
67
67
  safeWriteJsonAtomic,
68
68
  setConfigHash,
69
69
  tripClass
70
- } from "../chunk-BIR5WVM4.js";
70
+ } from "../chunk-6ZBFVSDC.js";
71
71
  import {
72
72
  getProjectDir as getProjectDir2,
73
73
  getReadyTasks,
@@ -154,7 +154,7 @@ import {
154
154
  webFetchBaselineValue,
155
155
  webFetchRestartNeeded,
156
156
  writeEgressAllowlist
157
- } from "../chunk-44254DEU.js";
157
+ } from "../chunk-XJ4JK4C7.js";
158
158
  import {
159
159
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
160
160
  AnchorSessionClient,
@@ -263,7 +263,7 @@ import {
263
263
  subagentActivityAgeSeconds,
264
264
  sumTranscriptUsageInWindow,
265
265
  transcriptActivityAgeSeconds
266
- } from "../chunk-ELRALWJ7.js";
266
+ } from "../chunk-NEGFSB2W.js";
267
267
  import {
268
268
  classifyUnanswerablePane,
269
269
  paneRemedy
@@ -14141,7 +14141,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
14141
14141
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
14142
14142
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
14143
14143
  async function channelInboundActivityAgeSecondsFor(codeName) {
14144
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-PKMKC2VS.js");
14144
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-VDL3QULE.js");
14145
14145
  const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
14146
14146
  if (newest === null) return null;
14147
14147
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -14899,7 +14899,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
14899
14899
  var lastVersionCheckAt = 0;
14900
14900
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14901
14901
  var lastResponsivenessProbeAt = 0;
14902
- var agtCliVersion = true ? "0.28.1083" : "dev";
14902
+ var agtCliVersion = true ? "0.28.1084" : "dev";
14903
14903
  function resolveBrewPath(execFileSync3) {
14904
14904
  try {
14905
14905
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -16516,7 +16516,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
16516
16516
  if (codeNames.length === 0) return;
16517
16517
  void (async () => {
16518
16518
  try {
16519
- const { collectDiagnostics } = await import("../persistent-session-UHSU52GZ.js");
16519
+ const { collectDiagnostics } = await import("../persistent-session-35BXCGHB.js");
16520
16520
  await api.post("/host/heartbeat", {
16521
16521
  host_id: hostId,
16522
16522
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -16658,7 +16658,7 @@ async function pollCycleInner() {
16658
16658
  }
16659
16659
  try {
16660
16660
  const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
16661
- const { collectDiagnostics } = await import("../persistent-session-UHSU52GZ.js");
16661
+ const { collectDiagnostics } = await import("../persistent-session-35BXCGHB.js");
16662
16662
  const diagCodeNames = [...agentState.persistentSessionAgents];
16663
16663
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
16664
16664
  let tailscaleHostname;
@@ -16866,7 +16866,7 @@ async function pollCycleInner() {
16866
16866
  collectPanelessActivityProbes,
16867
16867
  getResponsivenessIntervalMs,
16868
16868
  occupancyQualificationClassifications
16869
- } = await import("../responsiveness-probe-PKMKC2VS.js");
16869
+ } = await import("../responsiveness-probe-VDL3QULE.js");
16870
16870
  const probeIntervalMs = getResponsivenessIntervalMs();
16871
16871
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
16872
16872
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -16983,7 +16983,7 @@ async function pollCycleInner() {
16983
16983
  collectResponsivenessProbes,
16984
16984
  livePendingInboundOldestAgeSeconds,
16985
16985
  parkPendingInbound
16986
- } = await import("../responsiveness-probe-PKMKC2VS.js");
16986
+ } = await import("../responsiveness-probe-VDL3QULE.js");
16987
16987
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
16988
16988
  const wedgeNow = /* @__PURE__ */ new Date();
16989
16989
  const liveAgents = agentState.persistentSessionAgents;
@@ -17269,7 +17269,7 @@ async function pollCycleInner() {
17269
17269
  }
17270
17270
  }
17271
17271
  );
17272
- const { parkPendingInbound } = await import("../responsiveness-probe-PKMKC2VS.js");
17272
+ const { parkPendingInbound } = await import("../responsiveness-probe-VDL3QULE.js");
17273
17273
  const { parked, deadLettered } = parkPendingInbound(codeName, new Date(fatalNowMs));
17274
17274
  paneFatalStreak.delete(codeName);
17275
17275
  paneFatalRestarts.set(codeName, [...history, fatalNowMs]);
@@ -17300,7 +17300,7 @@ async function pollCycleInner() {
17300
17300
  TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS,
17301
17301
  bindSourceEscalations
17302
17302
  } = await import("../transcript-mount-health-OHE6IVJV.js");
17303
- const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-UHSU52GZ.js");
17303
+ const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-35BXCGHB.js");
17304
17304
  const mountConfig = resolveTranscriptMountConfig();
17305
17305
  const liveAgents = agentState.persistentSessionAgents;
17306
17306
  for (const tracked of [
@@ -17465,7 +17465,7 @@ async function pollCycleInner() {
17465
17465
  }
17466
17466
  try {
17467
17467
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
17468
- const { probeSessionAuth } = await import("../session-auth-dead-KOZOXQOP.js");
17468
+ const { probeSessionAuth } = await import("../session-auth-dead-L7ZD5ZZO.js");
17469
17469
  const observations = [];
17470
17470
  const pendingCacheCommits = [];
17471
17471
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -22030,7 +22030,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
22030
22030
  try {
22031
22031
  const freshId = rotateSessionForWedge(codeName);
22032
22032
  consecutiveWedgeCycles.delete(codeName);
22033
- const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-PKMKC2VS.js");
22033
+ const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-VDL3QULE.js");
22034
22034
  const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
22035
22035
  const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
22036
22036
  const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
@@ -22073,7 +22073,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
22073
22073
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
22074
22074
  void (async () => {
22075
22075
  try {
22076
- const { collectDiagnostics } = await import("../persistent-session-UHSU52GZ.js");
22076
+ const { collectDiagnostics } = await import("../persistent-session-35BXCGHB.js");
22077
22077
  await api.post("/host/heartbeat", {
22078
22078
  host_id: hostId,
22079
22079
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -22124,7 +22124,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
22124
22124
  }
22125
22125
  try {
22126
22126
  const hostId = await getHostId();
22127
- const { collectDiagnostics } = await import("../persistent-session-UHSU52GZ.js");
22127
+ const { collectDiagnostics } = await import("../persistent-session-35BXCGHB.js");
22128
22128
  await api.post("/host/heartbeat", {
22129
22129
  host_id: hostId,
22130
22130
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -22796,7 +22796,7 @@ async function processClaudePairSessions(agents) {
22796
22796
  // cannot take it for itself — by the time it runs, the write it is looking
22797
22797
  // for may already have happened.
22798
22798
  snapshotPairConfig
22799
- } = await import("../claude-pair-runtime-U6LVU5CI.js");
22799
+ } = await import("../claude-pair-runtime-EUFDQGRU.js");
22800
22800
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
22801
22801
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
22802
22802
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -34190,6 +34190,136 @@ var INTEGRATION_REGISTRY = [
34190
34190
  // `registryRemoteMcpKeys`, which would strand the `.mcp.json` entry on
34191
34191
  // every host that installed the MCP variant.
34192
34192
  },
34193
+ {
34194
+ // Quiver (api.quiver.ai) — AI vector graphics: draw an SVG from a prompt,
34195
+ // redraw one from an instruction, trace a raster, add animation.
34196
+ //
34197
+ // PREMIUM (ADR-0031, epic ENG-6920). Ninjafy holds ONE Quiver account whose
34198
+ // key (`QUIVER_ACCOUNT_KEY`) every customer's drawing bills back to, so the
34199
+ // credential is a single platform-held secret and never a per-install one.
34200
+ // `auth_type: 'none'` on the catalog row and `credential_source:
34201
+ // 'platform_env'` on every runtime scope, so `resolveBrokerToken` reads the
34202
+ // env var and skips the install-row lookup entirely.
34203
+ //
34204
+ // Ships DARK: until the secret is set the resolver fails closed with
34205
+ // `platform_credential_missing` and every drawing errors clearly.
34206
+ // Installable but inert, by design — the same posture x-search shipped with.
34207
+ //
34208
+ // WHY IT STOPPED BEING BYO. It launched bring-your-own-key. Premium means WE
34209
+ // pay the vendor, so a customer key would defeat the point: there would be
34210
+ // nothing to meter and nothing to bill. The flip cost nothing because Quiver
34211
+ // had never deployed — zero installs, so none of the origami free→premium
34212
+ // grandfathering applies (there is no cohort whose `credential_source`
34213
+ // default would misclassify them as billed and take the integration dark).
34214
+ // A later BYO tier is possible (ADR-0055, the Firecrawl shape) and would
34215
+ // need its own entitlement gate; it is deliberately not offered now, because
34216
+ // offering two auth types renders a connect picker that does not check
34217
+ // `plans.byo_credentials` (ENG-9236).
34218
+ //
34219
+ // WHY TWO METERS, when the vendor bills in one unit. `credits` is Quiver's
34220
+ // own billing unit and the response carries it per call, so metering it
34221
+ // makes our margin a constant multiple no matter which model an agent picks
34222
+ // — `arrow-1.1-max` costs materially more than `arrow-1.1`, which a flat
34223
+ // per-call price would silently eat. But `credits` is documented as
34224
+ // "omitted for token-priced models, whose measured totals are returned in
34225
+ // `usage`", so a credits-only meter bills those calls at ZERO: free to the
34226
+ // customer, invisible to the budget gate, and with nothing in the ledger to
34227
+ // notice it by. `svg_operation` is the floor that closes that hole — it
34228
+ // fires ONLY when `credits` is absent, so the two can never double-bill the
34229
+ // same call. See `lib/quiver-metering.ts`.
34230
+ id: "quiver",
34231
+ name: "Quiver",
34232
+ category: "media",
34233
+ description: "AI vector graphics \u2014 draw an SVG from a description, redraw an existing one, trace a photo or screenshot into vector shapes, and add animation. Ninjafy manages the Quiver account for you; there is no key to enter.",
34234
+ supported_auth_types: ["none"],
34235
+ docs_url: "https://docs.quiver.ai/developers",
34236
+ capabilities: [
34237
+ {
34238
+ id: "quiver:create",
34239
+ name: "Create and change vector graphics",
34240
+ description: "Draw, redraw, trace and animate SVG artwork. Billed per Quiver credit consumed.",
34241
+ access: "write"
34242
+ },
34243
+ {
34244
+ id: "quiver:read",
34245
+ name: "Read models",
34246
+ description: "List the available drawing models and their per-call credit cost. Free.",
34247
+ access: "read"
34248
+ }
34249
+ ],
34250
+ beta: true,
34251
+ // No `installable` on purpose: quiver is a seed integration
34252
+ // (integration-definitions.json), so the seed catalog already makes it
34253
+ // picker-visible. This entry exists to carry the `premium` descriptor that
34254
+ // `isPremiumDefinition` reads — which arms the per-org opt-in gate, the
34255
+ // priced acknowledgement modal and the admin pricing tab. Same reasoning as
34256
+ // social-scraping above.
34257
+ premium: {
34258
+ pricing: "usage",
34259
+ note: "Billed per Quiver credit consumed. Listing models is free; drawing, editing, tracing and animating each debit credits.",
34260
+ meters: [
34261
+ { event_type: "svg_credits", unit: "credit" },
34262
+ { event_type: "svg_operation", unit: "operation" }
34263
+ ]
34264
+ }
34265
+ },
34266
+ {
34267
+ // theSVG (thesvg.org) — 6,500+ REAL brand marks as SVG, so an agent building
34268
+ // a page can use the actual Stripe/Slack/AWS logo instead of asking a
34269
+ // drawing model for one. That distinction is the whole point of the
34270
+ // integration: an AI-generated "Stripe logo" is a plausible fake, wrong in
34271
+ // the way a customer notices and a trademark owner minds. Original artwork
34272
+ // is Quiver's job; existing marks are this one's.
34273
+ //
34274
+ // WHY A LOCAL STDIO MCP AND NOT THE DIRECT-HTTP LANE. thesvg.org is a
34275
+ // STATIC SITE — its own CLI says so in as many words ("there is no dynamic
34276
+ // API"). The only two endpoints are `/api/registry.json`, the entire
34277
+ // 2.97 MB / 6,523-entry manifest, and `/icons/{slug}/{variant}.svg`. Search
34278
+ // is client-side filtering over that manifest, which the Direct-HTTP broker
34279
+ // cannot do: it forwards the vendor's whole response body to the agent, so
34280
+ // a `search_icons` descriptor would put 2.97 MB of registry into the
34281
+ // agent's context on every call. The vendor's own MCP server bundles the
34282
+ // registry and searches it in-process, which is precisely the shape the
34283
+ // missing API leaves you needing.
34284
+ //
34285
+ // WHY THE VERSION IS PINNED and AWS's is `@latest`: this server's registry
34286
+ // is baked in at BUILD time, so the pin is what decides which icons exist
34287
+ // AND what markup lands on a customer's published page. Bumping it is a
34288
+ // deliberate act that also refreshes the icon set — not a silent
34289
+ // third-party update to artwork we are about to publish under a customer's
34290
+ // domain.
34291
+ //
34292
+ // No credential anywhere: the registry and the jsDelivr CDN the server
34293
+ // fetches SVG from are both public, so `auth_types: ['none']` is the honest
34294
+ // classification rather than the ENG-8440 kind of lie Hard Rule 17 warns
34295
+ // about — there genuinely is no key to enter and the install IS live
34296
+ // immediately.
34297
+ id: "thesvg",
34298
+ name: "theSVG",
34299
+ category: "media",
34300
+ description: "Brand logos and icons as real SVG \u2014 search 6,500+ marks by name and pull the exact artwork, in mono, colour, light, dark or wordmark variants",
34301
+ supported_auth_types: ["none"],
34302
+ docs_url: "https://thesvg.org",
34303
+ capabilities: [
34304
+ {
34305
+ id: "thesvg:read",
34306
+ name: "Find and fetch brand icons",
34307
+ description: "Search the icon library, list an icon's variants and categories, and fetch its SVG markup or CDN URL",
34308
+ access: "read"
34309
+ }
34310
+ ],
34311
+ installable: { category: "Media", authTypes: ["none"] },
34312
+ beta: true,
34313
+ // ENG-5815 data-driven path — no buildMcpJson edit, same as AWS.
34314
+ nativeMcp: {
34315
+ command: "npx",
34316
+ args: ["-y", "@thesvg/mcp-server@0.8.2"],
34317
+ env: {
34318
+ PATH: "{{process_env.PATH}}",
34319
+ HOME: "{{process_env.HOME}}"
34320
+ }
34321
+ }
34322
+ },
34193
34323
  {
34194
34324
  id: "qmd",
34195
34325
  name: "QMD Memory Search",
@@ -35315,6 +35445,10 @@ var NOTICE_KIND_AUDIENCE = {
35315
35445
  // "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
35316
35446
  // uuid and all.
35317
35447
  approval_expired: "agent",
35448
+ // ENG-11334: canvas.publish_public approved / denied / approved-but-not-applied.
35449
+ // Second-person instructions to the agent ("Tell the user...", "do not
35450
+ // republish"); the user learns the outcome from the agent, not this row.
35451
+ canvas_public_approval_resolved: "agent",
35318
35452
  // A routine fired; the agent picks the work up.
35319
35453
  routine_firing_result: "agent",
35320
35454
  // Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
@@ -38126,7 +38260,7 @@ var FLAG_REGISTRY = [
38126
38260
  },
38127
38261
  {
38128
38262
  key: "approval-unified-authority",
38129
- description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict and log approval_authority_would_reject (ingress, verb, org, reason) for every tap it would refuse, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
38263
+ description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict, including the verb's declared approver boundary (ENG-11337), and log approval_authority_would_reject (ingress, verb, org, reason, boundary) for every tap it would refuse and approval_authority_would_admit (ingress, verb, org, basis, boundary) for every tap it would admit, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
38130
38264
  flagType: "enum",
38131
38265
  allowedValues: ["off", "shadow", "enforce"],
38132
38266
  // Safe/default value is `off` (no computation, no extra reads on the tap path). A flag-DB read
package/dist/mcp/index.js CHANGED
@@ -26693,6 +26693,136 @@ var INTEGRATION_REGISTRY = [
26693
26693
  // `registryRemoteMcpKeys`, which would strand the `.mcp.json` entry on
26694
26694
  // every host that installed the MCP variant.
26695
26695
  },
26696
+ {
26697
+ // Quiver (api.quiver.ai) — AI vector graphics: draw an SVG from a prompt,
26698
+ // redraw one from an instruction, trace a raster, add animation.
26699
+ //
26700
+ // PREMIUM (ADR-0031, epic ENG-6920). Ninjafy holds ONE Quiver account whose
26701
+ // key (`QUIVER_ACCOUNT_KEY`) every customer's drawing bills back to, so the
26702
+ // credential is a single platform-held secret and never a per-install one.
26703
+ // `auth_type: 'none'` on the catalog row and `credential_source:
26704
+ // 'platform_env'` on every runtime scope, so `resolveBrokerToken` reads the
26705
+ // env var and skips the install-row lookup entirely.
26706
+ //
26707
+ // Ships DARK: until the secret is set the resolver fails closed with
26708
+ // `platform_credential_missing` and every drawing errors clearly.
26709
+ // Installable but inert, by design — the same posture x-search shipped with.
26710
+ //
26711
+ // WHY IT STOPPED BEING BYO. It launched bring-your-own-key. Premium means WE
26712
+ // pay the vendor, so a customer key would defeat the point: there would be
26713
+ // nothing to meter and nothing to bill. The flip cost nothing because Quiver
26714
+ // had never deployed — zero installs, so none of the origami free→premium
26715
+ // grandfathering applies (there is no cohort whose `credential_source`
26716
+ // default would misclassify them as billed and take the integration dark).
26717
+ // A later BYO tier is possible (ADR-0055, the Firecrawl shape) and would
26718
+ // need its own entitlement gate; it is deliberately not offered now, because
26719
+ // offering two auth types renders a connect picker that does not check
26720
+ // `plans.byo_credentials` (ENG-9236).
26721
+ //
26722
+ // WHY TWO METERS, when the vendor bills in one unit. `credits` is Quiver's
26723
+ // own billing unit and the response carries it per call, so metering it
26724
+ // makes our margin a constant multiple no matter which model an agent picks
26725
+ // — `arrow-1.1-max` costs materially more than `arrow-1.1`, which a flat
26726
+ // per-call price would silently eat. But `credits` is documented as
26727
+ // "omitted for token-priced models, whose measured totals are returned in
26728
+ // `usage`", so a credits-only meter bills those calls at ZERO: free to the
26729
+ // customer, invisible to the budget gate, and with nothing in the ledger to
26730
+ // notice it by. `svg_operation` is the floor that closes that hole — it
26731
+ // fires ONLY when `credits` is absent, so the two can never double-bill the
26732
+ // same call. See `lib/quiver-metering.ts`.
26733
+ id: "quiver",
26734
+ name: "Quiver",
26735
+ category: "media",
26736
+ description: "AI vector graphics \u2014 draw an SVG from a description, redraw an existing one, trace a photo or screenshot into vector shapes, and add animation. Ninjafy manages the Quiver account for you; there is no key to enter.",
26737
+ supported_auth_types: ["none"],
26738
+ docs_url: "https://docs.quiver.ai/developers",
26739
+ capabilities: [
26740
+ {
26741
+ id: "quiver:create",
26742
+ name: "Create and change vector graphics",
26743
+ description: "Draw, redraw, trace and animate SVG artwork. Billed per Quiver credit consumed.",
26744
+ access: "write"
26745
+ },
26746
+ {
26747
+ id: "quiver:read",
26748
+ name: "Read models",
26749
+ description: "List the available drawing models and their per-call credit cost. Free.",
26750
+ access: "read"
26751
+ }
26752
+ ],
26753
+ beta: true,
26754
+ // No `installable` on purpose: quiver is a seed integration
26755
+ // (integration-definitions.json), so the seed catalog already makes it
26756
+ // picker-visible. This entry exists to carry the `premium` descriptor that
26757
+ // `isPremiumDefinition` reads — which arms the per-org opt-in gate, the
26758
+ // priced acknowledgement modal and the admin pricing tab. Same reasoning as
26759
+ // social-scraping above.
26760
+ premium: {
26761
+ pricing: "usage",
26762
+ note: "Billed per Quiver credit consumed. Listing models is free; drawing, editing, tracing and animating each debit credits.",
26763
+ meters: [
26764
+ { event_type: "svg_credits", unit: "credit" },
26765
+ { event_type: "svg_operation", unit: "operation" }
26766
+ ]
26767
+ }
26768
+ },
26769
+ {
26770
+ // theSVG (thesvg.org) — 6,500+ REAL brand marks as SVG, so an agent building
26771
+ // a page can use the actual Stripe/Slack/AWS logo instead of asking a
26772
+ // drawing model for one. That distinction is the whole point of the
26773
+ // integration: an AI-generated "Stripe logo" is a plausible fake, wrong in
26774
+ // the way a customer notices and a trademark owner minds. Original artwork
26775
+ // is Quiver's job; existing marks are this one's.
26776
+ //
26777
+ // WHY A LOCAL STDIO MCP AND NOT THE DIRECT-HTTP LANE. thesvg.org is a
26778
+ // STATIC SITE — its own CLI says so in as many words ("there is no dynamic
26779
+ // API"). The only two endpoints are `/api/registry.json`, the entire
26780
+ // 2.97 MB / 6,523-entry manifest, and `/icons/{slug}/{variant}.svg`. Search
26781
+ // is client-side filtering over that manifest, which the Direct-HTTP broker
26782
+ // cannot do: it forwards the vendor's whole response body to the agent, so
26783
+ // a `search_icons` descriptor would put 2.97 MB of registry into the
26784
+ // agent's context on every call. The vendor's own MCP server bundles the
26785
+ // registry and searches it in-process, which is precisely the shape the
26786
+ // missing API leaves you needing.
26787
+ //
26788
+ // WHY THE VERSION IS PINNED and AWS's is `@latest`: this server's registry
26789
+ // is baked in at BUILD time, so the pin is what decides which icons exist
26790
+ // AND what markup lands on a customer's published page. Bumping it is a
26791
+ // deliberate act that also refreshes the icon set — not a silent
26792
+ // third-party update to artwork we are about to publish under a customer's
26793
+ // domain.
26794
+ //
26795
+ // No credential anywhere: the registry and the jsDelivr CDN the server
26796
+ // fetches SVG from are both public, so `auth_types: ['none']` is the honest
26797
+ // classification rather than the ENG-8440 kind of lie Hard Rule 17 warns
26798
+ // about — there genuinely is no key to enter and the install IS live
26799
+ // immediately.
26800
+ id: "thesvg",
26801
+ name: "theSVG",
26802
+ category: "media",
26803
+ description: "Brand logos and icons as real SVG \u2014 search 6,500+ marks by name and pull the exact artwork, in mono, colour, light, dark or wordmark variants",
26804
+ supported_auth_types: ["none"],
26805
+ docs_url: "https://thesvg.org",
26806
+ capabilities: [
26807
+ {
26808
+ id: "thesvg:read",
26809
+ name: "Find and fetch brand icons",
26810
+ description: "Search the icon library, list an icon's variants and categories, and fetch its SVG markup or CDN URL",
26811
+ access: "read"
26812
+ }
26813
+ ],
26814
+ installable: { category: "Media", authTypes: ["none"] },
26815
+ beta: true,
26816
+ // ENG-5815 data-driven path — no buildMcpJson edit, same as AWS.
26817
+ nativeMcp: {
26818
+ command: "npx",
26819
+ args: ["-y", "@thesvg/mcp-server@0.8.2"],
26820
+ env: {
26821
+ PATH: "{{process_env.PATH}}",
26822
+ HOME: "{{process_env.HOME}}"
26823
+ }
26824
+ }
26825
+ },
26696
26826
  {
26697
26827
  id: "qmd",
26698
26828
  name: "QMD Memory Search",
@@ -27818,6 +27948,10 @@ var NOTICE_KIND_AUDIENCE = {
27818
27948
  // "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
27819
27949
  // uuid and all.
27820
27950
  approval_expired: "agent",
27951
+ // ENG-11334: canvas.publish_public approved / denied / approved-but-not-applied.
27952
+ // Second-person instructions to the agent ("Tell the user...", "do not
27953
+ // republish"); the user learns the outcome from the agent, not this row.
27954
+ canvas_public_approval_resolved: "agent",
27821
27955
  // A routine fired; the agent picks the work up.
27822
27956
  routine_firing_result: "agent",
27823
27957
  // Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
@@ -30344,7 +30478,7 @@ var FLAG_REGISTRY = [
30344
30478
  },
30345
30479
  {
30346
30480
  key: "approval-unified-authority",
30347
- description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict and log approval_authority_would_reject (ingress, verb, org, reason) for every tap it would refuse, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
30481
+ description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict, including the verb's declared approver boundary (ENG-11337), and log approval_authority_would_reject (ingress, verb, org, reason, boundary) for every tap it would refuse and approval_authority_would_admit (ingress, verb, org, basis, boundary) for every tap it would admit, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
30348
30482
  flagType: "enum",
30349
30483
  allowedValues: ["off", "shadow", "enforce"],
30350
30484
  // Safe/default value is `off` (no computation, no extra reads on the tap path). A flag-DB read
@@ -40819,6 +40819,136 @@ var INTEGRATION_REGISTRY = [
40819
40819
  // `registryRemoteMcpKeys`, which would strand the `.mcp.json` entry on
40820
40820
  // every host that installed the MCP variant.
40821
40821
  },
40822
+ {
40823
+ // Quiver (api.quiver.ai) — AI vector graphics: draw an SVG from a prompt,
40824
+ // redraw one from an instruction, trace a raster, add animation.
40825
+ //
40826
+ // PREMIUM (ADR-0031, epic ENG-6920). Ninjafy holds ONE Quiver account whose
40827
+ // key (`QUIVER_ACCOUNT_KEY`) every customer's drawing bills back to, so the
40828
+ // credential is a single platform-held secret and never a per-install one.
40829
+ // `auth_type: 'none'` on the catalog row and `credential_source:
40830
+ // 'platform_env'` on every runtime scope, so `resolveBrokerToken` reads the
40831
+ // env var and skips the install-row lookup entirely.
40832
+ //
40833
+ // Ships DARK: until the secret is set the resolver fails closed with
40834
+ // `platform_credential_missing` and every drawing errors clearly.
40835
+ // Installable but inert, by design — the same posture x-search shipped with.
40836
+ //
40837
+ // WHY IT STOPPED BEING BYO. It launched bring-your-own-key. Premium means WE
40838
+ // pay the vendor, so a customer key would defeat the point: there would be
40839
+ // nothing to meter and nothing to bill. The flip cost nothing because Quiver
40840
+ // had never deployed — zero installs, so none of the origami free→premium
40841
+ // grandfathering applies (there is no cohort whose `credential_source`
40842
+ // default would misclassify them as billed and take the integration dark).
40843
+ // A later BYO tier is possible (ADR-0055, the Firecrawl shape) and would
40844
+ // need its own entitlement gate; it is deliberately not offered now, because
40845
+ // offering two auth types renders a connect picker that does not check
40846
+ // `plans.byo_credentials` (ENG-9236).
40847
+ //
40848
+ // WHY TWO METERS, when the vendor bills in one unit. `credits` is Quiver's
40849
+ // own billing unit and the response carries it per call, so metering it
40850
+ // makes our margin a constant multiple no matter which model an agent picks
40851
+ // — `arrow-1.1-max` costs materially more than `arrow-1.1`, which a flat
40852
+ // per-call price would silently eat. But `credits` is documented as
40853
+ // "omitted for token-priced models, whose measured totals are returned in
40854
+ // `usage`", so a credits-only meter bills those calls at ZERO: free to the
40855
+ // customer, invisible to the budget gate, and with nothing in the ledger to
40856
+ // notice it by. `svg_operation` is the floor that closes that hole — it
40857
+ // fires ONLY when `credits` is absent, so the two can never double-bill the
40858
+ // same call. See `lib/quiver-metering.ts`.
40859
+ id: "quiver",
40860
+ name: "Quiver",
40861
+ category: "media",
40862
+ description: "AI vector graphics \u2014 draw an SVG from a description, redraw an existing one, trace a photo or screenshot into vector shapes, and add animation. Ninjafy manages the Quiver account for you; there is no key to enter.",
40863
+ supported_auth_types: ["none"],
40864
+ docs_url: "https://docs.quiver.ai/developers",
40865
+ capabilities: [
40866
+ {
40867
+ id: "quiver:create",
40868
+ name: "Create and change vector graphics",
40869
+ description: "Draw, redraw, trace and animate SVG artwork. Billed per Quiver credit consumed.",
40870
+ access: "write"
40871
+ },
40872
+ {
40873
+ id: "quiver:read",
40874
+ name: "Read models",
40875
+ description: "List the available drawing models and their per-call credit cost. Free.",
40876
+ access: "read"
40877
+ }
40878
+ ],
40879
+ beta: true,
40880
+ // No `installable` on purpose: quiver is a seed integration
40881
+ // (integration-definitions.json), so the seed catalog already makes it
40882
+ // picker-visible. This entry exists to carry the `premium` descriptor that
40883
+ // `isPremiumDefinition` reads — which arms the per-org opt-in gate, the
40884
+ // priced acknowledgement modal and the admin pricing tab. Same reasoning as
40885
+ // social-scraping above.
40886
+ premium: {
40887
+ pricing: "usage",
40888
+ note: "Billed per Quiver credit consumed. Listing models is free; drawing, editing, tracing and animating each debit credits.",
40889
+ meters: [
40890
+ { event_type: "svg_credits", unit: "credit" },
40891
+ { event_type: "svg_operation", unit: "operation" }
40892
+ ]
40893
+ }
40894
+ },
40895
+ {
40896
+ // theSVG (thesvg.org) — 6,500+ REAL brand marks as SVG, so an agent building
40897
+ // a page can use the actual Stripe/Slack/AWS logo instead of asking a
40898
+ // drawing model for one. That distinction is the whole point of the
40899
+ // integration: an AI-generated "Stripe logo" is a plausible fake, wrong in
40900
+ // the way a customer notices and a trademark owner minds. Original artwork
40901
+ // is Quiver's job; existing marks are this one's.
40902
+ //
40903
+ // WHY A LOCAL STDIO MCP AND NOT THE DIRECT-HTTP LANE. thesvg.org is a
40904
+ // STATIC SITE — its own CLI says so in as many words ("there is no dynamic
40905
+ // API"). The only two endpoints are `/api/registry.json`, the entire
40906
+ // 2.97 MB / 6,523-entry manifest, and `/icons/{slug}/{variant}.svg`. Search
40907
+ // is client-side filtering over that manifest, which the Direct-HTTP broker
40908
+ // cannot do: it forwards the vendor's whole response body to the agent, so
40909
+ // a `search_icons` descriptor would put 2.97 MB of registry into the
40910
+ // agent's context on every call. The vendor's own MCP server bundles the
40911
+ // registry and searches it in-process, which is precisely the shape the
40912
+ // missing API leaves you needing.
40913
+ //
40914
+ // WHY THE VERSION IS PINNED and AWS's is `@latest`: this server's registry
40915
+ // is baked in at BUILD time, so the pin is what decides which icons exist
40916
+ // AND what markup lands on a customer's published page. Bumping it is a
40917
+ // deliberate act that also refreshes the icon set — not a silent
40918
+ // third-party update to artwork we are about to publish under a customer's
40919
+ // domain.
40920
+ //
40921
+ // No credential anywhere: the registry and the jsDelivr CDN the server
40922
+ // fetches SVG from are both public, so `auth_types: ['none']` is the honest
40923
+ // classification rather than the ENG-8440 kind of lie Hard Rule 17 warns
40924
+ // about — there genuinely is no key to enter and the install IS live
40925
+ // immediately.
40926
+ id: "thesvg",
40927
+ name: "theSVG",
40928
+ category: "media",
40929
+ description: "Brand logos and icons as real SVG \u2014 search 6,500+ marks by name and pull the exact artwork, in mono, colour, light, dark or wordmark variants",
40930
+ supported_auth_types: ["none"],
40931
+ docs_url: "https://thesvg.org",
40932
+ capabilities: [
40933
+ {
40934
+ id: "thesvg:read",
40935
+ name: "Find and fetch brand icons",
40936
+ description: "Search the icon library, list an icon's variants and categories, and fetch its SVG markup or CDN URL",
40937
+ access: "read"
40938
+ }
40939
+ ],
40940
+ installable: { category: "Media", authTypes: ["none"] },
40941
+ beta: true,
40942
+ // ENG-5815 data-driven path — no buildMcpJson edit, same as AWS.
40943
+ nativeMcp: {
40944
+ command: "npx",
40945
+ args: ["-y", "@thesvg/mcp-server@0.8.2"],
40946
+ env: {
40947
+ PATH: "{{process_env.PATH}}",
40948
+ HOME: "{{process_env.HOME}}"
40949
+ }
40950
+ }
40951
+ },
40822
40952
  {
40823
40953
  id: "qmd",
40824
40954
  name: "QMD Memory Search",
@@ -41944,6 +42074,10 @@ var NOTICE_KIND_AUDIENCE = {
41944
42074
  // "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
41945
42075
  // uuid and all.
41946
42076
  approval_expired: "agent",
42077
+ // ENG-11334: canvas.publish_public approved / denied / approved-but-not-applied.
42078
+ // Second-person instructions to the agent ("Tell the user...", "do not
42079
+ // republish"); the user learns the outcome from the agent, not this row.
42080
+ canvas_public_approval_resolved: "agent",
41947
42081
  // A routine fired; the agent picks the work up.
41948
42082
  routine_firing_result: "agent",
41949
42083
  // Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
@@ -44267,7 +44401,7 @@ var FLAG_REGISTRY = [
44267
44401
  },
44268
44402
  {
44269
44403
  key: "approval-unified-authority",
44270
- description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict and log approval_authority_would_reject (ingress, verb, org, reason) for every tap it would refuse, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
44404
+ description: "One authority check for every approval ingress (ENG-11207, ADR-0124 Phase 0b): canDecide() runs inside tryDispatchApprovalCore for console, Slack (channel, alerts, Socket Mode, which also carries Telegram) and Direct Chat taps alike. off = not computed. shadow = compute the verdict, including the verb's declared approver boundary (ENG-11337), and log approval_authority_would_reject (ingress, verb, org, reason, boundary) for every tap it would refuse and approval_authority_would_admit (ingress, verb, org, basis, boundary) for every tap it would admit, then decide exactly as today. enforce = reserved for the per-(org, verb) allowlist slice; until that ships it behaves as shadow. Evaluated per-org. Ships dark.",
44271
44405
  flagType: "enum",
44272
44406
  allowedValues: ["off", "shadow", "enforce"],
44273
44407
  // Safe/default value is `off` (no computation, no extra reads on the tap path). A flag-DB read