@akasecurity/ai-tc-claude-code 0.9.1 → 0.9.2

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/stop.js CHANGED
@@ -491,9 +491,13 @@ var require_ignore = __commonJS({
491
491
  }
492
492
  });
493
493
 
494
+ // ../../packages/plugin-sdk/src/config.ts
495
+ import { existsSync as existsSync3 } from "fs";
496
+ import { join as join6 } from "path";
497
+
494
498
  // ../../packages/persistence/src/database.ts
495
499
  import { randomUUID as randomUUID8 } from "crypto";
496
- import { existsSync, renameSync, rmSync } from "fs";
500
+ import { existsSync, renameSync as renameSync2, rmSync as rmSync2 } from "fs";
497
501
  import { join, sep } from "path";
498
502
  import { DatabaseSync } from "node:sqlite";
499
503
 
@@ -15182,7 +15186,12 @@ var FindingFacets = external_exports.object({
15182
15186
  severity: external_exports.array(FindingFacetItem),
15183
15187
  subtype: external_exports.array(FindingFacetItem),
15184
15188
  provider: external_exports.array(FindingFacetItem),
15185
- action: external_exports.array(FindingFacetItem)
15189
+ action: external_exports.array(FindingFacetItem),
15190
+ // Counts by the group's derived status. The SQLite store derives a status
15191
+ // for every instance, so every group lands in a bucket; a status-less
15192
+ // group (possible only for callers whose rows carry no statuses) is
15193
+ // counted under no value.
15194
+ status: external_exports.array(FindingFacetItem)
15186
15195
  }).meta({ id: "FindingFacets" });
