@akasecurity/ai-tc-claude-code 0.8.2 → 0.9.0
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/README.md +11 -3
- package/commands/setup.md +563 -151
- package/package.json +5 -5
- package/scripts/apply-suppressions.js +821 -115
- package/scripts/backfill.js +364 -91
- package/scripts/filescan.js +341 -76
- package/scripts/firstrun.js +476 -107
- package/scripts/intro.js +328 -137
- package/scripts/onboard.js +406 -83
- package/scripts/package.json +1 -0
- package/scripts/post-tool-use.js +344 -77
- package/scripts/pre-tool-use.js +342 -76
- package/scripts/query.js +332 -66
- package/scripts/reconcile.js +329 -69
- package/scripts/remediate.js +26695 -0
- package/scripts/session-start.js +329 -69
- package/scripts/start-light.js +17542 -0
- package/scripts/statusline.js +334 -66
- package/scripts/stop.js +234 -51
- package/scripts/triage-rubric.md +10 -2
- package/scripts/user-prompt-submit.js +345 -79
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
|
|
@@ -15645,6 +15610,10 @@ var ListActivitySessionsQuery = external_exports.object({
|
|
|
15645
15610
|
from: external_exports.union([external_exports.iso.date(), external_exports.iso.datetime()]).optional(),
|
|
15646
15611
|
/** Upper bound on startedAt; omitted defaults to now. */
|
|
15647
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(),
|
|
15648
15617
|
/** Page size, 1–100; out-of-range values are a 400. `z.coerce` — query params arrive as strings. */
|
|
15649
15618
|
limit: external_exports.coerce.number().int().min(1).max(100).default(50),
|
|
15650
15619
|
/** Opaque pagination cursor (most-recent first). */
|
|
@@ -15653,7 +15622,11 @@ var ListActivitySessionsQuery = external_exports.object({
|
|
|
15653
15622
|
var ListActivitySessionsResponse = external_exports.object({
|
|
15654
15623
|
items: external_exports.array(ActivitySessionSummary),
|
|
15655
15624
|
/** `null` once the last page is reached. */
|
|
15656
|
-
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()
|
|
15657
15630
|
}).meta({ id: "ListActivitySessionsResponse" });
|
|
15658
15631
|
var ListSessionEventsQuery = external_exports.object({
|
|
15659
15632
|
/** Default 100, range 1–500. */
|
|
@@ -15688,6 +15661,12 @@ var EventMetadata = external_exports.object({
|
|
|
15688
15661
|
sessionId: external_exports.string().optional(),
|
|
15689
15662
|
repo: external_exports.string().optional(),
|
|
15690
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(),
|
|
15691
15670
|
// Set (true) by the worktree scanner when the file is excluded by the
|
|
15692
15671
|
// repo's .gitignore. Gitignored files ARE still scanned — local scratch and
|
|
15693
15672
|
// generated code can leak real secrets — but the provenance is recorded so
|
|
@@ -16019,7 +15998,10 @@ var ExceptionBundleEntry = DetectionException.pick({
|
|
|
16019
15998
|
var MatcherType = external_exports.enum(["keyword", "regex", "validator"]).meta({ id: "MatcherType" });
|
|
16020
15999
|
var KeywordMatcher = external_exports.object({
|
|
16021
16000
|
type: external_exports.literal("keyword"),
|
|
16022
|
-
|
|
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),
|
|
16023
16005
|
caseSensitive: external_exports.boolean().default(false)
|
|
16024
16006
|
});
|
|
16025
16007
|
function isValidRegex(pattern, flags) {
|
|
@@ -16261,6 +16243,10 @@ var ListEventsResponse = external_exports.object({
|
|
|
16261
16243
|
items: external_exports.array(Event),
|
|
16262
16244
|
nextCursor: external_exports.string().nullable()
|
|
16263
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" });
|
|
16264
16250
|
var ListFindingsQuery = external_exports.object({
|
|
16265
16251
|
cursor: external_exports.string().optional(),
|
|
16266
16252
|
limit: external_exports.coerce.number().int().min(1).max(LIST_QUERY_MAX_LIMIT).default(50),
|
|
@@ -16581,6 +16567,65 @@ var ProjectFilesScan = external_exports.object({
|
|
|
16581
16567
|
scannedAt: external_exports.string()
|
|
16582
16568
|
});
|
|
16583
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
|
+
|
|
16584
16629
|
// ../../packages/schema/src/zod/rule-test.ts
|
|
16585
16630
|
var TestRulesRequest = external_exports.object({
|
|
16586
16631
|
rules: external_exports.array(Rule).min(1).max(100),
|
|
@@ -16639,10 +16684,8 @@ var SeveritySummaryResponse = external_exports.object({
|
|
|
16639
16684
|
// All four severity levels are always present (count may be 0).
|
|
16640
16685
|
bySeverity: external_exports.array(SeveritySummaryItem)
|
|
16641
16686
|
}).meta({ id: "SeveritySummaryResponse" });
|
|
16642
|
-
var SECURITY_RANGES = ["7d", "30d", "3m", "6m"];
|
|
16643
|
-
var SecurityRange = external_exports.enum(SECURITY_RANGES).meta({ id: "SecurityRange" });
|
|
16644
16687
|
var SecurityRangeQuery = external_exports.object({
|
|
16645
|
-
range: external_exports.enum(
|
|
16688
|
+
range: external_exports.enum(TIME_RANGES).default(DEFAULT_TIME_RANGE)
|
|
16646
16689
|
});
|
|
16647
16690
|
var EnforcementActionKind = external_exports.enum(["blocked", "redacted", "warned"]).meta({ id: "EnforcementActionKind" });
|
|
16648
16691
|
var EnforcementAction = external_exports.object({
|
|
@@ -16652,7 +16695,7 @@ var EnforcementAction = external_exports.object({
|
|
|
16652
16695
|
delta: external_exports.number().int()
|
|
16653
16696
|
}).meta({ id: "EnforcementAction" });
|
|
16654
16697
|
var EnforcementActionsResponse = external_exports.object({
|
|
16655
|
-
range:
|
|
16698
|
+
range: TimeRange,
|
|
16656
16699
|
// Sum of actions[].count in the window.
|
|
16657
16700
|
total: external_exports.number().int().nonnegative(),
|
|
16658
16701
|
// One entry per kind, always all three present (count may be 0).
|
|
@@ -16667,7 +16710,7 @@ var FindingsTimeseriesPoint = external_exports.object({
|
|
|
16667
16710
|
medium: external_exports.number().int().nonnegative()
|
|
16668
16711
|
}).meta({ id: "FindingsTimeseriesPoint" });
|
|
16669
16712
|
var FindingsTimeseriesResponse = external_exports.object({
|
|
16670
|
-
range:
|
|
16713
|
+
range: TimeRange,
|
|
16671
16714
|
granularity: TimeseriesGranularity,
|
|
16672
16715
|
points: external_exports.array(FindingsTimeseriesPoint)
|
|
16673
16716
|
}).meta({ id: "FindingsTimeseriesResponse" });
|
|
@@ -16682,7 +16725,7 @@ var MttrTrendPoint = external_exports.object({
|
|
|
16682
16725
|
})
|
|
16683
16726
|
}).meta({ id: "MttrTrendPoint" });
|
|
16684
16727
|
var MttrTrendResponse = external_exports.object({
|
|
16685
|
-
range:
|
|
16728
|
+
range: TimeRange,
|
|
16686
16729
|
granularity: TimeseriesGranularity,
|
|
16687
16730
|
points: external_exports.array(MttrTrendPoint)
|
|
16688
16731
|
}).meta({ id: "MttrTrendResponse" });
|
|
@@ -16709,11 +16752,11 @@ var TopSource = external_exports.object({
|
|
|
16709
16752
|
findingsCount: external_exports.number().int().nonnegative()
|
|
16710
16753
|
}).meta({ id: "TopSource" });
|
|
16711
16754
|
var TopSourcesResponse = external_exports.object({
|
|
16712
|
-
range:
|
|
16755
|
+
range: TimeRange,
|
|
16713
16756
|
items: external_exports.array(TopSource)
|
|
16714
16757
|
}).meta({ id: "TopSourcesResponse" });
|
|
16715
16758
|
var TopSourcesQuery = external_exports.object({
|
|
16716
|
-
range: external_exports.enum(
|
|
16759
|
+
range: external_exports.enum(TIME_RANGES).default(DEFAULT_TIME_RANGE),
|
|
16717
16760
|
limit: external_exports.coerce.number().int().min(1).max(50).default(5),
|
|
16718
16761
|
// Omit for both kinds.
|
|
16719
16762
|
kind: external_exports.enum(SOURCE_KINDS).optional()
|
|
@@ -16726,7 +16769,7 @@ var ScanCoverageProvider = external_exports.object({
|
|
|
16726
16769
|
supported: external_exports.boolean()
|
|
16727
16770
|
}).meta({ id: "ScanCoverageProvider" });
|
|
16728
16771
|
var ScanCoverageResponse = external_exports.object({
|
|
16729
|
-
range:
|
|
16772
|
+
range: TimeRange,
|
|
16730
16773
|
providers: external_exports.array(ScanCoverageProvider)
|
|
16731
16774
|
}).meta({ id: "ScanCoverageResponse" });
|
|
16732
16775
|
var SubjectType = external_exports.enum(["repo", "user", "team", "policy", "share", "rule"]).meta({
|
|
@@ -16775,6 +16818,114 @@ var ApplyRecommendedActionResponse = external_exports.object({
|
|
|
16775
16818
|
var DismissRecommendedActionResponse = external_exports.object({ id: external_exports.string(), status: external_exports.literal("dismissed") }).meta({ id: "DismissRecommendedActionResponse" });
|
|
16776
16819
|
var RecommendedActionIdParam = external_exports.object({ id: external_exports.string() });
|
|
16777
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
|
+
|
|
16778
16929
|
// ../../packages/schema/src/zod/shares.ts
|
|
16779
16930
|
var DestinationKind = external_exports.enum(["provider", "internal", "ip"]).meta({ id: "DestinationKind" });
|
|
16780
16931
|
var Transport = external_exports.enum(["https", "http", "sftp", "grpc", "smtp"]).meta({ id: "Transport" });
|
|
@@ -16914,35 +17065,15 @@ var ExportSharesQuery = external_exports.object({
|
|
|
16914
17065
|
kind: external_exports.array(DestinationKind).optional()
|
|
16915
17066
|
});
|
|
16916
17067
|
|
|
16917
|
-
//
|
|
16918
|
-
|
|
16919
|
-
|
|
16920
|
-
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16926
|
-
confidence: external_exports.number().min(0).max(1),
|
|
16927
|
-
id: external_exports.string().optional(),
|
|
16928
|
-
valueFingerprint: external_exports.string().optional(),
|
|
16929
|
-
keyVersion: external_exports.number().int().nonnegative().optional()
|
|
16930
|
-
});
|
|
16931
|
-
var TriagePolicy = BuiltinPolicyId;
|
|
16932
|
-
var TriageCategoryRec = external_exports.object({
|
|
16933
|
-
category: DetectionCategory,
|
|
16934
|
-
action: TriagePolicy,
|
|
16935
|
-
reasoning: external_exports.string(),
|
|
16936
|
-
genuineCount: external_exports.number().int().nonnegative(),
|
|
16937
|
-
fpCount: external_exports.number().int().nonnegative(),
|
|
16938
|
-
// TriageHit ids judged false-positive in this category. fpCount must equal
|
|
16939
|
-
// this array's length — enforced by the consumer, not this schema.
|
|
16940
|
-
fpIds: external_exports.array(external_exports.string())
|
|
16941
|
-
});
|
|
16942
|
-
var TriageRecommendation = external_exports.object({
|
|
16943
|
-
perCategory: external_exports.array(TriageCategoryRec),
|
|
16944
|
-
notes: external_exports.string()
|
|
16945
|
-
});
|
|
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";
|
|
16946
17077
|
|
|
16947
17078
|
// ../../packages/persistence/src/ids.ts
|
|
16948
17079
|
import { createHash } from "crypto";
|
|
@@ -17020,21 +17151,28 @@ import { readdirSync, readFileSync as readFileSync4, realpathSync, statSync as s
|
|
|
17020
17151
|
import { homedir as homedir2 } from "os";
|
|
17021
17152
|
import { basename as basename2, join as join7 } from "path";
|
|
17022
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;
|
|
17161
|
+
|
|
17023
17162
|
// ../../packages/detections/src/matchers/keyword.ts
|
|
17024
17163
|
var KeywordMatcher2 = class {
|
|
17025
17164
|
match(text, rule) {
|
|
17026
17165
|
if (rule.matcher.type !== "keyword") return [];
|
|
17027
17166
|
const { keywords, caseSensitive } = rule.matcher;
|
|
17028
|
-
const haystack = caseSensitive ? text : text.toLowerCase();
|
|
17029
17167
|
const spans = [];
|
|
17030
17168
|
for (const kw of keywords) {
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
spans.push({ start:
|
|
17037
|
-
|
|
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;
|
|
17038
17176
|
}
|
|
17039
17177
|
}
|
|
17040
17178
|
return spans;
|
|
@@ -17042,7 +17180,6 @@ var KeywordMatcher2 = class {
|
|
|
17042
17180
|
};
|
|
17043
17181
|
|
|
17044
17182
|
// ../../packages/detections/src/matchers/regex.ts
|
|
17045
|
-
var MAX_MATCHES_PER_RULE = 1e4;
|
|
17046
17183
|
var RegexMatcher2 = class {
|
|
17047
17184
|
match(text, rule) {
|
|
17048
17185
|
if (rule.matcher.type !== "regex") return [];
|
|
@@ -17157,6 +17294,65 @@ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
|
17157
17294
|
import { mkdirSync as mkdirSync4, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
17158
17295
|
import { join as join10 } from "path";
|
|
17159
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
|
+
}
|
|
17355
|
+
|
|
17160
17356
|
// src/render.ts
|
|
17161
17357
|
var SEVERITY_GLYPH = {
|
|
17162
17358
|
critical: SHADE.full,
|
|
@@ -17166,47 +17362,42 @@ var SEVERITY_GLYPH = {
|
|
|
17166
17362
|
};
|
|
17167
17363
|
var CATEGORY_ORDER = DetectionCategory.options;
|
|
17168
17364
|
function renderSetupIntro(meta3) {
|
|
17169
|
-
const
|
|
17170
|
-
const
|
|
17171
|
-
|
|
17172
|
-
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
|
|
17176
|
-
|
|
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");
|
|
17177
17377
|
}
|
|
17178
17378
|
|
|
17179
|
-
// src/intro.ts
|
|
17180
|
-
var NAME = "AKA Security";
|
|
17181
|
-
var TAGLINE = "Agent Harness Security for Claude Code.";
|
|
17182
|
-
var ADDS = "Secures your local environment to prevent secret leakage and vulnerabilities.";
|
|
17379
|
+
// src/intro-card.ts
|
|
17183
17380
|
function repoLabel(homepage) {
|
|
17184
17381
|
if (!homepage) return "";
|
|
17185
17382
|
const stripped = homepage.replace(/^https?:\/\//, "");
|
|
17186
17383
|
const parts = stripped.split("/");
|
|
17187
17384
|
return parts.length >= 3 ? parts.slice(0, 3).join("/") : stripped;
|
|
17188
17385
|
}
|
|
17189
|
-
function
|
|
17190
|
-
|
|
17191
|
-
|
|
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
|
+
});
|
|
17192
17393
|
}
|
|
17394
|
+
|
|
17395
|
+
// src/intro.ts
|
|
17193
17396
|
var manifestPath = process.argv[2];
|
|
17194
17397
|
var manifest = {};
|
|
17195
17398
|
try {
|
|
17196
17399
|
manifest = JSON.parse(readFileSync7(manifestPath ?? "", "utf8"));
|
|
17197
17400
|
} catch {
|
|
17198
17401
|
}
|
|
17199
|
-
process.stdout.write(
|
|
17200
|
-
`${fenced(
|
|
17201
|
-
renderSetupIntro({
|
|
17202
|
-
name: NAME,
|
|
17203
|
-
tagline: TAGLINE,
|
|
17204
|
-
repository: repoLabel(manifest.homepage),
|
|
17205
|
-
version: manifest.version ?? "",
|
|
17206
|
-
publisher: authorName(manifest.author),
|
|
17207
|
-
adds: ADDS
|
|
17208
|
-
})
|
|
17209
|
-
)}
|
|
17210
|
-
`
|
|
17211
|
-
);
|
|
17402
|
+
process.stdout.write(show(fenced(buildIntroCard(manifest))));
|
|
17212
17403
|
process.exit(0);
|