@akasecurity/cli 0.9.12 → 0.9.13
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/dist/cli.js +553 -82
- package/extension/background.js +1 -1
- package/extension/bridge.js +1 -0
- package/extension/content.js +1 -1
- package/extension/manifest.json +24 -1
- package/extension/popup.html +9 -0
- package/extension/popup.js +1 -1
- package/extension/tap.js +1 -0
- package/native-host/host.js +919 -142
- package/native-host/scan-worker.js +209 -17
- package/native-host/sync.js +250 -32
- package/package.json +6 -6
- package/web-ui/web-ui/.next/BUILD_ID +1 -1
- package/web-ui/web-ui/.next/app-build-manifest.json +72 -72
- package/web-ui/web-ui/.next/app-path-routes-manifest.json +7 -7
- package/web-ui/web-ui/.next/build-manifest.json +2 -2
- package/web-ui/web-ui/.next/prerender-manifest.json +18 -18
- package/web-ui/web-ui/.next/server/app/(app)/activity/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/activity/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/activity/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/data-shares/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/data-shares/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/data-shares/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/detections/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/detections/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/detections/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/[id]/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/[id]/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/[id]/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/new/page.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/new/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/new/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/page.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/exceptions/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/findings/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/findings/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/findings/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/inventory/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/inventory/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/inventory/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/policies/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/policies/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/policies/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/scan/page.js +3 -3
- package/web-ui/web-ui/.next/server/app/(app)/scan/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/scan/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/security/page.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/security/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/security/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/settings/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/settings/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/settings/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/updates/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/updates/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/updates/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/vault/page.js +2 -2
- package/web-ui/web-ui/.next/server/app/(app)/vault/page.js.nft.json +1 -1
- package/web-ui/web-ui/.next/server/app/(app)/vault/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app/_not-found.html +1 -1
- package/web-ui/web-ui/.next/server/app/_not-found.rsc +2 -2
- package/web-ui/web-ui/.next/server/app/index.html +1 -1
- package/web-ui/web-ui/.next/server/app/index.rsc +2 -2
- package/web-ui/web-ui/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/app-paths-manifest.json +7 -7
- package/web-ui/web-ui/.next/server/chunks/121.js +1 -1
- package/web-ui/web-ui/.next/server/chunks/130.js +1026 -0
- package/web-ui/web-ui/.next/server/chunks/290.js +1 -1
- package/web-ui/web-ui/.next/server/chunks/3.js +1017 -0
- package/web-ui/web-ui/.next/server/chunks/300.js +1 -0
- package/web-ui/web-ui/.next/server/chunks/475.js +1 -1
- package/web-ui/web-ui/.next/server/chunks/662.js +1 -0
- package/web-ui/web-ui/.next/server/chunks/70.js +1 -0
- package/web-ui/web-ui/.next/server/functions-config-manifest.json +6 -6
- package/web-ui/web-ui/.next/server/middleware-manifest.json +5 -5
- package/web-ui/web-ui/.next/server/pages/404.html +1 -1
- package/web-ui/web-ui/.next/server/pages/500.html +1 -1
- package/web-ui/web-ui/.next/server/server-reference-manifest.js +1 -1
- package/web-ui/web-ui/.next/server/server-reference-manifest.json +1 -1
- package/web-ui/web-ui/.next/static/chunks/421-cc967c01935826d1.js +1 -0
- package/web-ui/web-ui/.next/static/chunks/app/(app)/activity/{page-a27c8937989448e4.js → page-41fba0354cc950be.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/data-shares/{page-2b805f9e1f995092.js → page-d2e03c3ab61af01a.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/detections/{page-a87cfee370c4e0f4.js → page-566036afcc87e4c9.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/{error-190085728a856072.js → error-4baae46bcee63009.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/exceptions/[id]/{page-4e214491c7be8d43.js → page-73dbcf0078b82ec4.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/exceptions/new/page-8051503193da1baf.js +1 -0
- package/web-ui/web-ui/.next/static/chunks/app/(app)/exceptions/{page-f16ba40d88e414b1.js → page-32c8a853bc8b5d34.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/findings/page-dc8fadb56d6d1e77.js +1 -0
- package/web-ui/web-ui/.next/static/chunks/app/(app)/inventory/page-9b49ef42350ea7bd.js +1 -0
- package/web-ui/web-ui/.next/static/chunks/app/(app)/{layout-cb3c8c7b6b33414c.js → layout-f5f361f817f90ac9.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/policies/{page-ab639e48f60ad7ee.js → page-01b303adf3c8ee56.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/scan/page-8db3b62245c333a3.js +1 -0
- package/web-ui/web-ui/.next/static/chunks/app/(app)/security/{page-a3095119b3e87341.js → page-7a4ba61626e0d130.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/settings/page-0930b49f6ab951bc.js +1 -0
- package/web-ui/web-ui/.next/static/chunks/app/(app)/updates/{page-5b32bd569c9569d9.js → page-9b04f3441a1a3f96.js} +1 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/vault/page-911a76e75f5a1419.js +1 -0
- package/web-ui/web-ui/.next/static/css/298a651f6af38209.css +2 -0
- package/web-ui/web-ui/dist/scan-worker.js +209 -17
- package/web-ui/web-ui/.next/server/chunks/611.js +0 -1015
- package/web-ui/web-ui/.next/server/chunks/7.js +0 -1
- package/web-ui/web-ui/.next/server/chunks/816.js +0 -1
- package/web-ui/web-ui/.next/server/chunks/968.js +0 -1006
- package/web-ui/web-ui/.next/static/chunks/674-d8237c5d0faa4a53.js +0 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/exceptions/new/page-c1bb992ee1f12566.js +0 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/findings/page-59c76da638f22b0e.js +0 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/inventory/page-c37447caf89a86e1.js +0 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/scan/page-494614fccc8c62cc.js +0 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/settings/page-469613d499e41093.js +0 -1
- package/web-ui/web-ui/.next/static/chunks/app/(app)/vault/page-3152ceb31f024b8d.js +0 -1
- package/web-ui/web-ui/.next/static/css/6e72259eccdf4435.css +0 -2
- /package/web-ui/web-ui/.next/static/{PMeePXfXsQ2xxrXppySG_ → pkVZ1_T311YNkJgZOLTx5}/_buildManifest.js +0 -0
- /package/web-ui/web-ui/.next/static/{PMeePXfXsQ2xxrXppySG_ → pkVZ1_T311YNkJgZOLTx5}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -20885,7 +20885,17 @@ var UNPRICEABLE_PROVIDERS = Object.freeze([
|
|
|
20885
20885
|
"gateway",
|
|
20886
20886
|
"unknown",
|
|
20887
20887
|
"cli",
|
|
20888
|
-
"api"
|
|
20888
|
+
"api",
|
|
20889
|
+
// The browser extension's native host records these as `llm_call.provider`
|
|
20890
|
+
// for a web-chat turn — the web tool id, deliberately never the vendor id
|
|
20891
|
+
// (`openai`/`anthropic`) the session root carries. Subscription traffic
|
|
20892
|
+
// burns rate-limit budget, not dollar credits, and listing them here is
|
|
20893
|
+
// what keeps that true structurally: a later maintainer who wants to price
|
|
20894
|
+
// web-chat traffic at API rates has to delete this entry first, and meet
|
|
20895
|
+
// the reason on the way, rather than quietly adding one to
|
|
20896
|
+
// PROVIDER_PLATFORM.
|
|
20897
|
+
"chatgpt",
|
|
20898
|
+
"claude-ai"
|
|
20889
20899
|
]);
|
|
20890
20900
|
function platformForProvider(provider) {
|
|
20891
20901
|
return PROVIDER_PLATFORM.get(provider.trim().toLowerCase()) ?? null;
|
|
@@ -21094,7 +21104,12 @@ var HARNESS = {
|
|
|
21094
21104
|
ClaudeDesktop: "claudedesktop",
|
|
21095
21105
|
ChatGpt: "chatgpt",
|
|
21096
21106
|
ClaudeAi: "claudeai",
|
|
21097
|
-
Api: "api"
|
|
21107
|
+
Api: "api",
|
|
21108
|
+
// Not a coding assistant a person drives — an in-process SDK embedded in an
|
|
21109
|
+
// application, so it has no IDE/CLI/desktop/web surface of its own. Carries
|
|
21110
|
+
// the same id as its SOURCE_TOOL counterpart, unlike every capture-side tool
|
|
21111
|
+
// whose wire spelling differs from its display spelling.
|
|
21112
|
+
AiTcSdk: "ai-tc-sdk"
|
|
21098
21113
|
};
|
|
21099
21114
|
var Harness = external_exports.enum(HARNESS).meta({ id: "Harness" });
|
|
21100
21115
|
var SOURCE_TOOL = {
|
|
@@ -21110,9 +21125,15 @@ var SOURCE_TOOL = {
|
|
|
21110
21125
|
// whose tool could not be identified both render through the read side's
|
|
21111
21126
|
// miss path rather than as a harness of their own.
|
|
21112
21127
|
Cli: "cli",
|
|
21113
|
-
Unknown: "unknown"
|
|
21128
|
+
Unknown: "unknown",
|
|
21129
|
+
// The wire id an in-process, request-path SDK stamps on its own structural
|
|
21130
|
+
// rows (`request_decision`) — never a capture of prompt/response/tool text,
|
|
21131
|
+
// since the SDK sits in front of a model call rather than inside a coding
|
|
21132
|
+
// assistant's own hook contract.
|
|
21133
|
+
AiTcSdk: "ai-tc-sdk"
|
|
21114
21134
|
};
|
|
21115
21135
|
var SourceTool = external_exports.enum(SOURCE_TOOL).meta({ id: "SourceTool" });
|
|
21136
|
+
var WebSourceTool = SourceTool.extract(["ChatGpt", "ClaudeAi"]);
|
|
21116
21137
|
var TOOL_TO_HARNESS = {
|
|
21117
21138
|
[SOURCE_TOOL.ClaudeCode]: HARNESS.ClaudeCode,
|
|
21118
21139
|
[SOURCE_TOOL.ClaudeDesktop]: HARNESS.ClaudeDesktop,
|
|
@@ -21121,7 +21142,12 @@ var TOOL_TO_HARNESS = {
|
|
|
21121
21142
|
[SOURCE_TOOL.ChatGpt]: HARNESS.ChatGpt,
|
|
21122
21143
|
[SOURCE_TOOL.Codex]: HARNESS.Codex,
|
|
21123
21144
|
[SOURCE_TOOL.Antigravity]: HARNESS.Antigravity,
|
|
21124
|
-
[SOURCE_TOOL.ClaudeAi]: HARNESS.ClaudeAi
|
|
21145
|
+
[SOURCE_TOOL.ClaudeAi]: HARNESS.ClaudeAi,
|
|
21146
|
+
// Wire and display id are the same string here, but the row still belongs:
|
|
21147
|
+
// both vocabularies carry the `AiTcSdk` member, and the join is exactly
|
|
21148
|
+
// their intersection — leaving a shared member out would read as an
|
|
21149
|
+
// uninstrumented tool on both surfaces, which this one is not.
|
|
21150
|
+
[SOURCE_TOOL.AiTcSdk]: HARNESS.AiTcSdk
|
|
21125
21151
|
};
|
|
21126
21152
|
|
|
21127
21153
|
// ../packages/schema/src/zod/finding.ts
|
|
@@ -21155,7 +21181,8 @@ var FindingProvider = Harness.extract([
|
|
|
21155
21181
|
"ClaudeAi",
|
|
21156
21182
|
"Codex",
|
|
21157
21183
|
"Antigravity",
|
|
21158
|
-
"Api"
|
|
21184
|
+
"Api",
|
|
21185
|
+
"AiTcSdk"
|
|
21159
21186
|
]).meta({ id: "FindingProvider" });
|
|
21160
21187
|
var FindingCategory = external_exports.enum([
|
|
21161
21188
|
"secret",
|
|
@@ -21532,18 +21559,41 @@ var AuditEventType = external_exports.enum([
|
|
|
21532
21559
|
// 'tool_call' is the reconciler's structural row for every call, while
|
|
21533
21560
|
// 'tool_use' exists only where a hook enforced against the arguments.
|
|
21534
21561
|
"tool_use",
|
|
21535
|
-
// One row per model REFUSAL
|
|
21536
|
-
//
|
|
21537
|
-
//
|
|
21538
|
-
//
|
|
21539
|
-
//
|
|
21540
|
-
//
|
|
21562
|
+
// One row per model REFUSAL, across all four seams a prohibited model can be
|
|
21563
|
+
// stopped at: a switch onto it, a turn already running on it, a subagent
|
|
21564
|
+
// spawn asking for it, or a request-path refusal an embedded request-path
|
|
21565
|
+
// SDK makes in-process before the call leaves the application. Which seam
|
|
21566
|
+
// rides `attributes.refusal_seam`, never this member name. A structural row
|
|
21567
|
+
// like the ones above rather than a capture — it carries the model that was
|
|
21568
|
+
// refused and nothing the user typed, because what is worth recording about
|
|
21569
|
+
// a governance decision is the decision, and prompt text is the thing this
|
|
21570
|
+
// product exists to keep from travelling.
|
|
21541
21571
|
"model_refusal",
|
|
21572
|
+
// One row per request-path DECISION: a policy check an embedded request-path
|
|
21573
|
+
// SDK performs in-process before a model call leaves the application, or
|
|
21574
|
+
// against that call's non-streamed response. A structural row like
|
|
21575
|
+
// 'model_refusal' rather than a capture — content-free in the same way:
|
|
21576
|
+
// which side, which seam, what action and which field are decided rides
|
|
21577
|
+
// `attributes`, never this member name, and the matched text itself never
|
|
21578
|
+
// travels.
|
|
21579
|
+
//
|
|
21580
|
+
// A prohibited-model refusal on the request path is deliberately NOT this
|
|
21581
|
+
// member: it stays 'model_refusal' with `refusal_seam: 'request'`, so it
|
|
21582
|
+
// shares one bucket with the plugin's switch/turn/spawn refusals rather
|
|
21583
|
+
// than splitting one governance concept across two event types. This
|
|
21584
|
+
// member carries every OTHER request-path decision.
|
|
21585
|
+
"request_decision",
|
|
21542
21586
|
// One row per config-inventory scan, hung off the session root. It is the
|
|
21543
21587
|
// fact the posture inspection findings reference (findings require an
|
|
21544
21588
|
// audit_event_id), and its started_at is the "scanned Nm ago" the read
|
|
21545
21589
|
// surface renders.
|
|
21546
|
-
"config_scan"
|
|
21590
|
+
"config_scan",
|
|
21591
|
+
// One row per reported browser-extension capture status, hung off the web
|
|
21592
|
+
// session root. The durable home of what one tab's network interception
|
|
21593
|
+
// is doing — a write-through of the native host's in-memory tracker, so a
|
|
21594
|
+
// second process (aka extension status) and a restarted host both have
|
|
21595
|
+
// somewhere to read it back from.
|
|
21596
|
+
"capture_status"
|
|
21547
21597
|
]).meta({ id: "AuditEventType" });
|
|
21548
21598
|
var AttributeBag = external_exports.record(external_exports.string(), external_exports.unknown());
|
|
21549
21599
|
var HostAttributes = external_exports.object({
|
|
@@ -21703,6 +21753,20 @@ var CaptureAttributes = external_exports.object({
|
|
|
21703
21753
|
// repeated rather than referenced because a store reader opens this file.
|
|
21704
21754
|
redact_degraded_to: ActionTaken.optional()
|
|
21705
21755
|
}).catchall(external_exports.unknown());
|
|
21756
|
+
var CaptureStatusAttributes = external_exports.object({
|
|
21757
|
+
source_tool: external_exports.string().optional(),
|
|
21758
|
+
patched: external_exports.boolean().optional(),
|
|
21759
|
+
live: external_exports.boolean().optional(),
|
|
21760
|
+
blind: external_exports.boolean().optional(),
|
|
21761
|
+
sends_seen_dom: external_exports.number().int().nonnegative().optional(),
|
|
21762
|
+
exchanges_seen_net: external_exports.number().int().nonnegative().optional(),
|
|
21763
|
+
parse_failures: external_exports.number().int().nonnegative().optional(),
|
|
21764
|
+
unparsed_bodies: external_exports.number().int().nonnegative().optional(),
|
|
21765
|
+
shape_misses: external_exports.array(external_exports.string()).optional(),
|
|
21766
|
+
conversation_endpoints: external_exports.number().int().nonnegative().optional(),
|
|
21767
|
+
closed: external_exports.boolean().optional(),
|
|
21768
|
+
enforcement: external_exports.string().optional()
|
|
21769
|
+
}).catchall(external_exports.unknown());
|
|
21706
21770
|
var ToolCallInspection = external_exports.object({
|
|
21707
21771
|
ruleId: external_exports.string().min(1),
|
|
21708
21772
|
ruleName: external_exports.string(),
|
|
@@ -22562,6 +22626,30 @@ var AttachedCredential = external_exports.object({
|
|
|
22562
22626
|
keyPrefix: external_exports.string().min(1).max(16).optional(),
|
|
22563
22627
|
mintedAt: external_exports.iso.datetime().optional()
|
|
22564
22628
|
});
|
|
22629
|
+
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
22630
|
+
function unsafeEndpointReason(endpoint) {
|
|
22631
|
+
let parsed2;
|
|
22632
|
+
try {
|
|
22633
|
+
parsed2 = new URL(endpoint);
|
|
22634
|
+
} catch {
|
|
22635
|
+
return "unparseable";
|
|
22636
|
+
}
|
|
22637
|
+
if (parsed2.username !== "" || parsed2.password !== "") return "userinfo";
|
|
22638
|
+
if (parsed2.search !== "" || parsed2.hash !== "") return "query-or-fragment";
|
|
22639
|
+
if (parsed2.protocol === "https:") return null;
|
|
22640
|
+
return parsed2.protocol === "http:" && LOOPBACK_HOSTS.has(parsed2.hostname) ? null : "insecure";
|
|
22641
|
+
}
|
|
22642
|
+
function isSafeEndpoint(endpoint) {
|
|
22643
|
+
return unsafeEndpointReason(endpoint) === null;
|
|
22644
|
+
}
|
|
22645
|
+
function originOnly(endpoint) {
|
|
22646
|
+
try {
|
|
22647
|
+
const parsed2 = new URL(endpoint);
|
|
22648
|
+
return `${parsed2.protocol}//${parsed2.host}`;
|
|
22649
|
+
} catch {
|
|
22650
|
+
return "(unparseable endpoint)";
|
|
22651
|
+
}
|
|
22652
|
+
}
|
|
22565
22653
|
var MAX_DATE_MS = 253402300799999;
|
|
22566
22654
|
var MAX_INT4 = 2147483647;
|
|
22567
22655
|
var StorePosturePack = external_exports.object({
|
|
@@ -22716,6 +22804,11 @@ var RemoteFailureKind = external_exports.enum([
|
|
|
22716
22804
|
"rejected",
|
|
22717
22805
|
"unreachable"
|
|
22718
22806
|
]);
|
|
22807
|
+
var ControlPlaneFailure = RemoteFailureKind.extract([
|
|
22808
|
+
"unauthorized",
|
|
22809
|
+
"forbidden",
|
|
22810
|
+
"unreachable"
|
|
22811
|
+
]);
|
|
22719
22812
|
var AttachDeviceRequest = external_exports.object({
|
|
22720
22813
|
// This machine's own continuity id, so re-attaching ROTATES the credential
|
|
22721
22814
|
// on one machine record instead of producing a second one. Client-minted
|
|
@@ -23255,7 +23348,12 @@ var EventMetadata = external_exports.object({
|
|
|
23255
23348
|
// in — set by the browser extension's network capture so a stored `response`
|
|
23256
23349
|
// row can be joined to the `llm_call` leaf describing the same turn. Absent
|
|
23257
23350
|
// on every other capture path, which has no such id.
|
|
23258
|
-
|
|
23351
|
+
//
|
|
23352
|
+
// Non-empty for the reason WebExchange.messageId is: it is the join key, and
|
|
23353
|
+
// a blank one matches no `llm_call` leaf. That refusal reaches only the
|
|
23354
|
+
// places an event is PARSED; the local write path types the event and parses
|
|
23355
|
+
// nothing, which is why `toCaptureAttributes` omits a blank one separately.
|
|
23356
|
+
messageId: external_exports.string().min(1).optional(),
|
|
23259
23357
|
conversationId: external_exports.string().optional(),
|
|
23260
23358
|
// How long THIS capture's inspection blocked its caller, in whole
|
|
23261
23359
|
// milliseconds — the plugin's own added latency, NOT the LLM call it sat in
|
|
@@ -24358,6 +24456,22 @@ function isHistorySyncConsentStale(consent, endpoint) {
|
|
|
24358
24456
|
if (consent === void 0 || endpoint === void 0) return false;
|
|
24359
24457
|
return consent.endpoint === endpoint && consent.payloadVersion !== HISTORY_SYNC_PAYLOAD_VERSION;
|
|
24360
24458
|
}
|
|
24459
|
+
var WEB_CHAT_CAPTURE_CONSENT_VERSION = 1;
|
|
24460
|
+
var WebChatCaptureConsent = external_exports.object({
|
|
24461
|
+
acknowledgedAt: external_exports.iso.datetime(),
|
|
24462
|
+
version: external_exports.number().int().positive()
|
|
24463
|
+
});
|
|
24464
|
+
var WebChatResponseCapture = external_exports.enum(["with-findings", "always", "never"]);
|
|
24465
|
+
var WebChatCapture = external_exports.object({
|
|
24466
|
+
responses: WebChatResponseCapture.default("with-findings"),
|
|
24467
|
+
account: external_exports.boolean().default(false),
|
|
24468
|
+
// Absent until granted. Presence alone does not authorize anything — see
|
|
24469
|
+
// isWebChatCaptureConsentValid.
|
|
24470
|
+
consent: WebChatCaptureConsent.optional()
|
|
24471
|
+
});
|
|
24472
|
+
function isWebChatCaptureConsentValid(consent) {
|
|
24473
|
+
return consent?.version === WEB_CHAT_CAPTURE_CONSENT_VERSION;
|
|
24474
|
+
}
|
|
24361
24475
|
var BODY_RETENTION_DEFAULT_DAYS = 30;
|
|
24362
24476
|
var BodyRetention = external_exports.object({
|
|
24363
24477
|
enabled: external_exports.boolean().default(false),
|
|
@@ -24416,6 +24530,16 @@ var WorkspaceSettings = external_exports.object({
|
|
|
24416
24530
|
// both widenings. Absent until granted, and a grant for a different endpoint
|
|
24417
24531
|
// or an older payload no longer counts.
|
|
24418
24532
|
historySyncConsent: HistorySyncConsent.optional(),
|
|
24533
|
+
// What the browser extension may record from a web chat, and the grant that
|
|
24534
|
+
// authorizes it. Absent until the user answers: recording something that was
|
|
24535
|
+
// never recorded before is never an assumed grant on upgrade, so the whole
|
|
24536
|
+
// block is optional rather than defaulted in. What an absent block means is
|
|
24537
|
+
// webChatCaptureOf's answer, in one place.
|
|
24538
|
+
//
|
|
24539
|
+
// Enforcement is NOT gated on this. A machine that has never answered still
|
|
24540
|
+
// blocks, redacts and warns on what a user sends; the grant covers what is
|
|
24541
|
+
// written down.
|
|
24542
|
+
webChatCapture: WebChatCapture.optional(),
|
|
24419
24543
|
// Local body expiry (see BodyRetention). Off until switched on; expiring a
|
|
24420
24544
|
// body never removes the row or its findings.
|
|
24421
24545
|
bodyRetention: BodyRetention.default({
|
|
@@ -24426,6 +24550,9 @@ var WorkspaceSettings = external_exports.object({
|
|
|
24426
24550
|
function defaultWorkspaceSettings() {
|
|
24427
24551
|
return WorkspaceSettings.parse({});
|
|
24428
24552
|
}
|
|
24553
|
+
function webChatCaptureOf(settings) {
|
|
24554
|
+
return settings.webChatCapture ?? WebChatCapture.parse({});
|
|
24555
|
+
}
|
|
24429
24556
|
function isAttached(settings) {
|
|
24430
24557
|
return settings.runMode === "attached" && settings.controlPlane !== void 0;
|
|
24431
24558
|
}
|
|
@@ -24529,7 +24656,10 @@ function toCaptureAttributes(event) {
|
|
|
24529
24656
|
// `.catchall(z.unknown())` carries the long tail.
|
|
24530
24657
|
...metadata?.model !== void 0 ? { model: metadata.model } : {},
|
|
24531
24658
|
...metadata?.turnIndex !== void 0 ? { turn_index: metadata.turnIndex } : {},
|
|
24532
|
-
|
|
24659
|
+
// A blank id is omitted rather than stored: it is a join key and `''` joins
|
|
24660
|
+
// nothing. This runs on the local write path, which types the event but
|
|
24661
|
+
// never parses it, so EventMetadata's own `.min(1)` does not reach here.
|
|
24662
|
+
...metadata?.messageId !== void 0 && metadata.messageId !== "" ? { message_id: metadata.messageId } : {},
|
|
24533
24663
|
...metadata?.conversationId !== void 0 ? { conversation_id: metadata.conversationId } : {}
|
|
24534
24664
|
};
|
|
24535
24665
|
}
|
|
@@ -24913,12 +25043,14 @@ var RecommendedActionIdParam = external_exports.object({ id: external_exports.st
|
|
|
24913
25043
|
// ../packages/schema/src/zod/settings-action.ts
|
|
24914
25044
|
var HistorySyncConsentChoice = external_exports.enum(["granted", "revoked", "unchanged"]).meta({ id: "HistorySyncConsentChoice" });
|
|
24915
25045
|
var ModelJudgeConsentChoice = external_exports.enum(["granted", "revoked", "unchanged"]).meta({ id: "ModelJudgeConsentChoice" });
|
|
25046
|
+
var WebChatCaptureConsentChoice = external_exports.enum(["granted", "revoked", "unchanged"]).meta({ id: "WebChatCaptureConsentChoice" });
|
|
24916
25047
|
var SaveSettingsInput = external_exports.object({
|
|
24917
25048
|
historicalAccess: external_exports.string(),
|
|
24918
25049
|
modelJudgeConsent: ModelJudgeConsentChoice,
|
|
24919
25050
|
historySyncConsent: HistorySyncConsentChoice,
|
|
24920
25051
|
vaultConsent: external_exports.string(),
|
|
24921
25052
|
vaultInlineReveal: external_exports.string(),
|
|
25053
|
+
webChatCaptureConsent: WebChatCaptureConsentChoice,
|
|
24922
25054
|
// Widened to `string` like its neighbours rather than typed as
|
|
24923
25055
|
// `RedactFallback`, on this module's own layering rule: shape here, VALUE at
|
|
24924
25056
|
// the call site, so the domain check receives the type it was written for.
|
|
@@ -25133,11 +25265,24 @@ var WebExchange = external_exports.object({
|
|
|
25133
25265
|
turnIndex: external_exports.number().int().nonnegative().optional(),
|
|
25134
25266
|
toolCalls: external_exports.array(WebToolCall).default([]),
|
|
25135
25267
|
// Absent when the adapter recovered no text. Capped by the caller at
|
|
25136
|
-
// RESPONSE_TEXT_MAX_BYTES
|
|
25137
|
-
//
|
|
25268
|
+
// RESPONSE_TEXT_MAX_BYTES, so a short capture is never mistaken for a short
|
|
25269
|
+
// reply.
|
|
25138
25270
|
responseText: external_exports.string().optional(),
|
|
25271
|
+
// The stored text is short of the reply. It does NOT say which of the two
|
|
25272
|
+
// ceilings on this path cut it: the caller applies its own cap on the raw
|
|
25273
|
+
// bytes it reads off the wire, which can be reached by a stream whose
|
|
25274
|
+
// recovered text stays well under RESPONSE_TEXT_MAX_BYTES, and applies that
|
|
25275
|
+
// one to the text. A reader cannot tell them apart, and nothing downstream
|
|
25276
|
+
// should branch as though it could.
|
|
25139
25277
|
truncated: external_exports.boolean().default(false)
|
|
25140
25278
|
});
|
|
25279
|
+
var WebEnforcementState = external_exports.enum([
|
|
25280
|
+
"watching",
|
|
25281
|
+
"composer-only",
|
|
25282
|
+
"button-only",
|
|
25283
|
+
"unattached",
|
|
25284
|
+
"unknown"
|
|
25285
|
+
]);
|
|
25141
25286
|
var RESPONSE_TEXT_MAX_BYTES = 2 * 1024 * 1024;
|
|
25142
25287
|
var WebCaptureStatus = external_exports.object({
|
|
25143
25288
|
patched: external_exports.boolean(),
|
|
@@ -25149,8 +25294,66 @@ var WebCaptureStatus = external_exports.object({
|
|
|
25149
25294
|
unparsedBodies: external_exports.number().int().nonnegative(),
|
|
25150
25295
|
// The adapter-declared JSON key paths that were absent from a real payload —
|
|
25151
25296
|
// the earliest signal that a site's contract moved.
|
|
25152
|
-
shapeMisses: external_exports.array(external_exports.string()).default([])
|
|
25153
|
-
|
|
25297
|
+
shapeMisses: external_exports.array(external_exports.string()).default([]),
|
|
25298
|
+
// How many `kind: 'conversation'` endpoints the reporting tab's adapter
|
|
25299
|
+
// compiled. Zero means this build declares none for the site, so observing
|
|
25300
|
+
// nothing is the design rather than a fault — the one fact that separates a
|
|
25301
|
+
// site nobody has surveyed yet from one whose contract moved. Defaulted so a
|
|
25302
|
+
// build predating the field is read as declaring nothing rather than refused.
|
|
25303
|
+
conversationEndpoints: external_exports.number().int().nonnegative().default(0),
|
|
25304
|
+
// The document that sent this report is going away. The bridge sets it on
|
|
25305
|
+
// its `pagehide` report and nowhere else.
|
|
25306
|
+
//
|
|
25307
|
+
// A property of the REPORT rather than of capture health, which is why
|
|
25308
|
+
// nothing in `deriveWebCaptureState` reads it and why it stays out of the
|
|
25309
|
+
// bridge's own report signature — a closing tab's last word must not be
|
|
25310
|
+
// suppressed for carrying the same health as the report before it. What
|
|
25311
|
+
// reads it is the per-site fold: a document that said it was unloading stops
|
|
25312
|
+
// voting on the site's state, so the reload the `blind` remediation asks for
|
|
25313
|
+
// can actually clear the verdict it was shown. A document that dies without
|
|
25314
|
+
// sending one is covered by CAPTURE_STATUS_DOCUMENT_QUIET_MS instead.
|
|
25315
|
+
//
|
|
25316
|
+
// Defaulted so a build predating the field reads as a document that never
|
|
25317
|
+
// said it was closing — which keeps it voting, the same as every report that
|
|
25318
|
+
// is not a final one.
|
|
25319
|
+
closed: external_exports.boolean().default(false),
|
|
25320
|
+
// What the DOM enforcement path is doing, which none of the counters above
|
|
25321
|
+
// can say: `sendsSeenDom` rises only once a send has COMPLETED, so a tab
|
|
25322
|
+
// whose watcher never bound reports zero exactly like a tab nobody typed in.
|
|
25323
|
+
// Defaulted to 'unknown' rather than 'watching' so a status from a build
|
|
25324
|
+
// predating the field is not read as reporting a healthy one.
|
|
25325
|
+
enforcement: WebEnforcementState.default("unknown")
|
|
25326
|
+
});
|
|
25327
|
+
function webCaptureStatusObservedTurnPath(status) {
|
|
25328
|
+
if (!status.patched) return true;
|
|
25329
|
+
if (status.conversationEndpoints === 0) return true;
|
|
25330
|
+
return status.blind || status.shapeMisses.length > 0 || status.parseFailures > 0 || status.unparsedBodies > 0 || status.exchangesSeenNet > 0;
|
|
25331
|
+
}
|
|
25332
|
+
function pickReportedCaptureStatus(candidates) {
|
|
25333
|
+
return candidates.find((c) => webCaptureStatusObservedTurnPath(c.status)) ?? candidates[0];
|
|
25334
|
+
}
|
|
25335
|
+
var CAPTURE_STATUS_RECENCY_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
25336
|
+
var CAPTURE_STATUS_RECENCY_DAYS = CAPTURE_STATUS_RECENCY_MS / (24 * 60 * 60 * 1e3);
|
|
25337
|
+
var CAPTURE_STATUS_DOCUMENT_QUIET_MS = 12 * 60 * 60 * 1e3;
|
|
25338
|
+
function fromCaptureStatusAttributes(bag) {
|
|
25339
|
+
const parsedBag = CaptureStatusAttributes.safeParse(bag);
|
|
25340
|
+
if (!parsedBag.success) return null;
|
|
25341
|
+
const b = parsedBag.data;
|
|
25342
|
+
const parsedStatus = WebCaptureStatus.safeParse({
|
|
25343
|
+
patched: b.patched,
|
|
25344
|
+
live: b.live,
|
|
25345
|
+
blind: b.blind,
|
|
25346
|
+
sendsSeenDom: b.sends_seen_dom,
|
|
25347
|
+
exchangesSeenNet: b.exchanges_seen_net,
|
|
25348
|
+
parseFailures: b.parse_failures,
|
|
25349
|
+
unparsedBodies: b.unparsed_bodies,
|
|
25350
|
+
shapeMisses: b.shape_misses,
|
|
25351
|
+
conversationEndpoints: b.conversation_endpoints,
|
|
25352
|
+
closed: b.closed,
|
|
25353
|
+
enforcement: b.enforcement
|
|
25354
|
+
});
|
|
25355
|
+
return parsedStatus.success ? parsedStatus.data : null;
|
|
25356
|
+
}
|
|
25154
25357
|
|
|
25155
25358
|
// ../packages/local-ops/src/registry.ts
|
|
25156
25359
|
var AGENT_PLUGINS = [
|
|
@@ -27715,6 +27918,114 @@ var CONFIG_POSTURE_RULES = [
|
|
|
27715
27918
|
}
|
|
27716
27919
|
];
|
|
27717
27920
|
|
|
27921
|
+
// ../packages/detections/src/posture/web-capture-posture.ts
|
|
27922
|
+
var RULE_VERSION2 = "1";
|
|
27923
|
+
var DRIFT_MIN_PARSE_FAILURES = 2;
|
|
27924
|
+
var WEB_CAPTURE_DRIFT_STATES = /* @__PURE__ */ new Set([
|
|
27925
|
+
"blind",
|
|
27926
|
+
"degraded"
|
|
27927
|
+
]);
|
|
27928
|
+
var WEB_CAPTURE_DRIFT_RULE = {
|
|
27929
|
+
ruleId: "web-capture-drift",
|
|
27930
|
+
version: RULE_VERSION2,
|
|
27931
|
+
name: "Web chat capture is not reading the site",
|
|
27932
|
+
category: "config",
|
|
27933
|
+
severity: "medium",
|
|
27934
|
+
definition: JSON.stringify({
|
|
27935
|
+
kind: "web-capture-drift",
|
|
27936
|
+
states: [...WEB_CAPTURE_DRIFT_STATES],
|
|
27937
|
+
minParseFailures: DRIFT_MIN_PARSE_FAILURES
|
|
27938
|
+
})
|
|
27939
|
+
};
|
|
27940
|
+
function deriveWebCaptureState(status) {
|
|
27941
|
+
if (status === void 0) return "unreported";
|
|
27942
|
+
if (status.conversationEndpoints === 0) return "standby";
|
|
27943
|
+
if (!status.patched) return "unpatched";
|
|
27944
|
+
if (status.blind) return "blind";
|
|
27945
|
+
if (status.shapeMisses.length > 0) return "degraded";
|
|
27946
|
+
if (status.parseFailures >= DRIFT_MIN_PARSE_FAILURES) return "degraded";
|
|
27947
|
+
return status.live ? "active" : "idle";
|
|
27948
|
+
}
|
|
27949
|
+
var STATE_SEVERITY = {
|
|
27950
|
+
blind: 0,
|
|
27951
|
+
degraded: 1,
|
|
27952
|
+
unpatched: 2,
|
|
27953
|
+
idle: 3,
|
|
27954
|
+
standby: 4,
|
|
27955
|
+
active: 5,
|
|
27956
|
+
unreported: 6
|
|
27957
|
+
};
|
|
27958
|
+
function worseThan(a, b) {
|
|
27959
|
+
const sa = STATE_SEVERITY[deriveWebCaptureState(a.status)];
|
|
27960
|
+
const sb = STATE_SEVERITY[deriveWebCaptureState(b.status)];
|
|
27961
|
+
if (sa !== sb) return sa < sb;
|
|
27962
|
+
if (a.observedAt !== b.observedAt) return a.observedAt > b.observedAt;
|
|
27963
|
+
return (a.rootSessionId ?? "") > (b.rootSessionId ?? "");
|
|
27964
|
+
}
|
|
27965
|
+
function reportedCaptureDocumentForSite(documents) {
|
|
27966
|
+
let newestReport = "";
|
|
27967
|
+
for (const d of documents) if (d.lastReportAt > newestReport) newestReport = d.lastReportAt;
|
|
27968
|
+
const retired = (d) => {
|
|
27969
|
+
if (d.closed) return true;
|
|
27970
|
+
const behind = Date.parse(newestReport) - Date.parse(d.lastReportAt);
|
|
27971
|
+
return Number.isFinite(behind) && behind > CAPTURE_STATUS_DOCUMENT_QUIET_MS;
|
|
27972
|
+
};
|
|
27973
|
+
const voting = documents.filter((d) => !retired(d));
|
|
27974
|
+
const tested = voting.some((d) => webCaptureStatusObservedTurnPath(d.status));
|
|
27975
|
+
const pool = tested ? voting : documents;
|
|
27976
|
+
let worst;
|
|
27977
|
+
for (const d of pool) if (worst === void 0 || worseThan(d, worst)) worst = d;
|
|
27978
|
+
return worst;
|
|
27979
|
+
}
|
|
27980
|
+
var STATIC_COPY = {
|
|
27981
|
+
active: { headline: "turns are being observed on this site" },
|
|
27982
|
+
unreported: {
|
|
27983
|
+
// Says "recently" rather than "yet": the store read is bounded to
|
|
27984
|
+
// CAPTURE_STATUS_RECENCY_MS, so this state covers a site nothing has ever
|
|
27985
|
+
// reported for AND one whose last report has aged out. The two are the
|
|
27986
|
+
// same fact to a reader — nobody has confirmed anything lately — and the
|
|
27987
|
+
// copy may not claim the stronger of them.
|
|
27988
|
+
headline: `no report in the last ${String(CAPTURE_STATUS_RECENCY_DAYS)} days \u2014 open the site in Chrome with the extension loaded`
|
|
27989
|
+
},
|
|
27990
|
+
standby: {
|
|
27991
|
+
headline: "this build declares no endpoints for the site, so nothing is observed yet"
|
|
27992
|
+
},
|
|
27993
|
+
unpatched: {
|
|
27994
|
+
// Says what the flags say and no more. `patched` is false both for a tap
|
|
27995
|
+
// that installed and hooked neither transport and for one that never ran
|
|
27996
|
+
// at all — a page reports the same status either way, so the copy may not
|
|
27997
|
+
// assert one of them.
|
|
27998
|
+
headline: "the page tap captured neither fetch nor XHR \u2014 it may not have installed; reload the extension at chrome://extensions"
|
|
27999
|
+
},
|
|
28000
|
+
idle: { headline: "watching; no turn has been observed yet" },
|
|
28001
|
+
blind: {
|
|
28002
|
+
headline: "messages were sent in the page that the network capture never saw",
|
|
28003
|
+
remediation: "reload the tab. If it persists after `aka update` and reloading the extension at chrome://extensions, the site's send path has changed and needs a new extension build."
|
|
28004
|
+
},
|
|
28005
|
+
degraded: {
|
|
28006
|
+
headline: "the site's payloads no longer carry the fields the extension reads",
|
|
28007
|
+
remediation: "run `aka update`, then reload the extension at chrome://extensions. If it stays degraded after an update, the site's contract has changed and needs a new extension build."
|
|
28008
|
+
}
|
|
28009
|
+
};
|
|
28010
|
+
function webCaptureStateCopy(state) {
|
|
28011
|
+
return STATIC_COPY[state];
|
|
28012
|
+
}
|
|
28013
|
+
function webCaptureReport(documents) {
|
|
28014
|
+
return WebSourceTool.options.map((tool) => {
|
|
28015
|
+
const record2 = reportedCaptureDocumentForSite(documents.filter((d) => d.tool === tool));
|
|
28016
|
+
const state = deriveWebCaptureState(record2?.status);
|
|
28017
|
+
const copy = webCaptureStateCopy(state);
|
|
28018
|
+
return {
|
|
28019
|
+
tool,
|
|
28020
|
+
state,
|
|
28021
|
+
headline: copy.headline,
|
|
28022
|
+
...copy.remediation !== void 0 ? { remediation: copy.remediation } : {},
|
|
28023
|
+
drift: WEB_CAPTURE_DRIFT_STATES.has(state),
|
|
28024
|
+
...record2 !== void 0 ? { observedAt: record2.observedAt } : {}
|
|
28025
|
+
};
|
|
28026
|
+
});
|
|
28027
|
+
}
|
|
28028
|
+
|
|
27718
28029
|
// ../packages/detections/src/security/redos-probe.ts
|
|
27719
28030
|
var BUDGET_MS = 100;
|
|
27720
28031
|
var EXPONENTIAL_UNITS = [
|
|
@@ -27900,17 +28211,6 @@ function publishByLink(tmp, file2, data) {
|
|
|
27900
28211
|
function controlPlaneCredentialPath(settingsDir2) {
|
|
27901
28212
|
return join5(settingsDir2, ATTACHED_CREDENTIAL_FILENAME);
|
|
27902
28213
|
}
|
|
27903
|
-
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
27904
|
-
function isSafeEndpoint(endpoint) {
|
|
27905
|
-
let parsed2;
|
|
27906
|
-
try {
|
|
27907
|
-
parsed2 = new URL(endpoint);
|
|
27908
|
-
} catch {
|
|
27909
|
-
return false;
|
|
27910
|
-
}
|
|
27911
|
-
if (parsed2.protocol === "https:") return true;
|
|
27912
|
-
return parsed2.protocol === "http:" && LOOPBACK_HOSTS.has(parsed2.hostname);
|
|
27913
|
-
}
|
|
27914
28214
|
function repairOrRefuseMode(file2) {
|
|
27915
28215
|
const link = lstatSync2(file2, { throwIfNoEntry: false });
|
|
27916
28216
|
if (link === void 0) return "absent";
|
|
@@ -27969,10 +28269,23 @@ function readControlPlaneCredential(settingsDir2, connection) {
|
|
|
27969
28269
|
const read = readControlPlaneCredentialFile(settingsDir2, connection);
|
|
27970
28270
|
return read.usable ? read.credential : null;
|
|
27971
28271
|
}
|
|
28272
|
+
function unsafeEndpointRefusal(reason) {
|
|
28273
|
+
switch (reason) {
|
|
28274
|
+
case "unparseable":
|
|
28275
|
+
return "that does not look like a web address.";
|
|
28276
|
+
case "userinfo":
|
|
28277
|
+
return "the address carries a username or password, which must not be stored alongside the credential.";
|
|
28278
|
+
case "query-or-fragment":
|
|
28279
|
+
return "the address must be an origin, optionally with a path, not a query string or fragment.";
|
|
28280
|
+
case "insecure":
|
|
28281
|
+
return "an access key must not be stored for a non-HTTPS endpoint (http is accepted only for a loopback deployment).";
|
|
28282
|
+
}
|
|
28283
|
+
}
|
|
27972
28284
|
function writeControlPlaneCredential(settingsDir2, credential) {
|
|
27973
|
-
|
|
28285
|
+
const reason = unsafeEndpointReason(credential.endpoint);
|
|
28286
|
+
if (reason !== null) {
|
|
27974
28287
|
throw new Error(
|
|
27975
|
-
`refusing to store a control-plane credential for
|
|
28288
|
+
`refusing to store a control-plane credential for ${originOnly(credential.endpoint)}: ` + unsafeEndpointRefusal(reason)
|
|
27976
28289
|
);
|
|
27977
28290
|
}
|
|
27978
28291
|
ensureDataDirSync(settingsDir2);
|
|
@@ -29716,7 +30029,7 @@ var SESSION_ROOT = `event_type = 'session'`;
|
|
|
29716
30029
|
var HAS_ACTIVITY = `EXISTS (
|
|
29717
30030
|
SELECT 1 FROM audit_events c
|
|
29718
30031
|
WHERE c.root_session_id = audit_events.id
|
|
29719
|
-
AND c.event_type NOT IN ('hook', 'config_scan'))`;
|
|
30032
|
+
AND c.event_type NOT IN ('hook', 'config_scan', 'capture_status'))`;
|
|
29720
30033
|
var SqliteActivityRepository = class {
|
|
29721
30034
|
constructor(db, now = () => Date.now()) {
|
|
29722
30035
|
this.db = db;
|
|
@@ -29743,10 +30056,10 @@ var SqliteActivityRepository = class {
|
|
|
29743
30056
|
SELECT id FROM audit_events WHERE event_type = 'session' AND started_at >= ?
|
|
29744
30057
|
UNION
|
|
29745
30058
|
SELECT root_session_id FROM audit_events INDEXED BY idx_audit_started_at
|
|
29746
|
-
WHERE started_at >= ?
|
|
30059
|
+
WHERE started_at >= ? AND event_type <> 'capture_status'
|
|
29747
30060
|
UNION
|
|
29748
30061
|
SELECT root_session_id FROM audit_events INDEXED BY idx_audit_ended_at
|
|
29749
|
-
WHERE ended_at >= ?)`,
|
|
30062
|
+
WHERE ended_at >= ? AND event_type <> 'capture_status')`,
|
|
29750
30063
|
[liveThreshold, liveThreshold, liveThreshold]
|
|
29751
30064
|
);
|
|
29752
30065
|
const toolCallsToday = countScalar(
|
|
@@ -30153,7 +30466,10 @@ var SqliteAuditEventsRepository = class {
|
|
|
30153
30466
|
attributes = excluded.attributes,
|
|
30154
30467
|
ended_at = excluded.ended_at
|
|
30155
30468
|
WHERE COALESCE(json_extract(excluded.attributes, '$.output_tokens'), 0)
|
|
30156
|
-
> COALESCE(json_extract(audit_events.attributes, '$.output_tokens'), 0)
|
|
30469
|
+
> COALESCE(json_extract(audit_events.attributes, '$.output_tokens'), 0)
|
|
30470
|
+
OR (json_extract(excluded.attributes, '$.usage_source') IS NOT NULL
|
|
30471
|
+
AND json_extract(excluded.attributes, '$.output_tokens') IS NULL
|
|
30472
|
+
AND excluded.attributes <> audit_events.attributes)`
|
|
30157
30473
|
);
|
|
30158
30474
|
this.upsertSessionRootStmt = db.prepare(
|
|
30159
30475
|
`INSERT OR IGNORE INTO audit_events
|
|
@@ -30421,6 +30737,87 @@ var SqliteBodyRetentionRepository = class {
|
|
|
30421
30737
|
}
|
|
30422
30738
|
};
|
|
30423
30739
|
|
|
30740
|
+
// ../packages/persistence/src/repositories/capture-status.ts
|
|
30741
|
+
var STATUS_LOOKBACK_ROWS = 128;
|
|
30742
|
+
var SqliteCaptureStatusRepository = class {
|
|
30743
|
+
constructor(db) {
|
|
30744
|
+
this.db = db;
|
|
30745
|
+
this.recentStmt = db.prepare(
|
|
30746
|
+
`SELECT a.started_at AS startedAt,
|
|
30747
|
+
a.attributes AS attributes,
|
|
30748
|
+
a.root_session_id AS rootSessionId
|
|
30749
|
+
FROM audit_events a
|
|
30750
|
+
WHERE a.event_type = 'capture_status'
|
|
30751
|
+
AND a.source_tool = ?
|
|
30752
|
+
AND a.started_at >= ?
|
|
30753
|
+
ORDER BY a.started_at DESC, a.id DESC
|
|
30754
|
+
LIMIT ?`
|
|
30755
|
+
);
|
|
30756
|
+
}
|
|
30757
|
+
db;
|
|
30758
|
+
recentStmt;
|
|
30759
|
+
/**
|
|
30760
|
+
* Every document that reported for a site, in registry order by site, from
|
|
30761
|
+
* the last `CAPTURE_STATUS_RECENCY_MS`.
|
|
30762
|
+
*
|
|
30763
|
+
* SEVERAL per site, not one: a browser is many documents and each reports
|
|
30764
|
+
* for itself, so one row per site is a choice about which of them a user
|
|
30765
|
+
* sees — and the newest is the wrong one, since a healthy tab writing a
|
|
30766
|
+
* fresh report would hide a drifting tab's verdict, which is the whole
|
|
30767
|
+
* reason these rows exist. The pick WITHIN a document is made here (the
|
|
30768
|
+
* unchanged `pickReportedCaptureStatus`, over that document's own rows);
|
|
30769
|
+
* choosing between documents belongs where the state semantics live, and
|
|
30770
|
+
* that is `reportedCaptureDocumentForSite` in `@akasecurity/detections` —
|
|
30771
|
+
* this package may not import it.
|
|
30772
|
+
*
|
|
30773
|
+
* `now` is a required argument rather than a `Date.now()` read, so a caller
|
|
30774
|
+
* that already holds a render instant passes THAT one and a test can drive
|
|
30775
|
+
* the window without moving the wall clock.
|
|
30776
|
+
*
|
|
30777
|
+
* A site whose reports have all aged out contributes nothing, so it derives
|
|
30778
|
+
* to `unreported`. That is the point: nothing but the browser extension ever
|
|
30779
|
+
* writes these rows, so an uninstalled extension's last verdict would
|
|
30780
|
+
* otherwise stand as a live claim for ever with no later report able to
|
|
30781
|
+
* clear it.
|
|
30782
|
+
*/
|
|
30783
|
+
latest(now) {
|
|
30784
|
+
const since = now - CAPTURE_STATUS_RECENCY_MS;
|
|
30785
|
+
const documents = [];
|
|
30786
|
+
for (const tool of WebSourceTool.options) {
|
|
30787
|
+
const rows = /* @__PURE__ */ new Map();
|
|
30788
|
+
const lastWord = /* @__PURE__ */ new Map();
|
|
30789
|
+
for (const row of allRows(this.recentStmt, [
|
|
30790
|
+
tool,
|
|
30791
|
+
since,
|
|
30792
|
+
STATUS_LOOKBACK_ROWS
|
|
30793
|
+
])) {
|
|
30794
|
+
const status = fromCaptureStatusAttributes(parseJsonObject(row.attributes));
|
|
30795
|
+
if (status === null) continue;
|
|
30796
|
+
const record2 = { tool, observedAt: epochMillisToIso(row.startedAt), status };
|
|
30797
|
+
const group = rows.get(row.rootSessionId);
|
|
30798
|
+
if (group === void 0) {
|
|
30799
|
+
rows.set(row.rootSessionId, [record2]);
|
|
30800
|
+
lastWord.set(row.rootSessionId, { at: record2.observedAt, closed: status.closed });
|
|
30801
|
+
} else {
|
|
30802
|
+
group.push(record2);
|
|
30803
|
+
}
|
|
30804
|
+
}
|
|
30805
|
+
for (const [root, candidates] of rows) {
|
|
30806
|
+
const picked = pickReportedCaptureStatus(candidates);
|
|
30807
|
+
const last = lastWord.get(root);
|
|
30808
|
+
if (picked === void 0 || last === void 0) continue;
|
|
30809
|
+
documents.push({
|
|
30810
|
+
...picked,
|
|
30811
|
+
...root === null ? {} : { rootSessionId: root },
|
|
30812
|
+
lastReportAt: last.at,
|
|
30813
|
+
closed: last.closed
|
|
30814
|
+
});
|
|
30815
|
+
}
|
|
30816
|
+
}
|
|
30817
|
+
return documents;
|
|
30818
|
+
}
|
|
30819
|
+
};
|
|
30820
|
+
|
|
30424
30821
|
// ../packages/persistence/src/repositories/classified-data.ts
|
|
30425
30822
|
var SqliteClassifiedDataRepository = class {
|
|
30426
30823
|
constructor(db) {
|
|
@@ -36300,6 +36697,7 @@ function openAndInitialize(file2, base, skipTags) {
|
|
|
36300
36697
|
activity: new SqliteActivityRepository(db),
|
|
36301
36698
|
sourceProject: new SqliteSourceProjectRepository(db),
|
|
36302
36699
|
auditEvents: new SqliteAuditEventsRepository(db),
|
|
36700
|
+
captureStatus: new SqliteCaptureStatusRepository(db),
|
|
36303
36701
|
classifiedData: new SqliteClassifiedDataRepository(db),
|
|
36304
36702
|
inspectionDefinitions: new SqliteInspectionDefinitionsRepository(db),
|
|
36305
36703
|
inspectionFindings: new SqliteInspectionFindingsRepository(db),
|
|
@@ -36340,6 +36738,7 @@ function openLocalDatabase(dir, options = {}) {
|
|
|
36340
36738
|
activity,
|
|
36341
36739
|
sourceProject,
|
|
36342
36740
|
auditEvents,
|
|
36741
|
+
captureStatus,
|
|
36343
36742
|
classifiedData,
|
|
36344
36743
|
inspectionDefinitions,
|
|
36345
36744
|
inspectionFindings,
|
|
@@ -36557,6 +36956,7 @@ function openLocalDatabase(dir, options = {}) {
|
|
|
36557
36956
|
activity,
|
|
36558
36957
|
sourceProject,
|
|
36559
36958
|
auditEvents,
|
|
36959
|
+
captureStatus,
|
|
36560
36960
|
classifiedData,
|
|
36561
36961
|
inspectionDefinitions,
|
|
36562
36962
|
inspectionFindings,
|
|
@@ -36801,11 +37201,6 @@ function keyStateOf(key) {
|
|
|
36801
37201
|
// ../packages/persistence/src/forward-health.ts
|
|
36802
37202
|
import { readFileSync as readFileSync11 } from "fs";
|
|
36803
37203
|
import { join as join12 } from "path";
|
|
36804
|
-
var FAILURES = /* @__PURE__ */ new Set([
|
|
36805
|
-
"unauthorized",
|
|
36806
|
-
"forbidden",
|
|
36807
|
-
"unreachable"
|
|
36808
|
-
]);
|
|
36809
37204
|
var BREAKER_COOLDOWN_MS = 3e4;
|
|
36810
37205
|
function parseForwardHealth(raw, nowMs) {
|
|
36811
37206
|
try {
|
|
@@ -36814,7 +37209,8 @@ function parseForwardHealth(raw, nowMs) {
|
|
|
36814
37209
|
const record2 = parsed2;
|
|
36815
37210
|
const failures = typeof record2.consecutiveFailures === "number" && record2.consecutiveFailures >= 0 ? record2.consecutiveFailures : 0;
|
|
36816
37211
|
const openedAtMs = typeof record2.openedAtMs === "number" && Number.isFinite(record2.openedAtMs) && record2.openedAtMs <= nowMs ? record2.openedAtMs : null;
|
|
36817
|
-
const
|
|
37212
|
+
const parsedFailure = ControlPlaneFailure.safeParse(record2.lastFailure);
|
|
37213
|
+
const lastFailure = parsedFailure.success ? parsedFailure.data : null;
|
|
36818
37214
|
return { consecutiveFailures: failures, openedAtMs, lastFailure };
|
|
36819
37215
|
} catch {
|
|
36820
37216
|
return null;
|
|
@@ -41044,6 +41440,12 @@ var RemoteRequestInvalid = class extends Error {
|
|
|
41044
41440
|
}
|
|
41045
41441
|
cause;
|
|
41046
41442
|
};
|
|
41443
|
+
var RemoteEndpointRefused = class extends Error {
|
|
41444
|
+
constructor(endpoint) {
|
|
41445
|
+
super(`refusing to talk to an unsafe control-plane endpoint: ${originOnly(endpoint)}`);
|
|
41446
|
+
this.name = "RemoteEndpointRefused";
|
|
41447
|
+
}
|
|
41448
|
+
};
|
|
41047
41449
|
var RemoteResponseInvalid = class extends Error {
|
|
41048
41450
|
constructor(route, detail) {
|
|
41049
41451
|
super(`control plane answered ${route} with ${detail}`);
|
|
@@ -41196,14 +41598,15 @@ function parsed(schema, body, route) {
|
|
|
41196
41598
|
}
|
|
41197
41599
|
return result.data;
|
|
41198
41600
|
}
|
|
41199
|
-
function
|
|
41601
|
+
function resolveBaseUrl(endpoint) {
|
|
41602
|
+
if (!isSafeEndpoint(endpoint)) throw new RemoteEndpointRefused(endpoint);
|
|
41200
41603
|
let end = endpoint.length;
|
|
41201
41604
|
while (end > 0 && endpoint.charCodeAt(end - 1) === SLASH2) end -= 1;
|
|
41202
41605
|
return endpoint.slice(0, end);
|
|
41203
41606
|
}
|
|
41204
41607
|
var SLASH2 = "/".charCodeAt(0);
|
|
41205
41608
|
function createRemoteClient(options) {
|
|
41206
|
-
const base =
|
|
41609
|
+
const base = resolveBaseUrl(options.endpoint);
|
|
41207
41610
|
const url2 = (route) => `${base}${route}`;
|
|
41208
41611
|
const common = { apiKey: options.apiKey, timeoutMs: options.timeoutMs };
|
|
41209
41612
|
const sendOne = async (event) => {
|
|
@@ -41321,7 +41724,7 @@ var ATTACH_ROUTES = {
|
|
|
41321
41724
|
token: "/v1/attach/token"
|
|
41322
41725
|
};
|
|
41323
41726
|
function createAttachClient(options) {
|
|
41324
|
-
const base =
|
|
41727
|
+
const base = resolveBaseUrl(options.endpoint);
|
|
41325
41728
|
const common = { timeoutMs: options.timeoutMs };
|
|
41326
41729
|
return {
|
|
41327
41730
|
notOfferedStatus: 404,
|
|
@@ -41362,6 +41765,7 @@ function classifyRemoteFailure(err) {
|
|
|
41362
41765
|
case "RemoteRouteAbsent":
|
|
41363
41766
|
return "route-absent";
|
|
41364
41767
|
case "RemoteRequestInvalid":
|
|
41768
|
+
case "RemoteEndpointRefused":
|
|
41365
41769
|
return "invalid-request";
|
|
41366
41770
|
case "RemoteResponseInvalid":
|
|
41367
41771
|
return "rejected";
|
|
@@ -41451,7 +41855,16 @@ function rebuildCapture(row) {
|
|
|
41451
41855
|
const metadata = {
|
|
41452
41856
|
...rootSessionId === null ? {} : { sessionId: rootSessionId },
|
|
41453
41857
|
...filePath === void 0 ? {} : { filePath },
|
|
41454
|
-
...pick2(attributes, {
|
|
41858
|
+
...pick2(attributes, {
|
|
41859
|
+
repo: "repo",
|
|
41860
|
+
toolName: "tool_name",
|
|
41861
|
+
model: "model",
|
|
41862
|
+
// The join back to the llm_call leaf for the same web-chat turn.
|
|
41863
|
+
// Stripping these would forward a response capture the deployment can
|
|
41864
|
+
// never correlate to the llm_call leaf describing the same turn.
|
|
41865
|
+
messageId: "message_id",
|
|
41866
|
+
conversationId: "conversation_id"
|
|
41867
|
+
}),
|
|
41455
41868
|
// The two constrained strings, kept only if they satisfy the wire.
|
|
41456
41869
|
...withField("traceId", keep(stringOrUndefined(attributes.trace_id), TRACE_ID)),
|
|
41457
41870
|
...withField(
|
|
@@ -42099,10 +42512,15 @@ import { join as join32 } from "path";
|
|
|
42099
42512
|
// ../packages/plugin-runtime/src/attached/atomic-publish.ts
|
|
42100
42513
|
import { rename as rename2 } from "fs/promises";
|
|
42101
42514
|
var RETRYABLE = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY"]);
|
|
42102
|
-
var
|
|
42515
|
+
var IMMEDIATE_RETRIES = 8;
|
|
42516
|
+
var TIMED_RETRIES = 4;
|
|
42517
|
+
var ATTEMPTS = 1 + IMMEDIATE_RETRIES + TIMED_RETRIES;
|
|
42103
42518
|
var delay = (ms) => new Promise((resolve7) => {
|
|
42104
42519
|
setTimeout(resolve7, ms);
|
|
42105
42520
|
});
|
|
42521
|
+
var yieldToLoop = () => new Promise((resolve7) => {
|
|
42522
|
+
setImmediate(resolve7);
|
|
42523
|
+
});
|
|
42106
42524
|
async function publishByRename(tmp, file2, move = rename2) {
|
|
42107
42525
|
for (let attempt = 1; ; attempt += 1) {
|
|
42108
42526
|
try {
|
|
@@ -42111,7 +42529,7 @@ async function publishByRename(tmp, file2, move = rename2) {
|
|
|
42111
42529
|
} catch (err) {
|
|
42112
42530
|
const code = err.code;
|
|
42113
42531
|
if (attempt >= ATTEMPTS || code === void 0 || !RETRYABLE.has(code)) throw err;
|
|
42114
|
-
await delay(attempt * 10);
|
|
42532
|
+
await (attempt <= IMMEDIATE_RETRIES ? yieldToLoop() : delay((attempt - IMMEDIATE_RETRIES) * 10));
|
|
42115
42533
|
}
|
|
42116
42534
|
}
|
|
42117
42535
|
}
|
|
@@ -42854,6 +43272,18 @@ function parseAttachArgs(argv) {
|
|
|
42854
43272
|
var CONTROL_CHARS = /[\p{Cc}\p{Cf}]/u;
|
|
42855
43273
|
var MUTUALLY_EXCLUSIVE = "--sync-history and --no-sync-history are mutually exclusive";
|
|
42856
43274
|
var isError = (v) => "error" in v;
|
|
43275
|
+
function unsafeEndpointMessage(reason) {
|
|
43276
|
+
switch (reason) {
|
|
43277
|
+
case "unparseable":
|
|
43278
|
+
return "that does not look like a web address; include the scheme, as in https://aka.example.com.";
|
|
43279
|
+
case "userinfo":
|
|
43280
|
+
return "the address carries a username or password; remove them, the access key is sent separately.";
|
|
43281
|
+
case "query-or-fragment":
|
|
43282
|
+
return "the address must be an origin, optionally with a path; drop the query string or fragment.";
|
|
43283
|
+
case "insecure":
|
|
43284
|
+
return "an access key must not travel in the clear. Use an https URL (http is accepted only for a loopback deployment).";
|
|
43285
|
+
}
|
|
43286
|
+
}
|
|
42857
43287
|
async function runAttach(argv, deps = {}) {
|
|
42858
43288
|
const io = deps.prompter ?? terminalPrompter();
|
|
42859
43289
|
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
@@ -42872,10 +43302,9 @@ ${USAGE}`);
|
|
|
42872
43302
|
exit(2);
|
|
42873
43303
|
return;
|
|
42874
43304
|
}
|
|
42875
|
-
|
|
42876
|
-
|
|
42877
|
-
|
|
42878
|
-
);
|
|
43305
|
+
const unsafeReason = unsafeEndpointReason(endpoint);
|
|
43306
|
+
if (unsafeReason !== null) {
|
|
43307
|
+
io.err(`refusing to attach to ${originOnly(endpoint)}: ${unsafeEndpointMessage(unsafeReason)}`);
|
|
42879
43308
|
exit(2);
|
|
42880
43309
|
return;
|
|
42881
43310
|
}
|
|
@@ -44512,6 +44941,7 @@ import { createRequire as createRequire3 } from "module";
|
|
|
44512
44941
|
import { homedir as homedir8 } from "os";
|
|
44513
44942
|
import { dirname as dirname10, join as join36 } from "path";
|
|
44514
44943
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
44944
|
+
import { parseArgs as parseArgs5 } from "util";
|
|
44515
44945
|
var require4 = createRequire3(import.meta.url);
|
|
44516
44946
|
var here2 = dirname10(fileURLToPath7(import.meta.url));
|
|
44517
44947
|
function cliRoot() {
|
|
@@ -44625,13 +45055,18 @@ function registerWindowsHost(manifestPath) {
|
|
|
44625
45055
|
]);
|
|
44626
45056
|
}
|
|
44627
45057
|
function runExtension(argv) {
|
|
44628
|
-
const
|
|
45058
|
+
const { values, positionals } = parseArgs5({
|
|
45059
|
+
args: argv,
|
|
45060
|
+
options: HOME_OPTION,
|
|
45061
|
+
allowPositionals: true
|
|
45062
|
+
});
|
|
45063
|
+
const sub = positionals[0];
|
|
44629
45064
|
if (sub === "install") {
|
|
44630
45065
|
runInstall(chromeManifestDir());
|
|
44631
45066
|
return;
|
|
44632
45067
|
}
|
|
44633
45068
|
if (sub === "status") {
|
|
44634
|
-
runStatus2(chromeManifestDir());
|
|
45069
|
+
runStatus2(chromeManifestDir(), homeBase(values.home));
|
|
44635
45070
|
return;
|
|
44636
45071
|
}
|
|
44637
45072
|
process.stderr.write(
|
|
@@ -44705,7 +45140,40 @@ function manifestFault(manifestPath) {
|
|
|
44705
45140
|
if (missing.length === 0) return null;
|
|
44706
45141
|
return `does not grant ${missing.length === 1 ? "the extension id" : "the extension ids"} ${missing.join(", ")}`;
|
|
44707
45142
|
}
|
|
44708
|
-
function
|
|
45143
|
+
function captureBlock(home) {
|
|
45144
|
+
try {
|
|
45145
|
+
const effective = readEffectiveSettings(home);
|
|
45146
|
+
const webChat = webChatCaptureOf(effective.settings);
|
|
45147
|
+
if (!isWebChatCaptureConsentValid(webChat.consent)) {
|
|
45148
|
+
return "\nnetwork capture: not enabled\n no web-chat capture consent is recorded, so nothing is observed or stored\n enable it under Settings in `aka dashboard`\n";
|
|
45149
|
+
}
|
|
45150
|
+
const db = openLocalDatabase(dataDir(home));
|
|
45151
|
+
let records;
|
|
45152
|
+
try {
|
|
45153
|
+
records = db.captureStatus.latest(Date.now());
|
|
45154
|
+
} finally {
|
|
45155
|
+
db.close();
|
|
45156
|
+
}
|
|
45157
|
+
const lines = webCaptureReport(records).map((site) => {
|
|
45158
|
+
let line = ` ${site.tool.padEnd(10)} ${site.state.padEnd(10)} ${site.headline}
|
|
45159
|
+
`;
|
|
45160
|
+
if (site.drift && site.remediation !== void 0) {
|
|
45161
|
+
line += ` ${WEB_CAPTURE_DRIFT_RULE.ruleId} (${WEB_CAPTURE_DRIFT_RULE.severity}) \u2014 ${site.remediation}
|
|
45162
|
+
`;
|
|
45163
|
+
}
|
|
45164
|
+
return line;
|
|
45165
|
+
});
|
|
45166
|
+
return `
|
|
45167
|
+
network capture
|
|
45168
|
+
${lines.join("")}`;
|
|
45169
|
+
} catch (err) {
|
|
45170
|
+
return `
|
|
45171
|
+
network capture: unavailable
|
|
45172
|
+
the local store could not be read (${err instanceof Error ? err.message : String(err)})
|
|
45173
|
+
`;
|
|
45174
|
+
}
|
|
45175
|
+
}
|
|
45176
|
+
function runStatus2(manifestDir, home) {
|
|
44709
45177
|
const manifestPath = join36(manifestDir, `${NATIVE_HOST_NAME}.json`);
|
|
44710
45178
|
if (!existsSync18(manifestPath)) {
|
|
44711
45179
|
process.stdout.write(
|
|
@@ -44714,29 +45182,32 @@ function runStatus2(manifestDir) {
|
|
|
44714
45182
|
run \`aka extension install\` to set it up
|
|
44715
45183
|
`
|
|
44716
45184
|
);
|
|
44717
|
-
|
|
44718
|
-
|
|
44719
|
-
|
|
44720
|
-
|
|
44721
|
-
`native-messaging host: ${fault ? "installed (out of date)" : "installed"}
|
|
45185
|
+
} else {
|
|
45186
|
+
const fault = manifestFault(manifestPath);
|
|
45187
|
+
process.stdout.write(
|
|
45188
|
+
`native-messaging host: ${fault ? "installed (out of date)" : "installed"}
|
|
44722
45189
|
manifest: ${manifestPath}
|
|
44723
45190
|
` + (fault ? ` this manifest ${fault}
|
|
44724
45191
|
Chrome refuses a connection from any origin the manifest omits \u2014
|
|
44725
45192
|
re-run \`aka extension install\` to rewrite it
|
|
44726
45193
|
` : "")
|
|
44727
|
-
|
|
44728
|
-
|
|
45194
|
+
);
|
|
45195
|
+
if (fault) process.exitCode = 1;
|
|
45196
|
+
}
|
|
45197
|
+
if (home !== void 0) {
|
|
45198
|
+
process.stdout.write(captureBlock(home));
|
|
45199
|
+
}
|
|
44729
45200
|
}
|
|
44730
45201
|
|
|
44731
45202
|
// src/commands/init.ts
|
|
44732
45203
|
import { existsSync as existsSync20, lstatSync as lstatSync4, readdirSync as readdirSync7, statSync as statSync13 } from "fs";
|
|
44733
45204
|
import { join as join37 } from "path";
|
|
44734
45205
|
import * as readline from "readline/promises";
|
|
44735
|
-
import { parseArgs as
|
|
45206
|
+
import { parseArgs as parseArgs7 } from "util";
|
|
44736
45207
|
|
|
44737
45208
|
// src/commands/plugins.ts
|
|
44738
45209
|
import { existsSync as existsSync19 } from "fs";
|
|
44739
|
-
import { parseArgs as
|
|
45210
|
+
import { parseArgs as parseArgs6 } from "util";
|
|
44740
45211
|
function runPlugins(argv, deps = {}) {
|
|
44741
45212
|
const [sub, ...rest] = argv;
|
|
44742
45213
|
if (!sub || sub === "list") return listPlugins(rest);
|
|
@@ -44746,7 +45217,7 @@ function runPlugins(argv, deps = {}) {
|
|
|
44746
45217
|
process.exitCode = 1;
|
|
44747
45218
|
}
|
|
44748
45219
|
async function listPlugins(argv) {
|
|
44749
|
-
const { values } =
|
|
45220
|
+
const { values } = parseArgs6({ args: argv, options: HOME_OPTION });
|
|
44750
45221
|
const home = homeBase(values.home);
|
|
44751
45222
|
const active = /* @__PURE__ */ new Set();
|
|
44752
45223
|
if (existsSync19(dbPath(home))) {
|
|
@@ -44774,7 +45245,7 @@ async function listPlugins(argv) {
|
|
|
44774
45245
|
out.write("Update: aka update (or: aka check-updates)\n");
|
|
44775
45246
|
}
|
|
44776
45247
|
async function installPlugin(argv, deps) {
|
|
44777
|
-
const { positionals } =
|
|
45248
|
+
const { positionals } = parseArgs6({ args: argv, options: HOME_OPTION, allowPositionals: true });
|
|
44778
45249
|
const id = positionals[0];
|
|
44779
45250
|
if (!id) {
|
|
44780
45251
|
process.stderr.write("aka plugins install: missing <agent> (try: aka plugins list)\n");
|
|
@@ -44939,7 +45410,7 @@ function existsAsNonDirectory(path) {
|
|
|
44939
45410
|
}
|
|
44940
45411
|
}
|
|
44941
45412
|
async function runInit(argv) {
|
|
44942
|
-
const { values } =
|
|
45413
|
+
const { values } = parseArgs7({
|
|
44943
45414
|
args: argv,
|
|
44944
45415
|
options: { ...HOME_OPTION, yes: { type: "boolean", short: "y" } }
|
|
44945
45416
|
});
|
|
@@ -45036,7 +45507,7 @@ async function confirm(question) {
|
|
|
45036
45507
|
}
|
|
45037
45508
|
|
|
45038
45509
|
// src/commands/prune.ts
|
|
45039
|
-
import { parseArgs as
|
|
45510
|
+
import { parseArgs as parseArgs8 } from "util";
|
|
45040
45511
|
var USAGE2 = `Usage: aka prune [--dry-run] [--days <n>]
|
|
45041
45512
|
|
|
45042
45513
|
Expire captured bodies past the retention horizon. Keeps every event row and
|
|
@@ -45062,7 +45533,7 @@ function fmtBytes(n) {
|
|
|
45062
45533
|
function runPrune(argv, io = terminalPrompter(), managedOverride) {
|
|
45063
45534
|
let values;
|
|
45064
45535
|
try {
|
|
45065
|
-
({ values } =
|
|
45536
|
+
({ values } = parseArgs8({
|
|
45066
45537
|
args: argv,
|
|
45067
45538
|
options: {
|
|
45068
45539
|
...HOME_OPTION,
|
|
@@ -45137,7 +45608,7 @@ function runPrune(argv, io = terminalPrompter(), managedOverride) {
|
|
|
45137
45608
|
|
|
45138
45609
|
// src/commands/scan.ts
|
|
45139
45610
|
import { statSync as statSync14 } from "fs";
|
|
45140
|
-
import { parseArgs as
|
|
45611
|
+
import { parseArgs as parseArgs9 } from "util";
|
|
45141
45612
|
function severityRank2(s) {
|
|
45142
45613
|
return Severity.options.indexOf(s);
|
|
45143
45614
|
}
|
|
@@ -45166,7 +45637,7 @@ function renderForwardLine(outcome) {
|
|
|
45166
45637
|
}
|
|
45167
45638
|
}
|
|
45168
45639
|
async function runScan(argv, deps = {}) {
|
|
45169
|
-
const { values, positionals } =
|
|
45640
|
+
const { values, positionals } = parseArgs9({
|
|
45170
45641
|
args: argv,
|
|
45171
45642
|
options: {
|
|
45172
45643
|
...HOME_OPTION,
|
|
@@ -45314,10 +45785,10 @@ async function runScan(argv, deps = {}) {
|
|
|
45314
45785
|
}
|
|
45315
45786
|
|
|
45316
45787
|
// src/commands/stats.ts
|
|
45317
|
-
import { parseArgs as
|
|
45788
|
+
import { parseArgs as parseArgs10 } from "util";
|
|
45318
45789
|
var DAY_MS6 = 864e5;
|
|
45319
45790
|
async function runStats(argv) {
|
|
45320
|
-
const { values } =
|
|
45791
|
+
const { values } = parseArgs10({
|
|
45321
45792
|
args: argv,
|
|
45322
45793
|
options: { ...HOME_OPTION, range: { type: "string" } }
|
|
45323
45794
|
});
|
|
@@ -45419,7 +45890,7 @@ function renderTokenUsage(summary, range) {
|
|
|
45419
45890
|
}
|
|
45420
45891
|
|
|
45421
45892
|
// src/commands/sync-history.ts
|
|
45422
|
-
import { parseArgs as
|
|
45893
|
+
import { parseArgs as parseArgs11 } from "util";
|
|
45423
45894
|
var USAGE3 = `Usage: aka sync-history [--on | --off] [--run]
|
|
45424
45895
|
|
|
45425
45896
|
Whether this machine may send the activity it recorded before attaching.
|
|
@@ -45437,7 +45908,7 @@ async function runSyncHistory(argv, deps = {}) {
|
|
|
45437
45908
|
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
45438
45909
|
let values;
|
|
45439
45910
|
try {
|
|
45440
|
-
({ values } =
|
|
45911
|
+
({ values } = parseArgs11({
|
|
45441
45912
|
args: argv,
|
|
45442
45913
|
options: {
|
|
45443
45914
|
...HOME_OPTION,
|
|
@@ -45566,7 +46037,7 @@ applies. Run \`aka sync-history --on\` to grant it again.`;
|
|
|
45566
46037
|
}
|
|
45567
46038
|
|
|
45568
46039
|
// src/commands/tui.tsx
|
|
45569
|
-
import { parseArgs as
|
|
46040
|
+
import { parseArgs as parseArgs12 } from "util";
|
|
45570
46041
|
import { render } from "ink";
|
|
45571
46042
|
|
|
45572
46043
|
// src/tui/Dashboard.tsx
|
|
@@ -46076,7 +46547,7 @@ function parseView(positionals) {
|
|
|
46076
46547
|
return VIEWS2.includes(first) ? first : "health";
|
|
46077
46548
|
}
|
|
46078
46549
|
async function runTui(argv) {
|
|
46079
|
-
const { values, positionals } =
|
|
46550
|
+
const { values, positionals } = parseArgs12({
|
|
46080
46551
|
args: argv,
|
|
46081
46552
|
options: HOME_OPTION,
|
|
46082
46553
|
allowPositionals: true
|
|
@@ -46120,7 +46591,7 @@ async function runTui(argv) {
|
|
|
46120
46591
|
|
|
46121
46592
|
// src/commands/update.ts
|
|
46122
46593
|
import * as readline2 from "readline/promises";
|
|
46123
|
-
import { parseArgs as
|
|
46594
|
+
import { parseArgs as parseArgs13 } from "util";
|
|
46124
46595
|
|
|
46125
46596
|
// src/lib/install-origin.ts
|
|
46126
46597
|
import { dirname as dirname11 } from "path";
|
|
@@ -46135,7 +46606,7 @@ function cliInstallOrigin() {
|
|
|
46135
46606
|
|
|
46136
46607
|
// src/commands/update.ts
|
|
46137
46608
|
async function runUpdate(argv) {
|
|
46138
|
-
const { values, positionals } =
|
|
46609
|
+
const { values, positionals } = parseArgs13({
|
|
46139
46610
|
args: argv,
|
|
46140
46611
|
options: { ...HOME_OPTION, yes: { type: "boolean", short: "y" } },
|
|
46141
46612
|
allowPositionals: true
|
|
@@ -46268,11 +46739,11 @@ function applyPluginUpdate2(status) {
|
|
|
46268
46739
|
}
|
|
46269
46740
|
|
|
46270
46741
|
// src/commands/vault.ts
|
|
46271
|
-
import { parseArgs as
|
|
46742
|
+
import { parseArgs as parseArgs15 } from "util";
|
|
46272
46743
|
|
|
46273
46744
|
// src/commands/vault-prune.ts
|
|
46274
46745
|
import { randomUUID as randomUUID21 } from "crypto";
|
|
46275
|
-
import { parseArgs as
|
|
46746
|
+
import { parseArgs as parseArgs14 } from "util";
|
|
46276
46747
|
|
|
46277
46748
|
// src/lib/transcript-rewrite.ts
|
|
46278
46749
|
import {
|
|
@@ -46540,7 +47011,7 @@ function plural(count2, one, many) {
|
|
|
46540
47011
|
return `${String(count2)} ${count2 === 1 ? one : many}`;
|
|
46541
47012
|
}
|
|
46542
47013
|
async function runPrune2(argv, io) {
|
|
46543
|
-
const { values } =
|
|
47014
|
+
const { values } = parseArgs14({
|
|
46544
47015
|
args: argv,
|
|
46545
47016
|
options: {
|
|
46546
47017
|
...HOME_OPTION,
|
|
@@ -46768,7 +47239,7 @@ function descriptorLine(d) {
|
|
|
46768
47239
|
return `${kind} \xB7 seen ${String(d.occurrences)}\xD7 \xB7 first ${d.firstSeen.slice(0, 10)}`;
|
|
46769
47240
|
}
|
|
46770
47241
|
async function runShow2(argv, io) {
|
|
46771
|
-
const { values, positionals } =
|
|
47242
|
+
const { values, positionals } = parseArgs15({
|
|
46772
47243
|
args: argv,
|
|
46773
47244
|
options: { ...HOME_OPTION, help: { type: "boolean", short: "h" } },
|
|
46774
47245
|
allowPositionals: true
|