15187
15196
  var ListGroupedFindingsQuery = external_exports.object({
15188
15197
  // NOTE: severity filters by Severity (critical/high/medium/low), not by
@@ -15191,6 +15200,10 @@ var ListGroupedFindingsQuery = external_exports.object({
15191
15200
  subtype: external_exports.array(external_exports.string()).optional(),
15192
15201
  provider: external_exports.array(FindingProvider).optional(),
15193
15202
  action: external_exports.array(FindingAction).optional(),
15203
+ // Matches a group's DERIVED status (see FindingGroup.status), not its
15204
+ // individual instances' — so a filtered group's Status column always reads
15205
+ // one of the requested values.
15206
+ status: external_exports.array(FindingStatus).optional(),
15194
15207
  q: external_exports.string().optional(),
15195
15208
  // Scope to findings whose event carries this session id (the Activity page's
15196
15209
  // session → findings drilldown). Findings without a session never match.
@@ -15371,6 +15384,33 @@ var ToolCallAttributes = external_exports.object({
15371
15384
  parent_uuid: external_exports.string().optional(),
15372
15385
  run_key: external_exports.string().optional()
15373
15386
  }).catchall(external_exports.unknown());
15387
+ var CaptureAttributes = external_exports.object({
15388
+ // The harness/tool that produced the capture (`claude-code`, `cli`, …). A
15389
+ // column on the legacy `events` table; here it rides the bag because a
15390
+ // capture-typed audit row has no equivalent column of its own.
15391
+ source_tool: external_exports.string().optional(),
15392
+ file_path: external_exports.string().optional(),
15393
+ repo: external_exports.string().optional(),
15394
+ // The host tool whose input/output was scanned (e.g. 'Bash', 'WebFetch') —
15395
+ // gives a non-file capture a display location ("via Bash") when file_path
15396
+ // is absent. The tool NAME only, never its arguments/output.
15397
+ tool_name: external_exports.string().optional(),
15398
+ // Presence-only provenance flag: set when the file is excluded by the
15399
+ // repo's .gitignore. Omitted (not false) for tracked files.
15400
+ gitignored: external_exports.boolean().optional(),
15401
+ // Set ONLY when the capture is a COMPLETE file snapshot (a worktree scan
15402
+ // reading from disk), never a partial fragment (a hook-captured edit).
15403
+ whole_file: external_exports.boolean().optional(),
15404
+ // Distributed-tracing correlation: `correlation_id` ties the capture back to
15405
+ // the request that produced it; `trace_id` is the originating span's W3C
15406
+ // trace id when telemetry is enabled.
15407
+ correlation_id: external_exports.uuid().optional(),
15408
+ trace_id: external_exports.string().regex(/^[0-9a-f]{32}$/).optional(),
15409
+ // Ids of the detection exceptions that downgraded findings in this capture
15410
+ // to 'allow' — the enforcement audit trail's link back to the grant that
15411
+ // authorized the bypass.
15412
+ exception_ids: external_exports.array(external_exports.guid()).optional()
15413
+ }).catchall(external_exports.unknown());
15374
15414
  var ToolCallInspection = external_exports.object({
15375
15415
  ruleId: external_exports.string().min(1),
15376
15416
  ruleName: external_exports.string(),
@@ -15457,7 +15497,18 @@ var InspectionFindingInput = external_exports.object({
15457
15497
  span: Span,
15458
15498
  maskedMatch: external_exports.string(),
15459
15499
  actionTaken: ActionTaken,
15460
- confidence: external_exports.number().min(0).max(1)
15500
+ confidence: external_exports.number().min(0).max(1),
15501
+ // Stable, content-addressed key correlating this finding across re-detections
15502
+ // — mirrors the legacy `findings.finding_key` (uq_inspection_findings_key is
15503
+ // its unique index). Optional: only an at-rest/re-scannable finding carries
15504
+ // one; an in-flight capture (prompt/response) has nothing to re-detect
15505
+ // against and leaves it unset, so every insert is a fresh row.
15506
+ findingKey: external_exports.string().optional(),
15507
+ // The ORIGINAL detection time, preserved across a later re-detection of the
15508
+ // same findingKey — mirrors the legacy `findings.first_detected_at`.
15509
+ // Optional: when omitted, the writer derives it from the referenced audit
15510
+ // event's startedAt on first insert (see SqliteInspectionFindingsRepository).
15511
+ firstDetectedAt: external_exports.iso.datetime().optional()
15461
15512
  });
15462
15513
  var InventoryContext = external_exports.object({
15463
15514
  host: InventoryInput.optional(),
@@ -15656,6 +15707,7 @@ var ActivityOverviewResponse = external_exports.object({
15656
15707
 
15657
15708
  // ../../packages/schema/src/zod/event.ts
15658
15709
  var EventKind = external_exports.enum(["prompt", "response", "code_change", "tool_use"]).meta({ id: "EventKind" });
15710
+ var CAPTURE_EVENT_TYPES_SQL = EventKind.options.map((k) => `'${k}'`).join(",");
15659
15711
  var SourceTool = external_exports.enum(["claude-code", "claude-desktop", "cursor", "chatgpt", "github-copilot", "cli", "unknown"]).meta({ id: "SourceTool" });
15660
15712
  var EventMetadata = external_exports.object({
15661
15713
  sessionId: external_exports.string().optional(),
@@ -16145,6 +16197,12 @@ var PolicyBundle = external_exports.object({
16145
16197
  // on-disk caches — that omit the field still parse; consumers read
16146
16198
  // `bundle.exceptions ?? []`.
16147
16199
  exceptions: external_exports.array(ExceptionBundleEntry).optional(),
16200
+ // Installed pack version, keyed by ruleId, for rules in `rules` that came
16201
+ // from a versioned installed pack. Optional so older backends — and older
16202
+ // on-disk caches — that omit the field still parse; consumers fall back to
16203
+ // the rule's own spec version. NOT the bundle version above — see
16204
+ // installedRuleset's ruleVersions for the source of truth.
16205
+ ruleVersions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
16148
16206
  customKeywords: external_exports.array(external_exports.string()),
16149
16207
  fetchedAt: external_exports.iso.datetime()
16150
16208
  }).meta({ id: "PolicyBundle" });
@@ -16743,10 +16801,14 @@ var PatchInstalledPackRequest = external_exports.object({
16743
16801
  }).meta({ id: "PatchInstalledPackRequest" });
16744
16802
 
16745
16803
  // ../../packages/schema/src/zod/local.ts
16746
- var WORKSPACE_SETTINGS_SPEC_VERSION = 3;
16804
+ var WORKSPACE_SETTINGS_SPEC_VERSION = 4;
16747
16805
  var RunMode = external_exports.enum(["standalone"]);
16748
16806
  var SimpleDetectionPolicy = external_exports.enum(["redact", "warn"]);
16749
16807
  var HistoricalAccess = external_exports.enum(["full", "session-only"]);
16808
+ var ModelJudgeConsent = external_exports.object({
16809
+ acknowledgedAt: external_exports.iso.datetime(),
16810
+ payloadVersion: external_exports.number().int().positive()
16811
+ });
16750
16812
  var WorkspaceSettings = external_exports.object({
16751
16813
  specVersion: external_exports.number().int().positive().default(WORKSPACE_SETTINGS_SPEC_VERSION),
16752
16814
  // Settings files written by earlier releases may carry the retired 'attached'
@@ -16762,7 +16824,12 @@ var WorkspaceSettings = external_exports.object({
16762
16824
  // Shares writes.
16763
16825
  dataSharesInPlace: external_exports.boolean().default(true),
16764
16826
  // Absent until /aka:setup completes; its presence is what "onboarded" means.
16765
- onboardedAt: external_exports.iso.datetime().optional()
16827
+ onboardedAt: external_exports.iso.datetime().optional(),
16828
+ // Records that the user consented to sending findings to the model API for
16829
+ // the /aka:setup judge, along with the payload-shape version they agreed to.
16830
+ // Absent until granted; a stale payloadVersion means the consent no longer
16831
+ // covers the current payload and must be re-granted.
16832
+ modelJudgeConsent: ModelJudgeConsent.optional()
16766
16833
  });
16767
16834
  function defaultWorkspaceSettings() {
16768
16835
  return WorkspaceSettings.parse({});
@@ -17144,9 +17211,29 @@ var SetupHandoffOffer = external_exports.object({
17144
17211
  import { createHash } from "crypto";
17145
17212
 
17146
17213
  // ../../packages/persistence/src/paths.ts
17147
- import { chmodSync, mkdirSync } from "fs";
17214
+ import { chmodSync, lstatSync, mkdirSync, renameSync, rmSync, writeFileSync } from "fs";
17148
17215
  var DATA_DIR_MODE = 448;
17149
17216
  var DATA_FILE_MODE = 384;
17217
+ function chmodBestEffort(path, mode) {
17218
+ try {
17219
+ chmodSync(path, mode);
17220
+ } catch {
17221
+ }
17222
+ }
17223
+ function tightenDir(dir) {
17224
+ chmodBestEffort(dir, DATA_DIR_MODE);
17225
+ }
17226
+ function ensureDataDirSync(dir) {
17227
+ mkdirSync(dir, { recursive: true, mode: DATA_DIR_MODE });
17228
+ tightenDir(dir);
17229
+ }
17230
+ function tightenFile(file2) {
17231
+ try {
17232
+ if (lstatSync(file2).isSymbolicLink()) return;
17233
+ } catch {
17234
+ }
17235
+ chmodBestEffort(file2, DATA_FILE_MODE);
17236
+ }
17150
17237
 
17151
17238
  // ../../packages/persistence/src/internal/json.ts
17152
17239
  function parseJsonObject(s) {
@@ -17187,14 +17274,17 @@ import { randomUUID as randomUUID6 } from "crypto";
17187
17274
  // ../../packages/persistence/src/repositories/shares.ts
17188
17275
  import { randomUUID as randomUUID7 } from "crypto";
17189
17276
 
17277
+ // ../../packages/persistence/src/finding-key.ts
17278
+ import { createHash as createHash3 } from "crypto";
17279
+
17190
17280
  // ../../packages/persistence/src/fingerprint.ts
17191
17281
  import { createHmac, randomBytes } from "crypto";
17192
- import { chmodSync as chmodSync2, readFileSync, renameSync as renameSync2, writeFileSync } from "fs";
17282
+ import { readFileSync } from "fs";
17193
17283
  import { join as join2 } from "path";
17194
17284
 
17195
17285
  // ../../packages/persistence/src/local-layout.ts
17196
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync2, renameSync as renameSync3 } from "fs";
17197
- import { chmod, mkdir } from "fs/promises";
17286
+ import { renameSync as renameSync3 } from "fs";
17287
+ import { mkdir } from "fs/promises";
17198
17288
  import { homedir } from "os";
17199
17289
  import { join as join3 } from "path";
17200
17290
  function defaultDataDir() {
@@ -17209,6 +17299,9 @@ function dataDir(base = defaultDataDir()) {
17209
17299
  function dbPath(base = defaultDataDir()) {
17210
17300
  return join3(dataDir(base), "aka.db");
17211
17301
  }
17302
+ function ensureLayoutDirSync(dir = defaultDataDir()) {
17303
+ ensureDataDirSync(dir);
17304
+ }
17212
17305
  function migrateLegacyLayout(base = defaultDataDir()) {
17213
17306
  const moves = [
17214
17307
  { name: "config.json", dest: settingsDir(base) },
@@ -17216,19 +17309,17 @@ function migrateLegacyLayout(base = defaultDataDir()) {
17216
17309
  ];
17217
17310
  for (const { name, dest } of moves) {
17218
17311
  try {
17219
- mkdirSync2(dest, { recursive: true, mode: DATA_DIR_MODE });
17220
- try {
17221
- chmodSync3(dest, DATA_DIR_MODE);
17222
- } catch {
17223
- }
17224
- renameSync3(join3(base, name), join3(dest, name));
17312
+ ensureDataDirSync(dest);
17313
+ const moved = join3(dest, name);
17314
+ renameSync3(join3(base, name), moved);
17315
+ tightenFile(moved);
17225
17316
  } catch {
17226
17317
  }
17227
17318
  }
17228
17319
  }
17229
17320
 
17230
17321
  // ../../packages/persistence/src/settings.ts
17231
- import { readFileSync as readFileSync2, renameSync as renameSync4, writeFileSync as writeFileSync2 } from "fs";
17322
+ import { readFileSync as readFileSync2 } from "fs";
17232
17323
  import { join as join4 } from "path";
17233
17324
  function readWorkspaceSettings(base = defaultDataDir()) {
17234
17325
  const record2 = readJson(join4(settingsDir(base), "settings.json"));
@@ -17250,7 +17341,7 @@ function readJson(file2) {
17250
17341
  }
17251
17342
 
17252
17343
  // ../../packages/persistence/src/warn-era-cap.ts
17253
- import { existsSync as existsSync2, writeFileSync as writeFileSync3 } from "fs";
17344
+ import { existsSync as existsSync2, writeFileSync as writeFileSync2 } from "fs";
17254
17345
  import { join as join5 } from "path";
17255
17346
 
17256
17347
  // ../../packages/plugin-sdk/src/provider-env.ts
@@ -17303,6 +17394,12 @@ function resolveProvider() {
17303
17394
 
17304
17395
  // ../../packages/plugin-sdk/src/config.ts
17305
17396
  function loadConfig(base = defaultDataDir()) {
17397
+ try {
17398
+ ensureLayoutDirSync(base);
17399
+ const settingsFile = join6(settingsDir(base), "settings.json");
17400
+ if (existsSync3(settingsFile)) tightenFile(settingsFile);
17401
+ } catch {
17402
+ }
17306
17403
  migrateLegacyLayout(base);
17307
17404
  const settings = readWorkspaceSettings(base);
17308
17405
  return {
@@ -17325,7 +17422,7 @@ function resolveProviderSafe() {
17325
17422
  // ../../packages/plugin-sdk/src/config-inventory.ts
17326
17423
  import { readdirSync, readFileSync as readFileSync4, realpathSync, statSync as statSync2 } from "fs";
17327
17424
  import { homedir as homedir2 } from "os";
17328
- import { basename as basename2, join as join7 } from "path";
17425
+ import { basename as basename2, join as join8 } from "path";
17329
17426
 
17330
17427
  // ../../packages/detections/src/egress/registry.ts
17331
17428
  var EXTRACTOR_VERSION = "1";
@@ -18036,21 +18133,18 @@ var POLYNOMIAL_PROBES = ["abc-", "a.", "a ", "a=", "x", "0", "a@", "a/", "ab"].m
18036
18133
  );
18037
18134
 
18038
18135
  // ../../packages/plugin-sdk/src/repo.ts
18039
- import { existsSync as existsSync3, readFileSync as readFileSync3, statSync } from "fs";
18040
- import { basename, dirname, isAbsolute, join as join6, sep as sep2 } from "path";
18136
+ import { existsSync as existsSync4, readFileSync as readFileSync3, statSync } from "fs";
18137
+ import { basename, dirname, isAbsolute, join as join7, sep as sep2 } from "path";
18041
18138
 
18042
18139
  // ../../packages/plugin-sdk/src/events.ts
18043
- import { createHash as createHash3, randomUUID as randomUUID9 } from "crypto";
18044
-
18045
- // ../../packages/plugin-sdk/src/finding-key.ts
18046
- import { createHash as createHash4 } from "crypto";
18140
+ import { createHash as createHash4, randomUUID as randomUUID9 } from "crypto";
18047
18141
 
18048
18142
  // ../../packages/plugin-sdk/src/inventory-resolver.ts
18049
18143
  import { arch, hostname as hostname3, platform, release } from "os";
18050
18144
 
18051
18145
  // ../../packages/plugin-sdk/src/nudge.ts
18052
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
18053
- import { join as join8 } from "path";
18146
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
18147
+ import { join as join9 } from "path";
18054
18148
 
18055
18149
  // ../../packages/plugin-sdk/src/paths.ts
18056
18150
  import { readdirSync as readdirSync2, realpathSync as realpathSync2 } from "fs";
@@ -18058,8 +18152,8 @@ import { basename as basename3, dirname as dirname2, sep as sep3 } from "path";
18058
18152
 
18059
18153
  // ../../packages/plugin-sdk/src/project-files.ts
18060
18154
  var import_ignore = __toESM(require_ignore(), 1);
18061
- import { existsSync as existsSync4, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
18062
- import { basename as basename4, join as join9, relative, sep as sep4 } from "path";
18155
+ import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
18156
+ import { basename as basename4, join as join10, relative, sep as sep4 } from "path";
18063
18157
 
18064
18158
  // ../../packages/plugin-sdk/src/runtime.ts
18065
18159
  import { randomUUID as randomUUID10 } from "crypto";
@@ -18068,17 +18162,17 @@ import { randomUUID as randomUUID10 } from "crypto";
18068
18162
  var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
18069
18163
 
18070
18164
  // ../../packages/plugin-sdk/src/throttle.ts
18071
- import { mkdirSync as mkdirSync4, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
18072
- import { join as join10 } from "path";
18165
+ import { mkdirSync as mkdirSync3, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
18166
+ import { join as join11 } from "path";
18073
18167
  function throttled(dataDir2, markerName, windowMs) {
18074
- const marker = join10(dataDir2, markerName);
18168
+ const marker = join11(dataDir2, markerName);
18075
18169
  try {
18076
18170
  if (Date.now() - statSync3(marker).mtimeMs < windowMs) return true;
18077
18171
  } catch {
18078
18172
  }
18079
18173
  try {
18080
- mkdirSync4(dataDir2, { recursive: true, mode: DATA_DIR_MODE });
18081
- writeFileSync5(marker, String(Date.now()), { mode: DATA_FILE_MODE });
18174
+ mkdirSync3(dataDir2, { recursive: true, mode: DATA_DIR_MODE });
18175
+ writeFileSync4(marker, String(Date.now()), { mode: DATA_FILE_MODE });
18082
18176
  } catch {
18083
18177
  }
18084
18178
  return false;
@@ -18086,7 +18180,7 @@ function throttled(dataDir2, markerName, windowMs) {
18086
18180
 
18087
18181
  // src/history/reconcile-trigger.ts
18088
18182
  import { spawn } from "child_process";
18089
- import { dirname as dirname3, join as join12 } from "path";
18183
+ import { dirname as dirname3, join as join13 } from "path";
18090
18184
  import { fileURLToPath } from "url";
18091
18185
 
18092
18186
  // src/history/tail.ts
@@ -18094,13 +18188,13 @@ import { createHash as createHash5 } from "crypto";
18094
18188
  import {
18095
18189
  closeSync,
18096
18190
  fstatSync,
18097
- mkdirSync as mkdirSync5,
18191
+ mkdirSync as mkdirSync4,
18098
18192
  openSync,
18099
18193
  readFileSync as readFileSync7,
18100
18194
  readSync,
18101
- writeFileSync as writeFileSync6
18195
+ writeFileSync as writeFileSync5
18102
18196
  } from "fs";
18103
- import { join as join11 } from "path";
18197
+ import { join as join12 } from "path";
18104
18198
  var SAFE_SESSION_ID = /^[A-Za-z0-9._-]+$/;
18105
18199
  function safeSessionId(sessionId) {
18106
18200
  if (SAFE_SESSION_ID.test(sessionId) && sessionId !== "." && sessionId !== "..") {
@@ -18117,7 +18211,7 @@ function triggerReconcile(dataDir2, sessionId, transcriptPath) {
18117
18211
  const marker = `${RECONCILE_MARKER_PREFIX}-${safeSessionId(sessionId)}`;
18118
18212
  if (throttled(dataDir2, marker, RECONCILE_THROTTLE_MS)) return;
18119
18213
  const here = dirname3(fileURLToPath(import.meta.url));
18120
- const child = spawn(process.execPath, [join12(here, "reconcile.js"), sessionId, transcriptPath], {
18214
+ const child = spawn(process.execPath, [join13(here, "reconcile.js"), sessionId, transcriptPath], {
18121
18215
  detached: true,
18122
18216
  stdio: "ignore"
18123
18217
  });
@@ -3,8 +3,9 @@
3
3
  You are the AKA Security setup wizard's inline triage step. You have just
4
4
  scanned a workspace (working tree and/or history) and detected a set of raw
5
5
  hits — matches from AKA's deterministic regex detection rules, shown to you
6
- with their real (unmasked) value and surrounding context so you can judge them
7
- accurately. This is a one-time, transient look: the raw values are **never
6
+ with their real (unmasked) value (`rawMatch`) and a surrounding context window
7
+ that has itself been masked for any other secrets, so you can judge each hit by
8
+ its own value. This is a one-time, transient look: the raw values are **never
8
9
  persisted** — only your verdicts are written, as neutral exceptions and
9
10
  per-category policies.
10
11
 
@@ -12,7 +13,7 @@ You will receive the hits below as a JSONL block, one `TriageHit` object per
12
13
  line:
13
14
 
14
15
  ```
15
- {"ruleId":"...","category":"...","severity":"...","maskedMatch":"...","rawMatch":"...","context":"...","filePath":"...","confidence":0.9}
16
+ {"id":"...","ruleId":"...","category":"...","severity":"...","maskedMatch":"...","rawMatch":"...","context":"...","confidence":0.9}
16
17
  ```
17
18
 
18
19
  ## Step 1 — Silently filter false positives