@akasecurity/ai-tc-claude-code 0.8.1 → 0.9.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/scripts/intro.js CHANGED
@@ -494,71 +494,15 @@ var require_ignore = __commonJS({
494
494
  // src/intro.ts
495
495
  import { readFileSync as readFileSync7 } from "fs";
496
496
 
497
- // src/present.ts
498
- var SHADE = {
499
- light: "\u2591",
500
- medium: "\u2592",
501
- dark: "\u2593",
502
- full: "\u2588"
503
- };
504
- var ANSI_RE = /\x1b\[[0-9;]*m/g;
505
- function visibleLength(text) {
506
- return text.replace(ANSI_RE, "").length;
507
- }
508
- var fg = (hex3) => (text) => {
509
- const r = Number.parseInt(hex3.slice(1, 3), 16);
510
- const g = Number.parseInt(hex3.slice(3, 5), 16);
511
- const b = Number.parseInt(hex3.slice(5, 7), 16);
512
- return `\x1B[38;2;${String(r)};${String(g)};${String(b)}m${text}\x1B[0m`;
513
- };
514
- var paint = {
515
- brand: fg("#33e6c6"),
516
- // --color-brand · ▸▸ AKA wordmark (accent text)
517
- dim: fg("#838995"),
518
- // --color-text-3 · separators · "/100" · the "unreviewed" label
519
- bold: (text) => `\x1B[1m${text}\x1B[0m`,
520
- // the health score number
521
- ok: fg("#0db15f"),
522
- // --color-ok · healthy ● dot
523
- critical: fg("#e63448"),
524
- // --color-sev-critical · ■ and the open-findings flag
525
- high: fg("#e97a0a"),
526
- // --color-sev-high · ■ and the mid-health dot
527
- medium: fg("#f7bd00"),
528
- // --color-sev-medium · ■
529
- low: fg("#0581d4")
530
- // --color-sev-low · ■ (azure blue, not purple)
531
- };
532
- function padEnd(text, width) {
533
- const pad = width - visibleLength(text);
534
- return pad > 0 ? text + " ".repeat(pad) : text;
535
- }
536
- function defList(rows, gap = 4) {
537
- const labelWidth = Math.max(0, ...rows.map(([label]) => visibleLength(label)));
538
- return rows.map(([label, value]) => `${padEnd(label, labelWidth)}${" ".repeat(gap)}${value}`).join("\n");
539
- }
540
- function indent(text, spaces = 2) {
541
- const pad = " ".repeat(spaces);
542
- return text.split("\n").map((line) => pad + line).join("\n");
543
- }
544
- function fenced(body) {
545
- const longestRun = Math.max(0, ...[...body.matchAll(/`+/g)].map((m) => m[0].length));
546
- const fence = "`".repeat(Math.max(3, longestRun + 1));
547
- return [fence, body, fence].join("\n");
548
- }
549
-
550
- // ../../packages/persistence/src/database.ts
551
- import { randomUUID as randomUUID8 } from "crypto";
552
- import { existsSync, renameSync, rmSync } from "fs";
553
- import { join, sep } from "path";
554
- import { DatabaseSync } from "node:sqlite";
555
-
556
497
  // ../../packages/schema/src/exception-scope.ts
557
498
  var MINUTE_MS = 6e4;
558
499
  var HOUR_MS = 60 * MINUTE_MS;
559
500
  var MAX_TEMPORARY_MS = 24 * HOUR_MS;
560
501
  var ONCE_BACKSTOP_MS = 30 * MINUTE_MS;
561
502
 
503
+ // ../../packages/schema/src/identity.ts
504
+ var PRODUCT_NAME = "AKA Security";
505
+
562
506
  // ../../packages/schema/src/token/cost-model.ts
563
507
  var CACHE_WRITE_5M_MULT = 1.25;
564
508
  var CACHE_WRITE_1H_MULT = 2;
@@ -603,6 +547,12 @@ var PRICE_MAP = {
603
547
  };
604
548
  var CANONICAL_ANTHROPIC_MODELS = Object.keys(ANTHROPIC_PRICES);
605
549
 
550
+ // ../../packages/schema/src/token/format.ts
551
+ var COMPACT = new Intl.NumberFormat("en-US", {
552
+ notation: "compact",
553
+ maximumFractionDigits: 1
554
+ });
555
+
606
556
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
607
557
  var external_exports = {};
608
558
  __export(external_exports, {
@@ -15181,6 +15131,12 @@ var FindingInstance = external_exports.object({
15181
15131
  provider: FindingProvider,
15182
15132
  repo: external_exports.string(),
15183
15133
  file: external_exports.string(),
15134
+ // Host tool that produced the scanned text (event metadata's toolName).
15135
+ // Present whenever the capturing hook recorded one — including
15136
+ // file-attributed captures (views prefer `file`); its display value is
15137
+ // the location fallback ("via Bash") when no filePath exists. Absent for
15138
+ // legacy rows and non-tool captures (prompts, worktree scans).
15139
+ toolName: external_exports.string().optional(),
15184
15140
  // Effective action: override.action ?? actionTaken, translated to FindingAction.
15185
15141
  action: FindingAction,
15186
15142
  detectedAt: external_exports.iso.datetime(),
@@ -15236,6 +15192,9 @@ var ListGroupedFindingsQuery = external_exports.object({
15236
15192
  provider: external_exports.array(FindingProvider).optional(),
15237
15193
  action: external_exports.array(FindingAction).optional(),
15238
15194
  q: external_exports.string().optional(),
15195
+ // Scope to findings whose event carries this session id (the Activity page's
15196
+ // session → findings drilldown). Findings without a session never match.
15197
+ sessionId: external_exports.string().optional(),
15239
15198
  groupBy: external_exports.literal("type").optional(),
15240
15199
  limit: external_exports.coerce.number().int().min(1).max(100).optional(),
15241
15200
  cursor: external_exports.string().optional()
@@ -15247,7 +15206,13 @@ var ListGroupedFindingsResponse = external_exports.object({
15247
15206
  }),
15248
15207
  facets: FindingFacets,
15249
15208
  items: external_exports.array(FindingGroup),
15250
- nextCursor: external_exports.string().nullable()
15209
+ nextCursor: external_exports.string().nullable(),
15210
+ // Present only on session-scoped queries (`sessionId` set): per ruleId, how
15211
+ // many times that rule fired in the session's persisted transcript. Findings
15212
+ // here are deduplicated to unique values while the transcript tally counts
15213
+ // every firing, so the two numbers legitimately differ — this map lets a
15214
+ // session-scoped view show both.
15215
+ sessionFirings: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()).optional()
15251
15216
  }).meta({ id: "ListGroupedFindingsResponse" });
15252
15217
  var ApplyFindingActionRequest = external_exports.object({
15253
15218
  // 'quarantined' is system-assigned (see FindingAction) — clients may not set
@@ -15289,6 +15254,11 @@ var AuditEventType = external_exports.enum([
15289
15254
  "prompt",
15290
15255
  "response",
15291
15256
  "code_change",
15257
+ // The events.kind of a scanned tool call, widened in to keep this a
15258
+ // superset. Narrower than 'tool_call' above and not a duplicate of it:
15259
+ // 'tool_call' is the reconciler's structural row for every call, while
15260
+ // 'tool_use' exists only where a hook enforced against the arguments.
15261
+ "tool_use",
15292
15262
  // One row per config-inventory scan, hung off the session root. It is the
15293
15263
  // fact the posture inspection findings reference (findings require an
15294
15264
  // audit_event_id), and its started_at is the "scanned Nm ago" the read
@@ -15640,6 +15610,10 @@ var ListActivitySessionsQuery = external_exports.object({
15640
15610
  from: external_exports.union([external_exports.iso.date(), external_exports.iso.datetime()]).optional(),
15641
15611
  /** Upper bound on startedAt; omitted defaults to now. */
15642
15612
  to: external_exports.union([external_exports.iso.date(), external_exports.iso.datetime()]).optional(),
15613
+ /** Exclude zero-activity sessions — roots whose only recorded children are
15614
+ * bookkeeping rows (hooks, config scans), typically background `claude`
15615
+ * launches. Omitted = list everything. `z.stringbool()` per the note above. */
15616
+ excludeEmpty: external_exports.stringbool().optional(),
15643
15617
  /** Page size, 1–100; out-of-range values are a 400. `z.coerce` — query params arrive as strings. */
15644
15618
  limit: external_exports.coerce.number().int().min(1).max(100).default(50),
15645
15619
  /** Opaque pagination cursor (most-recent first). */
@@ -15648,7 +15622,11 @@ var ListActivitySessionsQuery = external_exports.object({
15648
15622
  var ListActivitySessionsResponse = external_exports.object({
15649
15623
  items: external_exports.array(ActivitySessionSummary),
15650
15624
  /** `null` once the last page is reached. */
15651
- nextCursor: external_exports.string().nullable()
15625
+ nextCursor: external_exports.string().nullable(),
15626
+ /** Zero-activity sessions matching the query's filters/range (whether or
15627
+ * not `excludeEmpty` dropped them from `items`) — the count a UI toggle
15628
+ * shows when collapsing them. */
15629
+ emptyCount: external_exports.number().int().nonnegative()
15652
15630
  }).meta({ id: "ListActivitySessionsResponse" });
15653
15631
  var ListSessionEventsQuery = external_exports.object({
15654
15632
  /** Default 100, range 1–500. */
@@ -15677,12 +15655,18 @@ var ActivityOverviewResponse = external_exports.object({
15677
15655
  }).meta({ id: "ActivityOverviewResponse" });
15678
15656
 
15679
15657
  // ../../packages/schema/src/zod/event.ts
15680
- var EventKind = external_exports.enum(["prompt", "response", "code_change"]).meta({ id: "EventKind" });
15658
+ var EventKind = external_exports.enum(["prompt", "response", "code_change", "tool_use"]).meta({ id: "EventKind" });
15681
15659
  var SourceTool = external_exports.enum(["claude-code", "claude-desktop", "cursor", "chatgpt", "github-copilot", "cli", "unknown"]).meta({ id: "SourceTool" });
15682
15660
  var EventMetadata = external_exports.object({
15683
15661
  sessionId: external_exports.string().optional(),
15684
15662
  repo: external_exports.string().optional(),
15685
15663
  filePath: external_exports.string().optional(),
15664
+ // The host tool whose input/output was scanned (e.g. 'Bash', 'WebFetch'),
15665
+ // set by the tool-scanning hooks. The tool NAME only — never the tool's
15666
+ // arguments or output, which can carry the very value a finding masked
15667
+ // (metadata is stored unredacted). Gives findings on non-file captures a
15668
+ // display location ("via Bash") when no filePath exists.
15669
+ toolName: external_exports.string().optional(),
15686
15670
  // Set (true) by the worktree scanner when the file is excluded by the
15687
15671
  // repo's .gitignore. Gitignored files ARE still scanned — local scratch and
15688
15672
  // generated code can leak real secrets — but the provenance is recorded so
@@ -15990,7 +15974,7 @@ var DetectionException = external_exports.object({
15990
15974
  justification: external_exports.string().min(1),
15991
15975
  conditions: ExceptionConditions.nullable(),
15992
15976
  createdBy: external_exports.string(),
15993
- createdVia: external_exports.enum(["cli-approve", "cli-add", "web-approve", "web-add", "api"]),
15977
+ createdVia: external_exports.enum(["cli-approve", "cli-add", "web-approve", "web-add", "api", "setup-triage"]),
15994
15978
  createdAt: external_exports.iso.datetime(),
15995
15979
  updatedAt: external_exports.iso.datetime(),
15996
15980
  // Revocation is terminal and retained — consumed/expired/revoked rows are
@@ -16014,7 +15998,10 @@ var ExceptionBundleEntry = DetectionException.pick({
16014
15998
  var MatcherType = external_exports.enum(["keyword", "regex", "validator"]).meta({ id: "MatcherType" });
16015
15999
  var KeywordMatcher = external_exports.object({
16016
16000
  type: external_exports.literal("keyword"),
16017
- keywords: external_exports.array(external_exports.string()).min(1),
16001
+ // An empty keyword matches at every position, yielding one zero-length span
16002
+ // per character. Rejected here because a keyword that matches everything is
16003
+ // never intentional.
16004
+ keywords: external_exports.array(external_exports.string().min(1)).min(1),
16018
16005
  caseSensitive: external_exports.boolean().default(false)
16019
16006
  });
16020
16007
  function isValidRegex(pattern, flags) {
@@ -16161,6 +16148,24 @@ var PolicyBundle = external_exports.object({
16161
16148
  }).meta({ id: "PolicyBundle" });
16162
16149
  var OBSERVE_ONLY_CATEGORIES = ["config"];
16163
16150
  var ENFORCEABLE_CATEGORIES = DetectionCategory.options.filter((c) => !OBSERVE_ONLY_CATEGORIES.includes(c));
16151
+ var CATEGORY_PEAK_SEVERITY = {
16152
+ secret: "critical",
16153
+ financial: "critical",
16154
+ // core-financial/credit-card
16155
+ code_flaw: "critical",
16156
+ pii: "high",
16157
+ phi: "high",
16158
+ custom: "high",
16159
+ // user-defined; conservative
16160
+ code_context: "low",
16161
+ config: "low"
16162
+ // observe-only; floors to monitor regardless
16163
+ };
16164
+ function severityFloorPolicy(category) {
16165
+ if (OBSERVE_ONLY_CATEGORIES.includes(category)) return "monitor";
16166
+ const peak = CATEGORY_PEAK_SEVERITY[category];
16167
+ return peak === "critical" || peak === "high" ? "warn" : "monitor";
16168
+ }
16164
16169
  var PolicyKind = external_exports.enum(["builtin", "custom"]).meta({ id: "PolicyKind" });
16165
16170
  var KNOWN_BUILTIN_IDS = ["monitor", "warn", "redact", "block"];
16166
16171
  var BuiltinPolicyId = external_exports.enum(KNOWN_BUILTIN_IDS).meta({ id: "BuiltinPolicyId" });
@@ -16186,6 +16191,12 @@ var BUILTIN_POLICY_SPECS = {
16186
16191
  description: "Refuse the request entirely whenever any rule in this detection matches."
16187
16192
  }
16188
16193
  };
16194
+ function builtinPolicyToAction(id) {
16195
+ return BUILTIN_POLICY_SPECS[id].action;
16196
+ }
16197
+ var DEFAULT_ACTIONS = Object.fromEntries(
16198
+ DetectionCategory.options.map((c) => [c, builtinPolicyToAction(severityFloorPolicy(c))])
16199
+ );
16189
16200
  var BUILTIN_POLICIES = Object.fromEntries(
16190
16201
  KNOWN_BUILTIN_IDS.map((id) => [id, { id, ...BUILTIN_POLICY_SPECS[id] }])
16191
16202
  );
@@ -16232,6 +16243,10 @@ var ListEventsResponse = external_exports.object({
16232
16243
  items: external_exports.array(Event),
16233
16244
  nextCursor: external_exports.string().nullable()
16234
16245
  }).meta({ id: "ListEventsResponse" });
16246
+ var IngestResponse = external_exports.object({
16247
+ accepted: external_exports.number().int().nonnegative(),
16248
+ duplicates: external_exports.number().int().nonnegative()
16249
+ }).meta({ id: "IngestResponse" });
16235
16250
  var ListFindingsQuery = external_exports.object({
16236
16251
  cursor: external_exports.string().optional(),
16237
16252
  limit: external_exports.coerce.number().int().min(1).max(LIST_QUERY_MAX_LIMIT).default(50),
@@ -16552,6 +16567,65 @@ var ProjectFilesScan = external_exports.object({
16552
16567
  scannedAt: external_exports.string()
16553
16568
  });
16554
16569
 
16570
+ // ../../packages/schema/src/zod/ranges.ts
16571
+ var TIME_RANGES = ["7d", "30d", "3m", "6m"];
16572
+ var TimeRange = external_exports.enum(TIME_RANGES).meta({ id: "TimeRange" });
16573
+ var DEFAULT_TIME_RANGE = "7d";
16574
+ var TIME_RANGE_OR_DEFAULT = TimeRange.catch(DEFAULT_TIME_RANGE);
16575
+
16576
+ // ../../packages/schema/src/zod/remediation.ts
16577
+ var SecretFindingState = external_exports.enum(["still-valid", "unknown", "invalid"]);
16578
+ var MaskedFindingLocation = external_exports.object({
16579
+ filePath: external_exports.string(),
16580
+ span: Span.optional()
16581
+ }).strict();
16582
+ var MaskedSecretFinding = external_exports.object({
16583
+ provider: external_exports.string(),
16584
+ maskedToken: external_exports.string(),
16585
+ where: MaskedFindingLocation,
16586
+ state: SecretFindingState,
16587
+ observedAt: external_exports.iso.datetime().optional()
16588
+ }).strict();
16589
+ var RotationChecklistEntry = external_exports.object({
16590
+ provider: external_exports.string(),
16591
+ maskedToken: external_exports.string(),
16592
+ consolePath: external_exports.string(),
16593
+ occurrenceSpread: external_exports.number().int().positive()
16594
+ }).strict();
16595
+ var RemediationOption = external_exports.enum([
16596
+ "redact-rotation-checklist",
16597
+ "redact-only",
16598
+ "set-secret-redact",
16599
+ "leave"
16600
+ ]);
16601
+ var RemediationEntrySource = external_exports.enum(["first-run", "pre-push", "secret-scan"]);
16602
+ var RemediationEntryContext = external_exports.object({
16603
+ entrySource: RemediationEntrySource
16604
+ }).strict();
16605
+ var RemediationOptionChoice = external_exports.object({
16606
+ id: RemediationOption,
16607
+ label: external_exports.string()
16608
+ });
16609
+ var BatchedRemediationDecision = external_exports.object({
16610
+ kind: external_exports.literal("decision"),
16611
+ entrySource: RemediationEntrySource,
16612
+ secretCount: external_exports.number().int().positive(),
16613
+ prompt: external_exports.string(),
16614
+ options: external_exports.tuple([
16615
+ RemediationOptionChoice.extend({ id: external_exports.literal("redact-rotation-checklist") }),
16616
+ RemediationOptionChoice.extend({ id: external_exports.literal("redact-only") }),
16617
+ RemediationOptionChoice.extend({ id: external_exports.literal("set-secret-redact") }),
16618
+ RemediationOptionChoice.extend({ id: external_exports.literal("leave") })
16619
+ ])
16620
+ });
16621
+ var NoRemediationDecision = external_exports.object({
16622
+ kind: external_exports.literal("no-decision")
16623
+ });
16624
+ var BatchedRemediation = external_exports.discriminatedUnion("kind", [
16625
+ BatchedRemediationDecision,
16626
+ NoRemediationDecision
16627
+ ]);
16628
+
16555
16629
  // ../../packages/schema/src/zod/rule-test.ts
16556
16630
  var TestRulesRequest = external_exports.object({
16557
16631
  rules: external_exports.array(Rule).min(1).max(100),
@@ -16610,10 +16684,8 @@ var SeveritySummaryResponse = external_exports.object({
16610
16684
  // All four severity levels are always present (count may be 0).
16611
16685
  bySeverity: external_exports.array(SeveritySummaryItem)
16612
16686
  }).meta({ id: "SeveritySummaryResponse" });
16613
- var SECURITY_RANGES = ["7d", "30d", "3m", "6m"];
16614
- var SecurityRange = external_exports.enum(SECURITY_RANGES).meta({ id: "SecurityRange" });
16615
16687
  var SecurityRangeQuery = external_exports.object({
16616
- range: external_exports.enum(SECURITY_RANGES).default("30d")
16688
+ range: external_exports.enum(TIME_RANGES).default(DEFAULT_TIME_RANGE)
16617
16689
  });
16618
16690
  var EnforcementActionKind = external_exports.enum(["blocked", "redacted", "warned"]).meta({ id: "EnforcementActionKind" });
16619
16691
  var EnforcementAction = external_exports.object({
@@ -16623,7 +16695,7 @@ var EnforcementAction = external_exports.object({
16623
16695
  delta: external_exports.number().int()
16624
16696
  }).meta({ id: "EnforcementAction" });
16625
16697
  var EnforcementActionsResponse = external_exports.object({
16626
- range: SecurityRange,
16698
+ range: TimeRange,
16627
16699
  // Sum of actions[].count in the window.
16628
16700
  total: external_exports.number().int().nonnegative(),
16629
16701
  // One entry per kind, always all three present (count may be 0).
@@ -16638,7 +16710,7 @@ var FindingsTimeseriesPoint = external_exports.object({
16638
16710
  medium: external_exports.number().int().nonnegative()
16639
16711
  }).meta({ id: "FindingsTimeseriesPoint" });
16640
16712
  var FindingsTimeseriesResponse = external_exports.object({
16641
- range: SecurityRange,
16713
+ range: TimeRange,
16642
16714
  granularity: TimeseriesGranularity,
16643
16715
  points: external_exports.array(FindingsTimeseriesPoint)
16644
16716
  }).meta({ id: "FindingsTimeseriesResponse" });
@@ -16653,7 +16725,7 @@ var MttrTrendPoint = external_exports.object({
16653
16725
  })
16654
16726
  }).meta({ id: "MttrTrendPoint" });
16655
16727
  var MttrTrendResponse = external_exports.object({
16656
- range: SecurityRange,
16728
+ range: TimeRange,
16657
16729
  granularity: TimeseriesGranularity,
16658
16730
  points: external_exports.array(MttrTrendPoint)
16659
16731
  }).meta({ id: "MttrTrendResponse" });
@@ -16680,11 +16752,11 @@ var TopSource = external_exports.object({
16680
16752
  findingsCount: external_exports.number().int().nonnegative()
16681
16753
  }).meta({ id: "TopSource" });
16682
16754
  var TopSourcesResponse = external_exports.object({
16683
- range: SecurityRange,
16755
+ range: TimeRange,
16684
16756
  items: external_exports.array(TopSource)
16685
16757
  }).meta({ id: "TopSourcesResponse" });
16686
16758
  var TopSourcesQuery = external_exports.object({
16687
- range: external_exports.enum(SECURITY_RANGES).default("30d"),
16759
+ range: external_exports.enum(TIME_RANGES).default(DEFAULT_TIME_RANGE),
16688
16760
  limit: external_exports.coerce.number().int().min(1).max(50).default(5),
16689
16761
  // Omit for both kinds.
16690
16762
  kind: external_exports.enum(SOURCE_KINDS).optional()
@@ -16697,7 +16769,7 @@ var ScanCoverageProvider = external_exports.object({
16697
16769
  supported: external_exports.boolean()
16698
16770
  }).meta({ id: "ScanCoverageProvider" });
16699
16771
  var ScanCoverageResponse = external_exports.object({
16700
- range: SecurityRange,
16772
+ range: TimeRange,
16701
16773
  providers: external_exports.array(ScanCoverageProvider)
16702
16774
  }).meta({ id: "ScanCoverageResponse" });
16703
16775
  var SubjectType = external_exports.enum(["repo", "user", "team", "policy", "share", "rule"]).meta({
@@ -16746,6 +16818,114 @@ var ApplyRecommendedActionResponse = external_exports.object({
16746
16818
  var DismissRecommendedActionResponse = external_exports.object({ id: external_exports.string(), status: external_exports.literal("dismissed") }).meta({ id: "DismissRecommendedActionResponse" });
16747
16819
  var RecommendedActionIdParam = external_exports.object({ id: external_exports.string() });
16748
16820
 
16821
+ // ../../packages/schema/src/zod/triage.ts
16822
+ var TriageHit = external_exports.object({
16823
+ ruleId: external_exports.string(),
16824
+ category: DetectionCategory,
16825
+ severity: Severity,
16826
+ maskedMatch: external_exports.string(),
16827
+ rawMatch: external_exports.string(),
16828
+ context: external_exports.string(),
16829
+ filePath: external_exports.string().optional(),
16830
+ confidence: external_exports.number().min(0).max(1),
16831
+ id: external_exports.string().optional(),
16832
+ valueFingerprint: external_exports.string().optional(),
16833
+ keyVersion: external_exports.number().int().nonnegative().optional()
16834
+ });
16835
+ var TriagePolicy = BuiltinPolicyId;
16836
+ var TriageCategoryRec = external_exports.object({
16837
+ category: DetectionCategory,
16838
+ action: TriagePolicy,
16839
+ reasoning: external_exports.string(),
16840
+ genuineCount: external_exports.number().int().nonnegative(),
16841
+ fpCount: external_exports.number().int().nonnegative(),
16842
+ // TriageHit ids judged false-positive in this category. fpCount must equal
16843
+ // this array's length — enforced by the consumer, not this schema.
16844
+ fpIds: external_exports.array(external_exports.string())
16845
+ });
16846
+ var TriageRecommendation = external_exports.object({
16847
+ perCategory: external_exports.array(TriageCategoryRec),
16848
+ notes: external_exports.string()
16849
+ });
16850
+
16851
+ // ../../packages/schema/src/zod/setup-frame.ts
16852
+ var CalibrationCounts = external_exports.object({
16853
+ total: external_exports.number().int().nonnegative(),
16854
+ important: external_exports.number().int().nonnegative(),
16855
+ routine: external_exports.number().int().nonnegative()
16856
+ }).refine((c) => c.total === c.important + c.routine, {
16857
+ message: "total must equal important + routine",
16858
+ path: ["total"]
16859
+ });
16860
+ var FalsePositivePatternValue = external_exports.object({
16861
+ ruleId: external_exports.string(),
16862
+ category: DetectionCategory,
16863
+ valueFingerprint: external_exports.string(),
16864
+ keyVersion: external_exports.number().int().nonnegative()
16865
+ });
16866
+ var FalsePositivePatternGroup = external_exports.object({
16867
+ pattern: external_exports.string(),
16868
+ count: external_exports.number().int().nonnegative(),
16869
+ values: external_exports.array(FalsePositivePatternValue).min(1)
16870
+ });
16871
+ var CalibrationFindingKind = external_exports.object({
16872
+ category: DetectionCategory,
16873
+ count: external_exports.number().int().nonnegative(),
16874
+ egress: external_exports.boolean()
16875
+ });
16876
+ var CalibrationFrame = external_exports.object({
16877
+ counts: CalibrationCounts,
16878
+ routineCategories: external_exports.array(DetectionCategory),
16879
+ surfacedCategories: external_exports.array(DetectionCategory),
16880
+ findingKinds: external_exports.array(CalibrationFindingKind),
16881
+ posture: external_exports.record(DetectionCategory, BuiltinPolicyId),
16882
+ maskedFindings: external_exports.array(MaskedSecretFinding).optional(),
16883
+ falsePositivePatterns: external_exports.array(FalsePositivePatternGroup).optional()
16884
+ });
16885
+ var CalibrationPreviewCategory = TriageCategoryRec.pick({
16886
+ category: true,
16887
+ genuineCount: true,
16888
+ fpCount: true
16889
+ }).extend({
16890
+ egress: external_exports.boolean()
16891
+ });
16892
+ var CalibrationPreview = external_exports.object({
16893
+ categories: external_exports.array(CalibrationPreviewCategory),
16894
+ posture: external_exports.record(DetectionCategory, BuiltinPolicyId)
16895
+ });
16896
+ var CalibrationResult = external_exports.object({
16897
+ frame: CalibrationFrame,
16898
+ copy: external_exports.string()
16899
+ });
16900
+ var FirstRunCalibration = external_exports.enum(["scan", "floor"]);
16901
+ var SetupHandoffOption = external_exports.object({
16902
+ id: external_exports.enum(["enter-remediation", "open-dashboard", "not-now"]),
16903
+ label: external_exports.string()
16904
+ });
16905
+ var DashboardHandoffOptions = external_exports.tuple([
16906
+ SetupHandoffOption.extend({ id: external_exports.literal("open-dashboard") }),
16907
+ SetupHandoffOption.extend({ id: external_exports.literal("not-now") })
16908
+ ]);
16909
+ var ComposedRemediationOptions = external_exports.tuple([
16910
+ SetupHandoffOption.extend({ id: external_exports.literal("enter-remediation") }),
16911
+ SetupHandoffOption.extend({ id: external_exports.literal("open-dashboard") }),
16912
+ SetupHandoffOption.extend({ id: external_exports.literal("not-now") })
16913
+ ]);
16914
+ var SetupHandoffOffer = external_exports.object({
16915
+ worthALook: external_exports.number().int().nonnegative(),
16916
+ liveKeys: external_exports.number().int().nonnegative().optional(),
16917
+ options: external_exports.union([DashboardHandoffOptions, ComposedRemediationOptions])
16918
+ }).refine(
16919
+ (o) => o.options.some((opt) => opt.id === "enter-remediation") === (o.liveKeys ?? 0) > 0,
16920
+ {
16921
+ message: "the chain-entry option is present exactly when liveKeys > 0",
16922
+ path: ["options"]
16923
+ }
16924
+ ).refine((o) => (o.liveKeys ?? 0) <= o.worthALook, {
16925
+ message: "liveKeys is a subset of worthALook and cannot exceed it",
16926
+ path: ["liveKeys"]
16927
+ });
16928
+
16749
16929
  // ../../packages/schema/src/zod/shares.ts
16750
16930
  var DestinationKind = external_exports.enum(["provider", "internal", "ip"]).meta({ id: "DestinationKind" });
16751
16931
  var Transport = external_exports.enum(["https", "http", "sftp", "grpc", "smtp"]).meta({ id: "Transport" });
@@ -16885,6 +17065,16 @@ var ExportSharesQuery = external_exports.object({
16885
17065
  kind: external_exports.array(DestinationKind).optional()
16886
17066
  });
16887
17067
 
17068
+ // src/provenance.ts
17069
+ import { execFileSync } from "child_process";
17070
+ var USE_SHELL = process.platform === "win32";
17071
+
17072
+ // ../../packages/persistence/src/database.ts
17073
+ import { randomUUID as randomUUID8 } from "crypto";
17074
+ import { existsSync, renameSync, rmSync } from "fs";
17075
+ import { join, sep } from "path";
17076
+ import { DatabaseSync } from "node:sqlite";
17077
+
16888
17078
  // ../../packages/persistence/src/ids.ts
16889
17079
  import { createHash } from "crypto";
16890
17080
 
@@ -16934,6 +17124,10 @@ import { join as join3 } from "path";
16934
17124
  import { readFileSync as readFileSync2, renameSync as renameSync4, writeFileSync as writeFileSync2 } from "fs";
16935
17125
  import { join as join4 } from "path";
16936
17126
 
17127
+ // ../../packages/persistence/src/warn-era-cap.ts
17128
+ import { existsSync as existsSync2, writeFileSync as writeFileSync3 } from "fs";
17129
+ import { join as join5 } from "path";
17130
+
16937
17131
  // ../../packages/plugin-sdk/src/provider-env.ts
16938
17132
  var booleanish = external_exports.string().optional().transform((v) => {
16939
17133
  if (v === void 0) return void 0;
@@ -16955,23 +17149,30 @@ var ProviderEnvSchema = external_exports.object(providerEnvShape);
16955
17149
  // ../../packages/plugin-sdk/src/config-inventory.ts
16956
17150
  import { readdirSync, readFileSync as readFileSync4, realpathSync, statSync as statSync2 } from "fs";
16957
17151
  import { homedir as homedir2 } from "os";
16958
- import { basename as basename2, join as join6 } from "path";
17152
+ import { basename as basename2, join as join7 } from "path";
17153
+
17154
+ // ../../packages/detections/src/escape-regexp.ts
17155
+ function escapeRegExp(value) {
17156
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
17157
+ }
17158
+
17159
+ // ../../packages/detections/src/matchers/limits.ts
17160
+ var MAX_MATCHES_PER_RULE = 1e4;
16959
17161
 
16960
17162
  // ../../packages/detections/src/matchers/keyword.ts
16961
17163
  var KeywordMatcher2 = class {
16962
17164
  match(text, rule) {
16963
17165
  if (rule.matcher.type !== "keyword") return [];
16964
17166
  const { keywords, caseSensitive } = rule.matcher;
16965
- const haystack = caseSensitive ? text : text.toLowerCase();
16966
17167
  const spans = [];
16967
17168
  for (const kw of keywords) {
16968
- const needle = caseSensitive ? kw : kw.toLowerCase();
16969
- let idx = 0;
16970
- while (idx < haystack.length) {
16971
- const pos = haystack.indexOf(needle, idx);
16972
- if (pos === -1) break;
16973
- spans.push({ start: pos, end: pos + kw.length });
16974
- idx = pos + 1;
17169
+ if (kw.length === 0) continue;
17170
+ if (spans.length >= MAX_MATCHES_PER_RULE) break;
17171
+ const re = new RegExp(escapeRegExp(kw), caseSensitive ? "gu" : "giu");
17172
+ let m;
17173
+ while ((m = re.exec(text)) !== null) {
17174
+ spans.push({ start: m.index, end: m.index + m[0].length });
17175
+ if (spans.length >= MAX_MATCHES_PER_RULE) break;
16975
17176
  }
16976
17177
  }
16977
17178
  return spans;
@@ -16979,7 +17180,6 @@ var KeywordMatcher2 = class {
16979
17180
  };
16980
17181
 
16981
17182
  // ../../packages/detections/src/matchers/regex.ts
16982
- var MAX_MATCHES_PER_RULE = 1e4;
16983
17183
  var RegexMatcher2 = class {
16984
17184
  match(text, rule) {
16985
17185
  if (rule.matcher.type !== "regex") return [];
@@ -17063,8 +17263,8 @@ var CONFIG_POSTURE_RULES = [
17063
17263
  ];
17064
17264
 
17065
17265
  // ../../packages/plugin-sdk/src/repo.ts
17066
- import { existsSync as existsSync2, readFileSync as readFileSync3, statSync } from "fs";
17067
- import { basename, dirname, isAbsolute, join as join5, sep as sep2 } from "path";
17266
+ import { existsSync as existsSync3, readFileSync as readFileSync3, statSync } from "fs";
17267
+ import { basename, dirname, isAbsolute, join as join6, sep as sep2 } from "path";
17068
17268
 
17069
17269
  // ../../packages/plugin-sdk/src/events.ts
17070
17270
  import { createHash as createHash3, randomUUID as randomUUID9 } from "crypto";
@@ -17076,20 +17276,82 @@ import { createHash as createHash4 } from "crypto";
17076
17276
  import { arch, hostname as hostname3, platform, release } from "os";
17077
17277
 
17078
17278
  // ../../packages/plugin-sdk/src/nudge.ts
17079
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
17080
- import { join as join7 } from "path";
17279
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
17280
+ import { join as join8 } from "path";
17081
17281
 
17082
17282
  // ../../packages/plugin-sdk/src/project-files.ts
17083
17283
  var import_ignore = __toESM(require_ignore(), 1);
17084
- import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "fs";
17085
- import { basename as basename3, join as join8, relative, sep as sep3 } from "path";
17284
+ import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "fs";
17285
+ import { basename as basename3, join as join9, relative, sep as sep3 } from "path";
17086
17286
 
17087
17287
  // ../../packages/plugin-sdk/src/runtime.ts
17088
17288
  import { randomUUID as randomUUID10 } from "crypto";
17089
17289
 
17290
+ // ../../packages/plugin-sdk/src/suppressions.ts
17291
+ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
17292
+
17090
17293
  // ../../packages/plugin-sdk/src/throttle.ts
17091
- import { mkdirSync as mkdirSync4, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
17092
- import { join as join9 } from "path";
17294
+ import { mkdirSync as mkdirSync4, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
17295
+ import { join as join10 } from "path";
17296
+
17297
+ // src/command-registry.ts
17298
+ import { readdirSync as readdirSync3 } from "fs";
17299
+ import { fileURLToPath } from "url";
17300
+ var COMMANDS_DIR = fileURLToPath(new URL("../commands", import.meta.url));
17301
+
17302
+ // src/setup-show.ts
17303
+ var SHOW_BEGIN = "<<<AKA_SHOW";
17304
+ var SHOW_END = "AKA_SHOW>>>";
17305
+ function showBlock(body) {
17306
+ return `${SHOW_BEGIN}
17307
+ ${body}
17308
+ ${SHOW_END}
17309
+ `;
17310
+ }
17311
+
17312
+ // src/present.ts
17313
+ var SHADE = {
17314
+ light: "\u2591",
17315
+ medium: "\u2592",
17316
+ dark: "\u2593",
17317
+ full: "\u2588"
17318
+ };
17319
+ var fg = (hex3) => (text) => {
17320
+ const r = Number.parseInt(hex3.slice(1, 3), 16);
17321
+ const g = Number.parseInt(hex3.slice(3, 5), 16);
17322
+ const b = Number.parseInt(hex3.slice(5, 7), 16);
17323
+ return `\x1B[38;2;${String(r)};${String(g)};${String(b)}m${text}\x1B[0m`;
17324
+ };
17325
+ var paint = {
17326
+ brand: fg("#33e6c6"),
17327
+ // --color-brand · ▸▸ AKA wordmark (accent text)
17328
+ dim: fg("#838995"),
17329
+ // --color-text-3 · separators · "/100" · the "unreviewed" label
17330
+ bold: (text) => `\x1B[1m${text}\x1B[0m`,
17331
+ // the health score number
17332
+ ok: fg("#0db15f"),
17333
+ // --color-ok · healthy ● dot
17334
+ critical: fg("#e63448"),
17335
+ // --color-sev-critical · ■ and the open-findings flag
17336
+ high: fg("#e97a0a"),
17337
+ // --color-sev-high · ■ and the mid-health dot
17338
+ medium: fg("#f7bd00"),
17339
+ // --color-sev-medium · ■
17340
+ low: fg("#0581d4")
17341
+ // --color-sev-low · ■ (azure blue, not purple)
17342
+ };
17343
+ function indent(text, spaces = 2) {
17344
+ const pad = " ".repeat(spaces);
17345
+ return text.split("\n").map((line) => pad + line).join("\n");
17346
+ }
17347
+ function fenced(body) {
17348
+ const longestRun = Math.max(0, ...[...body.matchAll(/`+/g)].map((m) => m[0].length));
17349
+ const fence = "`".repeat(Math.max(3, longestRun + 1));
17350
+ return [fence, body, fence].join("\n");
17351
+ }
17352
+ function show(body) {
17353
+ return showBlock(body);
17354
+ }
17093
17355
 
17094
17356
  // src/render.ts
17095
17357
  var SEVERITY_GLYPH = {
@@ -17098,48 +17360,44 @@ var SEVERITY_GLYPH = {
17098
17360
  medium: SHADE.medium,
17099
17361
  low: SHADE.light
17100
17362
  };
17363
+ var CATEGORY_ORDER = DetectionCategory.options;
17101
17364
  function renderSetupIntro(meta3) {
17102
- const heading = `\u25CF Found ${meta3.name} \u2014 ${meta3.tagline}`;
17103
- const details = defList([
17104
- ["Repository", meta3.repository],
17105
- ["Version", `${meta3.version} \xB7 ${meta3.publisher}`],
17106
- ["Adds", meta3.adds]
17107
- ]);
17108
- const ask = "Before installing I'll ask two quick questions to tailor the setup.";
17109
- return [heading, "", indent(details), "", indent(ask)].join("\n");
17365
+ const provenance = meta3.verified === true ? `v${meta3.version} \xB7 ${meta3.repository} \xB7 verified` : `v${meta3.version} \xB7 ${meta3.repository}`;
17366
+ const heading = `\u25CF ${meta3.name} \xB7 ${provenance}`;
17367
+ return [
17368
+ heading,
17369
+ "",
17370
+ indent("I'm a security harness for Claude."),
17371
+ "",
17372
+ indent(
17373
+ "While it codes, I keep the sensitive information \u2014 secrets, keys, regulated data \u2014 safely on your machine."
17374
+ ),
17375
+ indent("Most of it I handle quietly; I only notify you when it's worth your call.")
17376
+ ].join("\n");
17110
17377
  }
17111
17378
 
17112
- // src/intro.ts
17113
- var NAME = "AKA Security";
17114
- var TAGLINE = "Agent Harness Security for Claude Code.";
17115
- var ADDS = "Secures your local environment to prevent secret leakage and vulnerabilities.";
17379
+ // src/intro-card.ts
17116
17380
  function repoLabel(homepage) {
17117
17381
  if (!homepage) return "";
17118
17382
  const stripped = homepage.replace(/^https?:\/\//, "");
17119
17383
  const parts = stripped.split("/");
17120
17384
  return parts.length >= 3 ? parts.slice(0, 3).join("/") : stripped;
17121
17385
  }
17122
- function authorName(author) {
17123
- if (typeof author === "string") return author;
17124
- return author?.name ?? "";
17386
+ function buildIntroCard(manifest2, verified) {
17387
+ return renderSetupIntro({
17388
+ name: PRODUCT_NAME,
17389
+ repository: repoLabel(manifest2.homepage),
17390
+ version: manifest2.version ?? "",
17391
+ verified: verified === true
17392
+ });
17125
17393
  }
17394
+
17395
+ // src/intro.ts
17126
17396
  var manifestPath = process.argv[2];
17127
17397
  var manifest = {};
17128
17398
  try {
17129
17399
  manifest = JSON.parse(readFileSync7(manifestPath ?? "", "utf8"));
17130
17400
  } catch {
17131
17401
  }
17132
- process.stdout.write(
17133
- `${fenced(
17134
- renderSetupIntro({
17135
- name: NAME,
17136
- tagline: TAGLINE,
17137
- repository: repoLabel(manifest.homepage),
17138
- version: manifest.version ?? "",
17139
- publisher: authorName(manifest.author),
17140
- adds: ADDS
17141
- })
17142
- )}
17143
- `
17144
- );
17402
+ process.stdout.write(show(fenced(buildIntroCard(manifest))));
17145
17403
  process.exit(0);