@akasecurity/ai-tc-claude-code 0.9.2 → 0.9.3
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/.claude-plugin/plugin.json +1 -1
- package/package.json +3 -3
- package/scripts/apply-suppressions.js +94 -45
- package/scripts/backfill.js +139 -47
- package/scripts/filescan.js +141 -49
- package/scripts/firstrun.js +93 -44
- package/scripts/intro.js +6 -5
- package/scripts/onboard.js +93 -44
- package/scripts/post-tool-use.js +139 -47
- package/scripts/pre-tool-use.js +139 -47
- package/scripts/query.js +93 -44
- package/scripts/reconcile.js +95 -46
- package/scripts/remediate.js +139 -47
- package/scripts/session-start.js +96 -47
- package/scripts/start-light.js +6 -5
- package/scripts/statusline.js +93 -44
- package/scripts/stop.js +7 -6
- package/scripts/user-prompt-submit.js +139 -47
|
@@ -492,7 +492,7 @@ var require_ignore = __commonJS({
|
|
|
492
492
|
});
|
|
493
493
|
|
|
494
494
|
// ../../packages/plugin-sdk/src/config.ts
|
|
495
|
-
import { existsSync as
|
|
495
|
+
import { existsSync as existsSync4 } from "fs";
|
|
496
496
|
import { join as join6 } from "path";
|
|
497
497
|
|
|
498
498
|
// ../../packages/persistence/src/database.ts
|
|
@@ -23389,11 +23389,22 @@ function purgeSampleData(db) {
|
|
|
23389
23389
|
function linkHost(input, hostId) {
|
|
23390
23390
|
return hostId ? { ...input, hostId } : input;
|
|
23391
23391
|
}
|
|
23392
|
+
function closeQuietly(db) {
|
|
23393
|
+
try {
|
|
23394
|
+
db.close();
|
|
23395
|
+
} catch {
|
|
23396
|
+
}
|
|
23397
|
+
}
|
|
23392
23398
|
function openWithPragmas(file2) {
|
|
23393
23399
|
const db = new DatabaseSync(file2);
|
|
23394
|
-
|
|
23395
|
-
|
|
23396
|
-
|
|
23400
|
+
try {
|
|
23401
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
23402
|
+
db.exec("PRAGMA busy_timeout = 2000");
|
|
23403
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
23404
|
+
} catch (err) {
|
|
23405
|
+
closeQuietly(db);
|
|
23406
|
+
throw err;
|
|
23407
|
+
}
|
|
23397
23408
|
return db;
|
|
23398
23409
|
}
|
|
23399
23410
|
function backupLegacyStore(file2) {
|
|
@@ -23405,43 +23416,80 @@ function backupLegacyStore(file2) {
|
|
|
23405
23416
|
}
|
|
23406
23417
|
return backup;
|
|
23407
23418
|
}
|
|
23419
|
+
function openAndInitialize(file2) {
|
|
23420
|
+
let db = openWithPragmas(file2);
|
|
23421
|
+
try {
|
|
23422
|
+
if (isForeignSqliteLineage(db)) {
|
|
23423
|
+
db.close();
|
|
23424
|
+
const backup = backupLegacyStore(file2);
|
|
23425
|
+
db = openWithPragmas(file2);
|
|
23426
|
+
akaWarn(
|
|
23427
|
+
`Detected an older, incompatible (tenant-bearing) ${DB_FILENAME}; backed it up to ${backup} and created a fresh store.`
|
|
23428
|
+
);
|
|
23429
|
+
}
|
|
23430
|
+
applyMigrations(db, file2);
|
|
23431
|
+
tightenPerms(file2);
|
|
23432
|
+
const policies = new SqlitePoliciesRepository(db);
|
|
23433
|
+
const installedPacks = new SqliteInstalledPacksRepository(db);
|
|
23434
|
+
const repositories = {
|
|
23435
|
+
events: new SqliteEventsRepository(db),
|
|
23436
|
+
findings: new SqliteFindingsRepository(db),
|
|
23437
|
+
policies,
|
|
23438
|
+
installedPacks,
|
|
23439
|
+
scanLedger: new SqliteScanLedgerRepository(db),
|
|
23440
|
+
exceptions: new SqliteExceptionsRepository(db),
|
|
23441
|
+
resolutions: new SqliteResolutionsRepository(db),
|
|
23442
|
+
ruleProbeCache: new SqliteRuleProbeCacheRepository(db),
|
|
23443
|
+
security: new SqliteSecurityRepository(db),
|
|
23444
|
+
detections: new SqliteDetectionsRepository(db),
|
|
23445
|
+
shares: new SqliteSharesRepository(db),
|
|
23446
|
+
policyCatalog: new SqlitePolicyCatalogRepository(installedPacks),
|
|
23447
|
+
inventory: new SqliteInventoryRepository(db),
|
|
23448
|
+
inventoryAssets: new SqliteInventoryAssetsRepository(db),
|
|
23449
|
+
projectFiles: new SqliteProjectFilesRepository(db),
|
|
23450
|
+
activity: new SqliteActivityRepository(db),
|
|
23451
|
+
sourceProject: new SqliteSourceProjectRepository(db),
|
|
23452
|
+
auditEvents: new SqliteAuditEventsRepository(db),
|
|
23453
|
+
classifiedData: new SqliteClassifiedDataRepository(db),
|
|
23454
|
+
inspectionDefinitions: new SqliteInspectionDefinitionsRepository(db),
|
|
23455
|
+
inspectionFindings: new SqliteInspectionFindingsRepository(db),
|
|
23456
|
+
configInventory: new SqliteConfigInventoryRepository(db)
|
|
23457
|
+
};
|
|
23458
|
+
policies.seedDefaults();
|
|
23459
|
+
return { db, ...repositories };
|
|
23460
|
+
} catch (err) {
|
|
23461
|
+
closeQuietly(db);
|
|
23462
|
+
throw err;
|
|
23463
|
+
}
|
|
23464
|
+
}
|
|
23408
23465
|
function openLocalDatabase(dir) {
|
|
23409
23466
|
ensureDataDirSync(dir);
|
|
23410
23467
|
const file2 = join(dir, DB_FILENAME);
|
|
23411
|
-
|
|
23412
|
-
|
|
23413
|
-
|
|
23414
|
-
|
|
23415
|
-
|
|
23416
|
-
|
|
23417
|
-
|
|
23418
|
-
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
|
|
23423
|
-
|
|
23424
|
-
|
|
23425
|
-
|
|
23426
|
-
|
|
23427
|
-
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
|
|
23435
|
-
|
|
23436
|
-
const projectFiles = new SqliteProjectFilesRepository(db);
|
|
23437
|
-
const activity = new SqliteActivityRepository(db);
|
|
23438
|
-
const sourceProject = new SqliteSourceProjectRepository(db);
|
|
23439
|
-
const auditEvents = new SqliteAuditEventsRepository(db);
|
|
23440
|
-
const classifiedData = new SqliteClassifiedDataRepository(db);
|
|
23441
|
-
const inspectionDefinitions = new SqliteInspectionDefinitionsRepository(db);
|
|
23442
|
-
const inspectionFindings = new SqliteInspectionFindingsRepository(db);
|
|
23443
|
-
const configInventory = new SqliteConfigInventoryRepository(db);
|
|
23444
|
-
policies.seedDefaults();
|
|
23468
|
+
const {
|
|
23469
|
+
db,
|
|
23470
|
+
events,
|
|
23471
|
+
findings,
|
|
23472
|
+
policies,
|
|
23473
|
+
installedPacks,
|
|
23474
|
+
scanLedger,
|
|
23475
|
+
exceptions,
|
|
23476
|
+
resolutions,
|
|
23477
|
+
ruleProbeCache,
|
|
23478
|
+
security,
|
|
23479
|
+
detections,
|
|
23480
|
+
shares,
|
|
23481
|
+
policyCatalog,
|
|
23482
|
+
inventory,
|
|
23483
|
+
inventoryAssets,
|
|
23484
|
+
projectFiles,
|
|
23485
|
+
activity,
|
|
23486
|
+
sourceProject,
|
|
23487
|
+
auditEvents,
|
|
23488
|
+
classifiedData,
|
|
23489
|
+
inspectionDefinitions,
|
|
23490
|
+
inspectionFindings,
|
|
23491
|
+
configInventory
|
|
23492
|
+
} = openAndInitialize(file2);
|
|
23445
23493
|
function recordCapture(event, detected) {
|
|
23446
23494
|
failOpenTransaction(db, () => {
|
|
23447
23495
|
const sessionId = event.metadata?.sessionId;
|
|
@@ -23653,8 +23701,9 @@ function computeFindingKey(input) {
|
|
|
23653
23701
|
|
|
23654
23702
|
// ../../packages/persistence/src/fingerprint.ts
|
|
23655
23703
|
import { createHmac, randomBytes } from "crypto";
|
|
23656
|
-
import { readFileSync } from "fs";
|
|
23704
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
23657
23705
|
import { join as join2 } from "path";
|
|
23706
|
+
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
23658
23707
|
var KEY_FILENAME = "exception.key";
|
|
23659
23708
|
var KEY_MATERIAL_BYTES = 32;
|
|
23660
23709
|
function keyFilePath(dataDir2) {
|
|
@@ -23678,6 +23727,46 @@ function parseKeyFile(raw) {
|
|
|
23678
23727
|
}
|
|
23679
23728
|
return { version: version2, material: bytes };
|
|
23680
23729
|
}
|
|
23730
|
+
var KEY_VERSION_TABLES = ["exceptions", "blocked_detections"];
|
|
23731
|
+
var SQLITE_ERROR = 1;
|
|
23732
|
+
var FLOOR_BUSY_TIMEOUT_MS = 250;
|
|
23733
|
+
var FloorUnreadableError = class extends Error {
|
|
23734
|
+
code = "floor-unreadable";
|
|
23735
|
+
constructor(cause) {
|
|
23736
|
+
super(
|
|
23737
|
+
`cannot read the stored fingerprint key versions: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
23738
|
+
{ cause }
|
|
23739
|
+
);
|
|
23740
|
+
this.name = "FloorUnreadableError";
|
|
23741
|
+
}
|
|
23742
|
+
};
|
|
23743
|
+
function storedKeyVersionFloor(dataDir2) {
|
|
23744
|
+
const file2 = join2(dataDir2, DB_FILENAME);
|
|
23745
|
+
if (!existsSync2(file2)) return 0;
|
|
23746
|
+
let db;
|
|
23747
|
+
try {
|
|
23748
|
+
db = new DatabaseSync2(file2, { readOnly: true });
|
|
23749
|
+
db.exec(`PRAGMA busy_timeout = ${String(FLOOR_BUSY_TIMEOUT_MS)}`);
|
|
23750
|
+
let floor = 0;
|
|
23751
|
+
for (const table of KEY_VERSION_TABLES) {
|
|
23752
|
+
try {
|
|
23753
|
+
const row = getRow(
|
|
23754
|
+
db.prepare(`SELECT MAX(key_version) AS v FROM ${table}`)
|
|
23755
|
+
);
|
|
23756
|
+
floor = Math.max(floor, row?.v ?? 0);
|
|
23757
|
+
} catch (err) {
|
|
23758
|
+
if (err.errcode !== SQLITE_ERROR) {
|
|
23759
|
+
throw new FloorUnreadableError(err);
|
|
23760
|
+
}
|
|
23761
|
+
}
|
|
23762
|
+
}
|
|
23763
|
+
return floor;
|
|
23764
|
+
} catch (err) {
|
|
23765
|
+
throw err instanceof FloorUnreadableError ? err : new FloorUnreadableError(err);
|
|
23766
|
+
} finally {
|
|
23767
|
+
db?.close();
|
|
23768
|
+
}
|
|
23769
|
+
}
|
|
23681
23770
|
function writeKeyFile(dataDir2, key) {
|
|
23682
23771
|
ensureDataDirSync(dataDir2);
|
|
23683
23772
|
const file2 = keyFilePath(dataDir2);
|
|
@@ -23702,7 +23791,10 @@ function loadOrCreateFingerprintKey(dataDir2) {
|
|
|
23702
23791
|
tightenFile(keyFilePath(dataDir2));
|
|
23703
23792
|
return existing;
|
|
23704
23793
|
}
|
|
23705
|
-
return writeKeyFile(dataDir2, {
|
|
23794
|
+
return writeKeyFile(dataDir2, {
|
|
23795
|
+
version: storedKeyVersionFloor(dataDir2) + 1,
|
|
23796
|
+
material: randomBytes(KEY_MATERIAL_BYTES)
|
|
23797
|
+
});
|
|
23706
23798
|
}
|
|
23707
23799
|
function fingerprintValue(key, raw) {
|
|
23708
23800
|
return createHmac("sha256", key.material).update(raw, "utf8").digest("hex");
|
|
@@ -23767,13 +23859,13 @@ function readJson(file2) {
|
|
|
23767
23859
|
}
|
|
23768
23860
|
|
|
23769
23861
|
// ../../packages/persistence/src/warn-era-cap.ts
|
|
23770
|
-
import { existsSync as
|
|
23862
|
+
import { existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
23771
23863
|
import { join as join5 } from "path";
|
|
23772
23864
|
var MARKER = "warn-era-capped";
|
|
23773
23865
|
function capWarnEraEnforcementOnce(db, policyMode, dataDir2) {
|
|
23774
23866
|
if (policyMode !== "warn") return { capped: 0, skipped: "not-warn" };
|
|
23775
23867
|
const marker = join5(dataDir2, MARKER);
|
|
23776
|
-
if (
|
|
23868
|
+
if (existsSync3(marker)) return { capped: 0, skipped: "already-run" };
|
|
23777
23869
|
const capped = db.policies.capCategoryActions();
|
|
23778
23870
|
writeFileSync2(marker, `${new Date(Date.now()).toISOString()}
|
|
23779
23871
|
`, { mode: DATA_FILE_MODE });
|
|
@@ -23833,7 +23925,7 @@ function loadConfig(base = defaultDataDir()) {
|
|
|
23833
23925
|
try {
|
|
23834
23926
|
ensureLayoutDirSync(base);
|
|
23835
23927
|
const settingsFile = join6(settingsDir(base), "settings.json");
|
|
23836
|
-
if (
|
|
23928
|
+
if (existsSync4(settingsFile)) tightenFile(settingsFile);
|
|
23837
23929
|
} catch {
|
|
23838
23930
|
}
|
|
23839
23931
|
migrateLegacyLayout(base);
|
|
@@ -26879,7 +26971,7 @@ function uniqueRuleIds(findings) {
|
|
|
26879
26971
|
}
|
|
26880
26972
|
|
|
26881
26973
|
// ../../packages/plugin-sdk/src/repo.ts
|
|
26882
|
-
import { existsSync as
|
|
26974
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, statSync } from "fs";
|
|
26883
26975
|
import { basename, dirname, isAbsolute, join as join7, sep as sep2 } from "path";
|
|
26884
26976
|
function resolveRepo(cwd) {
|
|
26885
26977
|
try {
|
|
@@ -26895,7 +26987,7 @@ function resolveRepo(cwd) {
|
|
|
26895
26987
|
function findGitRoot(start) {
|
|
26896
26988
|
let dir = start;
|
|
26897
26989
|
for (; ; ) {
|
|
26898
|
-
if (
|
|
26990
|
+
if (existsSync5(join7(dir, ".git"))) return dir;
|
|
26899
26991
|
const parent = dirname(dir);
|
|
26900
26992
|
if (parent === dir) return void 0;
|
|
26901
26993
|
dir = parent;
|
|
@@ -26913,7 +27005,7 @@ function resolveGitContext(root) {
|
|
|
26913
27005
|
const target = /^gitdir:\s*(.+?)\s*$/m.exec(safeRead(dotGit) ?? "")?.[1];
|
|
26914
27006
|
if (!target) return void 0;
|
|
26915
27007
|
const gitdir = isAbsolute(target) ? target : join7(root, target);
|
|
26916
|
-
if (
|
|
27008
|
+
if (existsSync5(join7(gitdir, "config"))) {
|
|
26917
27009
|
return { configPath: join7(gitdir, "config"), headRoot: root };
|
|
26918
27010
|
}
|
|
26919
27011
|
const commonRaw = safeRead(join7(gitdir, "commondir"))?.trim();
|
|
@@ -27015,7 +27107,7 @@ import { basename as basename3, dirname as dirname2, sep as sep3 } from "path";
|
|
|
27015
27107
|
|
|
27016
27108
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
27017
27109
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
27018
|
-
import { existsSync as
|
|
27110
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
|
|
27019
27111
|
import { basename as basename4, join as join10, relative, sep as sep4 } from "path";
|
|
27020
27112
|
|
|
27021
27113
|
// ../../packages/plugin-sdk/src/rule-quarantine.ts
|