@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aka",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "AI Traffic Control — inspect and govern AI prompts in Claude Code. Detection runs locally; events are recorded to a local SQLite store on your machine.",
|
|
5
5
|
"homepage": "https://github.com/akasecurity/ai-tc",
|
|
6
6
|
"author": { "name": "AKA Security" }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akasecurity/ai-tc-claude-code",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "AI Traffic Control — inspect and govern AI prompts in Claude Code",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"zod": "^4.0.0",
|
|
30
30
|
"@akasecurity/eslint-config": "0.8.0",
|
|
31
31
|
"@akasecurity/persistence": "0.8.0",
|
|
32
|
-
"@akasecurity/
|
|
32
|
+
"@akasecurity/scanner": "0.8.0",
|
|
33
33
|
"@akasecurity/plugin-sdk": "0.8.0",
|
|
34
34
|
"@akasecurity/schema": "0.8.0",
|
|
35
|
-
"@akasecurity/
|
|
35
|
+
"@akasecurity/plugin-runtime": "0.8.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsup",
|
|
@@ -492,7 +492,7 @@ var require_ignore = __commonJS({
|
|
|
492
492
|
});
|
|
493
493
|
|
|
494
494
|
// src/apply-suppressions.ts
|
|
495
|
-
import { existsSync as
|
|
495
|
+
import { existsSync as existsSync7, readFileSync as readFileSync9 } from "fs";
|
|
496
496
|
import { userInfo } from "os";
|
|
497
497
|
import { dirname as dirname5, join as join14 } from "path";
|
|
498
498
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -23372,11 +23372,22 @@ function purgeSampleData(db) {
|
|
|
23372
23372
|
function linkHost(input, hostId) {
|
|
23373
23373
|
return hostId ? { ...input, hostId } : input;
|
|
23374
23374
|
}
|
|
23375
|
+
function closeQuietly(db) {
|
|
23376
|
+
try {
|
|
23377
|
+
db.close();
|
|
23378
|
+
} catch {
|
|
23379
|
+
}
|
|
23380
|
+
}
|
|
23375
23381
|
function openWithPragmas(file2) {
|
|
23376
23382
|
const db = new DatabaseSync(file2);
|
|
23377
|
-
|
|
23378
|
-
|
|
23379
|
-
|
|
23383
|
+
try {
|
|
23384
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
23385
|
+
db.exec("PRAGMA busy_timeout = 2000");
|
|
23386
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
23387
|
+
} catch (err) {
|
|
23388
|
+
closeQuietly(db);
|
|
23389
|
+
throw err;
|
|
23390
|
+
}
|
|
23380
23391
|
return db;
|
|
23381
23392
|
}
|
|
23382
23393
|
function backupLegacyStore(file2) {
|
|
@@ -23388,43 +23399,80 @@ function backupLegacyStore(file2) {
|
|
|
23388
23399
|
}
|
|
23389
23400
|
return backup;
|
|
23390
23401
|
}
|
|
23402
|
+
function openAndInitialize(file2) {
|
|
23403
|
+
let db = openWithPragmas(file2);
|
|
23404
|
+
try {
|
|
23405
|
+
if (isForeignSqliteLineage(db)) {
|
|
23406
|
+
db.close();
|
|
23407
|
+
const backup = backupLegacyStore(file2);
|
|
23408
|
+
db = openWithPragmas(file2);
|
|
23409
|
+
akaWarn(
|
|
23410
|
+
`Detected an older, incompatible (tenant-bearing) ${DB_FILENAME}; backed it up to ${backup} and created a fresh store.`
|
|
23411
|
+
);
|
|
23412
|
+
}
|
|
23413
|
+
applyMigrations(db, file2);
|
|
23414
|
+
tightenPerms(file2);
|
|
23415
|
+
const policies = new SqlitePoliciesRepository(db);
|
|
23416
|
+
const installedPacks = new SqliteInstalledPacksRepository(db);
|
|
23417
|
+
const repositories = {
|
|
23418
|
+
events: new SqliteEventsRepository(db),
|
|
23419
|
+
findings: new SqliteFindingsRepository(db),
|
|
23420
|
+
policies,
|
|
23421
|
+
installedPacks,
|
|
23422
|
+
scanLedger: new SqliteScanLedgerRepository(db),
|
|
23423
|
+
exceptions: new SqliteExceptionsRepository(db),
|
|
23424
|
+
resolutions: new SqliteResolutionsRepository(db),
|
|
23425
|
+
ruleProbeCache: new SqliteRuleProbeCacheRepository(db),
|
|
23426
|
+
security: new SqliteSecurityRepository(db),
|
|
23427
|
+
detections: new SqliteDetectionsRepository(db),
|
|
23428
|
+
shares: new SqliteSharesRepository(db),
|
|
23429
|
+
policyCatalog: new SqlitePolicyCatalogRepository(installedPacks),
|
|
23430
|
+
inventory: new SqliteInventoryRepository(db),
|
|
23431
|
+
inventoryAssets: new SqliteInventoryAssetsRepository(db),
|
|
23432
|
+
projectFiles: new SqliteProjectFilesRepository(db),
|
|
23433
|
+
activity: new SqliteActivityRepository(db),
|
|
23434
|
+
sourceProject: new SqliteSourceProjectRepository(db),
|
|
23435
|
+
auditEvents: new SqliteAuditEventsRepository(db),
|
|
23436
|
+
classifiedData: new SqliteClassifiedDataRepository(db),
|
|
23437
|
+
inspectionDefinitions: new SqliteInspectionDefinitionsRepository(db),
|
|
23438
|
+
inspectionFindings: new SqliteInspectionFindingsRepository(db),
|
|
23439
|
+
configInventory: new SqliteConfigInventoryRepository(db)
|
|
23440
|
+
};
|
|
23441
|
+
policies.seedDefaults();
|
|
23442
|
+
return { db, ...repositories };
|
|
23443
|
+
} catch (err) {
|
|
23444
|
+
closeQuietly(db);
|
|
23445
|
+
throw err;
|
|
23446
|
+
}
|
|
23447
|
+
}
|
|
23391
23448
|
function openLocalDatabase(dir) {
|
|
23392
23449
|
ensureDataDirSync(dir);
|
|
23393
23450
|
const file2 = join(dir, DB_FILENAME);
|
|
23394
|
-
|
|
23395
|
-
|
|
23396
|
-
|
|
23397
|
-
|
|
23398
|
-
|
|
23399
|
-
|
|
23400
|
-
|
|
23401
|
-
|
|
23402
|
-
|
|
23403
|
-
|
|
23404
|
-
|
|
23405
|
-
|
|
23406
|
-
|
|
23407
|
-
|
|
23408
|
-
|
|
23409
|
-
|
|
23410
|
-
|
|
23411
|
-
|
|
23412
|
-
|
|
23413
|
-
|
|
23414
|
-
|
|
23415
|
-
|
|
23416
|
-
|
|
23417
|
-
|
|
23418
|
-
|
|
23419
|
-
const projectFiles = new SqliteProjectFilesRepository(db);
|
|
23420
|
-
const activity = new SqliteActivityRepository(db);
|
|
23421
|
-
const sourceProject = new SqliteSourceProjectRepository(db);
|
|
23422
|
-
const auditEvents = new SqliteAuditEventsRepository(db);
|
|
23423
|
-
const classifiedData = new SqliteClassifiedDataRepository(db);
|
|
23424
|
-
const inspectionDefinitions = new SqliteInspectionDefinitionsRepository(db);
|
|
23425
|
-
const inspectionFindings = new SqliteInspectionFindingsRepository(db);
|
|
23426
|
-
const configInventory = new SqliteConfigInventoryRepository(db);
|
|
23427
|
-
policies.seedDefaults();
|
|
23451
|
+
const {
|
|
23452
|
+
db,
|
|
23453
|
+
events,
|
|
23454
|
+
findings,
|
|
23455
|
+
policies,
|
|
23456
|
+
installedPacks,
|
|
23457
|
+
scanLedger,
|
|
23458
|
+
exceptions,
|
|
23459
|
+
resolutions,
|
|
23460
|
+
ruleProbeCache,
|
|
23461
|
+
security,
|
|
23462
|
+
detections,
|
|
23463
|
+
shares,
|
|
23464
|
+
policyCatalog,
|
|
23465
|
+
inventory,
|
|
23466
|
+
inventoryAssets,
|
|
23467
|
+
projectFiles,
|
|
23468
|
+
activity,
|
|
23469
|
+
sourceProject,
|
|
23470
|
+
auditEvents,
|
|
23471
|
+
classifiedData,
|
|
23472
|
+
inspectionDefinitions,
|
|
23473
|
+
inspectionFindings,
|
|
23474
|
+
configInventory
|
|
23475
|
+
} = openAndInitialize(file2);
|
|
23428
23476
|
function recordCapture(event, detected) {
|
|
23429
23477
|
failOpenTransaction(db, () => {
|
|
23430
23478
|
const sessionId = event.metadata?.sessionId;
|
|
@@ -23629,8 +23677,9 @@ import { createHash as createHash3 } from "crypto";
|
|
|
23629
23677
|
|
|
23630
23678
|
// ../../packages/persistence/src/fingerprint.ts
|
|
23631
23679
|
import { createHmac, randomBytes } from "crypto";
|
|
23632
|
-
import { readFileSync } from "fs";
|
|
23680
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
23633
23681
|
import { join as join2 } from "path";
|
|
23682
|
+
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
23634
23683
|
|
|
23635
23684
|
// ../../packages/persistence/src/local-layout.ts
|
|
23636
23685
|
import { renameSync as renameSync3 } from "fs";
|
|
@@ -23691,11 +23740,11 @@ function readJson(file2) {
|
|
|
23691
23740
|
}
|
|
23692
23741
|
|
|
23693
23742
|
// ../../packages/persistence/src/warn-era-cap.ts
|
|
23694
|
-
import { existsSync as
|
|
23743
|
+
import { existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
23695
23744
|
import { join as join5 } from "path";
|
|
23696
23745
|
|
|
23697
23746
|
// ../../packages/plugin-sdk/src/config.ts
|
|
23698
|
-
import { existsSync as
|
|
23747
|
+
import { existsSync as existsSync4 } from "fs";
|
|
23699
23748
|
import { join as join6 } from "path";
|
|
23700
23749
|
|
|
23701
23750
|
// ../../packages/plugin-sdk/src/provider-env.ts
|
|
@@ -23751,7 +23800,7 @@ function loadConfig(base = defaultDataDir()) {
|
|
|
23751
23800
|
try {
|
|
23752
23801
|
ensureLayoutDirSync(base);
|
|
23753
23802
|
const settingsFile = join6(settingsDir(base), "settings.json");
|
|
23754
|
-
if (
|
|
23803
|
+
if (existsSync4(settingsFile)) tightenFile(settingsFile);
|
|
23755
23804
|
} catch {
|
|
23756
23805
|
}
|
|
23757
23806
|
migrateLegacyLayout(base);
|
|
@@ -26745,7 +26794,7 @@ function maskText(text) {
|
|
|
26745
26794
|
}
|
|
26746
26795
|
|
|
26747
26796
|
// ../../packages/plugin-sdk/src/repo.ts
|
|
26748
|
-
import { existsSync as
|
|
26797
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, statSync } from "fs";
|
|
26749
26798
|
import { basename, dirname, isAbsolute, join as join7, sep as sep2 } from "path";
|
|
26750
26799
|
|
|
26751
26800
|
// ../../packages/plugin-sdk/src/events.ts
|
|
@@ -26774,7 +26823,7 @@ function applyCategoryPosture(posture, repo, mode = "fill-gaps") {
|
|
|
26774
26823
|
|
|
26775
26824
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
26776
26825
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
26777
|
-
import { existsSync as
|
|
26826
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
|
|
26778
26827
|
import { basename as basename4, join as join10, relative, sep as sep4 } from "path";
|
|
26779
26828
|
|
|
26780
26829
|
// ../../packages/plugin-sdk/src/raw-egress.ts
|
|
@@ -27956,7 +28005,7 @@ function resolveCreatedBy() {
|
|
|
27956
28005
|
function loadRubric() {
|
|
27957
28006
|
const here = dirname5(fileURLToPath3(import.meta.url));
|
|
27958
28007
|
const shipped = join14(here, "triage-rubric.md");
|
|
27959
|
-
if (
|
|
28008
|
+
if (existsSync7(shipped)) return readFileSync9(shipped, "utf8");
|
|
27960
28009
|
return readFileSync9(join14(here, "..", "eval", "prompt.md"), "utf8");
|
|
27961
28010
|
}
|
|
27962
28011
|
async function main() {
|
package/scripts/backfill.js
CHANGED
|
@@ -495,7 +495,7 @@ var require_ignore = __commonJS({
|
|
|
495
495
|
import { fileURLToPath } from "url";
|
|
496
496
|
|
|
497
497
|
// ../../packages/plugin-sdk/src/config.ts
|
|
498
|
-
import { existsSync as
|
|
498
|
+
import { existsSync as existsSync4 } from "fs";
|
|
499
499
|
import { join as join6 } from "path";
|
|
500
500
|
|
|
501
501
|
// ../../packages/persistence/src/database.ts
|
|
@@ -23395,11 +23395,22 @@ function purgeSampleData(db) {
|
|
|
23395
23395
|
function linkHost(input, hostId) {
|
|
23396
23396
|
return hostId ? { ...input, hostId } : input;
|
|
23397
23397
|
}
|
|
23398
|
+
function closeQuietly(db) {
|
|
23399
|
+
try {
|
|
23400
|
+
db.close();
|
|
23401
|
+
} catch {
|
|
23402
|
+
}
|
|
23403
|
+
}
|
|
23398
23404
|
function openWithPragmas(file2) {
|
|
23399
23405
|
const db = new DatabaseSync(file2);
|
|
23400
|
-
|
|
23401
|
-
|
|
23402
|
-
|
|
23406
|
+
try {
|
|
23407
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
23408
|
+
db.exec("PRAGMA busy_timeout = 2000");
|
|
23409
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
23410
|
+
} catch (err) {
|
|
23411
|
+
closeQuietly(db);
|
|
23412
|
+
throw err;
|
|
23413
|
+
}
|
|
23403
23414
|
return db;
|
|
23404
23415
|
}
|
|
23405
23416
|
function backupLegacyStore(file2) {
|
|
@@ -23411,43 +23422,80 @@ function backupLegacyStore(file2) {
|
|
|
23411
23422
|
}
|
|
23412
23423
|
return backup;
|
|
23413
23424
|
}
|
|
23425
|
+
function openAndInitialize(file2) {
|
|
23426
|
+
let db = openWithPragmas(file2);
|
|
23427
|
+
try {
|
|
23428
|
+
if (isForeignSqliteLineage(db)) {
|
|
23429
|
+
db.close();
|
|
23430
|
+
const backup = backupLegacyStore(file2);
|
|
23431
|
+
db = openWithPragmas(file2);
|
|
23432
|
+
akaWarn(
|
|
23433
|
+
`Detected an older, incompatible (tenant-bearing) ${DB_FILENAME}; backed it up to ${backup} and created a fresh store.`
|
|
23434
|
+
);
|
|
23435
|
+
}
|
|
23436
|
+
applyMigrations(db, file2);
|
|
23437
|
+
tightenPerms(file2);
|
|
23438
|
+
const policies = new SqlitePoliciesRepository(db);
|
|
23439
|
+
const installedPacks = new SqliteInstalledPacksRepository(db);
|
|
23440
|
+
const repositories = {
|
|
23441
|
+
events: new SqliteEventsRepository(db),
|
|
23442
|
+
findings: new SqliteFindingsRepository(db),
|
|
23443
|
+
policies,
|
|
23444
|
+
installedPacks,
|
|
23445
|
+
scanLedger: new SqliteScanLedgerRepository(db),
|
|
23446
|
+
exceptions: new SqliteExceptionsRepository(db),
|
|
23447
|
+
resolutions: new SqliteResolutionsRepository(db),
|
|
23448
|
+
ruleProbeCache: new SqliteRuleProbeCacheRepository(db),
|
|
23449
|
+
security: new SqliteSecurityRepository(db),
|
|
23450
|
+
detections: new SqliteDetectionsRepository(db),
|
|
23451
|
+
shares: new SqliteSharesRepository(db),
|
|
23452
|
+
policyCatalog: new SqlitePolicyCatalogRepository(installedPacks),
|
|
23453
|
+
inventory: new SqliteInventoryRepository(db),
|
|
23454
|
+
inventoryAssets: new SqliteInventoryAssetsRepository(db),
|
|
23455
|
+
projectFiles: new SqliteProjectFilesRepository(db),
|
|
23456
|
+
activity: new SqliteActivityRepository(db),
|
|
23457
|
+
sourceProject: new SqliteSourceProjectRepository(db),
|
|
23458
|
+
auditEvents: new SqliteAuditEventsRepository(db),
|
|
23459
|
+
classifiedData: new SqliteClassifiedDataRepository(db),
|
|
23460
|
+
inspectionDefinitions: new SqliteInspectionDefinitionsRepository(db),
|
|
23461
|
+
inspectionFindings: new SqliteInspectionFindingsRepository(db),
|
|
23462
|
+
configInventory: new SqliteConfigInventoryRepository(db)
|
|
23463
|
+
};
|
|
23464
|
+
policies.seedDefaults();
|
|
23465
|
+
return { db, ...repositories };
|
|
23466
|
+
} catch (err) {
|
|
23467
|
+
closeQuietly(db);
|
|
23468
|
+
throw err;
|
|
23469
|
+
}
|
|
23470
|
+
}
|
|
23414
23471
|
function openLocalDatabase(dir) {
|
|
23415
23472
|
ensureDataDirSync(dir);
|
|
23416
23473
|
const file2 = join(dir, DB_FILENAME);
|
|
23417
|
-
|
|
23418
|
-
|
|
23419
|
-
|
|
23420
|
-
|
|
23421
|
-
|
|
23422
|
-
|
|
23423
|
-
|
|
23424
|
-
|
|
23425
|
-
|
|
23426
|
-
|
|
23427
|
-
|
|
23428
|
-
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
|
|
23435
|
-
|
|
23436
|
-
|
|
23437
|
-
|
|
23438
|
-
|
|
23439
|
-
|
|
23440
|
-
|
|
23441
|
-
|
|
23442
|
-
const projectFiles = new SqliteProjectFilesRepository(db);
|
|
23443
|
-
const activity = new SqliteActivityRepository(db);
|
|
23444
|
-
const sourceProject = new SqliteSourceProjectRepository(db);
|
|
23445
|
-
const auditEvents = new SqliteAuditEventsRepository(db);
|
|
23446
|
-
const classifiedData = new SqliteClassifiedDataRepository(db);
|
|
23447
|
-
const inspectionDefinitions = new SqliteInspectionDefinitionsRepository(db);
|
|
23448
|
-
const inspectionFindings = new SqliteInspectionFindingsRepository(db);
|
|
23449
|
-
const configInventory = new SqliteConfigInventoryRepository(db);
|
|
23450
|
-
policies.seedDefaults();
|
|
23474
|
+
const {
|
|
23475
|
+
db,
|
|
23476
|
+
events,
|
|
23477
|
+
findings,
|
|
23478
|
+
policies,
|
|
23479
|
+
installedPacks,
|
|
23480
|
+
scanLedger,
|
|
23481
|
+
exceptions,
|
|
23482
|
+
resolutions,
|
|
23483
|
+
ruleProbeCache,
|
|
23484
|
+
security,
|
|
23485
|
+
detections,
|
|
23486
|
+
shares,
|
|
23487
|
+
policyCatalog,
|
|
23488
|
+
inventory,
|
|
23489
|
+
inventoryAssets,
|
|
23490
|
+
projectFiles,
|
|
23491
|
+
activity,
|
|
23492
|
+
sourceProject,
|
|
23493
|
+
auditEvents,
|
|
23494
|
+
classifiedData,
|
|
23495
|
+
inspectionDefinitions,
|
|
23496
|
+
inspectionFindings,
|
|
23497
|
+
configInventory
|
|
23498
|
+
} = openAndInitialize(file2);
|
|
23451
23499
|
function recordCapture(event, detected) {
|
|
23452
23500
|
failOpenTransaction(db, () => {
|
|
23453
23501
|
const sessionId = event.metadata?.sessionId;
|
|
@@ -23659,8 +23707,9 @@ function computeFindingKey(input) {
|
|
|
23659
23707
|
|
|
23660
23708
|
// ../../packages/persistence/src/fingerprint.ts
|
|
23661
23709
|
import { createHmac, randomBytes } from "crypto";
|
|
23662
|
-
import { readFileSync } from "fs";
|
|
23710
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
23663
23711
|
import { join as join2 } from "path";
|
|
23712
|
+
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
23664
23713
|
var KEY_FILENAME = "exception.key";
|
|
23665
23714
|
var KEY_MATERIAL_BYTES = 32;
|
|
23666
23715
|
function keyFilePath(dataDir2) {
|
|
@@ -23684,6 +23733,46 @@ function parseKeyFile(raw) {
|
|
|
23684
23733
|
}
|
|
23685
23734
|
return { version: version2, material: bytes };
|
|
23686
23735
|
}
|
|
23736
|
+
var KEY_VERSION_TABLES = ["exceptions", "blocked_detections"];
|
|
23737
|
+
var SQLITE_ERROR = 1;
|
|
23738
|
+
var FLOOR_BUSY_TIMEOUT_MS = 250;
|
|
23739
|
+
var FloorUnreadableError = class extends Error {
|
|
23740
|
+
code = "floor-unreadable";
|
|
23741
|
+
constructor(cause) {
|
|
23742
|
+
super(
|
|
23743
|
+
`cannot read the stored fingerprint key versions: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
23744
|
+
{ cause }
|
|
23745
|
+
);
|
|
23746
|
+
this.name = "FloorUnreadableError";
|
|
23747
|
+
}
|
|
23748
|
+
};
|
|
23749
|
+
function storedKeyVersionFloor(dataDir2) {
|
|
23750
|
+
const file2 = join2(dataDir2, DB_FILENAME);
|
|
23751
|
+
if (!existsSync2(file2)) return 0;
|
|
23752
|
+
let db;
|
|
23753
|
+
try {
|
|
23754
|
+
db = new DatabaseSync2(file2, { readOnly: true });
|
|
23755
|
+
db.exec(`PRAGMA busy_timeout = ${String(FLOOR_BUSY_TIMEOUT_MS)}`);
|
|
23756
|
+
let floor = 0;
|
|
23757
|
+
for (const table of KEY_VERSION_TABLES) {
|
|
23758
|
+
try {
|
|
23759
|
+
const row = getRow(
|
|
23760
|
+
db.prepare(`SELECT MAX(key_version) AS v FROM ${table}`)
|
|
23761
|
+
);
|
|
23762
|
+
floor = Math.max(floor, row?.v ?? 0);
|
|
23763
|
+
} catch (err) {
|
|
23764
|
+
if (err.errcode !== SQLITE_ERROR) {
|
|
23765
|
+
throw new FloorUnreadableError(err);
|
|
23766
|
+
}
|
|
23767
|
+
}
|
|
23768
|
+
}
|
|
23769
|
+
return floor;
|
|
23770
|
+
} catch (err) {
|
|
23771
|
+
throw err instanceof FloorUnreadableError ? err : new FloorUnreadableError(err);
|
|
23772
|
+
} finally {
|
|
23773
|
+
db?.close();
|
|
23774
|
+
}
|
|
23775
|
+
}
|
|
23687
23776
|
function writeKeyFile(dataDir2, key) {
|
|
23688
23777
|
ensureDataDirSync(dataDir2);
|
|
23689
23778
|
const file2 = keyFilePath(dataDir2);
|
|
@@ -23708,7 +23797,10 @@ function loadOrCreateFingerprintKey(dataDir2) {
|
|
|
23708
23797
|
tightenFile(keyFilePath(dataDir2));
|
|
23709
23798
|
return existing;
|
|
23710
23799
|
}
|
|
23711
|
-
return writeKeyFile(dataDir2, {
|
|
23800
|
+
return writeKeyFile(dataDir2, {
|
|
23801
|
+
version: storedKeyVersionFloor(dataDir2) + 1,
|
|
23802
|
+
material: randomBytes(KEY_MATERIAL_BYTES)
|
|
23803
|
+
});
|
|
23712
23804
|
}
|
|
23713
23805
|
function fingerprintValue(key, raw) {
|
|
23714
23806
|
return createHmac("sha256", key.material).update(raw, "utf8").digest("hex");
|
|
@@ -23773,13 +23865,13 @@ function readJson(file2) {
|
|
|
23773
23865
|
}
|
|
23774
23866
|
|
|
23775
23867
|
// ../../packages/persistence/src/warn-era-cap.ts
|
|
23776
|
-
import { existsSync as
|
|
23868
|
+
import { existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
23777
23869
|
import { join as join5 } from "path";
|
|
23778
23870
|
var MARKER = "warn-era-capped";
|
|
23779
23871
|
function capWarnEraEnforcementOnce(db, policyMode, dataDir2) {
|
|
23780
23872
|
if (policyMode !== "warn") return { capped: 0, skipped: "not-warn" };
|
|
23781
23873
|
const marker = join5(dataDir2, MARKER);
|
|
23782
|
-
if (
|
|
23874
|
+
if (existsSync3(marker)) return { capped: 0, skipped: "already-run" };
|
|
23783
23875
|
const capped = db.policies.capCategoryActions();
|
|
23784
23876
|
writeFileSync2(marker, `${new Date(Date.now()).toISOString()}
|
|
23785
23877
|
`, { mode: DATA_FILE_MODE });
|
|
@@ -23849,7 +23941,7 @@ function loadConfig(base = defaultDataDir()) {
|
|
|
23849
23941
|
try {
|
|
23850
23942
|
ensureLayoutDirSync(base);
|
|
23851
23943
|
const settingsFile = join6(settingsDir(base), "settings.json");
|
|
23852
|
-
if (
|
|
23944
|
+
if (existsSync4(settingsFile)) tightenFile(settingsFile);
|
|
23853
23945
|
} catch {
|
|
23854
23946
|
}
|
|
23855
23947
|
migrateLegacyLayout(base);
|
|
@@ -26933,7 +27025,7 @@ function scanText(text, ruleVersions) {
|
|
|
26933
27025
|
}
|
|
26934
27026
|
|
|
26935
27027
|
// ../../packages/plugin-sdk/src/repo.ts
|
|
26936
|
-
import { existsSync as
|
|
27028
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, statSync } from "fs";
|
|
26937
27029
|
import { basename, dirname, isAbsolute, join as join7, sep as sep2 } from "path";
|
|
26938
27030
|
function resolveRepoIdentity(cwd) {
|
|
26939
27031
|
try {
|
|
@@ -26967,7 +27059,7 @@ function resolveRepoNwo(cwd) {
|
|
|
26967
27059
|
function findGitRoot(start) {
|
|
26968
27060
|
let dir = start;
|
|
26969
27061
|
for (; ; ) {
|
|
26970
|
-
if (
|
|
27062
|
+
if (existsSync5(join7(dir, ".git"))) return dir;
|
|
26971
27063
|
const parent = dirname(dir);
|
|
26972
27064
|
if (parent === dir) return void 0;
|
|
26973
27065
|
dir = parent;
|
|
@@ -26985,7 +27077,7 @@ function resolveGitContext(root) {
|
|
|
26985
27077
|
const target = /^gitdir:\s*(.+?)\s*$/m.exec(safeRead(dotGit) ?? "")?.[1];
|
|
26986
27078
|
if (!target) return void 0;
|
|
26987
27079
|
const gitdir = isAbsolute(target) ? target : join7(root, target);
|
|
26988
|
-
if (
|
|
27080
|
+
if (existsSync5(join7(gitdir, "config"))) {
|
|
26989
27081
|
return { configPath: join7(gitdir, "config"), headRoot: root };
|
|
26990
27082
|
}
|
|
26991
27083
|
const commonRaw = safeRead(join7(gitdir, "commondir"))?.trim();
|
|
@@ -27108,7 +27200,7 @@ import { basename as basename3, dirname as dirname2, sep as sep3 } from "path";
|
|
|
27108
27200
|
|
|
27109
27201
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
27110
27202
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
27111
|
-
import { existsSync as
|
|
27203
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
|
|
27112
27204
|
import { basename as basename4, join as join10, relative, sep as sep4 } from "path";
|
|
27113
27205
|
|
|
27114
27206
|
// ../../packages/plugin-sdk/src/raw-egress.ts
|