@akasecurity/ai-tc-claude-code 0.9.5 → 0.9.7

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.
@@ -15070,6 +15070,47 @@ function date4(params) {
15070
15070
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
15071
15071
  config(en_default());
15072
15072
 
15073
+ // ../../packages/schema/src/zod/harness-map.ts
15074
+ var HARNESS = {
15075
+ ClaudeCode: "claudecode",
15076
+ Cursor: "cursor",
15077
+ Copilot: "copilot",
15078
+ Codex: "codex",
15079
+ Antigravity: "antigravity",
15080
+ Windsurf: "windsurf",
15081
+ ClaudeDesktop: "claudedesktop",
15082
+ ChatGpt: "chatgpt",
15083
+ ClaudeAi: "claudeai",
15084
+ Api: "api"
15085
+ };
15086
+ var Harness = external_exports.enum(HARNESS).meta({ id: "Harness" });
15087
+ var SOURCE_TOOL = {
15088
+ ClaudeCode: "claude-code",
15089
+ ClaudeDesktop: "claude-desktop",
15090
+ Cursor: "cursor",
15091
+ ChatGpt: "chatgpt",
15092
+ ClaudeAi: "claude-ai",
15093
+ Copilot: "github-copilot",
15094
+ Codex: "codex",
15095
+ Antigravity: "antigravity",
15096
+ // No harness counterpart, deliberately: the CLI's own captures and a capture
15097
+ // whose tool could not be identified both render through the read side's
15098
+ // miss path rather than as a harness of their own.
15099
+ Cli: "cli",
15100
+ Unknown: "unknown"
15101
+ };
15102
+ var SourceTool = external_exports.enum(SOURCE_TOOL).meta({ id: "SourceTool" });
15103
+ var TOOL_TO_HARNESS = {
15104
+ [SOURCE_TOOL.ClaudeCode]: HARNESS.ClaudeCode,
15105
+ [SOURCE_TOOL.ClaudeDesktop]: HARNESS.ClaudeDesktop,
15106
+ [SOURCE_TOOL.Copilot]: HARNESS.Copilot,
15107
+ [SOURCE_TOOL.Cursor]: HARNESS.Cursor,
15108
+ [SOURCE_TOOL.ChatGpt]: HARNESS.ChatGpt,
15109
+ [SOURCE_TOOL.Codex]: HARNESS.Codex,
15110
+ [SOURCE_TOOL.Antigravity]: HARNESS.Antigravity,
15111
+ [SOURCE_TOOL.ClaudeAi]: HARNESS.ClaudeAi
15112
+ };
15113
+
15073
15114
  // ../../packages/schema/src/zod/finding.ts
15074
15115
  var DetectionCategory = external_exports.enum(["pii", "financial", "secret", "phi", "code_context", "code_flaw", "custom", "config"]).meta({ id: "DetectionCategory" });
15075
15116
  var Severity = external_exports.enum(["critical", "high", "medium", "low"]).meta({ id: "Severity" });
@@ -15092,21 +15133,22 @@ var Finding = external_exports.object({
15092
15133
  }).meta({ id: "Finding" });
15093
15134
  var DetectedFinding = Finding.meta({ id: "DetectedFinding" });
15094
15135
  var FindingAction = external_exports.enum(["blocked", "redacted", "warned", "allowed", "quarantined", "monitored"]).meta({ id: "FindingAction" });
15095
- var FindingProvider = external_exports.enum([
15096
- "claudecode",
15097
- "claudedesktop",
15098
- "cursor",
15099
- "copilot",
15100
- "chatgpt",
15101
- "claudeai",
15102
- "codex",
15103
- "antigravity",
15104
- "api"
15136
+ var FindingProvider = Harness.extract([
15137
+ "ClaudeCode",
15138
+ "ClaudeDesktop",
15139
+ "Cursor",
15140
+ "Copilot",
15141
+ "ChatGpt",
15142
+ "ClaudeAi",
15143
+ "Codex",
15144
+ "Antigravity",
15145
+ "Api"
15105
15146
  ]).meta({ id: "FindingProvider" });
15106
15147
  var FindingCategory = external_exports.enum([
15107
15148
  "secret",
15108
15149
  "pii",
15109
15150
  "source_code",
15151
+ "code_flaw",
15110
15152
  "external_share",
15111
15153
  "mcp_server",
15112
15154
  "customer_data",
@@ -15284,6 +15326,7 @@ var FindingInstanceDetail = FindingInstance.extend({
15284
15326
  detection: FindingDetectionRef,
15285
15327
  policy: FindingPolicyRef
15286
15328
  }).meta({ id: "FindingInstanceDetail" });
15329
+ var MAX_FLAT_FINDINGS_LIMIT = 200;
15287
15330
  var ListFindingInstancesQuery = external_exports.object({
15288
15331
  severity: external_exports.array(Severity).optional(),
15289
15332
  // Rule ids, the same vocabulary the grouped list's `subtype` carries.
@@ -15303,7 +15346,7 @@ var ListFindingInstancesQuery = external_exports.object({
15303
15346
  q: external_exports.string().optional(),
15304
15347
  sessionId: external_exports.string().optional(),
15305
15348
  from: external_exports.iso.datetime().optional(),
15306
- limit: external_exports.coerce.number().int().min(1).max(200).optional(),
15349
+ limit: external_exports.coerce.number().int().min(1).max(MAX_FLAT_FINDINGS_LIMIT).optional(),
15307
15350
  cursor: external_exports.string().optional()
15308
15351
  });
15309
15352
  var ListFindingInstancesResponse = external_exports.object({
@@ -15365,20 +15408,6 @@ var ListFindingLocationsResponse = external_exports.object({
15365
15408
  hasMore: external_exports.boolean()
15366
15409
  }).meta({ id: "ListFindingLocationsResponse" });
15367
15410
 
15368
- // ../../packages/schema/src/zod/harness-map.ts
15369
- var Harness = external_exports.enum([
15370
- "claudecode",
15371
- "cursor",
15372
- "copilot",
15373
- "codex",
15374
- "antigravity",
15375
- "windsurf",
15376
- "claudedesktop",
15377
- "chatgpt",
15378
- "claudeai",
15379
- "api"
15380
- ]).meta({ id: "Harness" });
15381
-
15382
15411
  // ../../packages/schema/src/zod/meta.ts
15383
15412
  var InventoryObjectType = external_exports.enum(["host", "harness", "user", "skill", "hook", "mcp_server", "config_file"]).meta({ id: "InventoryObjectType" });
15384
15413
  var AuditEventType = external_exports.enum([
@@ -15828,366 +15857,122 @@ var ActivityOverviewResponse = external_exports.object({
15828
15857
  sessions: ListActivitySessionsResponse
15829
15858
  }).meta({ id: "ActivityOverviewResponse" });
15830
15859
 
15831
- // ../../packages/schema/src/zod/event.ts
15832
- var EventKind = external_exports.enum(["prompt", "response", "code_change", "tool_use"]).meta({ id: "EventKind" });
15833
- var CAPTURE_EVENT_TYPES_SQL = EventKind.options.map((k) => `'${k}'`).join(",");
15834
- var SourceTool = external_exports.enum([
15835
- "claude-code",
15836
- "claude-desktop",
15837
- "cursor",
15838
- "chatgpt",
15839
- "claude-ai",
15840
- "github-copilot",
15841
- "codex",
15842
- "antigravity",
15843
- "cli",
15844
- "unknown"
15845
- ]).meta({ id: "SourceTool" });
15846
- var EventMetadata = external_exports.object({
15847
- sessionId: external_exports.string().optional(),
15848
- repo: external_exports.string().optional(),
15849
- filePath: external_exports.string().optional(),
15850
- // The host tool whose input/output was scanned (e.g. 'Bash', 'WebFetch'),
15851
- // set by the tool-scanning hooks. The tool NAME only — never the tool's
15852
- // arguments or output, which can carry the very value a finding masked
15853
- // (metadata is stored unredacted). Gives findings on non-file captures a
15854
- // display location ("via Bash") when no filePath exists.
15855
- toolName: external_exports.string().optional(),
15856
- // Set (true) by the worktree scanner when the file is excluded by the
15857
- // repo's .gitignore. Gitignored files ARE still scanned — local scratch and
15858
- // generated code can leak real secrets — but the provenance is recorded so
15859
- // policy/dashboards can treat those findings as informational rather than
15860
- // blocking. Omitted (not false) for tracked files and non-scan events.
15861
- gitignored: external_exports.boolean().optional(),
15862
- // Set (true) ONLY when the event's `content` is the COMPLETE file at
15863
- // capture time (a worktree scan reading from disk). Hook-captured edits
15864
- // (e.g. an Edit tool's new_string) are partial fragments and MUST NOT set
15865
- // this. The resolver-on-ingest keys its fixed-at-source dropout
15866
- // diff on this marker: only a whole-file snapshot can prove a previously
15867
- // open finding is gone; a fragment's absence proves nothing (the secret
15868
- // may live outside the hunk). Omitted (not false) for fragments and
15869
- // non-scan events, so pre-marker clients safely default to the
15870
- // non-authoritative path.
15871
- wholeFile: external_exports.boolean().optional(),
15872
- model: external_exports.string().optional(),
15873
- turnIndex: external_exports.number().int().nonnegative().optional(),
15874
- // Distributed-tracing correlation. `correlationId` ties a recorded event back
15875
- // to the request that captured/ingested it (a UUID, generated independently of
15876
- // the trace id); `traceId` is the W3C trace id (32 lowercase hex chars) of the
15877
- // originating span when telemetry is enabled. Both optional + backward
15878
- // compatible — populated by the plugin (see @akasecurity/plugin-sdk).
15879
- correlationId: external_exports.uuid().optional(),
15880
- traceId: external_exports.string().regex(/^[0-9a-f]{32}$/).optional(),
15881
- // Ids of the detection exceptions that downgraded findings in this capture
15882
- // to 'allow' — the enforcement audit trail's link back to the grant that
15883
- // authorized the bypass. Absent on captures where no exception applied.
15884
- exceptionIds: external_exports.array(external_exports.guid()).optional()
15885
- }).meta({ id: "EventMetadata" });
15886
- var Event = external_exports.object({
15887
- id: external_exports.guid(),
15888
- sourceTool: SourceTool,
15889
- kind: EventKind,
15890
- occurredAt: external_exports.iso.datetime(),
15891
- contentHash: external_exports.string(),
15892
- content: external_exports.string(),
15893
- metadata: EventMetadata.optional()
15894
- }).meta({ id: "Event" });
15895
- var IngestEvent = Event.meta({ id: "IngestEvent" });
15896
- var IngestBatch = external_exports.object({
15897
- events: external_exports.array(IngestEvent).min(1).max(100),
15898
- // Dedup policy for this batch. Id-dedup ALWAYS applies. 'content-hash'
15899
- // additionally rejects any event whose contentHash the store has already
15900
- // recorded — for re-runnable bulk ingest (worktree scan, transcript
15901
- // backfill), where a re-run mints fresh event ids for identical content and
15902
- // would otherwise accumulate duplicates. Live hook traffic must NOT set it:
15903
- // two genuinely separate prompts can be byte-identical and both belong on
15904
- // the timeline.
15905
- dedupe: external_exports.literal("content-hash").optional()
15906
- }).meta({ id: "IngestBatch" });
15907
-
15908
- // ../../packages/schema/src/zod/inventory.ts
15909
- var AssetType = external_exports.enum(["project", "skill", "mcp", "hook", "config"]).meta({ id: "AssetType" });
15910
- var AccessLevel = external_exports.enum(["open", "approved", "blocked"]).meta({ id: "AccessLevel" });
15911
- var Origin = external_exports.enum(["source", "public-dep", "vendored", "config", "data", "docs", "generated"]).meta({ id: "Origin" });
15912
- var TrustLevel = external_exports.enum(["known-good", "risky", "unapproved"]).meta({ id: "TrustLevel" });
15913
- var Flag = external_exports.enum(["update", "stale", "conflict", "unknown", "change", "untracked", "risk", "findings"]).meta({ id: "Flag" });
15914
- var Visibility = external_exports.enum(["public", "private"]).meta({ id: "Visibility" });
15915
- var HarnessEventKind = external_exports.enum(["block", "redact", "warn"]).meta({ id: "HarnessEventKind" });
15916
- var HarnessId = external_exports.enum(["claudecode", "cursor", "codex", "antigravity"]).meta({ id: "HarnessId" });
15917
- var AccessCounts = external_exports.object({
15918
- open: external_exports.number().int().nonnegative(),
15919
- approved: external_exports.number().int().nonnegative(),
15920
- blocked: external_exports.number().int().nonnegative(),
15921
- total: external_exports.number().int().nonnegative()
15922
- }).meta({ id: "AccessCounts" });
15923
- var AssetSummary = external_exports.object({
15924
- id: external_exports.string(),
15925
- type: AssetType,
15926
- name: external_exports.string(),
15927
- sub: external_exports.string(),
15928
- flags: external_exports.array(Flag),
15929
- /** MCP servers only — omitted for all other types. */
15930
- trust: TrustLevel.optional()
15931
- }).meta({ id: "AssetSummary" });
15932
- var ProjectSummary = external_exports.object({
15933
- id: external_exports.string(),
15934
- name: external_exports.string(),
15935
- repo: external_exports.string(),
15936
- visibility: Visibility,
15937
- language: external_exports.string(),
15938
- policyDefault: AccessLevel,
15939
- updatedAt: external_exports.iso.datetime(),
15940
- accessCounts: AccessCounts,
15941
- findingsCount: external_exports.number().int().nonnegative()
15942
- }).meta({ id: "ProjectSummary" });
15943
- var HarnessCategory = external_exports.object({
15944
- /** One of config/skill/mcp/hook — never project (enforced at service layer). */
15945
- type: AssetType,
15946
- assets: external_exports.array(AssetSummary)
15860
+ // ../../packages/schema/src/zod/config-inventory.ts
15861
+ var ConfigScope = external_exports.enum(["user", "project", "local", "plugin"]);
15862
+ var SkillScanEntry = external_exports.object({
15863
+ name: external_exports.string().min(1),
15864
+ // The identity source: a marketplace repo for plugin skills (e.g.
15865
+ // 'anthropics/skills'), 'local' for personal ~/.claude/skills, or
15866
+ // 'project:<repo-identity>' for checked-in project skills. The surrogate keeps
15867
+ // a personal skill named 'pdf' from colliding with the marketplace 'pdf'.
15868
+ source: external_exports.string().min(1),
15869
+ scope: ConfigScope,
15870
+ pluginName: external_exports.string().optional(),
15871
+ // Volatile — rides the attribute bag, never the identity hash.
15872
+ version: external_exports.string().optional(),
15873
+ description: external_exports.string().optional(),
15874
+ // Skill directory mtime (ISO) the "updated Nd ago" freshness signal.
15875
+ updatedAt: external_exports.iso.datetime().optional(),
15876
+ // Filesystem path — the promoted inventory `location` column.
15877
+ location: external_exports.string().optional()
15947
15878
  });
15948
- var HarnessSummary = external_exports.object({
15949
- id: HarnessId,
15950
- label: external_exports.string(),
15951
- kind: external_exports.string(),
15952
- version: external_exports.string(),
15953
- sessions: external_exports.number().int().nonnegative(),
15954
- assetCount: external_exports.number().int().nonnegative(),
15955
- flagCount: external_exports.number().int().nonnegative(),
15956
- projects: external_exports.array(ProjectSummary),
15957
- categories: external_exports.array(HarnessCategory)
15958
- }).meta({ id: "HarnessSummary" });
15959
- var ListHarnessesResponse = external_exports.object({ items: external_exports.array(HarnessSummary) }).meta({ id: "ListHarnessesResponse" });
15960
- var AssetGroup = external_exports.object({
15961
- /** Group key — never project (enforced at service layer). */
15962
- type: AssetType,
15963
- total: external_exports.number().int().nonnegative(),
15964
- /**
15965
- * MCP group only — omitted for all other types.
15966
- * Partial: only TrustLevel keys with non-zero counts are included.
15967
- * Strict: unknown keys are rejected — only TrustLevel values are valid keys.
15968
- */
15969
- trustRollup: external_exports.object({
15970
- "known-good": external_exports.number().int().nonnegative(),
15971
- risky: external_exports.number().int().nonnegative(),
15972
- unapproved: external_exports.number().int().nonnegative()
15973
- }).partial().strict().optional(),
15974
- /**
15975
- * Partial: only Flag keys with non-zero counts are included.
15976
- * Strict: unknown keys are rejected — only Flag values are valid keys.
15977
- */
15978
- flagRollup: external_exports.object({
15979
- update: external_exports.number().int().nonnegative(),
15980
- stale: external_exports.number().int().nonnegative(),
15981
- conflict: external_exports.number().int().nonnegative(),
15982
- unknown: external_exports.number().int().nonnegative(),
15983
- change: external_exports.number().int().nonnegative(),
15984
- untracked: external_exports.number().int().nonnegative(),
15985
- risk: external_exports.number().int().nonnegative(),
15986
- findings: external_exports.number().int().nonnegative()
15987
- }).partial().strict(),
15988
- items: external_exports.array(AssetSummary)
15989
- }).meta({ id: "AssetGroup" });
15990
- var ListAssetsResponse = external_exports.object({ groups: external_exports.array(AssetGroup) }).meta({ id: "ListAssetsResponse" });
15991
- var McpTool = external_exports.object({
15992
- name: external_exports.string(),
15993
- signature: external_exports.string(),
15994
- description: external_exports.string(),
15995
- write: external_exports.boolean(),
15996
- /** Non-null string when tool is dangerous / blocked; null otherwise. */
15997
- risk: external_exports.string().nullable()
15998
- }).meta({ id: "McpTool" });
15999
- var AssetFindingRef = external_exports.object({
16000
- id: external_exports.string(),
16001
- title: external_exports.string(),
16002
- note: external_exports.string()
15879
+ var HookScanEntry = external_exports.object({
15880
+ // Hook event name (PreToolUse, PostToolUse, …). Open string, not an enum: the
15881
+ // set is harness-defined and grows without a schema change.
15882
+ event: external_exports.string().min(1),
15883
+ // The tool matcher ('Bash', 'Edit|Write', …). Absent = matches all tools.
15884
+ matcher: external_exports.string().optional(),
15885
+ command: external_exports.string().min(1),
15886
+ timeout: external_exports.number().optional(),
15887
+ scope: ConfigScope,
15888
+ pluginName: external_exports.string().optional(),
15889
+ // The settings file / hooks.json the entry came from.
15890
+ location: external_exports.string().optional()
16003
15891
  });
16004
- var AssetDetail = AssetSummary.extend({
16005
- /** string | null null when no description is available. */
16006
- description: external_exports.string().nullable(),
16007
- /** trustLevel | null — null for non-MCP assets. */
16008
- trust: TrustLevel.nullable(),
16009
- /** Type-specific raw key/values — FE renders the grid. */
16010
- meta: external_exports.record(external_exports.string(), external_exports.unknown()),
16011
- /** always present object when there is an active finding, null when absent. */
16012
- finding: AssetFindingRef.nullable(),
16013
- /** MCP exposed-tools list — omitted for non-mcp. */
16014
- tools: external_exports.array(McpTool).optional()
16015
- }).meta({ id: "AssetDetail" });
16016
- var ListProjectsResponse = external_exports.object({ items: external_exports.array(ProjectSummary) }).meta({ id: "ListProjectsResponse" });
16017
- var InventoryStats = external_exports.object({
16018
- /** Total assets/projects with ≥1 flag or finding (drives the attention header chip). */
16019
- attention: external_exports.number().int().nonnegative(),
16020
- byType: external_exports.object({
16021
- project: external_exports.number().int().nonnegative(),
16022
- skill: external_exports.number().int().nonnegative(),
16023
- mcp: external_exports.number().int().nonnegative(),
16024
- hook: external_exports.number().int().nonnegative(),
16025
- config: external_exports.number().int().nonnegative()
16026
- }),
16027
- harnesses: external_exports.number().int().nonnegative(),
16028
- mcpTrust: external_exports.object({
16029
- "known-good": external_exports.number().int().nonnegative(),
16030
- risky: external_exports.number().int().nonnegative(),
16031
- unapproved: external_exports.number().int().nonnegative()
16032
- })
16033
- }).meta({ id: "InventoryStats" });
16034
- var FileSummary = external_exports.object({
16035
- path: external_exports.string(),
16036
- name: external_exports.string(),
16037
- origin: Origin,
16038
- /** Effective access (override applied). */
16039
- access: AccessLevel,
16040
- /** True when a file_access_override differs from the computed default. */
16041
- isCustom: external_exports.boolean(),
16042
- findings: external_exports.number().int().nonnegative(),
16043
- /** When the file was auto-blocked by a detection; null when not blocked. */
16044
- blockedAt: external_exports.iso.datetime().nullable().optional(),
16045
- /** Why the file was blocked; null when absent. */
16046
- note: external_exports.string().nullable().optional()
16047
- }).meta({ id: "FileSummary" });
16048
- var FolderSummary = external_exports.object({
16049
- name: external_exports.string(),
16050
- path: external_exports.string(),
16051
- /** Rollup of effective access across all descendants. */
16052
- accessCounts: AccessCounts
16053
- }).meta({ id: "FolderSummary" });
16054
- var ProjectTreeResponse = external_exports.object({
16055
- project: external_exports.object({
16056
- id: external_exports.string(),
16057
- repo: external_exports.string(),
16058
- visibility: Visibility
16059
- }),
16060
- path: external_exports.string(),
16061
- /** Browse mode: one-level folders at the current path. Omitted in search mode. */
16062
- folders: external_exports.array(FolderSummary).optional(),
16063
- files: external_exports.array(FileSummary)
16064
- }).meta({ id: "ProjectTreeResponse" });
16065
- var FileDetail = FileSummary.extend({
16066
- project: external_exports.object({
16067
- repo: external_exports.string(),
16068
- visibility: Visibility,
16069
- language: external_exports.string(),
16070
- policyDefault: AccessLevel,
16071
- updatedAt: external_exports.iso.datetime()
16072
- }),
16073
- findingsRefs: external_exports.array(external_exports.object({ id: external_exports.string(), title: external_exports.string() }))
16074
- }).meta({ id: "FileDetail" });
16075
- var SetFileAccessBody = external_exports.object({
16076
- path: external_exports.string(),
16077
- access: AccessLevel
16078
- }).meta({ id: "SetFileAccessBody" });
16079
- var SetFileAccessResponse = external_exports.object({
16080
- file: FileSummary,
16081
- accessCounts: AccessCounts
16082
- }).meta({ id: "SetFileAccessResponse" });
16083
- var SetMcpTrustBody = external_exports.object({ trust: TrustLevel }).meta({ id: "SetMcpTrustBody" });
16084
- var HarnessEventItem = external_exports.object({
16085
- kind: HarnessEventKind,
16086
- title: external_exports.string(),
16087
- detail: external_exports.string(),
16088
- occurredAt: external_exports.iso.datetime(),
16089
- findingId: external_exports.string().nullable().optional()
16090
- }).meta({ id: "HarnessEventItem" });
16091
- var HarnessEventsResponse = external_exports.object({
16092
- counts: external_exports.object({
16093
- block: external_exports.number().int().nonnegative(),
16094
- redact: external_exports.number().int().nonnegative(),
16095
- warn: external_exports.number().int().nonnegative()
16096
- }),
16097
- items: external_exports.array(HarnessEventItem)
16098
- }).meta({ id: "HarnessEventsResponse" });
16099
- var RescanResponse = external_exports.object({
16100
- jobId: external_exports.string(),
16101
- startedAt: external_exports.iso.datetime()
16102
- }).meta({ id: "RescanResponse" });
16103
- var ConnectProjectBody = external_exports.object({ repo: external_exports.string() }).meta({ id: "ConnectProjectBody" });
16104
- var ListAssetsQuery = external_exports.object({
16105
- /** Filter by one or more AssetType values; absent means all types. */
16106
- type: external_exports.array(AssetType).optional(),
16107
- /** Free-text search term. */
16108
- q: external_exports.string().optional()
16109
- });
16110
- var GetProjectTreeQuery = external_exports.object({
16111
- /** Subtree root path; defaults to repository root when absent. */
16112
- path: external_exports.string().optional(),
16113
- /** Free-text filter applied to file paths. */
16114
- q: external_exports.string().optional(),
16115
- /**
16116
- * Special listing mode. `blocked` returns every effectively-blocked, auto-blocked
16117
- * file across the whole repo (folders omitted, most-recent first), ignoring
16118
- * `path`/`q` — powers the project-wide "recently blocked" strip.
16119
- */
16120
- filter: external_exports.enum(["blocked"]).optional()
15892
+ var McpServerScanEntry = external_exports.object({
15893
+ // The server's config key ("github", "filesystem", …) identity, with the
15894
+ // qualified scope (see mcpServerIdentityKey).
15895
+ name: external_exports.string().min(1),
15896
+ scope: ConfigScope,
15897
+ pluginName: external_exports.string().optional(),
15898
+ // The owning plugin's marketplace — part of PLUGIN-scope identity: two
15899
+ // marketplaces can each ship a plugin named `guard`, and without this their
15900
+ // same-named servers would collapse to one row (the second silently dropped,
15901
+ // inheriting the first's trust).
15902
+ marketplace: external_exports.string().optional(),
15903
+ // The repo identity (remote url, or the cwd for un-remoted repos) — part of
15904
+ // PROJECT/LOCAL-scope identity: a server named `github` in repo A and one in
15905
+ // repo B are different servers with different commands, and MUST NOT share a
15906
+ // row a shared row would let a cloned repo's .mcp.json inherit the trust
15907
+ // the user granted elsewhere.
15908
+ project: external_exports.string().optional(),
15909
+ // 'stdio' when the entry carries a command; otherwise the config's `type`
15910
+ // ('http' / 'sse' / …). Open string — the transport set is harness-defined.
15911
+ transport: external_exports.string().min(1),
15912
+ // Volatile on purpose (unlike hook `command`): a changed command/url is drift
15913
+ // on a stable row — visible across config_scan snapshots and preserving the
15914
+ // user's trust decision — never a quiet new row. One of the two is present.
15915
+ // Secret-masked at collection time (the scanner runs the bundled detection
15916
+ // packs over both — tokens routinely ride command args and URLs).
15917
+ command: external_exports.string().optional(),
15918
+ url: external_exports.string().optional(),
15919
+ // Env var NAMES only, never values (the no-secrets rule).
15920
+ envKeys: external_exports.array(external_exports.string()).optional(),
15921
+ // The config file the entry came from.
15922
+ location: external_exports.string().optional()
16121
15923
  });
16122
- var GetProjectFileQuery = external_exports.object({
16123
- /** Repository-relative file path; absent or empty 400. */
16124
- path: external_exports.string()
15924
+ var ConfigFileScanEntry = external_exports.object({
15925
+ // Basename (settings.json, CLAUDE.md) or dir name (commands/, agents/).
15926
+ name: external_exports.string().min(1),
15927
+ // The absolute path — identity (with scope) and the promoted `location`.
15928
+ path: external_exports.string().min(1),
15929
+ scope: ConfigScope,
15930
+ // Human label: "User settings", "Project memory", "Slash commands", …
15931
+ kind: external_exports.string().min(1),
15932
+ // Derived SHAPE summary — top-level key names, entry counts, line counts.
15933
+ // Never file content or values (memory files can carry sensitive detail).
15934
+ detail: external_exports.string().optional(),
15935
+ // Dir configs (commands/, agents/) and .mcp.json: how many entries.
15936
+ entryCount: external_exports.number().optional(),
15937
+ // File mtime (ISO) — the freshness signal.
15938
+ updatedAt: external_exports.iso.datetime().optional()
16125
15939
  });
16126
- var GetHarnessEventsQuery = external_exports.object({
16127
- /** Maximum number of events to return. Range: 1–50; default: 7. */
16128
- limit: external_exports.coerce.number().int().min(1).max(50).default(7)
15940
+ var ConfigScanResult = external_exports.object({
15941
+ scannedAt: external_exports.iso.datetime(),
15942
+ skills: external_exports.array(SkillScanEntry),
15943
+ hooks: external_exports.array(HookScanEntry),
15944
+ mcpServers: external_exports.array(McpServerScanEntry),
15945
+ configFiles: external_exports.array(ConfigFileScanEntry),
15946
+ errors: external_exports.array(external_exports.object({ source: external_exports.string(), reason: external_exports.string() }))
16129
15947
  });
16130
-
16131
- // ../../packages/schema/src/zod/exception.ts
16132
- var ExceptionScope = external_exports.enum(["once", "temporary", "permanent"]);
16133
- var ExceptionConditions = external_exports.object({
16134
- repo: external_exports.string().optional(),
16135
- sourceTool: external_exports.string().optional(),
16136
- provider: external_exports.string().optional()
16137
- }).strict();
16138
- var ExceptionCapability = external_exports.enum(["suppress", "reveal_to_model"]);
16139
- var DetectionException = external_exports.object({
16140
- id: external_exports.guid(),
16141
- ruleId: external_exports.string(),
16142
- // Denormalized from the rule, for reporting — never matched on.
16143
- category: DetectionCategory,
16144
- // HMAC-SHA256 hex of the raw match under a machine-local key: a KEYED
16145
- // fingerprint, never the raw value, and never reversible. Matching recomputes
16146
- // the fingerprint from a fresh capture; the value itself is never stored.
16147
- // Shape-constrained so a malformed — or accidentally raw — value is rejected
16148
- // at the boundary rather than persisted.
16149
- valueFingerprint: external_exports.string().regex(/^[0-9a-f]{64}$/),
16150
- // Version of the fingerprint key the grant was written under; a rotated key
16151
- // invalidates old grants rather than silently mismatching them.
16152
- keyVersion: external_exports.number().int().positive(),
16153
- // maskMatch() preview of the approved value — never the raw value.
16154
- maskedValue: external_exports.string(),
16155
- capability: ExceptionCapability.default("suppress"),
16156
- scope: ExceptionScope,
16157
- expiresAt: external_exports.iso.datetime().nullable(),
16158
- maxUses: external_exports.number().int().positive().nullable(),
16159
- useCount: external_exports.number().int().nonnegative(),
16160
- lastUsedAt: external_exports.iso.datetime().nullable(),
16161
- // Mandatory: every grant carries the human reason it exists.
16162
- justification: external_exports.string().min(1),
16163
- conditions: ExceptionConditions.nullable(),
16164
- createdBy: external_exports.string(),
16165
- createdVia: external_exports.enum(["cli-approve", "cli-add", "web-approve", "web-add", "api", "setup-triage"]),
16166
- createdAt: external_exports.iso.datetime(),
16167
- updatedAt: external_exports.iso.datetime(),
16168
- // Revocation is terminal and retained — consumed/expired/revoked rows are
16169
- // audit evidence; nothing in the exception lifecycle hard-deletes.
16170
- revokedAt: external_exports.iso.datetime().nullable(),
16171
- revokedBy: external_exports.string().nullable(),
16172
- revokeReason: external_exports.string().nullable()
15948
+ var ConfigPostureFindingInput = external_exports.object({
15949
+ ruleId: external_exports.string().min(1),
15950
+ version: external_exports.string().min(1),
15951
+ span: Span,
15952
+ // For posture rules this is the offending COMMAND (config the user already
15953
+ // holds locally, not captured secret content) — it is also the correlation
15954
+ // key the read surface matches back to a hook row.
15955
+ maskedMatch: external_exports.string(),
15956
+ actionTaken: ActionTaken,
15957
+ confidence: external_exports.number().min(0).max(1)
16173
15958
  });
16174
- var ExceptionBundleEntry = DetectionException.pick({
16175
- id: true,
16176
- ruleId: true,
16177
- valueFingerprint: true,
16178
- keyVersion: true,
16179
- capability: true,
16180
- expiresAt: true,
16181
- maxUses: true,
16182
- useCount: true,
16183
- conditions: true
15959
+ var ConfigScanRecord = external_exports.object({
15960
+ items: external_exports.array(InventoryInput),
15961
+ scanEvent: AuditEventInput,
15962
+ definitions: external_exports.array(InspectionDefinitionInput).optional(),
15963
+ findings: external_exports.array(ConfigPostureFindingInput).optional()
16184
15964
  });
16185
- var ExceptionDescriptor = DetectionException.omit({ valueFingerprint: true });
15965
+
15966
+ // ../../packages/schema/src/zod/registry.ts
15967
+ var Namespace = external_exports.string().regex(/^[a-z][a-z0-9-]*$/);
15968
+ var PackId = external_exports.string().regex(/^[a-z][a-z0-9-]*$/);
15969
+ var SemVer = external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-.]+)?$/);
15970
+ var PublisherKind = external_exports.enum(["labs", "user", "org"]);
16186
15971
 
16187
15972
  // ../../packages/schema/src/zod/rule.ts
16188
- var MatcherType = external_exports.enum(["keyword", "regex", "validator"]).meta({ id: "MatcherType" });
15973
+ var MatcherType = external_exports.enum(["keyword", "regex"]).meta({ id: "MatcherType" });
16189
15974
  var RuleProbeVerdict = external_exports.enum(["safe", "quarantined"]).meta({ id: "RuleProbeVerdict" });
16190
- var KeywordMatcher = external_exports.object({
15975
+ var KeywordMatcher = external_exports.strictObject({
16191
15976
  type: external_exports.literal("keyword"),
16192
15977
  // An empty keyword matches at every position, yielding one zero-length span
16193
15978
  // per character. Rejected here because a keyword that matches everything is
@@ -16203,16 +15988,31 @@ function isValidRegex(pattern, flags) {
16203
15988
  return false;
16204
15989
  }
16205
15990
  }
15991
+ function probeFlags(flags) {
15992
+ return flags.replace(/[gy]/g, "");
15993
+ }
16206
15994
  function matchesEmptyString(pattern, flags) {
16207
15995
  try {
16208
- const re = new RegExp(pattern, flags.replace(/[gy]/g, ""));
15996
+ const re = new RegExp(pattern, probeFlags(flags));
16209
15997
  return re.exec("")?.[0].length === 0;
16210
15998
  } catch {
16211
15999
  return false;
16212
16000
  }
16213
16001
  }
16002
+ function spansWholeMatch(captureGroup) {
16003
+ return captureGroup === void 0 || captureGroup === 0;
16004
+ }
16005
+ function captureGroupCount(pattern, flags) {
16006
+ try {
16007
+ const probe = new RegExp(`${pattern}|`, probeFlags(flags));
16008
+ const result = probe.exec("");
16009
+ return result ? result.length - 1 : void 0;
16010
+ } catch {
16011
+ return void 0;
16012
+ }
16013
+ }
16214
16014
  var MAX_PATTERN_LENGTH = 2e3;
16215
- var RegexMatcher = external_exports.object({
16015
+ var RegexMatcher = external_exports.strictObject({
16216
16016
  type: external_exports.literal("regex"),
16217
16017
  pattern: external_exports.string().min(1).max(MAX_PATTERN_LENGTH),
16218
16018
  flags: external_exports.string().default("gi"),
@@ -16220,28 +16020,47 @@ var RegexMatcher = external_exports.object({
16220
16020
  }).refine((v) => isValidRegex(v.pattern, v.flags), {
16221
16021
  message: "pattern/flags do not form a valid JavaScript regular expression",
16222
16022
  path: ["pattern"]
16223
- }).refine((v) => v.captureGroup !== void 0 || !matchesEmptyString(v.pattern, v.flags), {
16023
+ }).refine((v) => !spansWholeMatch(v.captureGroup) || !matchesEmptyString(v.pattern, v.flags), {
16224
16024
  message: 'a whole-match regex that can match the empty string (e.g. "\\d*", "a?", "(?:)") can hang the matcher \u2014 scope the quantifier to a captureGroup, or require at least one character',
16225
16025
  path: ["pattern"]
16026
+ }).superRefine((v, ctx) => {
16027
+ if (v.captureGroup === void 0) return;
16028
+ const groups = captureGroupCount(v.pattern, v.flags);
16029
+ if (groups === void 0 || v.captureGroup <= groups) return;
16030
+ ctx.addIssue({
16031
+ code: "custom",
16032
+ path: ["captureGroup"],
16033
+ message: `captureGroup ${String(v.captureGroup)} is out of range \u2014 the pattern declares ${String(groups)} capture group(s), so valid values are 0-${String(groups)}. An out-of-range group never matches, which would make the rule silently never fire.`
16034
+ });
16226
16035
  });
16227
- var ValidatorMatcher = external_exports.object({
16228
- type: external_exports.literal("validator"),
16229
- name: external_exports.enum(["luhn", "entropy", "ssn-checksum"]),
16230
- config: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16231
- });
16232
- var Matcher = external_exports.discriminatedUnion("type", [KeywordMatcher, RegexMatcher, ValidatorMatcher]).meta({ id: "Matcher" });
16233
- var AppliesTo = external_exports.object({
16036
+ var Matcher = external_exports.discriminatedUnion("type", [KeywordMatcher, RegexMatcher]).meta({ id: "Matcher" });
16037
+ var MATCHER_TYPES = MatcherType.options;
16038
+ var AppliesTo = external_exports.strictObject({
16234
16039
  // Dot-prefixed, e.g. ".py" — matches the scanner's SOURCE_EXTENSIONS shape.
16235
16040
  extensions: external_exports.array(external_exports.string().regex(/^\.[A-Za-z0-9]+$/)).min(1)
16236
16041
  }).meta({ id: "AppliesTo" });
16237
- var PostValidatorRef = external_exports.union([
16238
- external_exports.string(),
16239
- external_exports.object({
16240
- name: external_exports.string(),
16241
- config: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16242
- })
16243
- ]).meta({ id: "PostValidatorRef" });
16244
- var RequiresNearby = external_exports.object({
16042
+ var PostValidatorName = external_exports.enum(["entropy", "luhn"]).meta({ id: "PostValidatorName" });
16043
+ var PostValidatorRef = external_exports.union(
16044
+ [
16045
+ PostValidatorName,
16046
+ external_exports.strictObject({
16047
+ name: PostValidatorName,
16048
+ config: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16049
+ })
16050
+ ],
16051
+ {
16052
+ // A union reports one collapsed issue for every way its arms can fail, so
16053
+ // this has to describe the whole shape rather than just the name — it is
16054
+ // what an author sees for a misspelled name AND for a stray key in the
16055
+ // object form. The names come from the enum so the message cannot go
16056
+ // stale. Without it Zod says only "Invalid input", which is precisely the
16057
+ // no-feedback outcome this schema exists to remove.
16058
+ error: () => `not a valid post-validator: use a bare name (${PostValidatorName.options.map((name) => JSON.stringify(name)).join(
16059
+ " or "
16060
+ )}) or { "name": ..., "config": { ... } }. An unrecognized name would be a false-positive guard that never runs.`
16061
+ }
16062
+ ).meta({ id: "PostValidatorRef" });
16063
+ var RequiresNearby = external_exports.strictObject({
16245
16064
  // Each array, when present, must be non-empty and contain non-empty strings —
16246
16065
  // an empty/blank criterion would either never fire or (for labels) match
16247
16066
  // everything.
@@ -16256,16 +16075,23 @@ var RequiresNearby = external_exports.object({
16256
16075
  (v) => (v.categories?.length ?? 0) + (v.ruleIds?.length ?? 0) + (v.labels?.length ?? 0) > 0,
16257
16076
  { message: "requiresNearby needs at least one of categories, ruleIds, or labels" }
16258
16077
  ).meta({ id: "RequiresNearby" });
16259
- var RuleFixture = external_exports.object({
16078
+ var RuleFixture = external_exports.strictObject({
16260
16079
  label: external_exports.string(),
16261
16080
  text: external_exports.string().max(5e4),
16262
16081
  shouldMatch: external_exports.boolean(),
16263
16082
  // Simulated file context for the scan, so fixtures can assert `appliesTo`
16264
16083
  // gating (e.g. a Python-only pattern must NOT fire in a .ts file).
16265
16084
  filePath: external_exports.string().optional(),
16266
- expectedSpans: external_exports.array(external_exports.object({ start: external_exports.number(), end: external_exports.number() })).optional()
16085
+ expectedSpans: external_exports.array(external_exports.strictObject({ start: external_exports.number(), end: external_exports.number() })).optional()
16267
16086
  }).meta({ id: "RuleFixture" });
16268
- var Rule = external_exports.object({
16087
+ var Rule = external_exports.strictObject({
16088
+ // A pinned literal over a STRICT object, and the two together decide how this
16089
+ // format may grow. A rule carrying a key not listed below is refused with
16090
+ // `unrecognized_keys`; a rule declaring `specVersion: 2` is refused with
16091
+ // `invalid_value`. So the only additive path is adding an OPTIONAL field here
16092
+ // — that keeps every rule authored before it valid — and a rule author has no
16093
+ // way to introduce a field of their own or to opt into a later version.
16094
+ // Widening the format means changing this literal and every consumer of it.
16269
16095
  specVersion: external_exports.literal(1),
16270
16096
  // `packId/ruleName` (e.g. `secrets/aws-access-key`). NOTE the first segment is
16271
16097
  // the PACK id, NOT a namespace — this is a DIFFERENT slug space from a
@@ -16301,293 +16127,6 @@ var PackManifest = external_exports.object({
16301
16127
  sourceUrl: external_exports.url().optional()
16302
16128
  }).meta({ id: "PackManifest" });
16303
16129
 
16304
- // ../../packages/schema/src/zod/policy.ts
16305
- var PolicyScope = external_exports.enum(["global", "repo", "user"]).meta({ id: "PolicyScope" });
16306
- var PolicyTarget = external_exports.union([external_exports.object({ ruleId: external_exports.string() }), external_exports.object({ category: DetectionCategory })]).meta({ id: "PolicyTarget" });
16307
- var Policy = external_exports.object({
16308
- id: external_exports.guid(),
16309
- scope: PolicyScope,
16310
- target: PolicyTarget,
16311
- action: ActionTaken,
16312
- enabled: external_exports.boolean().default(true),
16313
- customKeywords: external_exports.array(external_exports.string()).optional(),
16314
- // Display name — optional so older policy rows without name still parse.
16315
- // Added for the findings API (policy.name column migration).
16316
- name: external_exports.string().optional()
16317
- }).meta({ id: "Policy" });
16318
- var PolicyBundle = external_exports.object({
16319
- version: external_exports.string(),
16320
- policies: external_exports.array(Policy),
16321
- // Rules from the installed marketplace packs (snapshotted by the
16322
- // control plane). The plugin registers these in addition to its bundled
16323
- // packs. Optional so older backends — and older on-disk caches — that omit
16324
- // the field still parse; consumers read `bundle.rules ?? []`.
16325
- rules: external_exports.array(Rule).optional(),
16326
- // When true, `rules` IS the complete effective ruleset and the runtime must
16327
- // NOT merge its compiled-in bundled packs — the standalone gateway sets this
16328
- // after reading the user's installed snapshot (installed_packs, enabled
16329
- // packs only), which is how detection updates stay manual: new bundled
16330
- // rules run only after the user applies the pack update. Absent/false keeps
16331
- // the historical composition (bundled packs + rules) — older caches.
16332
- rulesComplete: external_exports.boolean().optional(),
16333
- // Active detection exceptions, evaluation subset only (see
16334
- // ExceptionBundleEntry). Optional so older bundle producers — and older
16335
- // on-disk caches — that omit the field still parse; consumers read
16336
- // `bundle.exceptions ?? []`.
16337
- exceptions: external_exports.array(ExceptionBundleEntry).optional(),
16338
- // Installed pack version, keyed by ruleId, for rules in `rules` that came
16339
- // from a versioned installed pack. Optional so older backends — and older
16340
- // on-disk caches — that omit the field still parse; consumers fall back to
16341
- // the rule's own spec version. NOT the bundle version above — see
16342
- // installedRuleset's ruleVersions for the source of truth.
16343
- ruleVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
16344
- customKeywords: external_exports.array(external_exports.string()),
16345
- fetchedAt: external_exports.iso.datetime()
16346
- }).meta({ id: "PolicyBundle" });
16347
- var OBSERVE_ONLY_CATEGORIES = ["config"];
16348
- var ENFORCEABLE_CATEGORIES = DetectionCategory.options.filter((c) => !OBSERVE_ONLY_CATEGORIES.includes(c));
16349
- var CATEGORY_PEAK_SEVERITY = {
16350
- secret: "critical",
16351
- financial: "critical",
16352
- // core-financial/credit-card
16353
- code_flaw: "critical",
16354
- pii: "high",
16355
- phi: "high",
16356
- custom: "high",
16357
- // user-defined; conservative
16358
- code_context: "low",
16359
- config: "low"
16360
- // observe-only; floors to monitor regardless
16361
- };
16362
- function severityFloorPolicy(category) {
16363
- if (OBSERVE_ONLY_CATEGORIES.includes(category)) return "monitor";
16364
- const peak = CATEGORY_PEAK_SEVERITY[category];
16365
- return peak === "critical" || peak === "high" ? "warn" : "monitor";
16366
- }
16367
- function severityFloorPosture() {
16368
- const out = {};
16369
- for (const c of DetectionCategory.options) out[c] = severityFloorPolicy(c);
16370
- return out;
16371
- }
16372
- var PolicyKind = external_exports.enum(["builtin", "custom"]).meta({ id: "PolicyKind" });
16373
- var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "block"];
16374
- var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
16375
- var BUILTIN_ORDER = KNOWN_BUILTIN_IDS;
16376
- var BUILTIN_POLICY_SPECS = {
16377
- monitor: {
16378
- name: "Monitor",
16379
- action: "log",
16380
- description: "Log every match for audit. The request is allowed through untouched."
16381
- },
16382
- warn: {
16383
- name: "Warn",
16384
- action: "warn",
16385
- description: "Allow the request, but warn the user inline before it is sent."
16386
- },
16387
- redact: {
16388
- name: "Redact",
16389
- action: "redact",
16390
- description: "Automatically strip the matched value from the request, then continue."
16391
- },
16392
- block: {
16393
- name: "Block",
16394
- action: "block",
16395
- description: "Refuse the request entirely whenever any rule in this detection matches."
16396
- }
16397
- };
16398
- function builtinPolicyToAction(id) {
16399
- return BUILTIN_POLICY_SPECS[id].action;
16400
- }
16401
- var DEFAULT_ACTIONS = Object.fromEntries(
16402
- DetectionCategory.options.map((c) => [c, builtinPolicyToAction(severityFloorPolicy(c))])
16403
- );
16404
- var BUILTIN_POLICIES = Object.fromEntries(
16405
- KNOWN_BUILTIN_IDS.map((id) => [id, { id, ...BUILTIN_POLICY_SPECS[id] }])
16406
- );
16407
- var UsedByItem = external_exports.object({
16408
- id: external_exports.string(),
16409
- name: external_exports.string(),
16410
- ruleCount: external_exports.number().int().nonnegative(),
16411
- enabled: external_exports.boolean()
16412
- }).meta({ id: "UsedByItem" });
16413
- var PolicyListItem = external_exports.object({
16414
- id: external_exports.string(),
16415
- kind: PolicyKind,
16416
- name: external_exports.string(),
16417
- enabled: external_exports.boolean(),
16418
- usedByCount: external_exports.number().int().nonnegative()
16419
- }).meta({ id: "PolicyListItem" });
16420
- var PolicyDetail = external_exports.object({
16421
- specVersion: external_exports.literal(1),
16422
- id: external_exports.string(),
16423
- kind: PolicyKind,
16424
- name: external_exports.string(),
16425
- enabled: external_exports.boolean(),
16426
- description: external_exports.string(),
16427
- usedBy: external_exports.array(UsedByItem)
16428
- }).meta({ id: "PolicyDetail" });
16429
- var PolicyStatsResponse = external_exports.object({
16430
- policies: external_exports.number().int().nonnegative(),
16431
- builtin: external_exports.number().int().nonnegative(),
16432
- custom: external_exports.number().int().nonnegative(),
16433
- detectionsGoverned: external_exports.number().int().nonnegative()
16434
- }).meta({ id: "PolicyStatsResponse" });
16435
-
16436
- // ../../packages/schema/src/zod/api.ts
16437
- var LIST_QUERY_MAX_LIMIT = 200;
16438
- var ListEventsQuery = external_exports.object({
16439
- cursor: external_exports.string().optional(),
16440
- limit: external_exports.coerce.number().int().min(1).max(LIST_QUERY_MAX_LIMIT).default(50),
16441
- sourceTool: external_exports.string().optional(),
16442
- kind: external_exports.string().optional(),
16443
- from: external_exports.iso.datetime().optional(),
16444
- to: external_exports.iso.datetime().optional()
16445
- });
16446
- var ListEventsResponse = external_exports.object({
16447
- items: external_exports.array(Event),
16448
- nextCursor: external_exports.string().nullable()
16449
- }).meta({ id: "ListEventsResponse" });
16450
- var IngestResponse = external_exports.object({
16451
- accepted: external_exports.number().int().nonnegative(),
16452
- duplicates: external_exports.number().int().nonnegative()
16453
- }).meta({ id: "IngestResponse" });
16454
- var ListFindingsQuery = external_exports.object({
16455
- cursor: external_exports.string().optional(),
16456
- limit: external_exports.coerce.number().int().min(1).max(LIST_QUERY_MAX_LIMIT).default(50),
16457
- severity: external_exports.string().optional(),
16458
- category: external_exports.string().optional(),
16459
- eventId: external_exports.guid().optional()
16460
- });
16461
- var ListFindingsResponse = external_exports.object({
16462
- items: external_exports.array(Finding),
16463
- nextCursor: external_exports.string().nullable()
16464
- }).meta({ id: "ListFindingsResponse" });
16465
- var ListPoliciesResponse = external_exports.object({ items: external_exports.array(PolicyListItem) }).meta({ id: "ListPoliciesResponse" });
16466
- var CreatePolicyRequest = Policy.omit({ id: true }).meta({
16467
- id: "CreatePolicyRequest"
16468
- });
16469
- var UpdatePolicyRequest = Policy.partial().required({ id: true }).meta({ id: "UpdatePolicyRequest" });
16470
- var RecordAuditEventResponse = external_exports.object({ accepted: external_exports.boolean() }).meta({ id: "RecordAuditEventResponse" });
16471
- var ErrorResponse = external_exports.object({
16472
- error: external_exports.object({
16473
- code: external_exports.string(),
16474
- message: external_exports.string(),
16475
- details: external_exports.unknown().optional()
16476
- })
16477
- }).meta({ id: "ErrorResponse" });
16478
-
16479
- // ../../packages/schema/src/zod/config-inventory.ts
16480
- var ConfigScope = external_exports.enum(["user", "project", "local", "plugin"]);
16481
- var SkillScanEntry = external_exports.object({
16482
- name: external_exports.string().min(1),
16483
- // The identity source: a marketplace repo for plugin skills (e.g.
16484
- // 'anthropics/skills'), 'local' for personal ~/.claude/skills, or
16485
- // 'project:<repo-identity>' for checked-in project skills. The surrogate keeps
16486
- // a personal skill named 'pdf' from colliding with the marketplace 'pdf'.
16487
- source: external_exports.string().min(1),
16488
- scope: ConfigScope,
16489
- pluginName: external_exports.string().optional(),
16490
- // Volatile — rides the attribute bag, never the identity hash.
16491
- version: external_exports.string().optional(),
16492
- description: external_exports.string().optional(),
16493
- // Skill directory mtime (ISO) — the "updated Nd ago" freshness signal.
16494
- updatedAt: external_exports.iso.datetime().optional(),
16495
- // Filesystem path — the promoted inventory `location` column.
16496
- location: external_exports.string().optional()
16497
- });
16498
- var HookScanEntry = external_exports.object({
16499
- // Hook event name (PreToolUse, PostToolUse, …). Open string, not an enum: the
16500
- // set is harness-defined and grows without a schema change.
16501
- event: external_exports.string().min(1),
16502
- // The tool matcher ('Bash', 'Edit|Write', …). Absent = matches all tools.
16503
- matcher: external_exports.string().optional(),
16504
- command: external_exports.string().min(1),
16505
- timeout: external_exports.number().optional(),
16506
- scope: ConfigScope,
16507
- pluginName: external_exports.string().optional(),
16508
- // The settings file / hooks.json the entry came from.
16509
- location: external_exports.string().optional()
16510
- });
16511
- var McpServerScanEntry = external_exports.object({
16512
- // The server's config key ("github", "filesystem", …) — identity, with the
16513
- // qualified scope (see mcpServerIdentityKey).
16514
- name: external_exports.string().min(1),
16515
- scope: ConfigScope,
16516
- pluginName: external_exports.string().optional(),
16517
- // The owning plugin's marketplace — part of PLUGIN-scope identity: two
16518
- // marketplaces can each ship a plugin named `guard`, and without this their
16519
- // same-named servers would collapse to one row (the second silently dropped,
16520
- // inheriting the first's trust).
16521
- marketplace: external_exports.string().optional(),
16522
- // The repo identity (remote url, or the cwd for un-remoted repos) — part of
16523
- // PROJECT/LOCAL-scope identity: a server named `github` in repo A and one in
16524
- // repo B are different servers with different commands, and MUST NOT share a
16525
- // row — a shared row would let a cloned repo's .mcp.json inherit the trust
16526
- // the user granted elsewhere.
16527
- project: external_exports.string().optional(),
16528
- // 'stdio' when the entry carries a command; otherwise the config's `type`
16529
- // ('http' / 'sse' / …). Open string — the transport set is harness-defined.
16530
- transport: external_exports.string().min(1),
16531
- // Volatile on purpose (unlike hook `command`): a changed command/url is drift
16532
- // on a stable row — visible across config_scan snapshots and preserving the
16533
- // user's trust decision — never a quiet new row. One of the two is present.
16534
- // Secret-masked at collection time (the scanner runs the bundled detection
16535
- // packs over both — tokens routinely ride command args and URLs).
16536
- command: external_exports.string().optional(),
16537
- url: external_exports.string().optional(),
16538
- // Env var NAMES only, never values (the no-secrets rule).
16539
- envKeys: external_exports.array(external_exports.string()).optional(),
16540
- // The config file the entry came from.
16541
- location: external_exports.string().optional()
16542
- });
16543
- var ConfigFileScanEntry = external_exports.object({
16544
- // Basename (settings.json, CLAUDE.md) or dir name (commands/, agents/).
16545
- name: external_exports.string().min(1),
16546
- // The absolute path — identity (with scope) and the promoted `location`.
16547
- path: external_exports.string().min(1),
16548
- scope: ConfigScope,
16549
- // Human label: "User settings", "Project memory", "Slash commands", …
16550
- kind: external_exports.string().min(1),
16551
- // Derived SHAPE summary — top-level key names, entry counts, line counts.
16552
- // Never file content or values (memory files can carry sensitive detail).
16553
- detail: external_exports.string().optional(),
16554
- // Dir configs (commands/, agents/) and .mcp.json: how many entries.
16555
- entryCount: external_exports.number().optional(),
16556
- // File mtime (ISO) — the freshness signal.
16557
- updatedAt: external_exports.iso.datetime().optional()
16558
- });
16559
- var ConfigScanResult = external_exports.object({
16560
- scannedAt: external_exports.iso.datetime(),
16561
- skills: external_exports.array(SkillScanEntry),
16562
- hooks: external_exports.array(HookScanEntry),
16563
- mcpServers: external_exports.array(McpServerScanEntry),
16564
- configFiles: external_exports.array(ConfigFileScanEntry),
16565
- errors: external_exports.array(external_exports.object({ source: external_exports.string(), reason: external_exports.string() }))
16566
- });
16567
- var ConfigPostureFindingInput = external_exports.object({
16568
- ruleId: external_exports.string().min(1),
16569
- version: external_exports.string().min(1),
16570
- span: Span,
16571
- // For posture rules this is the offending COMMAND (config the user already
16572
- // holds locally, not captured secret content) — it is also the correlation
16573
- // key the read surface matches back to a hook row.
16574
- maskedMatch: external_exports.string(),
16575
- actionTaken: ActionTaken,
16576
- confidence: external_exports.number().min(0).max(1)
16577
- });
16578
- var ConfigScanRecord = external_exports.object({
16579
- items: external_exports.array(InventoryInput),
16580
- scanEvent: AuditEventInput,
16581
- definitions: external_exports.array(InspectionDefinitionInput).optional(),
16582
- findings: external_exports.array(ConfigPostureFindingInput).optional()
16583
- });
16584
-
16585
- // ../../packages/schema/src/zod/registry.ts
16586
- var Namespace = external_exports.string().regex(/^[a-z][a-z0-9-]*$/);
16587
- var PackId = external_exports.string().regex(/^[a-z][a-z0-9-]*$/);
16588
- var SemVer = external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-.]+)?$/);
16589
- var PublisherKind = external_exports.enum(["labs", "user", "org"]);
16590
-
16591
16130
  // ../../packages/schema/src/zod/detection.ts
16592
16131
  var OriginEnum = external_exports.enum(["library"]).meta({ id: "OriginEnum" });
16593
16132
  var DetectionFilterEnum = external_exports.enum(["all", "library", "custom", "customized", "updates"]);
@@ -16632,81 +16171,306 @@ var ListDetectionsQuery = external_exports.object({
16632
16171
  filter: DetectionFilterEnum.optional().default("all"),
16633
16172
  q: external_exports.string().optional()
16634
16173
  });
16635
- var DetectionStats = external_exports.object({
16636
- detections: external_exports.number().int().nonnegative(),
16637
- rules: external_exports.number().int().nonnegative(),
16638
- active: external_exports.number().int().nonnegative(),
16639
- findingsLast30d: external_exports.number().int().nonnegative()
16640
- }).meta({ id: "DetectionStats" });
16641
- var DetectionRule = external_exports.object({
16642
- id: external_exports.string(),
16643
- name: external_exports.string(),
16644
- category: DetectionCategory,
16645
- severity: Severity,
16646
- matcher: Matcher
16647
- }).meta({ id: "DetectionRule" });
16648
- var DetectionUpdate = external_exports.object({
16649
- available: external_exports.boolean(),
16650
- latestVersion: SemVer,
16651
- // Rule count of the latest snapshot. Lets the update UI show a meaningful
16652
- // delta ("2 rules → 14 rules") when the version did NOT change but the rule
16653
- // content did — the OSS store compares content, not just version. Optional:
16654
- // registry-backed updates omit it.
16655
- latestRuleCount: external_exports.number().int().nonnegative().optional()
16656
- }).nullable().meta({ id: "DetectionUpdate" });
16657
- var DetectionDetail = external_exports.object({
16658
- id: external_exports.string(),
16659
- name: external_exports.string(),
16660
- version: SemVer,
16661
- enabled: external_exports.boolean(),
16662
- origin: OriginEnum,
16663
- publisher: Namespace.optional(),
16664
- publisherKind: PublisherKind.optional(),
16665
- ruleCount: external_exports.number().int().nonnegative(),
16666
- namespace: Namespace,
16667
- packId: PackId,
16668
- description: external_exports.string().optional(),
16669
- editedAt: external_exports.iso.datetime(),
16670
- findingsLast30d: external_exports.number().int().nonnegative(),
16671
- latestVersion: SemVer.nullable().optional(),
16672
- update: DetectionUpdate,
16673
- rules: external_exports.array(DetectionRule),
16674
- modified: external_exports.boolean(),
16675
- // Per-pack enforcement-policy assignment. Holds a BuiltinPolicyId ARCHETYPE
16676
- // (monitor|warn|redact|block) — NOT a policies-table Policy.id guid; a
16677
- // detection is a PACK, and its policy is the archetype applied to all its
16678
- // rules. Absent == unassigned, which resolves to Monitor everywhere
16679
- // (DEFAULT_PACK_POLICY_ID). Every enforcement surface expands it into
16680
- // per-rule policies (see policyIdToAction). Typed z.string() (not
16681
- // the enum) to keep the OpenAPI response tolerant of a future custom id.
16682
- policyId: external_exports.string().optional()
16683
- }).meta({ id: "DetectionDetail" });
16684
- var LibraryItem = external_exports.object({
16685
- id: external_exports.string(),
16686
- name: external_exports.string(),
16687
- publisher: Namespace,
16688
- publisherKind: PublisherKind.optional(),
16689
- // LOSSY single-category view of a pack. A pack MAY span several categories;
16690
- // this carries only the canonical-first one for display. Do NOT filter/facet
16691
- // on it — the library filter matches a pack's full category set (see
16692
- // ListLibraryResponse.categories).
16693
- category: DetectionCategory.optional(),
16694
- version: SemVer,
16695
- ruleCount: external_exports.number().int().nonnegative(),
16696
- description: external_exports.string().optional(),
16697
- updatedAt: external_exports.iso.datetime(),
16698
- state: LibraryStateEnum,
16699
- importedAs: external_exports.string().nullable()
16700
- }).meta({ id: "LibraryItem" });
16701
- var ListLibraryResponse = external_exports.object({
16702
- categories: external_exports.array(DetectionCategory),
16703
- items: external_exports.array(LibraryItem)
16704
- }).meta({ id: "ListLibraryResponse" });
16705
- var ImportDetectionRequest = external_exports.object({
16706
- libraryId: external_exports.string().refine((v) => /^[^/]+\/[^/]+$/.test(v), {
16707
- message: "libraryId must be in namespace/packId format"
16708
- })
16709
- }).meta({ id: "ImportDetectionRequest" });
16174
+ var DetectionStats = external_exports.object({
16175
+ detections: external_exports.number().int().nonnegative(),
16176
+ rules: external_exports.number().int().nonnegative(),
16177
+ active: external_exports.number().int().nonnegative(),
16178
+ findingsLast30d: external_exports.number().int().nonnegative()
16179
+ }).meta({ id: "DetectionStats" });
16180
+ var DetectionRule = external_exports.object({
16181
+ id: external_exports.string(),
16182
+ name: external_exports.string(),
16183
+ category: DetectionCategory,
16184
+ severity: Severity,
16185
+ matcher: Matcher
16186
+ }).meta({ id: "DetectionRule" });
16187
+ var DetectionUpdate = external_exports.object({
16188
+ available: external_exports.boolean(),
16189
+ latestVersion: SemVer,
16190
+ // Rule count of the latest snapshot. Lets the update UI show a meaningful
16191
+ // delta ("2 rules → 14 rules") when the version did NOT change but the rule
16192
+ // content did — the OSS store compares content, not just version. Optional:
16193
+ // registry-backed updates omit it.
16194
+ latestRuleCount: external_exports.number().int().nonnegative().optional()
16195
+ }).nullable().meta({ id: "DetectionUpdate" });
16196
+ var DetectionDetail = external_exports.object({
16197
+ id: external_exports.string(),
16198
+ name: external_exports.string(),
16199
+ version: SemVer,
16200
+ enabled: external_exports.boolean(),
16201
+ origin: OriginEnum,
16202
+ publisher: Namespace.optional(),
16203
+ publisherKind: PublisherKind.optional(),
16204
+ ruleCount: external_exports.number().int().nonnegative(),
16205
+ namespace: Namespace,
16206
+ packId: PackId,
16207
+ description: external_exports.string().optional(),
16208
+ editedAt: external_exports.iso.datetime(),
16209
+ findingsLast30d: external_exports.number().int().nonnegative(),
16210
+ latestVersion: SemVer.nullable().optional(),
16211
+ update: DetectionUpdate,
16212
+ rules: external_exports.array(DetectionRule),
16213
+ modified: external_exports.boolean(),
16214
+ // Per-pack enforcement-policy assignment. Holds a BuiltinPolicyId ARCHETYPE
16215
+ // (monitor|warn|redact|block) — NOT a policies-table Policy.id guid; a
16216
+ // detection is a PACK, and its policy is the archetype applied to all its
16217
+ // rules. Absent == unassigned, which resolves to Monitor everywhere
16218
+ // (DEFAULT_PACK_POLICY_ID). Every enforcement surface expands it into
16219
+ // per-rule policies (see policyIdToAction). Typed z.string() (not
16220
+ // the enum) to keep the OpenAPI response tolerant of a future custom id.
16221
+ policyId: external_exports.string().optional()
16222
+ }).meta({ id: "DetectionDetail" });
16223
+ var LibraryItem = external_exports.object({
16224
+ id: external_exports.string(),
16225
+ name: external_exports.string(),
16226
+ publisher: Namespace,
16227
+ publisherKind: PublisherKind.optional(),
16228
+ // LOSSY single-category view of a pack. A pack MAY span several categories;
16229
+ // this carries only the canonical-first one for display. Do NOT filter/facet
16230
+ // on it — the library filter matches a pack's full category set (see
16231
+ // ListLibraryResponse.categories).
16232
+ category: DetectionCategory.optional(),
16233
+ version: SemVer,
16234
+ ruleCount: external_exports.number().int().nonnegative(),
16235
+ description: external_exports.string().optional(),
16236
+ updatedAt: external_exports.iso.datetime(),
16237
+ state: LibraryStateEnum,
16238
+ importedAs: external_exports.string().nullable()
16239
+ }).meta({ id: "LibraryItem" });
16240
+ var ListLibraryResponse = external_exports.object({
16241
+ categories: external_exports.array(DetectionCategory),
16242
+ items: external_exports.array(LibraryItem)
16243
+ }).meta({ id: "ListLibraryResponse" });
16244
+ var ImportDetectionRequest = external_exports.object({
16245
+ libraryId: external_exports.string().refine((v) => /^[^/]+\/[^/]+$/.test(v), {
16246
+ message: "libraryId must be in namespace/packId format"
16247
+ })
16248
+ }).meta({ id: "ImportDetectionRequest" });
16249
+
16250
+ // ../../packages/schema/src/zod/inventory.ts
16251
+ var AssetType = external_exports.enum(["project", "skill", "mcp", "hook", "config"]).meta({ id: "AssetType" });
16252
+ var AccessLevel = external_exports.enum(["open", "approved", "blocked"]).meta({ id: "AccessLevel" });
16253
+ var Origin = external_exports.enum(["source", "public-dep", "vendored", "config", "data", "docs", "generated"]).meta({ id: "Origin" });
16254
+ var TrustLevel = external_exports.enum(["known-good", "risky", "unapproved"]).meta({ id: "TrustLevel" });
16255
+ var Flag = external_exports.enum(["update", "stale", "conflict", "unknown", "change", "untracked", "risk", "findings"]).meta({ id: "Flag" });
16256
+ var Visibility = external_exports.enum(["public", "private"]).meta({ id: "Visibility" });
16257
+ var HarnessEventKind = external_exports.enum(["block", "redact", "warn"]).meta({ id: "HarnessEventKind" });
16258
+ var HarnessId = Harness.extract(["ClaudeCode", "Cursor", "Codex", "Antigravity"]).meta({
16259
+ id: "HarnessId"
16260
+ });
16261
+ var AccessCounts = external_exports.object({
16262
+ open: external_exports.number().int().nonnegative(),
16263
+ approved: external_exports.number().int().nonnegative(),
16264
+ blocked: external_exports.number().int().nonnegative(),
16265
+ total: external_exports.number().int().nonnegative()
16266
+ }).meta({ id: "AccessCounts" });
16267
+ var AssetSummary = external_exports.object({
16268
+ id: external_exports.string(),
16269
+ type: AssetType,
16270
+ name: external_exports.string(),
16271
+ sub: external_exports.string(),
16272
+ flags: external_exports.array(Flag),
16273
+ /** MCP servers only — omitted for all other types. */
16274
+ trust: TrustLevel.optional()
16275
+ }).meta({ id: "AssetSummary" });
16276
+ var ProjectSummary = external_exports.object({
16277
+ id: external_exports.string(),
16278
+ name: external_exports.string(),
16279
+ repo: external_exports.string(),
16280
+ visibility: Visibility,
16281
+ language: external_exports.string(),
16282
+ policyDefault: AccessLevel,
16283
+ updatedAt: external_exports.iso.datetime(),
16284
+ accessCounts: AccessCounts,
16285
+ findingsCount: external_exports.number().int().nonnegative()
16286
+ }).meta({ id: "ProjectSummary" });
16287
+ var HarnessCategory = external_exports.object({
16288
+ /** One of config/skill/mcp/hook — never project (enforced at service layer). */
16289
+ type: AssetType,
16290
+ assets: external_exports.array(AssetSummary)
16291
+ });
16292
+ var HarnessSummary = external_exports.object({
16293
+ id: HarnessId,
16294
+ label: external_exports.string(),
16295
+ kind: external_exports.string(),
16296
+ version: external_exports.string(),
16297
+ sessions: external_exports.number().int().nonnegative(),
16298
+ assetCount: external_exports.number().int().nonnegative(),
16299
+ flagCount: external_exports.number().int().nonnegative(),
16300
+ projects: external_exports.array(ProjectSummary),
16301
+ categories: external_exports.array(HarnessCategory)
16302
+ }).meta({ id: "HarnessSummary" });
16303
+ var ListHarnessesResponse = external_exports.object({ items: external_exports.array(HarnessSummary) }).meta({ id: "ListHarnessesResponse" });
16304
+ var AssetGroup = external_exports.object({
16305
+ /** Group key — never project (enforced at service layer). */
16306
+ type: AssetType,
16307
+ total: external_exports.number().int().nonnegative(),
16308
+ /**
16309
+ * MCP group only — omitted for all other types.
16310
+ * Partial: only TrustLevel keys with non-zero counts are included.
16311
+ * Strict: unknown keys are rejected — only TrustLevel values are valid keys.
16312
+ */
16313
+ trustRollup: external_exports.object({
16314
+ "known-good": external_exports.number().int().nonnegative(),
16315
+ risky: external_exports.number().int().nonnegative(),
16316
+ unapproved: external_exports.number().int().nonnegative()
16317
+ }).partial().strict().optional(),
16318
+ /**
16319
+ * Partial: only Flag keys with non-zero counts are included.
16320
+ * Strict: unknown keys are rejected — only Flag values are valid keys.
16321
+ */
16322
+ flagRollup: external_exports.object({
16323
+ update: external_exports.number().int().nonnegative(),
16324
+ stale: external_exports.number().int().nonnegative(),
16325
+ conflict: external_exports.number().int().nonnegative(),
16326
+ unknown: external_exports.number().int().nonnegative(),
16327
+ change: external_exports.number().int().nonnegative(),
16328
+ untracked: external_exports.number().int().nonnegative(),
16329
+ risk: external_exports.number().int().nonnegative(),
16330
+ findings: external_exports.number().int().nonnegative()
16331
+ }).partial().strict(),
16332
+ items: external_exports.array(AssetSummary)
16333
+ }).meta({ id: "AssetGroup" });
16334
+ var ListAssetsResponse = external_exports.object({ groups: external_exports.array(AssetGroup) }).meta({ id: "ListAssetsResponse" });
16335
+ var McpTool = external_exports.object({
16336
+ name: external_exports.string(),
16337
+ signature: external_exports.string(),
16338
+ description: external_exports.string(),
16339
+ write: external_exports.boolean(),
16340
+ /** Non-null string when tool is dangerous / blocked; null otherwise. */
16341
+ risk: external_exports.string().nullable()
16342
+ }).meta({ id: "McpTool" });
16343
+ var AssetFindingRef = external_exports.object({
16344
+ id: external_exports.string(),
16345
+ title: external_exports.string(),
16346
+ note: external_exports.string()
16347
+ });
16348
+ var AssetDetail = AssetSummary.extend({
16349
+ /** string | null — null when no description is available. */
16350
+ description: external_exports.string().nullable(),
16351
+ /** trustLevel | null — null for non-MCP assets. */
16352
+ trust: TrustLevel.nullable(),
16353
+ /** Type-specific raw key/values — FE renders the grid. */
16354
+ meta: external_exports.record(external_exports.string(), external_exports.unknown()),
16355
+ /** always present — object when there is an active finding, null when absent. */
16356
+ finding: AssetFindingRef.nullable(),
16357
+ /** MCP exposed-tools list — omitted for non-mcp. */
16358
+ tools: external_exports.array(McpTool).optional()
16359
+ }).meta({ id: "AssetDetail" });
16360
+ var ListProjectsResponse = external_exports.object({ items: external_exports.array(ProjectSummary) }).meta({ id: "ListProjectsResponse" });
16361
+ var InventoryStats = external_exports.object({
16362
+ /** Total assets/projects with ≥1 flag or finding (drives the attention header chip). */
16363
+ attention: external_exports.number().int().nonnegative(),
16364
+ byType: external_exports.object({
16365
+ project: external_exports.number().int().nonnegative(),
16366
+ skill: external_exports.number().int().nonnegative(),
16367
+ mcp: external_exports.number().int().nonnegative(),
16368
+ hook: external_exports.number().int().nonnegative(),
16369
+ config: external_exports.number().int().nonnegative()
16370
+ }),
16371
+ harnesses: external_exports.number().int().nonnegative(),
16372
+ mcpTrust: external_exports.object({
16373
+ "known-good": external_exports.number().int().nonnegative(),
16374
+ risky: external_exports.number().int().nonnegative(),
16375
+ unapproved: external_exports.number().int().nonnegative()
16376
+ })
16377
+ }).meta({ id: "InventoryStats" });
16378
+ var FileSummary = external_exports.object({
16379
+ path: external_exports.string(),
16380
+ name: external_exports.string(),
16381
+ origin: Origin,
16382
+ /** Effective access (override applied). */
16383
+ access: AccessLevel,
16384
+ /** True when a file_access_override differs from the computed default. */
16385
+ isCustom: external_exports.boolean(),
16386
+ findings: external_exports.number().int().nonnegative(),
16387
+ /** When the file was auto-blocked by a detection; null when not blocked. */
16388
+ blockedAt: external_exports.iso.datetime().nullable().optional(),
16389
+ /** Why the file was blocked; null when absent. */
16390
+ note: external_exports.string().nullable().optional()
16391
+ }).meta({ id: "FileSummary" });
16392
+ var FolderSummary = external_exports.object({
16393
+ name: external_exports.string(),
16394
+ path: external_exports.string(),
16395
+ /** Rollup of effective access across all descendants. */
16396
+ accessCounts: AccessCounts
16397
+ }).meta({ id: "FolderSummary" });
16398
+ var ProjectTreeResponse = external_exports.object({
16399
+ project: external_exports.object({
16400
+ id: external_exports.string(),
16401
+ repo: external_exports.string(),
16402
+ visibility: Visibility
16403
+ }),
16404
+ path: external_exports.string(),
16405
+ /** Browse mode: one-level folders at the current path. Omitted in search mode. */
16406
+ folders: external_exports.array(FolderSummary).optional(),
16407
+ files: external_exports.array(FileSummary)
16408
+ }).meta({ id: "ProjectTreeResponse" });
16409
+ var FileDetail = FileSummary.extend({
16410
+ project: external_exports.object({
16411
+ repo: external_exports.string(),
16412
+ visibility: Visibility,
16413
+ language: external_exports.string(),
16414
+ policyDefault: AccessLevel,
16415
+ updatedAt: external_exports.iso.datetime()
16416
+ }),
16417
+ findingsRefs: external_exports.array(external_exports.object({ id: external_exports.string(), title: external_exports.string() }))
16418
+ }).meta({ id: "FileDetail" });
16419
+ var SetFileAccessBody = external_exports.object({
16420
+ path: external_exports.string(),
16421
+ access: AccessLevel
16422
+ }).meta({ id: "SetFileAccessBody" });
16423
+ var SetFileAccessResponse = external_exports.object({
16424
+ file: FileSummary,
16425
+ accessCounts: AccessCounts
16426
+ }).meta({ id: "SetFileAccessResponse" });
16427
+ var SetMcpTrustBody = external_exports.object({ trust: TrustLevel }).meta({ id: "SetMcpTrustBody" });
16428
+ var HarnessEventItem = external_exports.object({
16429
+ kind: HarnessEventKind,
16430
+ title: external_exports.string(),
16431
+ detail: external_exports.string(),
16432
+ occurredAt: external_exports.iso.datetime(),
16433
+ findingId: external_exports.string().nullable().optional()
16434
+ }).meta({ id: "HarnessEventItem" });
16435
+ var HarnessEventsResponse = external_exports.object({
16436
+ counts: external_exports.object({
16437
+ block: external_exports.number().int().nonnegative(),
16438
+ redact: external_exports.number().int().nonnegative(),
16439
+ warn: external_exports.number().int().nonnegative()
16440
+ }),
16441
+ items: external_exports.array(HarnessEventItem)
16442
+ }).meta({ id: "HarnessEventsResponse" });
16443
+ var RescanResponse = external_exports.object({
16444
+ jobId: external_exports.string(),
16445
+ startedAt: external_exports.iso.datetime()
16446
+ }).meta({ id: "RescanResponse" });
16447
+ var ConnectProjectBody = external_exports.object({ repo: external_exports.string() }).meta({ id: "ConnectProjectBody" });
16448
+ var ListAssetsQuery = external_exports.object({
16449
+ /** Filter by one or more AssetType values; absent means all types. */
16450
+ type: external_exports.array(AssetType).optional(),
16451
+ /** Free-text search term. */
16452
+ q: external_exports.string().optional()
16453
+ });
16454
+ var GetProjectTreeQuery = external_exports.object({
16455
+ /** Subtree root path; defaults to repository root when absent. */
16456
+ path: external_exports.string().optional(),
16457
+ /** Free-text filter applied to file paths. */
16458
+ q: external_exports.string().optional(),
16459
+ /**
16460
+ * Special listing mode. `blocked` returns every effectively-blocked, auto-blocked
16461
+ * file across the whole repo (folders omitted, most-recent first), ignoring
16462
+ * `path`/`q` — powers the project-wide "recently blocked" strip.
16463
+ */
16464
+ filter: external_exports.enum(["blocked"]).optional()
16465
+ });
16466
+ var GetProjectFileQuery = external_exports.object({
16467
+ /** Repository-relative file path; absent or empty → 400. */
16468
+ path: external_exports.string()
16469
+ });
16470
+ var GetHarnessEventsQuery = external_exports.object({
16471
+ /** Maximum number of events to return. Range: 1–50; default: 7. */
16472
+ limit: external_exports.coerce.number().int().min(1).max(50).default(7)
16473
+ });
16710
16474
 
16711
16475
  // ../../packages/schema/src/zod/shares.ts
16712
16476
  var DestinationKind = external_exports.enum(["provider", "internal", "external", "ip"]).meta({ id: "DestinationKind" });
@@ -16842,77 +16606,198 @@ var ListShareDestinationsQuery = external_exports.object({
16842
16606
  */
16843
16607
  review: external_exports.stringbool().default(false)
16844
16608
  });
16845
- var ExportSharesQuery = external_exports.object({
16846
- format: external_exports.enum(["csv", "json"]).default("csv"),
16847
- q: external_exports.string().optional(),
16848
- kind: external_exports.array(DestinationKind).optional()
16609
+ var ExportSharesQuery = external_exports.object({
16610
+ format: external_exports.enum(["csv", "json"]).default("csv"),
16611
+ q: external_exports.string().optional(),
16612
+ kind: external_exports.array(DestinationKind).optional()
16613
+ });
16614
+
16615
+ // ../../packages/schema/src/zod/egress-extraction.ts
16616
+ var EgressEcosystem = external_exports.enum(["npm", "pypi", "go", "maven", "rubygems", "cargo", "composer", "nuget"]).meta({ id: "EgressEcosystem" });
16617
+ var ProviderRegistryEntry = external_exports.object({
16618
+ id: external_exports.string(),
16619
+ name: external_exports.string(),
16620
+ category: external_exports.string(),
16621
+ /** Suffix-matched: 'stripe.com' matches api.stripe.com, never evilstripe.com. */
16622
+ hostSuffixes: external_exports.array(external_exports.string()).min(1),
16623
+ /** Canonical API base URL recorded for manifest-derived (method 'SDK') endpoints. */
16624
+ apiBase: external_exports.string(),
16625
+ /** Most-sensitive first; index 0 becomes the endpoint dataClass. */
16626
+ defaultDataClasses: external_exports.array(DataClass).min(1),
16627
+ /** SDK identifiers per ecosystem ('go' prefix-matched by path, 'maven' by group-id prefix). */
16628
+ sdks: external_exports.partialRecord(EgressEcosystem, external_exports.array(external_exports.string()))
16629
+ }).meta({ id: "ProviderRegistryEntry" });
16630
+ var EgressCallSiteHit = external_exports.object({
16631
+ file: external_exports.string(),
16632
+ line: external_exports.number().int().positive(),
16633
+ snippet: external_exports.string(),
16634
+ dynamic: external_exports.boolean(),
16635
+ vendored: external_exports.boolean()
16636
+ }).meta({ id: "EgressCallSiteHit" });
16637
+ var ResolvedEgressHit = external_exports.object({
16638
+ host: external_exports.string(),
16639
+ kind: DestinationKind,
16640
+ name: external_exports.string(),
16641
+ category: external_exports.string(),
16642
+ trust: ShareTrustLevel,
16643
+ network: DestinationNetwork.nullable(),
16644
+ method: HttpMethod,
16645
+ transport: Transport,
16646
+ url: external_exports.string(),
16647
+ template: external_exports.boolean(),
16648
+ dataClass: DataClass,
16649
+ site: EgressCallSiteHit
16650
+ }).meta({ id: "ResolvedEgressHit" });
16651
+ var EgressReconcile = external_exports.discriminatedUnion("mode", [
16652
+ external_exports.object({ mode: external_exports.literal("walk"), walkedPrefix: external_exports.string() }),
16653
+ external_exports.object({
16654
+ mode: external_exports.literal("ledger"),
16655
+ scannedFiles: external_exports.array(external_exports.string()),
16656
+ deletedFiles: external_exports.array(external_exports.string())
16657
+ })
16658
+ ]).meta({ id: "EgressReconcile" });
16659
+ var RecordProjectEgressInput = external_exports.object({
16660
+ /** Stable reconcile key: 'git:<repo identity>' or 'path:<abs root>' (non-git). */
16661
+ projectKey: external_exports.string().min(1),
16662
+ /** Display name only — never keys reconciliation. */
16663
+ project: external_exports.string(),
16664
+ projectId: external_exports.string().nullable(),
16665
+ reconcile: EgressReconcile,
16666
+ hits: external_exports.array(ResolvedEgressHit)
16667
+ }).meta({ id: "RecordProjectEgressInput" });
16668
+ var EgressWriteSummary = external_exports.object({
16669
+ destinations: external_exports.number().int().nonnegative(),
16670
+ endpoints: external_exports.number().int().nonnegative(),
16671
+ callSites: external_exports.number().int().nonnegative(),
16672
+ truncated: external_exports.boolean(),
16673
+ /**
16674
+ * Files the cap dropped whole. Their stored rows were left untouched, so a
16675
+ * ledger-keeping caller must withhold their ledger entries and read them
16676
+ * again next scan.
16677
+ */
16678
+ droppedFiles: external_exports.array(external_exports.string()).default([])
16679
+ }).meta({ id: "EgressWriteSummary" });
16680
+
16681
+ // ../../packages/schema/src/zod/event.ts
16682
+ var EventKind = external_exports.enum(["prompt", "response", "code_change", "tool_use"]).meta({ id: "EventKind" });
16683
+ var CAPTURE_EVENT_TYPES_SQL = EventKind.options.map((k) => `'${k}'`).join(",");
16684
+ var EventMetadata = external_exports.object({
16685
+ sessionId: external_exports.string().optional(),
16686
+ repo: external_exports.string().optional(),
16687
+ filePath: external_exports.string().optional(),
16688
+ // The host tool whose input/output was scanned (e.g. 'Bash', 'WebFetch'),
16689
+ // set by the tool-scanning hooks. The tool NAME only — never the tool's
16690
+ // arguments or output, which can carry the very value a finding masked
16691
+ // (metadata is stored unredacted). Gives findings on non-file captures a
16692
+ // display location ("via Bash") when no filePath exists.
16693
+ toolName: external_exports.string().optional(),
16694
+ // Set (true) by the worktree scanner when the file is excluded by the
16695
+ // repo's .gitignore. Gitignored files ARE still scanned — local scratch and
16696
+ // generated code can leak real secrets — but the provenance is recorded so
16697
+ // policy/dashboards can treat those findings as informational rather than
16698
+ // blocking. Omitted (not false) for tracked files and non-scan events.
16699
+ gitignored: external_exports.boolean().optional(),
16700
+ // Set (true) ONLY when the event's `content` is the COMPLETE file at
16701
+ // capture time (a worktree scan reading from disk). Hook-captured edits
16702
+ // (e.g. an Edit tool's new_string) are partial fragments and MUST NOT set
16703
+ // this. The resolver-on-ingest keys its fixed-at-source dropout
16704
+ // diff on this marker: only a whole-file snapshot can prove a previously
16705
+ // open finding is gone; a fragment's absence proves nothing (the secret
16706
+ // may live outside the hunk). Omitted (not false) for fragments and
16707
+ // non-scan events, so pre-marker clients safely default to the
16708
+ // non-authoritative path.
16709
+ wholeFile: external_exports.boolean().optional(),
16710
+ model: external_exports.string().optional(),
16711
+ turnIndex: external_exports.number().int().nonnegative().optional(),
16712
+ // Distributed-tracing correlation. `correlationId` ties a recorded event back
16713
+ // to the request that captured/ingested it (a UUID, generated independently of
16714
+ // the trace id); `traceId` is the W3C trace id (32 lowercase hex chars) of the
16715
+ // originating span when telemetry is enabled. Both optional + backward
16716
+ // compatible — populated by the plugin (see @akasecurity/plugin-sdk).
16717
+ correlationId: external_exports.uuid().optional(),
16718
+ traceId: external_exports.string().regex(/^[0-9a-f]{32}$/).optional(),
16719
+ // Ids of the detection exceptions that downgraded findings in this capture
16720
+ // to 'allow' — the enforcement audit trail's link back to the grant that
16721
+ // authorized the bypass. Absent on captures where no exception applied.
16722
+ exceptionIds: external_exports.array(external_exports.guid()).optional()
16723
+ }).meta({ id: "EventMetadata" });
16724
+ var Event = external_exports.object({
16725
+ id: external_exports.guid(),
16726
+ sourceTool: SourceTool,
16727
+ kind: EventKind,
16728
+ occurredAt: external_exports.iso.datetime(),
16729
+ contentHash: external_exports.string(),
16730
+ content: external_exports.string(),
16731
+ metadata: EventMetadata.optional()
16732
+ }).meta({ id: "Event" });
16733
+ var IngestEvent = Event.meta({ id: "IngestEvent" });
16734
+ var IngestBatch = external_exports.object({
16735
+ events: external_exports.array(IngestEvent).min(1).max(100),
16736
+ // Dedup policy for this batch. Id-dedup ALWAYS applies. 'content-hash'
16737
+ // additionally rejects any event whose contentHash the store has already
16738
+ // recorded — for re-runnable bulk ingest (worktree scan, transcript
16739
+ // backfill), where a re-run mints fresh event ids for identical content and
16740
+ // would otherwise accumulate duplicates. Live hook traffic must NOT set it:
16741
+ // two genuinely separate prompts can be byte-identical and both belong on
16742
+ // the timeline.
16743
+ dedupe: external_exports.literal("content-hash").optional()
16744
+ }).meta({ id: "IngestBatch" });
16745
+
16746
+ // ../../packages/schema/src/zod/exception.ts
16747
+ var ExceptionScope = external_exports.enum(["once", "temporary", "permanent"]);
16748
+ var ExceptionConditions = external_exports.object({
16749
+ repo: external_exports.string().optional(),
16750
+ sourceTool: external_exports.string().optional(),
16751
+ provider: external_exports.string().optional()
16752
+ }).strict();
16753
+ var ExceptionCapability = external_exports.enum(["suppress", "reveal_to_model"]);
16754
+ var DetectionException = external_exports.object({
16755
+ id: external_exports.guid(),
16756
+ ruleId: external_exports.string(),
16757
+ // Denormalized from the rule, for reporting — never matched on.
16758
+ category: DetectionCategory,
16759
+ // HMAC-SHA256 hex of the raw match under a machine-local key: a KEYED
16760
+ // fingerprint, never the raw value, and never reversible. Matching recomputes
16761
+ // the fingerprint from a fresh capture; the value itself is never stored.
16762
+ // Shape-constrained so a malformed — or accidentally raw — value is rejected
16763
+ // at the boundary rather than persisted.
16764
+ valueFingerprint: external_exports.string().regex(/^[0-9a-f]{64}$/),
16765
+ // Version of the fingerprint key the grant was written under; a rotated key
16766
+ // invalidates old grants rather than silently mismatching them.
16767
+ keyVersion: external_exports.number().int().positive(),
16768
+ // maskMatch() preview of the approved value — never the raw value.
16769
+ maskedValue: external_exports.string(),
16770
+ capability: ExceptionCapability.default("suppress"),
16771
+ scope: ExceptionScope,
16772
+ expiresAt: external_exports.iso.datetime().nullable(),
16773
+ maxUses: external_exports.number().int().positive().nullable(),
16774
+ useCount: external_exports.number().int().nonnegative(),
16775
+ lastUsedAt: external_exports.iso.datetime().nullable(),
16776
+ // Mandatory: every grant carries the human reason it exists.
16777
+ justification: external_exports.string().min(1),
16778
+ conditions: ExceptionConditions.nullable(),
16779
+ createdBy: external_exports.string(),
16780
+ createdVia: external_exports.enum(["cli-approve", "cli-add", "web-approve", "web-add", "api", "setup-triage"]),
16781
+ createdAt: external_exports.iso.datetime(),
16782
+ updatedAt: external_exports.iso.datetime(),
16783
+ // Revocation is terminal and retained — consumed/expired/revoked rows are
16784
+ // audit evidence; nothing in the exception lifecycle hard-deletes.
16785
+ revokedAt: external_exports.iso.datetime().nullable(),
16786
+ revokedBy: external_exports.string().nullable(),
16787
+ revokeReason: external_exports.string().nullable()
16788
+ });
16789
+ var ExceptionBundleEntry = DetectionException.pick({
16790
+ id: true,
16791
+ ruleId: true,
16792
+ valueFingerprint: true,
16793
+ keyVersion: true,
16794
+ capability: true,
16795
+ expiresAt: true,
16796
+ maxUses: true,
16797
+ useCount: true,
16798
+ conditions: true
16849
16799
  });
16850
-
16851
- // ../../packages/schema/src/zod/egress-extraction.ts
16852
- var EgressEcosystem = external_exports.enum(["npm", "pypi", "go", "maven", "rubygems", "cargo", "composer", "nuget"]).meta({ id: "EgressEcosystem" });
16853
- var ProviderRegistryEntry = external_exports.object({
16854
- id: external_exports.string(),
16855
- name: external_exports.string(),
16856
- category: external_exports.string(),
16857
- /** Suffix-matched: 'stripe.com' matches api.stripe.com, never evilstripe.com. */
16858
- hostSuffixes: external_exports.array(external_exports.string()).min(1),
16859
- /** Canonical API base URL recorded for manifest-derived (method 'SDK') endpoints. */
16860
- apiBase: external_exports.string(),
16861
- /** Most-sensitive first; index 0 becomes the endpoint dataClass. */
16862
- defaultDataClasses: external_exports.array(DataClass).min(1),
16863
- /** SDK identifiers per ecosystem ('go' prefix-matched by path, 'maven' by group-id prefix). */
16864
- sdks: external_exports.partialRecord(EgressEcosystem, external_exports.array(external_exports.string()))
16865
- }).meta({ id: "ProviderRegistryEntry" });
16866
- var EgressCallSiteHit = external_exports.object({
16867
- file: external_exports.string(),
16868
- line: external_exports.number().int().positive(),
16869
- snippet: external_exports.string(),
16870
- dynamic: external_exports.boolean(),
16871
- vendored: external_exports.boolean()
16872
- }).meta({ id: "EgressCallSiteHit" });
16873
- var ResolvedEgressHit = external_exports.object({
16874
- host: external_exports.string(),
16875
- kind: DestinationKind,
16876
- name: external_exports.string(),
16877
- category: external_exports.string(),
16878
- trust: ShareTrustLevel,
16879
- network: DestinationNetwork.nullable(),
16880
- method: HttpMethod,
16881
- transport: Transport,
16882
- url: external_exports.string(),
16883
- template: external_exports.boolean(),
16884
- dataClass: DataClass,
16885
- site: EgressCallSiteHit
16886
- }).meta({ id: "ResolvedEgressHit" });
16887
- var EgressReconcile = external_exports.discriminatedUnion("mode", [
16888
- external_exports.object({ mode: external_exports.literal("walk"), walkedPrefix: external_exports.string() }),
16889
- external_exports.object({
16890
- mode: external_exports.literal("ledger"),
16891
- scannedFiles: external_exports.array(external_exports.string()),
16892
- deletedFiles: external_exports.array(external_exports.string())
16893
- })
16894
- ]).meta({ id: "EgressReconcile" });
16895
- var RecordProjectEgressInput = external_exports.object({
16896
- /** Stable reconcile key: 'git:<repo identity>' or 'path:<abs root>' (non-git). */
16897
- projectKey: external_exports.string().min(1),
16898
- /** Display name only — never keys reconciliation. */
16899
- project: external_exports.string(),
16900
- projectId: external_exports.string().nullable(),
16901
- reconcile: EgressReconcile,
16902
- hits: external_exports.array(ResolvedEgressHit)
16903
- }).meta({ id: "RecordProjectEgressInput" });
16904
- var EgressWriteSummary = external_exports.object({
16905
- destinations: external_exports.number().int().nonnegative(),
16906
- endpoints: external_exports.number().int().nonnegative(),
16907
- callSites: external_exports.number().int().nonnegative(),
16908
- truncated: external_exports.boolean(),
16909
- /**
16910
- * Files the cap dropped whole. Their stored rows were left untouched, so a
16911
- * ledger-keeping caller must withhold their ledger entries and read them
16912
- * again next scan.
16913
- */
16914
- droppedFiles: external_exports.array(external_exports.string()).default([])
16915
- }).meta({ id: "EgressWriteSummary" });
16800
+ var ExceptionDescriptor = DetectionException.omit({ valueFingerprint: true });
16916
16801
 
16917
16802
  // ../../packages/schema/src/zod/exception-action.ts
16918
16803
  var confirmation = external_exports.string().optional();
@@ -17125,7 +17010,13 @@ var VaultConsent = external_exports.object({
17125
17010
 
17126
17011
  // ../../packages/schema/src/zod/local.ts
17127
17012
  var WORKSPACE_SETTINGS_SPEC_VERSION = 5;
17128
- var RunMode = external_exports.enum(["standalone"]);
17013
+ var RunMode = external_exports.enum(["standalone", "attached"]);
17014
+ var ControlPlaneConnection = external_exports.object({
17015
+ endpoint: external_exports.string().min(1),
17016
+ // Display name for the deployment, shown instead of the raw endpoint.
17017
+ label: external_exports.string().min(1).optional(),
17018
+ attachedAt: external_exports.iso.datetime()
17019
+ }).meta({ id: "ControlPlaneConnection" });
17129
17020
  var SimpleDetectionPolicy = external_exports.enum(["redact", "warn"]);
17130
17021
  var HistoricalAccess = external_exports.enum(["full", "session-only"]);
17131
17022
  var ModelJudgeConsent = external_exports.object({
@@ -17134,12 +17025,10 @@ var ModelJudgeConsent = external_exports.object({
17134
17025
  });
17135
17026
  var WorkspaceSettings = external_exports.object({
17136
17027
  specVersion: external_exports.number().int().positive().default(WORKSPACE_SETTINGS_SPEC_VERSION),
17137
- // Settings files written by earlier releases may carry the retired 'attached'
17138
- // value; it parses as 'standalone' so those files keep loading.
17139
- runMode: external_exports.preprocess(
17140
- (v) => v === "attached" ? "standalone" : v,
17141
- RunMode.default("standalone")
17142
- ),
17028
+ runMode: RunMode.default("standalone"),
17029
+ // Present only while attached; a detach clears it. Its presence is what makes
17030
+ // `runMode: 'attached'` mean anything — see isAttached.
17031
+ controlPlane: ControlPlaneConnection.optional(),
17143
17032
  policy: SimpleDetectionPolicy.default("redact"),
17144
17033
  // Consent for scanning pre-install surfaces; opt-in (see HistoricalAccess).
17145
17034
  historicalAccess: HistoricalAccess.default("session-only"),
@@ -17165,6 +17054,200 @@ var WorkspaceSettings = external_exports.object({
17165
17054
  modelJudgeConsent: ModelJudgeConsent.optional()
17166
17055
  });
17167
17056
 
17057
+ // ../../packages/schema/src/zod/managed.ts
17058
+ var MANAGED_SETTINGS_SPEC_VERSION = 1;
17059
+ var ManagedSettingKey = external_exports.enum([
17060
+ "runMode",
17061
+ "historicalAccess",
17062
+ "vaultConsent",
17063
+ "vaultKeyCustody",
17064
+ "vaultInlineReveal",
17065
+ "modelJudgeConsent",
17066
+ "dataSharesInPlace"
17067
+ ]).meta({ id: "ManagedSettingKey" });
17068
+ var ManagedSettingsValues = external_exports.object({
17069
+ runMode: external_exports.enum(["standalone", "attached"]).optional(),
17070
+ controlPlane: external_exports.object({
17071
+ endpoint: external_exports.string().min(1),
17072
+ label: external_exports.string().min(1).optional()
17073
+ }).optional(),
17074
+ historicalAccess: external_exports.enum(["full", "session-only"]).optional(),
17075
+ vaultConsent: external_exports.boolean().optional(),
17076
+ vaultKeyCustody: external_exports.enum(["file", "keychain"]).optional(),
17077
+ vaultInlineReveal: external_exports.enum(["masked", "full", "off"]).optional(),
17078
+ modelJudgeConsent: external_exports.boolean().optional(),
17079
+ dataSharesInPlace: external_exports.boolean().optional()
17080
+ }).meta({ id: "ManagedSettingsValues" });
17081
+ var ManagedSettings = external_exports.object({
17082
+ specVersion: external_exports.number().int().positive().default(MANAGED_SETTINGS_SPEC_VERSION),
17083
+ // Shown on every locked control, so the user can tell an administrative
17084
+ // decision from a bug. Absent renders as a generic "your organization".
17085
+ organization: external_exports.string().min(1).optional(),
17086
+ // What the administrator pinned.
17087
+ values: ManagedSettingsValues.default({}),
17088
+ // Which of those the user may not change. A key here with no matching value
17089
+ // freezes whatever the user last chose; a value with no lock is a DEFAULT
17090
+ // the user may still override. The two are separable on purpose.
17091
+ lockedFields: external_exports.array(ManagedSettingKey).default([])
17092
+ }).meta({ id: "ManagedSettings" });
17093
+
17094
+ // ../../packages/schema/src/zod/policy.ts
17095
+ var PolicyScope = external_exports.enum(["global", "repo", "user"]).meta({ id: "PolicyScope" });
17096
+ var PolicyTarget = external_exports.union([external_exports.object({ ruleId: external_exports.string() }), external_exports.object({ category: DetectionCategory })]).meta({ id: "PolicyTarget" });
17097
+ var Policy = external_exports.object({
17098
+ id: external_exports.guid(),
17099
+ scope: PolicyScope,
17100
+ target: PolicyTarget,
17101
+ action: ActionTaken,
17102
+ enabled: external_exports.boolean().default(true),
17103
+ customKeywords: external_exports.array(external_exports.string()).optional(),
17104
+ // Display name — optional so older policy rows without name still parse.
17105
+ // Added for the findings API (policy.name column migration).
17106
+ name: external_exports.string().optional()
17107
+ }).meta({ id: "Policy" });
17108
+ var PolicyBundle = external_exports.object({
17109
+ version: external_exports.string(),
17110
+ policies: external_exports.array(Policy),
17111
+ // Rules from the installed marketplace packs (snapshotted by the
17112
+ // control plane). The plugin registers these in addition to its bundled
17113
+ // packs. Optional so older backends — and older on-disk caches — that omit
17114
+ // the field still parse; consumers read `bundle.rules ?? []`.
17115
+ rules: external_exports.array(Rule).optional(),
17116
+ // When true, `rules` IS the complete effective ruleset and the runtime must
17117
+ // NOT merge its compiled-in bundled packs — the standalone gateway sets this
17118
+ // after reading the user's installed snapshot (installed_packs, enabled
17119
+ // packs only), which is how detection updates stay manual: new bundled
17120
+ // rules run only after the user applies the pack update. Absent/false keeps
17121
+ // the historical composition (bundled packs + rules) — older caches.
17122
+ rulesComplete: external_exports.boolean().optional(),
17123
+ // Active detection exceptions, evaluation subset only (see
17124
+ // ExceptionBundleEntry). Optional so older bundle producers — and older
17125
+ // on-disk caches — that omit the field still parse; consumers read
17126
+ // `bundle.exceptions ?? []`.
17127
+ exceptions: external_exports.array(ExceptionBundleEntry).optional(),
17128
+ // Rule ids whose pack is assigned a REVERSIBLE archetype (Redact & Vault).
17129
+ // A second axis over the same `redact` action, carried beside the policies
17130
+ // rather than on them: nothing writes ruleId-targeted policies to disk, so
17131
+ // widening Policy itself would change a persisted shape to express something
17132
+ // only the in-memory bundle needs. Optional so an older producer — or an
17133
+ // older on-disk cache — still parses; consumers read `?? []` and get the
17134
+ // pre-existing one-way behaviour, which is the safe direction to default.
17135
+ reversibleRuleIds: external_exports.array(external_exports.string()).optional(),
17136
+ // Installed pack version, keyed by ruleId, for rules in `rules` that came
17137
+ // from a versioned installed pack. Optional so older backends — and older
17138
+ // on-disk caches — that omit the field still parse; consumers fall back to
17139
+ // the rule's own spec version. NOT the bundle version above — see
17140
+ // installedRuleset's ruleVersions for the source of truth.
17141
+ ruleVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
17142
+ customKeywords: external_exports.array(external_exports.string()),
17143
+ fetchedAt: external_exports.iso.datetime()
17144
+ }).meta({ id: "PolicyBundle" });
17145
+ var OBSERVE_ONLY_CATEGORIES = ["config"];
17146
+ var ENFORCEABLE_CATEGORIES = DetectionCategory.options.filter((c) => !OBSERVE_ONLY_CATEGORIES.includes(c));
17147
+ var CATEGORY_PEAK_SEVERITY = {
17148
+ secret: "critical",
17149
+ financial: "critical",
17150
+ // core-financial/credit-card
17151
+ code_flaw: "critical",
17152
+ pii: "high",
17153
+ phi: "high",
17154
+ custom: "high",
17155
+ // user-defined; conservative
17156
+ code_context: "low",
17157
+ config: "low"
17158
+ // observe-only; floors to monitor regardless
17159
+ };
17160
+ function severityFloorPolicy(category) {
17161
+ if (OBSERVE_ONLY_CATEGORIES.includes(category)) return "monitor";
17162
+ const peak = CATEGORY_PEAK_SEVERITY[category];
17163
+ return peak === "critical" || peak === "high" ? "warn" : "monitor";
17164
+ }
17165
+ function severityFloorPosture() {
17166
+ const out = {};
17167
+ for (const c of DetectionCategory.options) out[c] = severityFloorPolicy(c);
17168
+ return out;
17169
+ }
17170
+ var PolicyKind = external_exports.enum(["builtin", "custom"]).meta({ id: "PolicyKind" });
17171
+ var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "vault", "block"];
17172
+ var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
17173
+ var BUILTIN_POLICY_SPECS = {
17174
+ monitor: {
17175
+ name: "Monitor",
17176
+ action: "log",
17177
+ reversible: false,
17178
+ description: "Log every match for audit. The request is allowed through untouched."
17179
+ },
17180
+ warn: {
17181
+ name: "Warn",
17182
+ action: "warn",
17183
+ reversible: false,
17184
+ description: "Allow the request, but warn the user inline before it is sent."
17185
+ },
17186
+ redact: {
17187
+ name: "Redact",
17188
+ action: "redact",
17189
+ reversible: false,
17190
+ description: "Strip the matched value from the request and destroy it, then continue. What was removed cannot be recovered."
17191
+ },
17192
+ vault: {
17193
+ name: "Redact & Vault",
17194
+ action: "redact",
17195
+ reversible: true,
17196
+ description: "Strip the matched value from the request and keep an encrypted, recoverable copy in the local vault, leaving a pointer in its place. Needs the vault consent granted under Settings; without it this behaves as Redact."
17197
+ },
17198
+ block: {
17199
+ name: "Block",
17200
+ action: "block",
17201
+ reversible: false,
17202
+ description: "Refuse the request entirely whenever any rule in this detection matches."
17203
+ }
17204
+ };
17205
+ function builtinPolicyToAction(id) {
17206
+ return BUILTIN_POLICY_SPECS[id].action;
17207
+ }
17208
+ var CATEGORY_EXPRESSIBLE_IDS = KNOWN_BUILTIN_IDS.filter(
17209
+ (id) => !BUILTIN_POLICY_SPECS[id].reversible
17210
+ );
17211
+ var CATEGORY_INEXPRESSIBLE_IDS = KNOWN_BUILTIN_IDS.filter(
17212
+ (id) => BUILTIN_POLICY_SPECS[id].reversible
17213
+ );
17214
+ var CategoryPolicyId = external_exports.enum(CATEGORY_EXPRESSIBLE_IDS).meta({ id: "CategoryPolicyId" });
17215
+ var DEFAULT_ACTIONS = Object.fromEntries(
17216
+ DetectionCategory.options.map((c) => [c, builtinPolicyToAction(severityFloorPolicy(c))])
17217
+ );
17218
+ var BUILTIN_POLICIES = Object.fromEntries(
17219
+ KNOWN_BUILTIN_IDS.map((id) => [id, { id, ...BUILTIN_POLICY_SPECS[id] }])
17220
+ );
17221
+ var UsedByItem = external_exports.object({
17222
+ id: external_exports.string(),
17223
+ name: external_exports.string(),
17224
+ ruleCount: external_exports.number().int().nonnegative(),
17225
+ enabled: external_exports.boolean()
17226
+ }).meta({ id: "UsedByItem" });
17227
+ var PolicyListItem = external_exports.object({
17228
+ id: external_exports.string(),
17229
+ kind: PolicyKind,
17230
+ name: external_exports.string(),
17231
+ enabled: external_exports.boolean(),
17232
+ usedByCount: external_exports.number().int().nonnegative()
17233
+ }).meta({ id: "PolicyListItem" });
17234
+ var ListPoliciesResponse = external_exports.object({ items: external_exports.array(PolicyListItem) }).meta({ id: "ListPoliciesResponse" });
17235
+ var PolicyDetail = external_exports.object({
17236
+ specVersion: external_exports.literal(1),
17237
+ id: external_exports.string(),
17238
+ kind: PolicyKind,
17239
+ name: external_exports.string(),
17240
+ enabled: external_exports.boolean(),
17241
+ description: external_exports.string(),
17242
+ usedBy: external_exports.array(UsedByItem)
17243
+ }).meta({ id: "PolicyDetail" });
17244
+ var PolicyStatsResponse = external_exports.object({
17245
+ policies: external_exports.number().int().nonnegative(),
17246
+ builtin: external_exports.number().int().nonnegative(),
17247
+ custom: external_exports.number().int().nonnegative(),
17248
+ detectionsGoverned: external_exports.number().int().nonnegative()
17249
+ }).meta({ id: "PolicyStatsResponse" });
17250
+
17168
17251
  // ../../packages/schema/src/zod/project-files.ts
17169
17252
  var ProjectFileInput = external_exports.object({
17170
17253
  path: external_exports.string().min(1),
@@ -17237,44 +17320,6 @@ var BatchedRemediation = external_exports.discriminatedUnion("kind", [
17237
17320
  NoRemediationDecision
17238
17321
  ]);
17239
17322
 
17240
- // ../../packages/schema/src/zod/rule-test.ts
17241
- var TestRulesRequest = external_exports.object({
17242
- rules: external_exports.array(Rule).min(1).max(100),
17243
- text: external_exports.string().max(5e4).optional(),
17244
- fixtures: external_exports.array(RuleFixture).max(200).optional()
17245
- }).refine((v) => v.text !== void 0 || (v.fixtures?.length ?? 0) > 0, {
17246
- message: "Provide `text`, `fixtures`, or both \u2014 there must be something to test"
17247
- }).meta({ id: "TestRulesRequest" });
17248
- var RuleTestMatch = external_exports.object({
17249
- ruleId: external_exports.string(),
17250
- category: DetectionCategory,
17251
- severity: Severity,
17252
- span: Span,
17253
- confidence: external_exports.number().min(0).max(1),
17254
- match: external_exports.string()
17255
- }).meta({ id: "RuleTestMatch" });
17256
- var FixtureResult = external_exports.object({
17257
- label: external_exports.string(),
17258
- shouldMatch: external_exports.boolean(),
17259
- didMatch: external_exports.boolean(),
17260
- passed: external_exports.boolean(),
17261
- matches: external_exports.array(RuleTestMatch)
17262
- }).meta({ id: "FixtureResult" });
17263
- var TestRulesResponse = external_exports.object({
17264
- // Present only when the request supplied `text`.
17265
- adhoc: external_exports.object({ matches: external_exports.array(RuleTestMatch) }).optional(),
17266
- fixtures: external_exports.array(FixtureResult),
17267
- summary: external_exports.object({
17268
- total: external_exports.number().int().nonnegative(),
17269
- passed: external_exports.number().int().nonnegative(),
17270
- failed: external_exports.number().int().nonnegative()
17271
- }),
17272
- // Ids of rules whose matcher type the engine cannot evaluate today (e.g.
17273
- // `validator`), so they silently never match. Surfaced so an author is not
17274
- // misled by a green run that actually skipped a rule.
17275
- unsupportedRuleIds: external_exports.array(external_exports.string())
17276
- }).meta({ id: "TestRulesResponse" });
17277
-
17278
17323
  // ../../packages/schema/src/zod/security.ts
17279
17324
  var SeveritySummaryItem = external_exports.object({
17280
17325
  severity: Severity,
@@ -17372,10 +17417,22 @@ var TopSourcesQuery = external_exports.object({
17372
17417
  // Omit for both kinds.
17373
17418
  kind: external_exports.enum(SOURCE_KINDS).optional()
17374
17419
  });
17375
- var Provider = external_exports.enum(["claudecode", "cursor", "codex", "antigravity", "claudeai", "chatgpt", "copilot", "api"]).meta({ id: "Provider" });
17420
+ var Provider = Harness.extract([
17421
+ "ClaudeCode",
17422
+ "Cursor",
17423
+ "Codex",
17424
+ "Antigravity",
17425
+ "ClaudeAi",
17426
+ "ChatGpt",
17427
+ "Copilot",
17428
+ "Api"
17429
+ ]).meta({ id: "Provider" });
17376
17430
  var ScanCoverageProvider = external_exports.object({
17377
17431
  provider: Provider,
17378
- // Percent of that provider's traffic scanned in the window. 0 when unsupported.
17432
+ // Percent of that provider's traffic the shipped capture surface reaches.
17433
+ // A curated business fact, constant across every `range` — not a measured
17434
+ // per-window metric. 0 exactly when `supported` is false. See the comment
17435
+ // above the block for where these numbers are decided.
17379
17436
  coverage: external_exports.number().int().min(0).max(100),
17380
17437
  supported: external_exports.boolean()
17381
17438
  }).meta({ id: "ScanCoverageProvider" });
@@ -17429,6 +17486,18 @@ var ApplyRecommendedActionResponse = external_exports.object({
17429
17486
  var DismissRecommendedActionResponse = external_exports.object({ id: external_exports.string(), status: external_exports.literal("dismissed") }).meta({ id: "DismissRecommendedActionResponse" });
17430
17487
  var RecommendedActionIdParam = external_exports.object({ id: external_exports.string() });
17431
17488
 
17489
+ // ../../packages/schema/src/zod/settings-action.ts
17490
+ var SaveSettingsInput = external_exports.object({
17491
+ historicalAccess: external_exports.string(),
17492
+ modelJudgeConsent: external_exports.boolean(),
17493
+ vaultConsent: external_exports.string(),
17494
+ vaultInlineReveal: external_exports.string()
17495
+ });
17496
+ var AttachInput = external_exports.object({
17497
+ endpoint: external_exports.string(),
17498
+ label: external_exports.string().optional()
17499
+ });
17500
+
17432
17501
  // ../../packages/schema/src/zod/triage.ts
17433
17502
  var TriageHit = external_exports.object({
17434
17503
  ruleId: external_exports.string(),
@@ -17443,7 +17512,7 @@ var TriageHit = external_exports.object({
17443
17512
  valueFingerprint: external_exports.string().optional(),
17444
17513
  keyVersion: external_exports.number().int().nonnegative().optional()
17445
17514
  });
17446
- var TriagePolicy = BuiltinPolicyId;
17515
+ var TriagePolicy = CategoryPolicyId;
17447
17516
  var TriageCategoryRec = external_exports.object({
17448
17517
  category: DetectionCategory,
17449
17518
  action: TriagePolicy,
@@ -17559,9 +17628,12 @@ import { threadId } from "worker_threads";
17559
17628
 
17560
17629
  // ../../packages/persistence/src/internal/snapshot.ts
17561
17630
  var STALE_PARTIAL_MS = 5 * 6e4;
17631
+ var SNAPSHOT_STAGING_SUFFIX = ".partial";
17632
+ var STAGED_NAME_SUFFIX = `.bak${SNAPSHOT_STAGING_SUFFIX}`;
17562
17633
 
17563
17634
  // ../../packages/persistence/src/repositories/activity.ts
17564
17635
  var LIVE_ACTIVITY_WINDOW_MS = 30 * 6e4;
17636
+ var DEFAULT_HARNESS = HARNESS.ClaudeCode;
17565
17637
 
17566
17638
  // ../../packages/persistence/src/repositories/exceptions.ts
17567
17639
  import { randomUUID as randomUUID2 } from "crypto";
@@ -17580,7 +17652,20 @@ import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
17580
17652
  // ../../packages/persistence/src/repositories/inventory-assets.ts
17581
17653
  import { randomUUID as randomUUID4 } from "crypto";
17582
17654
  var VALID_HARNESS_IDS = new Set(HarnessId.options);
17655
+ var HARNESS_LABELS = {
17656
+ [HARNESS.ClaudeCode]: "Claude Code",
17657
+ [HARNESS.Cursor]: "Cursor",
17658
+ [HARNESS.Codex]: "Codex",
17659
+ [HARNESS.Antigravity]: "Antigravity"
17660
+ };
17583
17661
  var HARNESS_LIVENESS_WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
17662
+ var stripSeparators = (value) => value.toLowerCase().replace(/[\s-]/g, "");
17663
+ var TITLE_NEEDLES = {
17664
+ ClaudeCode: stripSeparators(SOURCE_TOOL.ClaudeCode),
17665
+ Cursor: stripSeparators(SOURCE_TOOL.Cursor),
17666
+ Codex: stripSeparators(SOURCE_TOOL.Codex),
17667
+ Antigravity: stripSeparators(SOURCE_TOOL.Antigravity)
17668
+ };
17584
17669
 
17585
17670
  // ../../packages/persistence/src/repositories/policies.ts
17586
17671
  import { randomUUID as randomUUID5 } from "crypto";
@@ -17594,6 +17679,18 @@ import { randomUUID as randomUUID7 } from "crypto";
17594
17679
  // ../../packages/persistence/src/repositories/secret-vault.ts
17595
17680
  import { randomUUID as randomUUID8 } from "crypto";
17596
17681
 
17682
+ // ../../packages/persistence/src/repositories/security.ts
17683
+ var SCAN_COVERAGE = {
17684
+ [HARNESS.Antigravity]: { coverage: 60, supported: true },
17685
+ [HARNESS.Api]: { coverage: 0, supported: false },
17686
+ [HARNESS.ChatGpt]: { coverage: 40, supported: true },
17687
+ [HARNESS.ClaudeAi]: { coverage: 40, supported: true },
17688
+ [HARNESS.ClaudeCode]: { coverage: 100, supported: true },
17689
+ [HARNESS.Codex]: { coverage: 80, supported: true },
17690
+ [HARNESS.Copilot]: { coverage: 0, supported: false },
17691
+ [HARNESS.Cursor]: { coverage: 0, supported: false }
17692
+ };
17693
+
17597
17694
  // ../../packages/persistence/src/repositories/shares.ts
17598
17695
  import { randomUUID as randomUUID9 } from "crypto";
17599
17696
 
@@ -17626,8 +17723,12 @@ import { mkdir } from "fs/promises";
17626
17723
  import { homedir } from "os";
17627
17724
  import { join as join4 } from "path";
17628
17725
 
17629
- // ../../packages/persistence/src/settings.ts
17726
+ // ../../packages/persistence/src/managed-settings.ts
17630
17727
  import { readFileSync as readFileSync3 } from "fs";
17728
+ import { posix, win32 } from "path";
17729
+
17730
+ // ../../packages/persistence/src/settings.ts
17731
+ import { readFileSync as readFileSync4 } from "fs";
17631
17732
  import { join as join5 } from "path";
17632
17733
 
17633
17734
  // ../../packages/persistence/src/vault/crypto.ts
@@ -17642,15 +17743,7 @@ import {
17642
17743
  // ../../packages/persistence/src/vault/key-provider.ts
17643
17744
  import { execFileSync } from "child_process";
17644
17745
  import { randomBytes as randomBytes2 } from "crypto";
17645
- import {
17646
- chmodSync as chmodSync2,
17647
- mkdirSync as mkdirSync2,
17648
- readFileSync as readFileSync4,
17649
- renameSync as renameSync4,
17650
- rmSync as rmSync4,
17651
- statSync as statSync3,
17652
- writeFileSync as writeFileSync3
17653
- } from "fs";
17746
+ import { chmodSync as chmodSync2, readFileSync as readFileSync5, renameSync as renameSync4, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
17654
17747
  import { join as join6 } from "path";
17655
17748
 
17656
17749
  // ../../packages/persistence/src/vault/vault.ts
@@ -17679,7 +17772,7 @@ var providerEnvShape = {
17679
17772
  var ProviderEnvSchema = external_exports.object(providerEnvShape);
17680
17773
 
17681
17774
  // ../../packages/plugin-sdk/src/config-inventory.ts
17682
- import { readdirSync as readdirSync2, readFileSync as readFileSync6, realpathSync, statSync as statSync5 } from "fs";
17775
+ import { readdirSync as readdirSync2, readFileSync as readFileSync7, realpathSync, statSync as statSync5 } from "fs";
17683
17776
  import { homedir as homedir2 } from "os";
17684
17777
  import { basename as basename3, join as join10 } from "path";
17685
17778
 
@@ -18255,6 +18348,40 @@ function escapeRegExp2(value) {
18255
18348
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18256
18349
  }
18257
18350
 
18351
+ // ../../packages/detections/src/regex-cache.ts
18352
+ var singles = /* @__PURE__ */ new WeakMap();
18353
+ var keywordLists = /* @__PURE__ */ new WeakMap();
18354
+ var labelLists = /* @__PURE__ */ new WeakMap();
18355
+ function listCache(kind) {
18356
+ return kind === "keyword" ? keywordLists : labelLists;
18357
+ }
18358
+ function memoizedRegExp(owner, build) {
18359
+ const cached2 = singles.get(owner);
18360
+ if (cached2 !== void 0) {
18361
+ cached2.lastIndex = 0;
18362
+ return cached2;
18363
+ }
18364
+ const compiled = build();
18365
+ singles.set(owner, compiled);
18366
+ return compiled;
18367
+ }
18368
+ function memoizedRegExpList(kind, owner, build) {
18369
+ const cache = listCache(kind);
18370
+ const cached2 = cache.get(owner);
18371
+ if (cached2 !== void 0) {
18372
+ if (cached2.stateful) {
18373
+ for (const re of cached2.entries) if (re !== void 0) re.lastIndex = 0;
18374
+ }
18375
+ return cached2.entries;
18376
+ }
18377
+ const entries = build();
18378
+ cache.set(owner, {
18379
+ entries,
18380
+ stateful: entries.some((re) => re !== void 0 && (re.global || re.sticky))
18381
+ });
18382
+ return entries;
18383
+ }
18384
+
18258
18385
  // ../../packages/detections/src/matchers/limits.ts
18259
18386
  var MAX_MATCHES_PER_RULE = 1e4;
18260
18387
  var MAX_REGEX_INPUT_LENGTH = 2e5;
@@ -18265,10 +18392,17 @@ var KeywordMatcher2 = class {
18265
18392
  if (rule.matcher.type !== "keyword") return [];
18266
18393
  const { keywords, caseSensitive } = rule.matcher;
18267
18394
  const spans = [];
18268
- for (const kw of keywords) {
18269
- if (kw.length === 0) continue;
18395
+ const compiled = memoizedRegExpList(
18396
+ "keyword",
18397
+ rule.matcher,
18398
+ () => keywords.map((kw) => {
18399
+ if (kw.length === 0) return void 0;
18400
+ return new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
18401
+ })
18402
+ );
18403
+ for (const re of compiled) {
18404
+ if (re === void 0) continue;
18270
18405
  if (spans.length >= MAX_MATCHES_PER_RULE) break;
18271
- const re = new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
18272
18406
  let m;
18273
18407
  while ((m = re.exec(text)) !== null) {
18274
18408
  spans.push({ start: m.index, end: m.index + m[0].length });
@@ -18284,7 +18418,10 @@ var RegexMatcher2 = class {
18284
18418
  match(text, rule) {
18285
18419
  if (rule.matcher.type !== "regex") return [];
18286
18420
  const { pattern, flags, captureGroup } = rule.matcher;
18287
- const re = new RegExp(pattern, flags.includes("d") ? flags : `${flags}d`);
18421
+ const re = memoizedRegExp(
18422
+ rule.matcher,
18423
+ () => new RegExp(pattern, flags.includes("d") ? flags : `${flags}d`)
18424
+ );
18288
18425
  const scanText2 = text.length > MAX_REGEX_INPUT_LENGTH ? text.slice(0, MAX_REGEX_INPUT_LENGTH) : text;
18289
18426
  const spans = [];
18290
18427
  let m;
@@ -18367,6 +18504,7 @@ var CONFIG_POSTURE_RULES = [
18367
18504
  ];
18368
18505
 
18369
18506
  // ../../packages/detections/src/security/redos-probe.ts
18507
+ var BUDGET_MS = 100;
18370
18508
  var EXPONENTIAL_UNITS = [
18371
18509
  "a",
18372
18510
  "0",
@@ -18390,9 +18528,11 @@ var EXPONENTIAL_PROBES = EXPONENTIAL_UNITS.flatMap(
18390
18528
  var POLYNOMIAL_PROBES = ["abc-", "a.", "a ", "a=", "x", "0", "a@", "a/", "ab"].map(
18391
18529
  (unit) => unit.repeat(1e4).slice(0, 4e4) + "!"
18392
18530
  );
18531
+ var CPU_CORROBORATION_SHARE = 0.2;
18532
+ var CORROBORATION_FLOOR_MS = BUDGET_MS * CPU_CORROBORATION_SHARE;
18393
18533
 
18394
18534
  // ../../packages/plugin-sdk/src/repo.ts
18395
- import { existsSync as existsSync6, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
18535
+ import { existsSync as existsSync6, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
18396
18536
  import { basename as basename2, dirname as dirname2, isAbsolute, join as join9, sep as sep2 } from "path";
18397
18537
 
18398
18538
  // ../../packages/plugin-sdk/src/events.ts
@@ -18403,21 +18543,25 @@ import { existsSync as existsSync7 } from "fs";
18403
18543
  import { fileURLToPath } from "url";
18404
18544
  import { Worker } from "worker_threads";
18405
18545
 
18546
+ // ../../packages/plugin-sdk/src/ignore-layers.ts
18547
+ var import_ignore = __toESM(require_ignore(), 1);
18548
+ import { readFileSync as readFileSync8 } from "fs";
18549
+ import { join as join11 } from "path";
18550
+
18406
18551
  // ../../packages/plugin-sdk/src/inventory-resolver.ts
18407
18552
  import { arch, hostname as hostname4, platform, release } from "os";
18408
18553
 
18409
18554
  // ../../packages/plugin-sdk/src/nudge.ts
18410
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
18411
- import { join as join11 } from "path";
18555
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
18556
+ import { join as join12 } from "path";
18412
18557
 
18413
18558
  // ../../packages/plugin-sdk/src/paths.ts
18414
18559
  import { readdirSync as readdirSync3, realpathSync as realpathSync2 } from "fs";
18415
18560
  import { basename as basename4, dirname as dirname3, sep as sep3 } from "path";
18416
18561
 
18417
18562
  // ../../packages/plugin-sdk/src/project-files.ts
18418
- var import_ignore = __toESM(require_ignore(), 1);
18419
- import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync8 } from "fs";
18420
- import { basename as basename5, join as join12, relative, sep as sep4 } from "path";
18563
+ import { existsSync as existsSync8, readdirSync as readdirSync4 } from "fs";
18564
+ import { basename as basename5, join as join13 } from "path";
18421
18565
 
18422
18566
  // ../../packages/plugin-sdk/src/provider-env-antigravity.ts
18423
18567
  var optionalBaseUrl2 = external_exports.preprocess((v) => {
@@ -18452,8 +18596,8 @@ import { randomUUID as randomUUID14 } from "crypto";
18452
18596
  var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
18453
18597
 
18454
18598
  // ../../packages/plugin-sdk/src/throttle.ts
18455
- import { mkdirSync as mkdirSync4, statSync as statSync6, writeFileSync as writeFileSync6 } from "fs";
18456
- import { join as join13 } from "path";
18599
+ import { mkdirSync as mkdirSync3, statSync as statSync6, writeFileSync as writeFileSync6 } from "fs";
18600
+ import { join as join14 } from "path";
18457
18601
 
18458
18602
  // ../../packages/setup-wizard/src/onboard-posture.ts
18459
18603
  function parsePosture(json2) {
@@ -18463,10 +18607,10 @@ function parsePosture(json2) {
18463
18607
  for (const [key, value] of Object.entries(raw)) {
18464
18608
  const cat = DetectionCategory.safeParse(key);
18465
18609
  if (!cat.success) throw new Error(`unknown category "${key}"`);
18466
- const act = BuiltinPolicyId.safeParse(value);
18610
+ const act = CategoryPolicyId.safeParse(value);
18467
18611
  if (!act.success)
18468
18612
  throw new Error(
18469
- `invalid action "${String(value)}" for ${key} (expected monitor/warn/redact/block)`
18613
+ `invalid action "${String(value)}" for ${key} (expected ${CATEGORY_EXPRESSIBLE_IDS.join("/")})`
18470
18614
  );
18471
18615
  out[cat.data] = act.data;
18472
18616
  }
@@ -18492,7 +18636,7 @@ function parseCurrent(json2) {
18492
18636
 
18493
18637
  // ../../packages/setup-wizard/src/remediation/rotation-checklist.ts
18494
18638
  import { writeFileSync as writeFileSync7 } from "fs";
18495
- import { join as join14 } from "path";
18639
+ import { join as join15 } from "path";
18496
18640
 
18497
18641
  // ../../packages/setup-wizard/src/triage/gate-display.ts
18498
18642
  var ACTION_RANK = {
@@ -18513,10 +18657,15 @@ function downgradeWarning(downgrades) {
18513
18657
  Heads up \u2014 this would lower ${String(downgrades.length)} detection level${downgrades.length === 1 ? "" : "s"} (${downgrades.join(", ")}) below what you've already set. Confirm you mean to lower ${downgrades.length === 1 ? "it" : "them"} before I apply.`;
18514
18658
  }
18515
18659
 
18660
+ // ../../packages/setup-wizard/src/triage/merge.ts
18661
+ var RANK = Object.fromEntries(
18662
+ KNOWN_BUILTIN_IDS.map((id, i) => [id, i])
18663
+ );
18664
+
18516
18665
  // ../../packages/setup-wizard/src/triage/plan-file.ts
18517
- import { mkdtempSync, readFileSync as readFileSync9, rmdirSync, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "fs";
18666
+ import { mkdtempSync, readFileSync as readFileSync10, rmdirSync, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "fs";
18518
18667
  import { tmpdir } from "os";
18519
- import { basename as basename6, dirname as dirname4, join as join15 } from "path";
18668
+ import { basename as basename6, dirname as dirname4, join as join16 } from "path";
18520
18669
  var SuppressionEntrySchema = external_exports.object({
18521
18670
  ruleId: external_exports.string(),
18522
18671
  category: DetectionCategory,
@@ -18615,8 +18764,8 @@ function table(headers, rows, opts = {}) {
18615
18764
  const widths = headers.map(
18616
18765
  (h, i) => Math.max(visibleLength(h), ...rows.map((r) => visibleLength(r[i] ?? "")))
18617
18766
  );
18618
- const sep5 = " ".repeat(gap);
18619
- const fmt = (cells) => cells.map((cell, i) => padEnd(cell, widths[i] ?? 0)).join(sep5);
18767
+ const sep4 = " ".repeat(gap);
18768
+ const fmt = (cells) => cells.map((cell, i) => padEnd(cell, widths[i] ?? 0)).join(sep4);
18620
18769
  const headerLine = fmt(headers.map((h) => h.toUpperCase()));
18621
18770
  if (opts.rowSep === true) {
18622
18771
  const fullWidth = widths.reduce((n, w) => n + w, 0) + gap * Math.max(0, widths.length - 1);
@@ -18628,7 +18777,7 @@ function table(headers, rows, opts = {}) {
18628
18777
  });
18629
18778
  return [headerLine, rule, ...body].join("\n");
18630
18779
  }
18631
- const ruleLine = widths.map((w) => "\u2500".repeat(w)).join(sep5);
18780
+ const ruleLine = widths.map((w) => "\u2500".repeat(w)).join(sep4);
18632
18781
  return [headerLine, ruleLine, ...rows.map(fmt)].join("\n");
18633
18782
  }
18634
18783
  function fenced(body) {
@@ -18664,9 +18813,9 @@ function renderPostureGrid(posture) {
18664
18813
  );
18665
18814
  const rows = packs.map((category) => [
18666
18815
  category,
18667
- ...BUILTIN_ORDER.map((level) => posture[category] === level ? GRID_MARK : "")
18816
+ ...CATEGORY_EXPRESSIBLE_IDS.map((level) => posture[category] === level ? GRID_MARK : "")
18668
18817
  ]);
18669
- return indent(table(["Category", ...BUILTIN_ORDER], rows));
18818
+ return indent(table(["Category", ...CATEGORY_EXPRESSIBLE_IDS], rows));
18670
18819
  }
18671
18820
  var RE_TUNE_HINT = "Re-tune anytime with /aka:setup or the dashboard";
18672
18821
  var PACK_RATIONALE = {