@akasecurity/ai-tc-claude-code 0.9.10 → 0.9.11
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 +5 -5
- package/scripts/apply-suppressions.js +622 -430
- package/scripts/backfill.js +732 -504
- package/scripts/filescan.js +726 -496
- package/scripts/firstrun.js +772 -516
- package/scripts/history-sync.js +611 -418
- package/scripts/intro.js +240 -90
- package/scripts/message-display.js +604 -412
- package/scripts/onboard.js +601 -408
- package/scripts/post-model-switch.js +258 -110
- package/scripts/post-tool-use.js +880 -493
- package/scripts/pre-model-switch.js +691 -469
- package/scripts/pre-tool-use.js +728 -498
- package/scripts/query.js +845 -526
- package/scripts/reconcile.js +716 -494
- package/scripts/remediate.js +728 -498
- package/scripts/scan-worker.js +153 -58
- package/scripts/session-start.js +783 -558
- package/scripts/start-light.js +238 -88
- package/scripts/statusline.js +697 -475
- package/scripts/stop.js +490 -121
- package/scripts/sync.js +722 -494
- package/scripts/user-prompt-submit.js +725 -495
package/scripts/stop.js
CHANGED
|
@@ -492,8 +492,8 @@ var require_ignore = __commonJS({
|
|
|
492
492
|
});
|
|
493
493
|
|
|
494
494
|
// ../../packages/plugin-sdk/src/config.ts
|
|
495
|
-
import { existsSync as
|
|
496
|
-
import { join as
|
|
495
|
+
import { existsSync as existsSync8 } from "fs";
|
|
496
|
+
import { join as join14 } from "path";
|
|
497
497
|
|
|
498
498
|
// ../../packages/persistence/src/attached-derived.ts
|
|
499
499
|
import { rmSync } from "fs";
|
|
@@ -2320,18 +2320,18 @@ var validateAsync = async (schema, value, _ctx) => {
|
|
|
2320
2320
|
return result.issues.length === 0;
|
|
2321
2321
|
};
|
|
2322
2322
|
var _encode = (_Err) => {
|
|
2323
|
-
const
|
|
2323
|
+
const parse4 = _parse(_Err);
|
|
2324
2324
|
const fn = (schema, value, _ctx, _params) => {
|
|
2325
2325
|
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
|
2326
|
-
return
|
|
2326
|
+
return parse4(schema, value, ctx, finalizeParams(fn, _params));
|
|
2327
2327
|
};
|
|
2328
2328
|
return fn;
|
|
2329
2329
|
};
|
|
2330
2330
|
var encode = /* @__PURE__ */ _encode($ZodRealError);
|
|
2331
2331
|
var _decode = (_Err) => {
|
|
2332
|
-
const
|
|
2332
|
+
const parse4 = _parse(_Err);
|
|
2333
2333
|
const fn = (schema, value, _ctx, _params) => {
|
|
2334
|
-
return
|
|
2334
|
+
return parse4(schema, value, _ctx, finalizeParams(fn, _params));
|
|
2335
2335
|
};
|
|
2336
2336
|
return fn;
|
|
2337
2337
|
};
|
|
@@ -20385,13 +20385,11 @@ var FindingGroup = external_exports.object({
|
|
|
20385
20385
|
latestDetectedAt: external_exports.iso.datetime(),
|
|
20386
20386
|
instances: external_exports.array(FindingInstance),
|
|
20387
20387
|
// Derived from instances' statuses with open-dominates precedence (see
|
|
20388
|
-
//
|
|
20388
|
+
// foldGroupStatus). Undefined only when no instance carries a status.
|
|
20389
20389
|
status: FindingStatus.optional(),
|
|
20390
|
-
// The distinct people across the WHOLE group, not just the
|
|
20391
|
-
//
|
|
20392
|
-
//
|
|
20393
|
-
// instance carries a user, or when the store supplied whole-group folds
|
|
20394
|
-
// without one.
|
|
20390
|
+
// The distinct people across the WHOLE group, not just the instances
|
|
20391
|
+
// carried here. Undefined when no instance carries a user, or when the
|
|
20392
|
+
// store supplied whole-group folds without one.
|
|
20395
20393
|
users: external_exports.array(FindingUser).optional()
|
|
20396
20394
|
}).meta({ id: "FindingGroup" });
|
|
20397
20395
|
var FindingStats = external_exports.object({
|
|
@@ -20420,20 +20418,30 @@ var FindingFacets = external_exports.object({
|
|
|
20420
20418
|
// counted under no value.
|
|
20421
20419
|
status: external_exports.array(FindingFacetItem),
|
|
20422
20420
|
// Host tool (attributes.tool_name). Present only on the instance-level
|
|
20423
|
-
// reads, which can filter by it; the
|
|
20421
|
+
// reads, which can filter by it; the type-level read omits the dimension
|
|
20424
20422
|
// because a group spans tools.
|
|
20425
20423
|
tool: external_exports.array(FindingFacetItem).optional()
|
|
20426
20424
|
}).meta({ id: "FindingFacets" });
|
|
20427
|
-
var
|
|
20425
|
+
var FindingTypeSummary = FindingGroup.omit({ instances: true, match: true }).meta({
|
|
20426
|
+
id: "FindingTypeSummary"
|
|
20427
|
+
});
|
|
20428
|
+
var MAX_FINDING_TYPES_LIMIT = 100;
|
|
20429
|
+
var ListFindingTypesQuery = external_exports.object({
|
|
20428
20430
|
// NOTE: severity filters by Severity (critical/high/medium/low), not by
|
|
20429
|
-
// FindingAction.
|
|
20431
|
+
// FindingAction. It narrows TYPES: a type's severity is the one its newest
|
|
20432
|
+
// firing version carries, and this list pages types.
|
|
20433
|
+
//
|
|
20434
|
+
// That is NOT a claim the findings of a type share it. A rule can hold several
|
|
20435
|
+
// definition versions at different severities, so a type kept by this filter
|
|
20436
|
+
// can hold findings that individually do not match — see totals.findings on
|
|
20437
|
+
// ListFindingTypesResponse, which counts them all.
|
|
20430
20438
|
severity: external_exports.array(Severity).optional(),
|
|
20431
20439
|
subtype: external_exports.array(external_exports.string()).optional(),
|
|
20432
20440
|
provider: external_exports.array(FindingProvider).optional(),
|
|
20433
20441
|
action: external_exports.array(FindingAction).optional(),
|
|
20434
|
-
// Matches a
|
|
20435
|
-
// individual
|
|
20436
|
-
//
|
|
20442
|
+
// Matches a type's DERIVED status (see FindingGroup.status), not its
|
|
20443
|
+
// individual findings' — so a filtered row's status always reads one of the
|
|
20444
|
+
// requested values.
|
|
20437
20445
|
status: external_exports.array(FindingStatus).optional(),
|
|
20438
20446
|
q: external_exports.string().optional(),
|
|
20439
20447
|
// Scope to findings whose event carries this session id (the Activity page's
|
|
@@ -20443,23 +20451,37 @@ var ListGroupedFindingsQuery = external_exports.object({
|
|
|
20443
20451
|
// from a time-scoped page (Activity's range) can carry that scope. Absent
|
|
20444
20452
|
// means all time — this list has no default window.
|
|
20445
20453
|
from: external_exports.iso.datetime().optional(),
|
|
20446
|
-
// A
|
|
20447
|
-
//
|
|
20448
|
-
//
|
|
20449
|
-
//
|
|
20450
|
-
//
|
|
20454
|
+
// A RULE id that must appear in the page even when the cursor has already
|
|
20455
|
+
// advanced past its sort position. This is what keeps the selected type
|
|
20456
|
+
// visible in the list once it paginates: the target is appended out of sort
|
|
20457
|
+
// order rather than scanned forward for. Never affects totals, facets or the
|
|
20458
|
+
// cursor. Unlike the grouped read this replaces, it names a rule only — an
|
|
20459
|
+
// instance id is resolved by `findingInstance`, which is a primary-key seek
|
|
20460
|
+
// and so is not bounded by what any page happens to hold.
|
|
20451
20461
|
includeId: external_exports.string().optional(),
|
|
20452
|
-
|
|
20453
|
-
limit: external_exports.coerce.number().int().min(1).max(100).optional(),
|
|
20462
|
+
limit: external_exports.coerce.number().int().min(1).max(MAX_FINDING_TYPES_LIMIT).optional(),
|
|
20454
20463
|
cursor: external_exports.string().optional()
|
|
20455
20464
|
});
|
|
20456
|
-
var
|
|
20465
|
+
var ListFindingTypesResponse = external_exports.object({
|
|
20457
20466
|
totals: external_exports.object({
|
|
20467
|
+
// Findings belonging to the matching TYPES — not findings that each match
|
|
20468
|
+
// the filters. The filters here select types, so a type that survives
|
|
20469
|
+
// contributes its whole instanceCount.
|
|
20470
|
+
//
|
|
20471
|
+
// `status` is the one exception, narrowed per finding via
|
|
20472
|
+
// countInstancesByStatus. `severity`, `provider` and `action` are not, so
|
|
20473
|
+
// this can exceed what the instance read reports for the same filters: a
|
|
20474
|
+
// rule whose severity moved between versions is kept on its newest and
|
|
20475
|
+
// still counts its older findings. Narrowing the other three needs
|
|
20476
|
+
// per-dimension counts the aggregate does not carry today.
|
|
20458
20477
|
findings: external_exports.number().int().nonnegative(),
|
|
20459
|
-
|
|
20478
|
+
// Counts TYPES, which is the unit this read pages. The instance read's
|
|
20479
|
+
// own totals count findings; the two deliberately answer different
|
|
20480
|
+
// questions and are never summed.
|
|
20481
|
+
types: external_exports.number().int().nonnegative()
|
|
20460
20482
|
}),
|
|
20461
20483
|
facets: FindingFacets,
|
|
20462
|
-
items: external_exports.array(
|
|
20484
|
+
items: external_exports.array(FindingTypeSummary),
|
|
20463
20485
|
nextCursor: external_exports.string().nullable(),
|
|
20464
20486
|
// Present only on session-scoped queries (`sessionId` set): per ruleId, how
|
|
20465
20487
|
// many times that rule fired in the session's persisted transcript. Findings
|
|
@@ -20467,7 +20489,7 @@ var ListGroupedFindingsResponse = external_exports.object({
|
|
|
20467
20489
|
// every firing, so the two numbers legitimately differ — this map lets a
|
|
20468
20490
|
// session-scoped view show both.
|
|
20469
20491
|
sessionFirings: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()).optional()
|
|
20470
|
-
}).meta({ id: "
|
|
20492
|
+
}).meta({ id: "ListFindingTypesResponse" });
|
|
20471
20493
|
var ApplyFindingActionRequest = external_exports.object({
|
|
20472
20494
|
// 'quarantined' is system-assigned (see FindingAction) — clients may not set
|
|
20473
20495
|
// it, so it is excluded from the request contract. The mapping helper
|
|
@@ -20496,12 +20518,13 @@ var FindingInstanceDetail = FindingInstance.extend({
|
|
|
20496
20518
|
var MAX_FLAT_FINDINGS_LIMIT = 200;
|
|
20497
20519
|
var ListFindingInstancesQuery = external_exports.object({
|
|
20498
20520
|
severity: external_exports.array(Severity).optional(),
|
|
20499
|
-
// Rule ids, the same vocabulary the
|
|
20521
|
+
// Rule ids, the same vocabulary the types list's `subtype` carries. Pinning
|
|
20522
|
+
// ONE of them is how the master/detail view scopes its right-hand panel.
|
|
20500
20523
|
subtype: external_exports.array(external_exports.string()).optional(),
|
|
20501
20524
|
provider: external_exports.array(FindingProvider).optional(),
|
|
20502
20525
|
action: external_exports.array(FindingAction).optional(),
|
|
20503
20526
|
// Matches each instance's OWN derived status (deriveFindingStatus), unlike
|
|
20504
|
-
// the
|
|
20527
|
+
// the types query's type-level fold.
|
|
20505
20528
|
status: external_exports.array(FindingStatus).optional(),
|
|
20506
20529
|
// Exact host-tool names (attributes.tool_name, e.g. 'Bash'). A real filter,
|
|
20507
20530
|
// where the free-text `q` can only match the rendered "via Bash" label.
|
|
@@ -20518,37 +20541,46 @@ var ListFindingInstancesQuery = external_exports.object({
|
|
|
20518
20541
|
});
|
|
20519
20542
|
var ListFindingInstancesResponse = external_exports.object({
|
|
20520
20543
|
// Instances matching the filters across the whole scope, not just this
|
|
20521
|
-
// page — cursor-independent, like the
|
|
20544
|
+
// page — cursor-independent, like the types list's totals.
|
|
20522
20545
|
totals: external_exports.object({ findings: external_exports.number().int().nonnegative() }),
|
|
20523
|
-
// Counts in INSTANCES here, where the
|
|
20546
|
+
// Counts in INSTANCES here, where the types response counts types. Each
|
|
20524
20547
|
// dimension still excludes its own filter.
|
|
20525
20548
|
facets: FindingFacets,
|
|
20526
20549
|
items: external_exports.array(FindingInstanceDetail),
|
|
20527
20550
|
nextCursor: external_exports.string().nullable()
|
|
20528
20551
|
}).meta({ id: "ListFindingInstancesResponse" });
|
|
20529
|
-
var
|
|
20530
|
-
//
|
|
20531
|
-
//
|
|
20532
|
-
|
|
20533
|
-
|
|
20534
|
-
|
|
20535
|
-
|
|
20536
|
-
// Folded from the instances' derived statuses with the same
|
|
20537
|
-
// open-dominates precedence a group uses.
|
|
20538
|
-
status: FindingStatus.optional(),
|
|
20539
|
-
// Distinct rules seen at this location, capped — the row shows them as
|
|
20540
|
-
// chips, and the count is what conveys scale.
|
|
20541
|
-
ruleIds: external_exports.array(external_exports.string())
|
|
20542
|
-
}).meta({ id: "FindingLocationFile" });
|
|
20543
|
-
var FindingLocationRepo = external_exports.object({
|
|
20552
|
+
var FindingLocationSummary = external_exports.object({
|
|
20553
|
+
// Opaque, stable, minted from the pair by encodeLocationId. It exists
|
|
20554
|
+
// because a location's identity is two values and a URL param carries one:
|
|
20555
|
+
// `?loc=` names a location the way `?rule=` names a type. Only ever compared
|
|
20556
|
+
// for EQUALITY — the page's selection check, this read's `includeId`, the
|
|
20557
|
+
// client's page dedupe — never decoded, and never a sort key.
|
|
20558
|
+
id: external_exports.string(),
|
|
20544
20559
|
/** Empty when the instances carried no repo attribute. */
|
|
20545
20560
|
repo: external_exports.string(),
|
|
20561
|
+
// Empty when the instances carried no file path (a prompt, or a tool call
|
|
20562
|
+
// with no file attribution). Both halves empty is a real location — usually
|
|
20563
|
+
// the largest one in a store — and is selectable like any other.
|
|
20564
|
+
file: external_exports.string(),
|
|
20546
20565
|
instanceCount: external_exports.number().int().nonnegative(),
|
|
20566
|
+
// The WORST severity present, not the first row's. It is this list's primary
|
|
20567
|
+
// sort key, so it is also what explains why a row is where it is, and it is
|
|
20568
|
+
// how a reader decides what to open without opening everything.
|
|
20547
20569
|
maxSeverity: Severity,
|
|
20548
20570
|
latestDetectedAt: external_exports.iso.datetime(),
|
|
20571
|
+
// Folded from the instances' derived statuses with the same open-dominates
|
|
20572
|
+
// precedence a group uses, so it answers "is anything left to do here" and
|
|
20573
|
+
// not much more: a location holding 1 open among 40 resolved reads like one
|
|
20574
|
+
// holding 40 open. That loss is accepted — the panel beside this list
|
|
20575
|
+
// carries each finding's own status, and instanceCount sits next to the
|
|
20576
|
+
// badge.
|
|
20549
20577
|
status: FindingStatus.optional(),
|
|
20550
|
-
|
|
20551
|
-
|
|
20578
|
+
// Every distinct rule seen at this location, UNCAPPED — so the length is a
|
|
20579
|
+
// tally rather than a sample and a row can say how many there are. Bounded
|
|
20580
|
+
// by the ruleset, not by the store. The view bounds what it DISPLAYS.
|
|
20581
|
+
ruleIds: external_exports.array(external_exports.string())
|
|
20582
|
+
}).meta({ id: "FindingLocationSummary" });
|
|
20583
|
+
var MAX_FINDING_LOCATIONS_LIMIT = 100;
|
|
20552
20584
|
var ListFindingLocationsQuery = external_exports.object({
|
|
20553
20585
|
severity: external_exports.array(Severity).optional(),
|
|
20554
20586
|
subtype: external_exports.array(external_exports.string()).optional(),
|
|
@@ -20561,18 +20593,42 @@ var ListFindingLocationsQuery = external_exports.object({
|
|
|
20561
20593
|
q: external_exports.string().optional(),
|
|
20562
20594
|
sessionId: external_exports.string().optional(),
|
|
20563
20595
|
from: external_exports.iso.datetime().optional(),
|
|
20564
|
-
|
|
20596
|
+
// A LOCATION id (see FindingLocationSummary.id) that must appear in the page
|
|
20597
|
+
// even when the cursor has already advanced past its sort position — the
|
|
20598
|
+
// counterpart of ListFindingTypesQuery.includeId, and needed far more often
|
|
20599
|
+
// here. Selecting a row pushes the URL, which re-renders the server and resets
|
|
20600
|
+
// the client's page cache to page 0; with distinct (repo, file) pairs running
|
|
20601
|
+
// into the thousands, a selection sitting off page 0 is the ordinary case
|
|
20602
|
+
// rather than a deep-link corner. Never affects totals, facets or the cursor.
|
|
20603
|
+
includeId: external_exports.string().optional(),
|
|
20604
|
+
limit: external_exports.coerce.number().int().min(1).max(MAX_FINDING_LOCATIONS_LIMIT).optional(),
|
|
20605
|
+
cursor: external_exports.string().optional()
|
|
20565
20606
|
});
|
|
20566
20607
|
var ListFindingLocationsResponse = external_exports.object({
|
|
20567
20608
|
totals: external_exports.object({
|
|
20609
|
+
// Findings matching the filters across the whole scope. Unlike the types
|
|
20610
|
+
// read's same-named field this needs no caveat: the filters here narrow
|
|
20611
|
+
// per finding, so this is the sum of every row's instanceCount.
|
|
20568
20612
|
findings: external_exports.number().int().nonnegative(),
|
|
20569
|
-
|
|
20570
|
-
|
|
20613
|
+
// Counts LOCATIONS, the unit this read pages — the number the paginator
|
|
20614
|
+
// states. The facets beside it count FINDINGS (see below); a surface
|
|
20615
|
+
// showing both says which is which.
|
|
20616
|
+
locations: external_exports.number().int().nonnegative()
|
|
20571
20617
|
}),
|
|
20572
|
-
|
|
20573
|
-
|
|
20574
|
-
|
|
20575
|
-
|
|
20618
|
+
// Counts in FINDINGS, where the types response counts types, each dimension
|
|
20619
|
+
// still excluding its own filter. Deliberately not locations: counting those
|
|
20620
|
+
// needs a set of location keys per dimension per value — memory tracking the
|
|
20621
|
+
// store times the vocabulary, in a read whose scan promises flat memory —
|
|
20622
|
+
// and the cheap per-location version is not an approximation but WRONG. A
|
|
20623
|
+
// location holding {claudecode, block} and {codex, warn} would survive
|
|
20624
|
+
// provider=claudecode AND action=warn, under which no single finding
|
|
20625
|
+
// matches, so the facet would contradict the instanceCount this whole view
|
|
20626
|
+
// rests on. Findings also keep the toolbar in the same unit as the page
|
|
20627
|
+
// tally and the panel it sits above.
|
|
20628
|
+
facets: FindingFacets,
|
|
20629
|
+
/** Sorted by max severity, then most recent, then (repo, file). */
|
|
20630
|
+
items: external_exports.array(FindingLocationSummary),
|
|
20631
|
+
nextCursor: external_exports.string().nullable()
|
|
20576
20632
|
}).meta({ id: "ListFindingLocationsResponse" });
|
|
20577
20633
|
|
|
20578
20634
|
// ../../packages/schema/src/zod/meta.ts
|
|
@@ -21737,6 +21793,14 @@ var ControlPlaneErrorBody = external_exports.object({
|
|
|
21737
21793
|
message: external_exports.string().optional()
|
|
21738
21794
|
}).optional()
|
|
21739
21795
|
});
|
|
21796
|
+
var RemoteFailureKind = external_exports.enum([
|
|
21797
|
+
"unauthorized",
|
|
21798
|
+
"forbidden",
|
|
21799
|
+
"route-absent",
|
|
21800
|
+
"invalid-request",
|
|
21801
|
+
"rejected",
|
|
21802
|
+
"unreachable"
|
|
21803
|
+
]);
|
|
21740
21804
|
var AttachDeviceRequest = external_exports.object({
|
|
21741
21805
|
// This machine's own continuity id, so re-attaching ROTATES the credential
|
|
21742
21806
|
// on one machine record instead of producing a second one. Client-minted
|
|
@@ -22749,11 +22813,11 @@ var WorkspaceSettings = external_exports.object({
|
|
|
22749
22813
|
// covers the current payload and must be re-granted.
|
|
22750
22814
|
modelJudgeConsent: ModelJudgeConsent.optional(),
|
|
22751
22815
|
// Records that the user consented to the DEFERRED send — the outbox — along
|
|
22752
|
-
// with the payload shape and the endpoint they agreed to. Since payload
|
|
22753
|
-
// that covers
|
|
22754
|
-
// carry prompt/reply text in `content
|
|
22755
|
-
// Absent until granted, and a grant for a different endpoint
|
|
22756
|
-
// payload no longer counts.
|
|
22816
|
+
// with the payload shape and the endpoint they agreed to. Since payload v3
|
|
22817
|
+
// that covers the pre-attach backlog AND undelivered captures alike, and both
|
|
22818
|
+
// carry prompt/reply/tool-output text in `content`; the key name predates
|
|
22819
|
+
// both widenings. Absent until granted, and a grant for a different endpoint
|
|
22820
|
+
// or an older payload no longer counts.
|
|
22757
22821
|
historySyncConsent: HistorySyncConsent.optional()
|
|
22758
22822
|
});
|
|
22759
22823
|
function defaultWorkspaceSettings() {
|
|
@@ -22773,6 +22837,9 @@ var ManagedSettingKey = external_exports.enum([
|
|
|
22773
22837
|
"dataSharesInPlace",
|
|
22774
22838
|
"redactFallback"
|
|
22775
22839
|
]).meta({ id: "ManagedSettingKey" });
|
|
22840
|
+
function isManagedSettingKey(value) {
|
|
22841
|
+
return ManagedSettingKey.safeParse(value).success;
|
|
22842
|
+
}
|
|
22776
22843
|
var ManagedSettingsValues = external_exports.object({
|
|
22777
22844
|
runMode: external_exports.enum(["standalone", "attached"]).optional(),
|
|
22778
22845
|
controlPlane: external_exports.object({
|
|
@@ -22797,7 +22864,27 @@ var ManagedSettings = external_exports.object({
|
|
|
22797
22864
|
// Which of those the user may not change. A key here with no matching value
|
|
22798
22865
|
// freezes whatever the user last chose; a value with no lock is a DEFAULT
|
|
22799
22866
|
// the user may still override. The two are separable on purpose.
|
|
22800
|
-
|
|
22867
|
+
//
|
|
22868
|
+
// Parsed as NAMES rather than as the enum, and split below: a name this
|
|
22869
|
+
// build does not know is dropped from the locked set and reported, never a
|
|
22870
|
+
// reason to refuse the file. The same shape reaches an older build whenever
|
|
22871
|
+
// an administrator locks a key a newer build added, and refusing it there
|
|
22872
|
+
// ran that build entirely unmanaged — every pin and lock gone — on exactly
|
|
22873
|
+
// the fleets most likely to carry a version skew. A name outside the enum
|
|
22874
|
+
// is still never HONOURED: the lockable set stays explicit above.
|
|
22875
|
+
lockedFields: external_exports.array(external_exports.string()).default([])
|
|
22876
|
+
}).transform(({ lockedFields, ...rest }) => {
|
|
22877
|
+
const known = [];
|
|
22878
|
+
const unknown2 = [];
|
|
22879
|
+
for (const name of lockedFields) {
|
|
22880
|
+
if (isManagedSettingKey(name)) known.push(name);
|
|
22881
|
+
else unknown2.push(name);
|
|
22882
|
+
}
|
|
22883
|
+
return {
|
|
22884
|
+
...rest,
|
|
22885
|
+
lockedFields: known,
|
|
22886
|
+
...unknown2.length > 0 ? { unknownLockedFields: unknown2 } : {}
|
|
22887
|
+
};
|
|
22801
22888
|
}).meta({ id: "ManagedSettings" });
|
|
22802
22889
|
|
|
22803
22890
|
// ../../packages/schema/src/zod/project-files.ts
|
|
@@ -22915,7 +23002,11 @@ var FindingsTimeseriesPoint = external_exports.object({
|
|
|
22915
23002
|
timestamp: external_exports.iso.date(),
|
|
22916
23003
|
critical: external_exports.number().int().nonnegative(),
|
|
22917
23004
|
high: external_exports.number().int().nonnegative(),
|
|
22918
|
-
medium: external_exports.number().int().nonnegative()
|
|
23005
|
+
medium: external_exports.number().int().nonnegative(),
|
|
23006
|
+
// Optional and additive, so a producer written against the earlier
|
|
23007
|
+
// three-series contract keeps validating. A consumer plotting it resolves the
|
|
23008
|
+
// absent case itself — the chart point requires a number.
|
|
23009
|
+
low: external_exports.number().int().nonnegative().optional()
|
|
22919
23010
|
}).meta({ id: "FindingsTimeseriesPoint" });
|
|
22920
23011
|
var FindingsTimeseriesResponse = external_exports.object({
|
|
22921
23012
|
range: TimeRange,
|
|
@@ -22941,6 +23032,10 @@ var ResolvedFeedItem = external_exports.object({
|
|
|
22941
23032
|
findingKey: external_exports.string(),
|
|
22942
23033
|
ruleId: external_exports.string(),
|
|
22943
23034
|
severity: Severity,
|
|
23035
|
+
// Repository slug, and the file path RELATIVE to it. The pair is what
|
|
23036
|
+
// identifies the file: a bare path matches the same name in every repo.
|
|
23037
|
+
// Optional and additive; empty when the event carried no repo.
|
|
23038
|
+
repo: external_exports.string().optional(),
|
|
22944
23039
|
path: external_exports.string(),
|
|
22945
23040
|
// ISO-8601 datetime (matches FindingInstance.detectedAt / the rest of the
|
|
22946
23041
|
// findings domain). The reader `.toISOString()`s the DB epoch-ms values.
|
|
@@ -23212,6 +23307,26 @@ function ensureDataDirSync(dir) {
|
|
|
23212
23307
|
function tightenFile(file2) {
|
|
23213
23308
|
chmodBestEffort(file2, DATA_FILE_MODE);
|
|
23214
23309
|
}
|
|
23310
|
+
function writeExclusiveOwnerOnlySync(file2, data) {
|
|
23311
|
+
writeFileSync(file2, data, { mode: DATA_FILE_MODE, flag: "wx" });
|
|
23312
|
+
}
|
|
23313
|
+
function writeOwnerOnlyFileSync(file2, data) {
|
|
23314
|
+
const tmp = `${file2}.${String(process.pid)}.tmp`;
|
|
23315
|
+
try {
|
|
23316
|
+
rmSync2(tmp, { force: true });
|
|
23317
|
+
} catch {
|
|
23318
|
+
}
|
|
23319
|
+
try {
|
|
23320
|
+
writeExclusiveOwnerOnlySync(tmp, data);
|
|
23321
|
+
renameSync(tmp, file2);
|
|
23322
|
+
} finally {
|
|
23323
|
+
try {
|
|
23324
|
+
rmSync2(tmp, { force: true });
|
|
23325
|
+
} catch {
|
|
23326
|
+
}
|
|
23327
|
+
}
|
|
23328
|
+
tightenFile(file2);
|
|
23329
|
+
}
|
|
23215
23330
|
|
|
23216
23331
|
// ../../packages/persistence/src/database.ts
|
|
23217
23332
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
@@ -23269,6 +23384,32 @@ var ACTIVE_REVEAL_GRANT_PREDICATE = `capability = 'reveal_to_model'
|
|
|
23269
23384
|
AND conditions IS NULL
|
|
23270
23385
|
AND ${ACTIVE_PREDICATE}`;
|
|
23271
23386
|
|
|
23387
|
+
// ../../packages/persistence/src/repositories/resolution-sql.ts
|
|
23388
|
+
function latestResolutionColumnSql(column, findingsAlias) {
|
|
23389
|
+
return `(
|
|
23390
|
+
SELECT fr.${column} FROM finding_resolution fr
|
|
23391
|
+
WHERE fr.finding_key = ${findingsAlias}.finding_key
|
|
23392
|
+
ORDER BY fr.created_at DESC, fr.rowid DESC
|
|
23393
|
+
LIMIT 1
|
|
23394
|
+
)`;
|
|
23395
|
+
}
|
|
23396
|
+
function latestResolutionStatusSql(findingsAlias) {
|
|
23397
|
+
return latestResolutionColumnSql("status", findingsAlias);
|
|
23398
|
+
}
|
|
23399
|
+
|
|
23400
|
+
// ../../packages/persistence/src/repositories/findings.ts
|
|
23401
|
+
var FINDING_ROW_COLUMNS_SQL = `f.id AS id, d.rule_id AS rule_id, d.category AS category,
|
|
23402
|
+
d.severity AS severity, f.masked_match AS masked_match,
|
|
23403
|
+
f.action_taken AS action_taken, f.confidence AS confidence,
|
|
23404
|
+
e.started_at AS occurred_at,
|
|
23405
|
+
e.source_tool AS source_tool,
|
|
23406
|
+
e.repo AS repo,
|
|
23407
|
+
e.file_path AS file,
|
|
23408
|
+
e.tool_name AS tool_name,
|
|
23409
|
+
f.audit_event_id AS event_id, e.root_session_id AS session_id,
|
|
23410
|
+
e.event_type AS kind, f.finding_key AS finding_key,
|
|
23411
|
+
${latestResolutionStatusSql("f")} AS latest_status`;
|
|
23412
|
+
|
|
23272
23413
|
// ../../packages/persistence/src/repositories/history-sync.ts
|
|
23273
23414
|
var STRUCTURAL_EVENT_TYPES = ["session", "llm_call", "tool_call"];
|
|
23274
23415
|
var TYPE_LIST = STRUCTURAL_EVENT_TYPES.map((t) => `'${t}'`).join(", ");
|
|
@@ -23354,7 +23495,8 @@ function managedSettingsPaths(platform2 = process.platform) {
|
|
|
23354
23495
|
}
|
|
23355
23496
|
return [posix.join("/etc", "aka", MANAGED_SETTINGS_FILENAME)];
|
|
23356
23497
|
}
|
|
23357
|
-
|
|
23498
|
+
var testOnlyManagedPaths = null;
|
|
23499
|
+
function readManagedSettings(paths = testOnlyManagedPaths ?? managedSettingsPaths()) {
|
|
23358
23500
|
for (const path of paths) {
|
|
23359
23501
|
let text;
|
|
23360
23502
|
try {
|
|
@@ -23429,6 +23571,48 @@ function readJson(file2) {
|
|
|
23429
23571
|
return parseJsonObject(text) ?? null;
|
|
23430
23572
|
}
|
|
23431
23573
|
|
|
23574
|
+
// ../../packages/persistence/src/semver.ts
|
|
23575
|
+
function parse3(version2) {
|
|
23576
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-.]+))?$/.exec(version2.trim());
|
|
23577
|
+
if (!match) return null;
|
|
23578
|
+
return {
|
|
23579
|
+
core: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
23580
|
+
pre: match[4] ? match[4].split(".") : []
|
|
23581
|
+
};
|
|
23582
|
+
}
|
|
23583
|
+
function comparePre(a, b) {
|
|
23584
|
+
if (a.length === 0 && b.length === 0) return 0;
|
|
23585
|
+
if (a.length === 0) return 1;
|
|
23586
|
+
if (b.length === 0) return -1;
|
|
23587
|
+
const len = Math.min(a.length, b.length);
|
|
23588
|
+
for (let i = 0; i < len; i++) {
|
|
23589
|
+
const ai = a[i] ?? "";
|
|
23590
|
+
const bi = b[i] ?? "";
|
|
23591
|
+
if (ai === bi) continue;
|
|
23592
|
+
const an = /^\d+$/.test(ai);
|
|
23593
|
+
const bn = /^\d+$/.test(bi);
|
|
23594
|
+
if (an && !bn) return -1;
|
|
23595
|
+
if (!an && bn) return 1;
|
|
23596
|
+
if (an && bn) return Number(ai) < Number(bi) ? -1 : 1;
|
|
23597
|
+
return ai < bi ? -1 : 1;
|
|
23598
|
+
}
|
|
23599
|
+
return a.length === b.length ? 0 : a.length < b.length ? -1 : 1;
|
|
23600
|
+
}
|
|
23601
|
+
function compareBinaryVersions(a, b) {
|
|
23602
|
+
const pa = parse3(a);
|
|
23603
|
+
const pb = parse3(b);
|
|
23604
|
+
if (!pa || !pb) return 0;
|
|
23605
|
+
for (let i = 0; i < 3; i++) {
|
|
23606
|
+
const av = pa.core[i] ?? 0;
|
|
23607
|
+
const bv = pb.core[i] ?? 0;
|
|
23608
|
+
if (av !== bv) return av < bv ? -1 : 1;
|
|
23609
|
+
}
|
|
23610
|
+
return comparePre(pa.pre, pb.pre);
|
|
23611
|
+
}
|
|
23612
|
+
function isParseableBinaryVersion(version2) {
|
|
23613
|
+
return parse3(version2) !== null;
|
|
23614
|
+
}
|
|
23615
|
+
|
|
23432
23616
|
// ../../packages/persistence/src/repositories/inventory-assets.ts
|
|
23433
23617
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
23434
23618
|
var VALID_HARNESS_IDS = new Set(HarnessId.options);
|
|
@@ -23477,23 +23661,30 @@ import { randomUUID as randomUUID10 } from "crypto";
|
|
|
23477
23661
|
// ../../packages/persistence/src/database.ts
|
|
23478
23662
|
var CAPTURE_GRAIN = new Set(EventKind.options);
|
|
23479
23663
|
|
|
23480
|
-
// ../../packages/persistence/src/
|
|
23664
|
+
// ../../packages/persistence/src/egress-wire.ts
|
|
23481
23665
|
import { createHash as createHash3 } from "crypto";
|
|
23482
23666
|
|
|
23667
|
+
// ../../packages/persistence/src/finding-key.ts
|
|
23668
|
+
import { createHash as createHash4 } from "crypto";
|
|
23669
|
+
|
|
23483
23670
|
// ../../packages/persistence/src/fingerprint.ts
|
|
23484
23671
|
import { createHmac, randomBytes } from "crypto";
|
|
23485
23672
|
import { existsSync as existsSync3, readFileSync as readFileSync6 } from "fs";
|
|
23486
23673
|
import { join as join8 } from "path";
|
|
23487
23674
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
23488
23675
|
|
|
23489
|
-
// ../../packages/persistence/src/history-
|
|
23676
|
+
// ../../packages/persistence/src/history-backfill.ts
|
|
23490
23677
|
import { existsSync as existsSync4 } from "fs";
|
|
23491
23678
|
import { join as join9 } from "path";
|
|
23679
|
+
|
|
23680
|
+
// ../../packages/persistence/src/history-preview.ts
|
|
23681
|
+
import { existsSync as existsSync5 } from "fs";
|
|
23682
|
+
import { join as join10 } from "path";
|
|
23492
23683
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
23493
23684
|
|
|
23494
23685
|
// ../../packages/persistence/src/store-symlinks.ts
|
|
23495
|
-
import { existsSync as
|
|
23496
|
-
import { dirname as dirname3, join as
|
|
23686
|
+
import { existsSync as existsSync6, lstatSync as lstatSync3, readlinkSync, realpathSync, statSync as statSync4 } from "fs";
|
|
23687
|
+
import { dirname as dirname3, join as join11, resolve } from "path";
|
|
23497
23688
|
var STORE_DB = "the store database (including the prompt corpus)";
|
|
23498
23689
|
var STORE_SETTINGS = "your settings file";
|
|
23499
23690
|
function storeContents(home) {
|
|
@@ -23502,7 +23693,7 @@ function storeContents(home) {
|
|
|
23502
23693
|
[settingsDir(home), STORE_SETTINGS],
|
|
23503
23694
|
[dataDir(home), STORE_DB],
|
|
23504
23695
|
[keysDir(home), "the vault key"],
|
|
23505
|
-
[
|
|
23696
|
+
[join11(settingsDir(home), "settings.json"), STORE_SETTINGS],
|
|
23506
23697
|
[dbPath(home), STORE_DB]
|
|
23507
23698
|
]);
|
|
23508
23699
|
}
|
|
@@ -23517,7 +23708,7 @@ function symlinkedStorePaths(home, platform2 = process.platform) {
|
|
|
23517
23708
|
holds,
|
|
23518
23709
|
// existsSync follows the link, so a target that is gone reads as
|
|
23519
23710
|
// absent here while lstat above still sees the link itself.
|
|
23520
|
-
missing: !
|
|
23711
|
+
missing: !existsSync6(path),
|
|
23521
23712
|
mode: targetMode(path, platform2)
|
|
23522
23713
|
}
|
|
23523
23714
|
];
|
|
@@ -23555,14 +23746,14 @@ import {
|
|
|
23555
23746
|
import { execFileSync } from "child_process";
|
|
23556
23747
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
23557
23748
|
import { chmodSync as chmodSync3, readFileSync as readFileSync7, renameSync as renameSync4, rmSync as rmSync6, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
23558
|
-
import { join as
|
|
23749
|
+
import { join as join12 } from "path";
|
|
23559
23750
|
|
|
23560
23751
|
// ../../packages/persistence/src/vault/vault.ts
|
|
23561
23752
|
import { randomBytes as randomBytes3, randomUUID as randomUUID12 } from "crypto";
|
|
23562
23753
|
|
|
23563
23754
|
// ../../packages/persistence/src/warn-era-cap.ts
|
|
23564
|
-
import { existsSync as
|
|
23565
|
-
import { join as
|
|
23755
|
+
import { existsSync as existsSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
23756
|
+
import { join as join13 } from "path";
|
|
23566
23757
|
|
|
23567
23758
|
// ../../packages/plugin-sdk/src/provider-env.ts
|
|
23568
23759
|
var DEFAULT_ANTHROPIC_HOST = "api.anthropic.com";
|
|
@@ -23616,8 +23807,8 @@ function resolveProvider() {
|
|
|
23616
23807
|
function loadConfig(base = defaultDataDir(), resolveProviderFn = resolveProvider) {
|
|
23617
23808
|
try {
|
|
23618
23809
|
ensureLayoutDirSync(base);
|
|
23619
|
-
const settingsFile =
|
|
23620
|
-
if (
|
|
23810
|
+
const settingsFile = join14(settingsDir(base), "settings.json");
|
|
23811
|
+
if (existsSync8(settingsFile)) tightenFile(settingsFile);
|
|
23621
23812
|
} catch {
|
|
23622
23813
|
}
|
|
23623
23814
|
migrateLegacyLayout(base);
|
|
@@ -23642,7 +23833,7 @@ function resolveProviderSafe(resolveProviderFn) {
|
|
|
23642
23833
|
// ../../packages/plugin-sdk/src/config-inventory.ts
|
|
23643
23834
|
import { readdirSync as readdirSync2, readFileSync as readFileSync9, realpathSync as realpathSync2, statSync as statSync7 } from "fs";
|
|
23644
23835
|
import { homedir as homedir2 } from "os";
|
|
23645
|
-
import { basename as basename3, join as
|
|
23836
|
+
import { basename as basename3, join as join16 } from "path";
|
|
23646
23837
|
|
|
23647
23838
|
// ../../packages/detections/src/egress/registry.ts
|
|
23648
23839
|
var EXTRACTOR_VERSION = "1";
|
|
@@ -24400,24 +24591,20 @@ var CPU_CORROBORATION_SHARE = 0.2;
|
|
|
24400
24591
|
var CORROBORATION_FLOOR_MS = BUDGET_MS * CPU_CORROBORATION_SHARE;
|
|
24401
24592
|
|
|
24402
24593
|
// ../../packages/plugin-sdk/src/repo.ts
|
|
24403
|
-
import { existsSync as
|
|
24404
|
-
import { basename as basename2, dirname as dirname4, isAbsolute, join as
|
|
24594
|
+
import { existsSync as existsSync9, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
24595
|
+
import { basename as basename2, dirname as dirname4, isAbsolute, join as join15, sep as sep2 } from "path";
|
|
24405
24596
|
|
|
24406
24597
|
// ../../packages/plugin-sdk/src/events.ts
|
|
24407
|
-
import { createHash as
|
|
24598
|
+
import { createHash as createHash5, randomUUID as randomUUID13 } from "crypto";
|
|
24408
24599
|
|
|
24409
24600
|
// ../../packages/plugin-sdk/src/isolated-scan.ts
|
|
24410
|
-
import { existsSync as
|
|
24601
|
+
import { existsSync as existsSync10 } from "fs";
|
|
24411
24602
|
import { fileURLToPath } from "url";
|
|
24412
24603
|
import { Worker } from "worker_threads";
|
|
24413
24604
|
|
|
24414
|
-
// ../../packages/plugin-sdk/src/
|
|
24415
|
-
|
|
24416
|
-
import {
|
|
24417
|
-
import { join as join16 } from "path";
|
|
24418
|
-
|
|
24419
|
-
// ../../packages/plugin-sdk/src/inventory-resolver.ts
|
|
24420
|
-
import { arch, hostname as hostname4, platform, release } from "os";
|
|
24605
|
+
// ../../packages/plugin-sdk/src/host-floor.ts
|
|
24606
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
24607
|
+
import { join as join18 } from "path";
|
|
24421
24608
|
|
|
24422
24609
|
// ../../packages/plugin-sdk/src/model-governance.ts
|
|
24423
24610
|
import {
|
|
@@ -24425,24 +24612,146 @@ import {
|
|
|
24425
24612
|
fstatSync,
|
|
24426
24613
|
mkdirSync as mkdirSync2,
|
|
24427
24614
|
openSync as openSync2,
|
|
24428
|
-
readFileSync as
|
|
24615
|
+
readFileSync as readFileSync10,
|
|
24429
24616
|
readSync,
|
|
24430
24617
|
writeFileSync as writeFileSync5
|
|
24431
24618
|
} from "fs";
|
|
24432
24619
|
import { join as join17 } from "path";
|
|
24433
24620
|
var TAIL_BYTES = 256 * 1024;
|
|
24621
|
+
function readTail(path) {
|
|
24622
|
+
const fd = openSync2(path, "r");
|
|
24623
|
+
try {
|
|
24624
|
+
const { size } = fstatSync(fd);
|
|
24625
|
+
if (size <= TAIL_BYTES) return { text: readFileSync10(fd, "utf8"), truncated: false };
|
|
24626
|
+
const buffer = Buffer.allocUnsafe(TAIL_BYTES);
|
|
24627
|
+
let filled = 0;
|
|
24628
|
+
while (filled < TAIL_BYTES) {
|
|
24629
|
+
const n = readSync(fd, buffer, filled, TAIL_BYTES - filled, size - TAIL_BYTES + filled);
|
|
24630
|
+
if (n === 0) break;
|
|
24631
|
+
filled += n;
|
|
24632
|
+
}
|
|
24633
|
+
return { text: buffer.subarray(0, filled).toString("utf8"), truncated: true };
|
|
24634
|
+
} finally {
|
|
24635
|
+
closeSync2(fd);
|
|
24636
|
+
}
|
|
24637
|
+
}
|
|
24638
|
+
function modelFromTranscriptTail(transcriptPath, fromRecord) {
|
|
24639
|
+
if (transcriptPath === void 0 || transcriptPath === "") return void 0;
|
|
24640
|
+
try {
|
|
24641
|
+
const { text: slice, truncated } = readTail(transcriptPath);
|
|
24642
|
+
const lines = slice.split("\n");
|
|
24643
|
+
if (truncated) lines.shift();
|
|
24644
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
24645
|
+
const line = lines[i];
|
|
24646
|
+
if (line === void 0 || line === "") continue;
|
|
24647
|
+
let parsed;
|
|
24648
|
+
try {
|
|
24649
|
+
parsed = JSON.parse(line);
|
|
24650
|
+
} catch {
|
|
24651
|
+
continue;
|
|
24652
|
+
}
|
|
24653
|
+
const model = fromRecord(parsed);
|
|
24654
|
+
if (model !== void 0 && model !== "") return model;
|
|
24655
|
+
}
|
|
24656
|
+
return void 0;
|
|
24657
|
+
} catch {
|
|
24658
|
+
return void 0;
|
|
24659
|
+
}
|
|
24660
|
+
}
|
|
24661
|
+
|
|
24662
|
+
// ../../packages/plugin-sdk/src/host-floor.ts
|
|
24663
|
+
var HOST_FEATURE = {
|
|
24664
|
+
ModelSwitch: "model-switch",
|
|
24665
|
+
VaultPointerDisplay: "vault-pointer-display"
|
|
24666
|
+
};
|
|
24667
|
+
var HOST_FLOORS = {
|
|
24668
|
+
[HOST_FEATURE.ModelSwitch]: {
|
|
24669
|
+
label: "model-switch protection",
|
|
24670
|
+
hookEvents: ["PreModelSwitch", "PostModelSwitch"],
|
|
24671
|
+
since: "2.1.251"
|
|
24672
|
+
},
|
|
24673
|
+
[HOST_FEATURE.VaultPointerDisplay]: {
|
|
24674
|
+
label: "vault pointer display",
|
|
24675
|
+
hookEvents: ["MessageDisplay"],
|
|
24676
|
+
since: "2.1.152"
|
|
24677
|
+
}
|
|
24678
|
+
};
|
|
24679
|
+
var hostVersionFromRecord = (record2) => {
|
|
24680
|
+
if (typeof record2 !== "object" || record2 === null) return void 0;
|
|
24681
|
+
const { version: version2 } = record2;
|
|
24682
|
+
return typeof version2 === "string" && version2 !== "" ? version2 : void 0;
|
|
24683
|
+
};
|
|
24684
|
+
function hostVersionFromTranscript(transcriptPath) {
|
|
24685
|
+
return modelFromTranscriptTail(transcriptPath, hostVersionFromRecord);
|
|
24686
|
+
}
|
|
24687
|
+
function hostFloorGaps(hostVersion) {
|
|
24688
|
+
if (hostVersion === void 0) return [];
|
|
24689
|
+
const gaps = [];
|
|
24690
|
+
for (const [feature, row] of Object.entries(HOST_FLOORS)) {
|
|
24691
|
+
if (compareBinaryVersions(hostVersion, row.since) < 0) {
|
|
24692
|
+
gaps.push({ feature, label: row.label, since: row.since });
|
|
24693
|
+
}
|
|
24694
|
+
}
|
|
24695
|
+
return gaps;
|
|
24696
|
+
}
|
|
24697
|
+
function requiredHostVersion(gaps) {
|
|
24698
|
+
let highest;
|
|
24699
|
+
for (const gap of gaps) {
|
|
24700
|
+
if (highest === void 0 || compareBinaryVersions(gap.since, highest) > 0) highest = gap.since;
|
|
24701
|
+
}
|
|
24702
|
+
return highest;
|
|
24703
|
+
}
|
|
24704
|
+
function hostFloorNotice(hostVersion) {
|
|
24705
|
+
if (hostVersion === void 0) return null;
|
|
24706
|
+
const gaps = hostFloorGaps(hostVersion);
|
|
24707
|
+
const required2 = requiredHostVersion(gaps);
|
|
24708
|
+
if (required2 === void 0) return null;
|
|
24709
|
+
return `This Claude Code (${hostVersion}) is older than AKA needs \u2014 some of AKA's protections are inactive in this session. Update Claude Code to ${required2} or newer to turn them on. Everything else AKA does is working normally. Run \`aka status\` for detail.`;
|
|
24710
|
+
}
|
|
24711
|
+
var HOST_VERSION_MARKER = "host-version.json";
|
|
24712
|
+
function recordHostVersion(dataDir2, version2) {
|
|
24713
|
+
if (version2 === void 0 || !isParseableBinaryVersion(version2)) return;
|
|
24714
|
+
try {
|
|
24715
|
+
const current = readHostVersionCache(dataDir2);
|
|
24716
|
+
if (current !== null && compareBinaryVersions(version2, current.version) <= 0) return;
|
|
24717
|
+
const cache = { version: version2, observedAt: Date.now() };
|
|
24718
|
+
ensureDataDirSync(dataDir2);
|
|
24719
|
+
writeOwnerOnlyFileSync(join18(dataDir2, HOST_VERSION_MARKER), JSON.stringify(cache));
|
|
24720
|
+
} catch {
|
|
24721
|
+
}
|
|
24722
|
+
}
|
|
24723
|
+
function readHostVersionCache(dataDir2) {
|
|
24724
|
+
try {
|
|
24725
|
+
const parsed = JSON.parse(readFileSync11(join18(dataDir2, HOST_VERSION_MARKER), "utf8"));
|
|
24726
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
24727
|
+
const { version: version2, observedAt } = parsed;
|
|
24728
|
+
if (typeof version2 !== "string" || !isParseableBinaryVersion(version2)) return null;
|
|
24729
|
+
if (typeof observedAt !== "number" || !Number.isFinite(observedAt)) return null;
|
|
24730
|
+
return { version: version2, observedAt };
|
|
24731
|
+
} catch {
|
|
24732
|
+
return null;
|
|
24733
|
+
}
|
|
24734
|
+
}
|
|
24735
|
+
|
|
24736
|
+
// ../../packages/plugin-sdk/src/ignore-layers.ts
|
|
24737
|
+
var import_ignore = __toESM(require_ignore(), 1);
|
|
24738
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
24739
|
+
import { join as join19 } from "path";
|
|
24740
|
+
|
|
24741
|
+
// ../../packages/plugin-sdk/src/inventory-resolver.ts
|
|
24742
|
+
import { arch, hostname as hostname4, platform, release } from "os";
|
|
24434
24743
|
|
|
24435
24744
|
// ../../packages/plugin-sdk/src/nudge.ts
|
|
24436
|
-
import { mkdirSync as mkdirSync3, readFileSync as
|
|
24437
|
-
import { join as
|
|
24745
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
24746
|
+
import { join as join20 } from "path";
|
|
24438
24747
|
|
|
24439
24748
|
// ../../packages/plugin-sdk/src/paths.ts
|
|
24440
24749
|
import { readdirSync as readdirSync3, realpathSync as realpathSync3 } from "fs";
|
|
24441
24750
|
import { basename as basename4, dirname as dirname5, sep as sep3 } from "path";
|
|
24442
24751
|
|
|
24443
24752
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
24444
|
-
import { existsSync as
|
|
24445
|
-
import { basename as basename5, join as
|
|
24753
|
+
import { existsSync as existsSync11, readdirSync as readdirSync4 } from "fs";
|
|
24754
|
+
import { basename as basename5, join as join21 } from "path";
|
|
24446
24755
|
|
|
24447
24756
|
// ../../packages/plugin-sdk/src/provider-env-antigravity.ts
|
|
24448
24757
|
var optionalBaseUrl2 = external_exports.preprocess((v) => {
|
|
@@ -24478,9 +24787,9 @@ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
|
24478
24787
|
|
|
24479
24788
|
// ../../packages/plugin-sdk/src/throttle.ts
|
|
24480
24789
|
import { mkdirSync as mkdirSync4, statSync as statSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
24481
|
-
import { join as
|
|
24790
|
+
import { join as join22 } from "path";
|
|
24482
24791
|
function throttled(dataDir2, markerName, windowMs) {
|
|
24483
|
-
const marker =
|
|
24792
|
+
const marker = join22(dataDir2, markerName);
|
|
24484
24793
|
try {
|
|
24485
24794
|
if (Date.now() - statSync8(marker).mtimeMs < windowMs) return true;
|
|
24486
24795
|
} catch {
|
|
@@ -24495,27 +24804,27 @@ function throttled(dataDir2, markerName, windowMs) {
|
|
|
24495
24804
|
|
|
24496
24805
|
// src/history/reconcile-trigger.ts
|
|
24497
24806
|
import { spawn } from "child_process";
|
|
24498
|
-
import { dirname as dirname6, join as
|
|
24807
|
+
import { dirname as dirname6, join as join24 } from "path";
|
|
24499
24808
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
24500
24809
|
|
|
24501
24810
|
// src/history/tail.ts
|
|
24502
|
-
import { createHash as
|
|
24811
|
+
import { createHash as createHash6 } from "crypto";
|
|
24503
24812
|
import {
|
|
24504
24813
|
closeSync as closeSync3,
|
|
24505
24814
|
fstatSync as fstatSync2,
|
|
24506
24815
|
mkdirSync as mkdirSync5,
|
|
24507
24816
|
openSync as openSync3,
|
|
24508
|
-
readFileSync as
|
|
24817
|
+
readFileSync as readFileSync14,
|
|
24509
24818
|
readSync as readSync2,
|
|
24510
24819
|
writeFileSync as writeFileSync8
|
|
24511
24820
|
} from "fs";
|
|
24512
|
-
import { join as
|
|
24821
|
+
import { join as join23 } from "path";
|
|
24513
24822
|
var SAFE_SESSION_ID = /^[A-Za-z0-9._-]+$/;
|
|
24514
24823
|
function safeSessionId(sessionId) {
|
|
24515
24824
|
if (SAFE_SESSION_ID.test(sessionId) && sessionId !== "." && sessionId !== "..") {
|
|
24516
24825
|
return sessionId;
|
|
24517
24826
|
}
|
|
24518
|
-
return
|
|
24827
|
+
return createHash6("sha256").update(sessionId).digest("hex");
|
|
24519
24828
|
}
|
|
24520
24829
|
|
|
24521
24830
|
// src/history/reconcile-trigger.ts
|
|
@@ -24526,7 +24835,7 @@ function triggerReconcile(dataDir2, sessionId, transcriptPath) {
|
|
|
24526
24835
|
const marker = `${RECONCILE_MARKER_PREFIX}-${safeSessionId(sessionId)}`;
|
|
24527
24836
|
if (throttled(dataDir2, marker, RECONCILE_THROTTLE_MS)) return;
|
|
24528
24837
|
const here = dirname6(fileURLToPath2(import.meta.url));
|
|
24529
|
-
const child = spawn(process.execPath, [
|
|
24838
|
+
const child = spawn(process.execPath, [join24(here, "reconcile.js"), sessionId, transcriptPath], {
|
|
24530
24839
|
detached: true,
|
|
24531
24840
|
stdio: "ignore"
|
|
24532
24841
|
});
|
|
@@ -24535,6 +24844,68 @@ function triggerReconcile(dataDir2, sessionId, transcriptPath) {
|
|
|
24535
24844
|
}
|
|
24536
24845
|
}
|
|
24537
24846
|
|
|
24847
|
+
// src/hooks/host-floor-notice.ts
|
|
24848
|
+
import { mkdirSync as mkdirSync6, readdirSync as readdirSync5, rmSync as rmSync7, statSync as statSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
24849
|
+
import { join as join25 } from "path";
|
|
24850
|
+
var CLAIM_DIR = "host-floor-claims";
|
|
24851
|
+
var CLAIM_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
24852
|
+
var CLAIM_SWEEP_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
24853
|
+
function sweep(dir) {
|
|
24854
|
+
try {
|
|
24855
|
+
for (const name of readdirSync5(dir)) {
|
|
24856
|
+
const path = join25(dir, name);
|
|
24857
|
+
try {
|
|
24858
|
+
if (Date.now() - statSync9(path).mtimeMs > CLAIM_SWEEP_MS) rmSync7(path, { force: true });
|
|
24859
|
+
} catch {
|
|
24860
|
+
}
|
|
24861
|
+
}
|
|
24862
|
+
} catch {
|
|
24863
|
+
}
|
|
24864
|
+
}
|
|
24865
|
+
function tryClaim(dataDir2, sessionId) {
|
|
24866
|
+
if (sessionId === void 0 || sessionId === "") return () => void 0;
|
|
24867
|
+
const dir = join25(dataDir2, CLAIM_DIR);
|
|
24868
|
+
const path = join25(dir, encodeURIComponent(sessionId));
|
|
24869
|
+
try {
|
|
24870
|
+
if (Date.now() - statSync9(path).mtimeMs < CLAIM_TTL_MS) return null;
|
|
24871
|
+
rmSync7(path, { force: true });
|
|
24872
|
+
} catch {
|
|
24873
|
+
}
|
|
24874
|
+
try {
|
|
24875
|
+
mkdirSync6(dir, { recursive: true, mode: DATA_DIR_MODE });
|
|
24876
|
+
writeFileSync9(path, String(Date.now()), { flag: "wx", mode: DATA_FILE_MODE });
|
|
24877
|
+
} catch (err) {
|
|
24878
|
+
if (err.code === "EEXIST") return null;
|
|
24879
|
+
return () => void 0;
|
|
24880
|
+
}
|
|
24881
|
+
sweep(dir);
|
|
24882
|
+
return () => {
|
|
24883
|
+
try {
|
|
24884
|
+
rmSync7(path, { force: true });
|
|
24885
|
+
} catch {
|
|
24886
|
+
}
|
|
24887
|
+
};
|
|
24888
|
+
}
|
|
24889
|
+
function warnIfHostBelowFloor(config2, sessionId, transcriptPath, write = (message) => void process.stderr.write(message)) {
|
|
24890
|
+
try {
|
|
24891
|
+
const release2 = tryClaim(config2.dataDir, sessionId);
|
|
24892
|
+
if (release2 === null) return;
|
|
24893
|
+
let settled = false;
|
|
24894
|
+
try {
|
|
24895
|
+
const version2 = hostVersionFromTranscript(transcriptPath);
|
|
24896
|
+
if (version2 === void 0) return;
|
|
24897
|
+
recordHostVersion(config2.dataDir, version2);
|
|
24898
|
+
const notice = hostFloorNotice(version2);
|
|
24899
|
+
if (notice !== null) write(`[aka] ${notice}
|
|
24900
|
+
`);
|
|
24901
|
+
settled = true;
|
|
24902
|
+
} finally {
|
|
24903
|
+
if (!settled) release2();
|
|
24904
|
+
}
|
|
24905
|
+
} catch {
|
|
24906
|
+
}
|
|
24907
|
+
}
|
|
24908
|
+
|
|
24538
24909
|
// src/hooks/shared.ts
|
|
24539
24910
|
async function readStdin() {
|
|
24540
24911
|
return new Promise((resolve2) => {
|
|
@@ -24581,11 +24952,8 @@ function parseStopPayload(input2) {
|
|
|
24581
24952
|
}
|
|
24582
24953
|
|
|
24583
24954
|
// src/hooks/store-health.ts
|
|
24584
|
-
import { mkdirSync as
|
|
24585
|
-
import { dirname as dirname7, join as
|
|
24586
|
-
|
|
24587
|
-
// ../../packages/plugin-runtime/src/attached/egress-wire.ts
|
|
24588
|
-
import { createHash as createHash6 } from "crypto";
|
|
24955
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync20, writeFileSync as writeFileSync10 } from "fs";
|
|
24956
|
+
import { dirname as dirname7, join as join32 } from "path";
|
|
24589
24957
|
|
|
24590
24958
|
// ../../packages/remote/src/http.ts
|
|
24591
24959
|
import { request as httpRequest } from "http";
|
|
@@ -24596,18 +24964,18 @@ var MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
|
|
|
24596
24964
|
var SLASH = "/".charCodeAt(0);
|
|
24597
24965
|
|
|
24598
24966
|
// ../../packages/plugin-runtime/src/attached/forward-drops.ts
|
|
24599
|
-
import { readFileSync as
|
|
24600
|
-
import { join as
|
|
24967
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
24968
|
+
import { join as join26 } from "path";
|
|
24601
24969
|
|
|
24602
24970
|
// ../../packages/plugin-runtime/src/attached/forward-policy.ts
|
|
24603
24971
|
import { randomUUID as randomUUID15 } from "crypto";
|
|
24604
|
-
import { readFileSync as
|
|
24972
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
24605
24973
|
import { readFile, rename, writeFile } from "fs/promises";
|
|
24606
|
-
import { join as
|
|
24974
|
+
import { join as join27 } from "path";
|
|
24607
24975
|
|
|
24608
24976
|
// ../../packages/plugin-runtime/src/attached/history-state.ts
|
|
24609
|
-
import { readFileSync as
|
|
24610
|
-
import { join as
|
|
24977
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
24978
|
+
import { join as join28 } from "path";
|
|
24611
24979
|
|
|
24612
24980
|
// ../../packages/plugin-runtime/src/attached/history-sync.ts
|
|
24613
24981
|
import { createHash as createHash7 } from "crypto";
|
|
@@ -24624,12 +24992,12 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
24624
24992
|
var HISTORY_SYNC_THROTTLE_MS = 5 * 60 * 1e3;
|
|
24625
24993
|
|
|
24626
24994
|
// ../../packages/plugin-runtime/src/attached/plugin-block.ts
|
|
24627
|
-
import { readFileSync as
|
|
24995
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
24628
24996
|
|
|
24629
24997
|
// ../../packages/plugin-runtime/src/attached/policy-store.ts
|
|
24630
24998
|
import { randomUUID as randomUUID16 } from "crypto";
|
|
24631
24999
|
import { readFile as readFile2, rm, writeFile as writeFile2 } from "fs/promises";
|
|
24632
|
-
import { join as
|
|
25000
|
+
import { join as join29 } from "path";
|
|
24633
25001
|
|
|
24634
25002
|
// ../../packages/plugin-runtime/src/attached/atomic-publish.ts
|
|
24635
25003
|
import { rename as rename2 } from "fs/promises";
|
|
@@ -24638,17 +25006,17 @@ import { rename as rename2 } from "fs/promises";
|
|
|
24638
25006
|
var POSTURE_REPORT_INTERVAL_MS = 60 * 60 * 1e3;
|
|
24639
25007
|
|
|
24640
25008
|
// ../../packages/plugin-runtime/src/attached/posture-snapshot.ts
|
|
24641
|
-
import { statSync as
|
|
25009
|
+
import { statSync as statSync10 } from "fs";
|
|
24642
25010
|
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
24643
25011
|
|
|
24644
25012
|
// ../../packages/plugin-runtime/src/attached/posture-store.ts
|
|
24645
25013
|
import { randomUUID as randomUUID17 } from "crypto";
|
|
24646
25014
|
import { readFile as readFile3, rm as rm2, writeFile as writeFile3 } from "fs/promises";
|
|
24647
|
-
import { join as
|
|
25015
|
+
import { join as join30 } from "path";
|
|
24648
25016
|
|
|
24649
25017
|
// ../../packages/plugin-runtime/src/attached/sync-state.ts
|
|
24650
|
-
import { readFileSync as
|
|
24651
|
-
import { join as
|
|
25018
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
25019
|
+
import { join as join31 } from "path";
|
|
24652
25020
|
|
|
24653
25021
|
// ../../packages/plugin-runtime/src/attached/status.ts
|
|
24654
25022
|
var REFUSAL_LINES = {
|
|
@@ -24687,7 +25055,7 @@ function markerDirs(dataDir2) {
|
|
|
24687
25055
|
function alreadyClaimed(dirs, marker, sessionId) {
|
|
24688
25056
|
return dirs.some((dir) => {
|
|
24689
25057
|
try {
|
|
24690
|
-
return
|
|
25058
|
+
return readFileSync20(join32(dir, marker), "utf8") === sessionId;
|
|
24691
25059
|
} catch {
|
|
24692
25060
|
return false;
|
|
24693
25061
|
}
|
|
@@ -24696,8 +25064,8 @@ function alreadyClaimed(dirs, marker, sessionId) {
|
|
|
24696
25064
|
function recordClaim(dirs, marker, sessionId) {
|
|
24697
25065
|
for (const dir of dirs) {
|
|
24698
25066
|
try {
|
|
24699
|
-
|
|
24700
|
-
|
|
25067
|
+
mkdirSync7(dir, { recursive: true, mode: DATA_DIR_MODE });
|
|
25068
|
+
writeFileSync10(join32(dir, marker), sessionId, { mode: DATA_FILE_MODE });
|
|
24701
25069
|
return;
|
|
24702
25070
|
} catch {
|
|
24703
25071
|
}
|
|
@@ -24742,6 +25110,7 @@ async function main() {
|
|
|
24742
25110
|
if (trigger === void 0) return;
|
|
24743
25111
|
const config2 = loadConfig();
|
|
24744
25112
|
warnIfStoreRedirected(config2, trigger.sessionId);
|
|
25113
|
+
warnIfHostBelowFloor(config2, trigger.sessionId, trigger.transcriptPath);
|
|
24745
25114
|
triggerReconcile(config2.dataDir, trigger.sessionId, trigger.transcriptPath);
|
|
24746
25115
|
}
|
|
24747
25116
|
try {
|