@akasecurity/ai-tc-claude-code 0.9.11 → 0.9.12

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.
@@ -20630,6 +20630,15 @@ var FindingCategory = external_exports.enum([
20630
20630
  ]).meta({ id: "FindingCategory" });
20631
20631
  var FindingOrigin = external_exports.enum(["in-flight", "at-rest"]).meta({ id: "FindingOrigin" });
20632
20632
  var FindingStatus = external_exports.enum(["open", "handled", "resolved", "dismissed"]).meta({ id: "FindingStatus" });
20633
+ var SyncFailureReason = external_exports.enum(["deployment_refused", "payload_invalid", "detached_undelivered"]).meta({ id: "SyncFailureReason" });
20634
+ var FindingDeliveryState = external_exports.enum(["sent", "queued", "not_sent", "never_offered", "local_scan"]).meta({ id: "FindingDeliveryState" });
20635
+ var FindingDelivery = external_exports.object({
20636
+ state: FindingDeliveryState,
20637
+ // The delivery time for `sent`; the failure time for `not_sent` when recorded.
20638
+ at: external_exports.iso.datetime().optional(),
20639
+ // Only on `not_sent`, and only when a known reason was recorded.
20640
+ reason: SyncFailureReason.optional()
20641
+ }).meta({ id: "FindingDelivery" });
20633
20642
  var ResolutionMethod = external_exports.enum([
20634
20643
  "enforced-in-flight",
20635
20644
  "fixed-at-source",
@@ -20686,7 +20695,10 @@ var FindingInstance = external_exports.object({
20686
20695
  // The session that event belongs to, when it has one — the seam a
20687
20696
  // per-instance "view session" link needs. Absent for events captured
20688
20697
  // outside a session.
20689
- sessionId: external_exports.string().optional()
20698
+ sessionId: external_exports.string().optional(),
20699
+ // The delivery state of the event above (see FindingDelivery). Optional so
20700
+ // readers that do not project it stay valid.
20701
+ delivery: FindingDelivery.optional()
20690
20702
  }).meta({ id: "FindingInstance" });
20691
20703
  var FindingGroup = external_exports.object({
20692
20704
  id: external_exports.string(),
@@ -20738,7 +20750,10 @@ var FindingFacets = external_exports.object({
20738
20750
  // Host tool (attributes.tool_name). Present only on the instance-level
20739
20751
  // reads, which can filter by it; the type-level read omits the dimension
20740
20752
  // because a group spans tools.
20741
- tool: external_exports.array(FindingFacetItem).optional()
20753
+ tool: external_exports.array(FindingFacetItem).optional(),
20754
+ // Delivery states (FindingDeliveryState). Present only on the
20755
+ // instance-level reads, like `tool`.
20756
+ deployment: external_exports.array(FindingFacetItem).optional()
20742
20757
  }).meta({ id: "FindingFacets" });
20743
20758
  var FindingTypeSummary = FindingGroup.omit({ instances: true, match: true }).meta({
20744
20759
  id: "FindingTypeSummary"
@@ -20847,6 +20862,8 @@ var ListFindingInstancesQuery = external_exports.object({
20847
20862
  // Exact host-tool names (attributes.tool_name, e.g. 'Bash'). A real filter,
20848
20863
  // where the free-text `q` can only match the rendered "via Bash" label.
20849
20864
  tool: external_exports.array(external_exports.string()).optional(),
20865
+ // The delivery state of each finding's event (see FindingDelivery).
20866
+ deployment: external_exports.array(FindingDeliveryState).optional(),
20850
20867
  // Exact repository / file-path matches, for the drill-down out of the
20851
20868
  // locations view. A row whose event carries no repo/file matches neither.
20852
20869
  repo: external_exports.string().optional(),
@@ -20867,6 +20884,10 @@ var ListFindingInstancesResponse = external_exports.object({
20867
20884
  items: external_exports.array(FindingInstanceDetail),
20868
20885
  nextCursor: external_exports.string().nullable()
20869
20886
  }).meta({ id: "ListFindingInstancesResponse" });
20887
+ var ListFindingInstancesPage = external_exports.object({
20888
+ items: external_exports.array(FindingInstanceDetail),
20889
+ nextCursor: external_exports.string().nullable()
20890
+ }).meta({ id: "ListFindingInstancesPage" });
20870
20891
  var FindingLocationSummary = external_exports.object({
20871
20892
  // Opaque, stable, minted from the pair by encodeLocationId. It exists
20872
20893
  // because a location's identity is two values and a URL param carries one:
@@ -20908,6 +20929,8 @@ var ListFindingLocationsQuery = external_exports.object({
20908
20929
  // instances that match, and folds its status from those.
20909
20930
  status: external_exports.array(FindingStatus).optional(),
20910
20931
  tool: external_exports.array(external_exports.string()).optional(),
20932
+ // The delivery state of each finding's event (see FindingDelivery).
20933
+ deployment: external_exports.array(FindingDeliveryState).optional(),
20911
20934
  q: external_exports.string().optional(),
20912
20935
  sessionId: external_exports.string().optional(),
20913
20936
  from: external_exports.iso.datetime().optional(),
@@ -21110,6 +21133,10 @@ var CaptureAttributes = external_exports.object({
21110
21133
  // to 'allow' — the enforcement audit trail's link back to the grant that
21111
21134
  // authorized the bypass.
21112
21135
  exception_ids: external_exports.array(external_exports.guid()).optional(),
21136
+ // The persisted spellings of EventMetadata's messageId/conversationId — the
21137
+ // join back to the `llm_call` leaf for the same assistant turn.
21138
+ message_id: external_exports.string().optional(),
21139
+ conversation_id: external_exports.string().optional(),
21113
21140
  // Whole milliseconds this capture's inspection blocked its caller — the
21114
21141
  // plugin's own added latency (see EventMetadata.inspectionMs, whose value
21115
21142
  // this is). Promoted to the `inspection_ms` generated column so the facet is
@@ -21118,7 +21145,19 @@ var CaptureAttributes = external_exports.object({
21118
21145
  // inline json_extract and is not itself an optimization.
21119
21146
  // ABSENT on replayed captures (backfill / worktree scan) and on rows written
21120
21147
  // before the measurement shipped — never present as a placeholder 0.
21121
- inspection_ms: external_exports.number().int().nonnegative().optional()
21148
+ inspection_ms: external_exports.number().int().nonnegative().optional(),
21149
+ // What a `redact` this capture could not carry out became instead (see
21150
+ // EventMetadata.redactDegradedTo, whose value this is). Present only when a
21151
+ // degrade actually happened, so absence is the ordinary case rather than a
21152
+ // reader having to distinguish it from a zero.
21153
+ //
21154
+ // PER CAPTURE, while `inspection_findings.action_taken` is per finding —
21155
+ // so on a multi-finding row this does not say which finding degraded, and
21156
+ // its presence does not mean the fallback decided the capture's action. A
21157
+ // capture denied by another finding's own Block policy carries `block`
21158
+ // here too. The full statement is on EventMetadata.redactDegradedTo; it is
21159
+ // repeated rather than referenced because a store reader opens this file.
21160
+ redact_degraded_to: ActionTaken.optional()
21122
21161
  }).catchall(external_exports.unknown());
21123
21162
  var ToolCallInspection = external_exports.object({
21124
21163
  ruleId: external_exports.string().min(1),
@@ -21314,7 +21353,17 @@ var AuditEvent = external_exports.object({
21314
21353
  /** `share` to a first-party/internal destination. */
21315
21354
  internal: external_exports.boolean(),
21316
21355
  /** Event needs review (e.g. unverified egress). */
21317
- flagged: external_exports.boolean()
21356
+ flagged: external_exports.boolean(),
21357
+ /**
21358
+ * The body this event's `title` is drawn from was cleared by local body
21359
+ * expiry, so an EMPTY title here means "gone", not "never had one".
21360
+ *
21361
+ * A separate flag rather than a sentinel written into `title`: the title is
21362
+ * rendered text, and a store-layer module that invented display copy for it
21363
+ * would be choosing words the view is supposed to choose. Additive and
21364
+ * defaulted, so an older producer still validates.
21365
+ */
21366
+ bodyExpired: external_exports.boolean().default(false)
21318
21367
  }).meta({ id: "ActivityAuditEvent" });
21319
21368
  var ActivitySessionSummary = external_exports.object({
21320
21369
  id: external_exports.string(),
@@ -22537,6 +22586,12 @@ var EventMetadata = external_exports.object({
22537
22586
  // to 'allow' — the enforcement audit trail's link back to the grant that
22538
22587
  // authorized the bypass. Absent on captures where no exception applied.
22539
22588
  exceptionIds: external_exports.array(external_exports.guid()).optional(),
22589
+ // The assistant message this capture belongs to, and the conversation it sits
22590
+ // in — set by the browser extension's network capture so a stored `response`
22591
+ // row can be joined to the `llm_call` leaf describing the same turn. Absent
22592
+ // on every other capture path, which has no such id.
22593
+ messageId: external_exports.string().optional(),
22594
+ conversationId: external_exports.string().optional(),
22540
22595
  // How long THIS capture's inspection blocked its caller, in whole
22541
22596
  // milliseconds — the plugin's own added latency, NOT the LLM call it sat in
22542
22597
  // front of. Measured inside `capture()` (@akasecurity/plugin-sdk) across
@@ -22549,7 +22604,37 @@ var EventMetadata = external_exports.object({
22549
22604
  // Absent is also what every pre-measurement client writes, and what a
22550
22605
  // clock failure degrades to — a reader must treat absence as "not measured"
22551
22606
  // and never as a zero, which would read as "inspection is free".
22552
- inspectionMs: external_exports.number().int().nonnegative().optional()
22607
+ inspectionMs: external_exports.number().int().nonnegative().optional(),
22608
+ // What a `redact` this capture COULD NOT CARRY OUT became instead — the
22609
+ // workspace's `redactFallback`, applied because the field could not be
22610
+ // masked in place (a shell command, a URL, or any argument on a host whose
22611
+ // hook contract offers no rewrite channel).
22612
+ //
22613
+ // It exists because the action alone cannot say why. A finding recorded as
22614
+ // `warn` reads identically whether its detection was ASSIGNED Warn or was
22615
+ // assigned Redact on a field that could not take one — and those are
22616
+ // different facts about the same row: the first is a policy the user chose,
22617
+ // the second is a masking the host could not perform. Absent means no
22618
+ // degrade happened, which is every ordinary capture.
22619
+ //
22620
+ // TWO LIMITS a reader of a stored row has to know, because the grain here
22621
+ // is the CAPTURE while `actionTaken` is per FINDING:
22622
+ //
22623
+ // - It does not say WHICH finding degraded. A capture carrying a degraded
22624
+ // `redact` alongside a finding ASSIGNED the same action stores both
22625
+ // identically and one reason for the pair; attributing it to both
22626
+ // describes the assigned one wrongly, and to neither loses the degrade.
22627
+ // - PRESENCE IS NOT CAUSATION. The value is the action the lost redact
22628
+ // became, not the reason the capture ended as it did — a capture denied
22629
+ // by some other finding's own Block policy still carries `block` here,
22630
+ // and clearing the workspace's fallback would not have let it through.
22631
+ // Gate on the value against what a fallback can produce; never read the
22632
+ // field's presence as "this was the fallback's doing".
22633
+ //
22634
+ // Both are pinned as behaviour in @akasecurity/plugin-sdk's runtime suite.
22635
+ // Closing either means moving the reason onto the finding row, which
22636
+ // already carries its own action.
22637
+ redactDegradedTo: ActionTaken.optional()
22553
22638
  }).meta({ id: "EventMetadata" });
22554
22639
  var Event = external_exports.object({
22555
22640
  id: external_exports.guid(),
@@ -22659,6 +22744,15 @@ var RotateKeyInput = external_exports.object({
22659
22744
  confirmation: external_exports.string()
22660
22745
  });
22661
22746
 
22747
+ // ../../packages/schema/src/zod/finding-delivery.ts
22748
+ var KNOWN_REASONS = SyncFailureReason.options;
22749
+
22750
+ // ../../packages/schema/src/zod/findings-group-build.ts
22751
+ function rankByOrder(members2) {
22752
+ return Object.fromEntries(members2.map((member, index) => [member, index]));
22753
+ }
22754
+ var SEVERITY_RANK = rankByOrder(Severity.options);
22755
+
22662
22756
  // ../../packages/schema/src/zod/installed-pack.ts
22663
22757
  var InstalledPack = external_exports.object({
22664
22758
  id: external_exports.guid(),
@@ -22725,6 +22819,11 @@ var Policy = external_exports.object({
22725
22819
  // test `prohibitedModels` passes and `reversibleRuleIds` fails.
22726
22820
  provenance: PolicyProvenance.optional()
22727
22821
  }).meta({ id: "Policy" });
22822
+ var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "vault", "block"];
22823
+ var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
22824
+ var RedactFallback = BuiltinPolicyId.extract(["monitor", "warn", "block"]).meta({
22825
+ id: "RedactFallback"
22826
+ });
22728
22827
  var PolicyBundle = external_exports.object({
22729
22828
  version: external_exports.string(),
22730
22829
  policies: external_exports.array(Policy),
@@ -22772,6 +22871,16 @@ var PolicyBundle = external_exports.object({
22772
22871
  // control plane), so no name resolution stands between the decision and the
22773
22872
  // comparison.
22774
22873
  prohibitedModels: external_exports.array(external_exports.string()).optional(),
22874
+ // What a resolved `redact` becomes on a field the host cannot rewrite, as
22875
+ // the ORGANIZATION would have it. Merged raise-only against the device's own
22876
+ // `WorkspaceSettings.redactFallback` (see strongerRedactFallback below), so
22877
+ // a control plane can tighten a machine and never loosen one — the same
22878
+ // direction `mergeRaiseOnly` enforces for policies.
22879
+ //
22880
+ // Optional so an older backend, and an older on-disk cache, still parses;
22881
+ // absent leaves the device's own setting in force, which is the behaviour
22882
+ // that predates the field and the safe direction to default.
22883
+ redactFallback: RedactFallback.optional(),
22775
22884
  customKeywords: external_exports.array(external_exports.string()),
22776
22885
  fetchedAt: external_exports.iso.datetime()
22777
22886
  }).meta({ id: "PolicyBundle" });
@@ -22801,11 +22910,6 @@ function severityFloorPolicy(category) {
22801
22910
  const peak = CATEGORY_PEAK_SEVERITY[category];
22802
22911
  return peak === "critical" || peak === "high" ? "warn" : "monitor";
22803
22912
  }
22804
- var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "vault", "block"];
22805
- var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
22806
- var RedactFallback = BuiltinPolicyId.extract(["monitor", "warn", "block"]).meta({
22807
- id: "RedactFallback"
22808
- });
22809
22913
  var BUILTIN_POLICY_SPECS = {
22810
22914
  monitor: {
22811
22915
  name: "Monitor",
@@ -23067,7 +23171,7 @@ var VaultConsent = external_exports.object({
23067
23171
  });
23068
23172
 
23069
23173
  // ../../packages/schema/src/zod/local.ts
23070
- var WORKSPACE_SETTINGS_SPEC_VERSION = 7;
23174
+ var WORKSPACE_SETTINGS_SPEC_VERSION = 8;
23071
23175
  var RunMode = external_exports.enum(["standalone", "attached"]);
23072
23176
  var ControlPlaneConnection = external_exports.object({
23073
23177
  endpoint: external_exports.string().min(1),
@@ -23086,6 +23190,15 @@ var HistorySyncConsent = external_exports.object({
23086
23190
  payloadVersion: external_exports.number().int().positive(),
23087
23191
  endpoint: external_exports.string()
23088
23192
  });
23193
+ var BODY_RETENTION_DEFAULT_DAYS = 30;
23194
+ var BodyRetention = external_exports.object({
23195
+ enabled: external_exports.boolean().default(false),
23196
+ // Never 0, and the ceiling is a fat-finger guard rather than a policy
23197
+ // limit — `enabled` is the real gate. A low value cannot reach a row the
23198
+ // sync ledger still owes: the sweep's age filter only ever NARROWS a
23199
+ // candidate set that is already bounded by "delivered, or never owed".
23200
+ retainDays: external_exports.number().int().min(1).max(3650).default(BODY_RETENTION_DEFAULT_DAYS)
23201
+ }).meta({ id: "BodyRetention" });
23089
23202
  var WorkspaceSettings = external_exports.object({
23090
23203
  specVersion: external_exports.number().int().positive().default(WORKSPACE_SETTINGS_SPEC_VERSION),
23091
23204
  runMode: RunMode.default("standalone"),
@@ -23134,7 +23247,13 @@ var WorkspaceSettings = external_exports.object({
23134
23247
  // carry prompt/reply/tool-output text in `content`; the key name predates
23135
23248
  // both widenings. Absent until granted, and a grant for a different endpoint
23136
23249
  // or an older payload no longer counts.
23137
- historySyncConsent: HistorySyncConsent.optional()
23250
+ historySyncConsent: HistorySyncConsent.optional(),
23251
+ // Local body expiry (see BodyRetention). Off until switched on; expiring a
23252
+ // body never removes the row or its findings.
23253
+ bodyRetention: BodyRetention.default({
23254
+ enabled: false,
23255
+ retainDays: BODY_RETENTION_DEFAULT_DAYS
23256
+ })
23138
23257
  });
23139
23258
 
23140
23259
  // ../../packages/schema/src/zod/managed.ts
@@ -23147,13 +23266,22 @@ var ManagedSettingKey = external_exports.enum([
23147
23266
  "vaultInlineReveal",
23148
23267
  "modelJudgeConsent",
23149
23268
  "dataSharesInPlace",
23150
- "redactFallback"
23269
+ "redactFallback",
23270
+ // Pins the toggle and the day count together — see BodyRetention on why the
23271
+ // two are one unit. An administrator mandating a window wants the count
23272
+ // enforced with it, not one a user can widen while the toggle stays on.
23273
+ "bodyRetention"
23151
23274
  ]).meta({ id: "ManagedSettingKey" });
23152
23275
  function isManagedSettingKey(value) {
23153
23276
  return ManagedSettingKey.safeParse(value).success;
23154
23277
  }
23155
23278
  var ManagedSettingsValues = external_exports.object({
23156
23279
  runMode: external_exports.enum(["standalone", "attached"]).optional(),
23280
+ // `controlPlane` and `bodyRetention` are the two nested values, and both are
23281
+ // plain, non-strict objects: a key under either that this build does not know
23282
+ // is stripped and nothing reports it. The unknown-value split in
23283
+ // ManagedSettings below classifies top-level names only, so it stops at
23284
+ // these boundaries.
23157
23285
  controlPlane: external_exports.object({
23158
23286
  endpoint: external_exports.string().min(1),
23159
23287
  label: external_exports.string().min(1).optional()
@@ -23164,7 +23292,8 @@ var ManagedSettingsValues = external_exports.object({
23164
23292
  vaultInlineReveal: external_exports.enum(["masked", "full", "off"]).optional(),
23165
23293
  modelJudgeConsent: external_exports.boolean().optional(),
23166
23294
  dataSharesInPlace: external_exports.boolean().optional(),
23167
- redactFallback: RedactFallback.optional()
23295
+ redactFallback: RedactFallback.optional(),
23296
+ bodyRetention: BodyRetention.optional()
23168
23297
  }).meta({ id: "ManagedSettingsValues" });
23169
23298
  var ManagedSettings = external_exports.object({
23170
23299
  specVersion: external_exports.number().int().positive().default(MANAGED_SETTINGS_SPEC_VERSION),
@@ -23172,7 +23301,21 @@ var ManagedSettings = external_exports.object({
23172
23301
  // decision from a bug. Absent renders as a generic "your organization".
23173
23302
  organization: external_exports.string().min(1).optional(),
23174
23303
  // What the administrator pinned.
23175
- values: ManagedSettingsValues.default({}),
23304
+ //
23305
+ // Parsed as a RECORD rather than as the nested schema, and split below for
23306
+ // the same reason `lockedFields` is parsed as names: a plain `z.object`
23307
+ // drops an unrecognised key and succeeds, so a pin this build does not know
23308
+ // vanished and nothing anywhere said so. A pin with no lock is a supported
23309
+ // shape — it is a DEFAULT the user may still change — so that silence hit
23310
+ // exactly the file an administrator is most likely to write while a fleet
23311
+ // is mid-upgrade.
23312
+ //
23313
+ // Splitting here rather than calling `.strict()`: strict would REFUSE the
23314
+ // file, which is the outcome the lock half already rejected — an older
23315
+ // build then runs entirely unmanaged, every pin and lock gone. A bad KNOWN
23316
+ // value still fails, because the nested schema is re-run over the known
23317
+ // subset and its issues are re-raised on this parse.
23318
+ values: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
23176
23319
  // Which of those the user may not change. A key here with no matching value
23177
23320
  // freezes whatever the user last chose; a value with no lock is a DEFAULT
23178
23321
  // the user may still override. The two are separable on purpose.
@@ -23185,17 +23328,31 @@ var ManagedSettings = external_exports.object({
23185
23328
  // the fleets most likely to carry a version skew. A name outside the enum
23186
23329
  // is still never HONOURED: the lockable set stays explicit above.
23187
23330
  lockedFields: external_exports.array(external_exports.string()).default([])
23188
- }).transform(({ lockedFields, ...rest }) => {
23331
+ }).transform(({ lockedFields, values, ...rest }, ctx) => {
23189
23332
  const known = [];
23190
23333
  const unknown2 = [];
23191
23334
  for (const name of lockedFields) {
23192
23335
  if (isManagedSettingKey(name)) known.push(name);
23193
23336
  else unknown2.push(name);
23194
23337
  }
23338
+ const knownValues = /* @__PURE__ */ Object.create(null);
23339
+ const unknownValues = [];
23340
+ for (const [name, value] of Object.entries(values)) {
23341
+ if (Object.hasOwn(ManagedSettingsValues.shape, name)) knownValues[name] = value;
23342
+ else unknownValues.push(name);
23343
+ }
23344
+ const pinned = ManagedSettingsValues.safeParse(knownValues);
23345
+ if (!pinned.success) {
23346
+ for (const issue2 of pinned.error.issues)
23347
+ ctx.addIssue({ ...issue2, path: ["values", ...issue2.path] });
23348
+ return external_exports.NEVER;
23349
+ }
23195
23350
  return {
23196
23351
  ...rest,
23352
+ values: pinned.data,
23197
23353
  lockedFields: known,
23198
- ...unknown2.length > 0 ? { unknownLockedFields: unknown2 } : {}
23354
+ ...unknown2.length > 0 ? { unknownLockedFields: unknown2 } : {},
23355
+ ...unknownValues.length > 0 ? { unknownValueFields: unknownValues } : {}
23199
23356
  };
23200
23357
  }).meta({ id: "ManagedSettings" });
23201
23358
 
@@ -23453,7 +23610,23 @@ var SaveSettingsInput = external_exports.object({
23453
23610
  modelJudgeConsent: ModelJudgeConsentChoice,
23454
23611
  historySyncConsent: HistorySyncConsentChoice,
23455
23612
  vaultConsent: external_exports.string(),
23456
- vaultInlineReveal: external_exports.string()
23613
+ vaultInlineReveal: external_exports.string(),
23614
+ // Widened to `string` like its neighbours rather than typed as
23615
+ // `RedactFallback`, on this module's own layering rule: shape here, VALUE at
23616
+ // the call site, so the domain check receives the type it was written for.
23617
+ //
23618
+ // NOT because a narrower schema would reject differently. `parseActionInput`
23619
+ // is a `safeParse` wrapper and throws for no field schema, so either spelling
23620
+ // reaches a recoverable `{ ok: false }` and there is no rejected promise to
23621
+ // trade against. The real cost runs the other way and is the part worth
23622
+ // knowing: a value this schema admits and the domain enum then rejects lands
23623
+ // on the action's shared refusal, which names NO field, where a shape
23624
+ // rejection reaches `malformedInput` and names the schema key.
23625
+ redactFallback: external_exports.string(),
23626
+ // Shape only, the way the enum fields above are strings only: the RANGE is
23627
+ // `BodyRetention`'s and the action checks it there, so there is one place
23628
+ // that decides what a legal horizon is rather than two that can drift.
23629
+ bodyRetention: external_exports.object({ enabled: external_exports.boolean(), retainDays: external_exports.number() })
23457
23630
  });
23458
23631
  var AttachInput = external_exports.object({
23459
23632
  endpoint: external_exports.string(),
@@ -23579,6 +23752,52 @@ var SetupHandoffOffer = external_exports.object({
23579
23752
  path: ["liveKeys"]
23580
23753
  });
23581
23754
 
23755
+ // ../../packages/schema/src/zod/web-capture.ts
23756
+ var WebUsageSource = external_exports.enum(["site", "estimated", "none"]);
23757
+ var WebUsage = external_exports.object({
23758
+ inputTokens: external_exports.number().int().nonnegative().optional(),
23759
+ outputTokens: external_exports.number().int().nonnegative().optional(),
23760
+ cacheReadInputTokens: external_exports.number().int().nonnegative().optional(),
23761
+ cacheCreationInputTokens: external_exports.number().int().nonnegative().optional()
23762
+ });
23763
+ var WebToolCall = external_exports.object({
23764
+ toolUseId: external_exports.string().min(1),
23765
+ toolName: external_exports.string().min(1),
23766
+ target: external_exports.string().optional(),
23767
+ isError: external_exports.boolean().optional(),
23768
+ inputSize: external_exports.number().int().nonnegative().optional(),
23769
+ outputSize: external_exports.number().int().nonnegative().optional()
23770
+ });
23771
+ var WebExchange = external_exports.object({
23772
+ messageId: external_exports.string().min(1),
23773
+ startedAt: external_exports.iso.datetime(),
23774
+ model: external_exports.string().optional(),
23775
+ usage: WebUsage.optional(),
23776
+ usageSource: WebUsageSource,
23777
+ stopReason: external_exports.string().optional(),
23778
+ conversationId: external_exports.string().optional(),
23779
+ turnIndex: external_exports.number().int().nonnegative().optional(),
23780
+ toolCalls: external_exports.array(WebToolCall).default([]),
23781
+ // Absent when the adapter recovered no text. Capped by the caller at
23782
+ // RESPONSE_TEXT_MAX_BYTES; `truncated` records that the cap was reached, so a
23783
+ // short capture is never mistaken for a short reply.
23784
+ responseText: external_exports.string().optional(),
23785
+ truncated: external_exports.boolean().default(false)
23786
+ });
23787
+ var RESPONSE_TEXT_MAX_BYTES = 2 * 1024 * 1024;
23788
+ var WebCaptureStatus = external_exports.object({
23789
+ patched: external_exports.boolean(),
23790
+ live: external_exports.boolean(),
23791
+ blind: external_exports.boolean(),
23792
+ sendsSeenDom: external_exports.number().int().nonnegative(),
23793
+ exchangesSeenNet: external_exports.number().int().nonnegative(),
23794
+ parseFailures: external_exports.number().int().nonnegative(),
23795
+ unparsedBodies: external_exports.number().int().nonnegative(),
23796
+ // The adapter-declared JSON key paths that were absent from a real payload —
23797
+ // the earliest signal that a site's contract moved.
23798
+ shapeMisses: external_exports.array(external_exports.string()).default([])
23799
+ });
23800
+
23582
23801
  // ../../packages/detections/src/posture/config-posture.ts
23583
23802
  var RULE_VERSION = "1";
23584
23803
  var KNOWN_TOOLS = /* @__PURE__ */ new Set([