sliccy 3.39.2 → 3.40.1
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/node-server/_shared/cdp-frame-unmask.d.ts +30 -0
- package/dist/node-server/_shared/cdp-frame-unmask.d.ts.map +1 -0
- package/dist/node-server/_shared/cdp-frame-unmask.js +82 -0
- package/dist/node-server/_shared/cdp-frame-unmask.js.map +1 -0
- package/dist/node-server/_shared/index.d.ts +2 -0
- package/dist/node-server/_shared/index.d.ts.map +1 -1
- package/dist/node-server/_shared/index.js +2 -0
- package/dist/node-server/_shared/index.js.map +1 -1
- package/dist/node-server/_shared/secrets-pipeline.d.ts +9 -0
- package/dist/node-server/_shared/secrets-pipeline.d.ts.map +1 -1
- package/dist/node-server/_shared/secrets-pipeline.js +8 -1
- package/dist/node-server/_shared/secrets-pipeline.js.map +1 -1
- package/dist/node-server/_shared/session-secret-store.d.ts +48 -0
- package/dist/node-server/_shared/session-secret-store.d.ts.map +1 -0
- package/dist/node-server/_shared/session-secret-store.js +78 -0
- package/dist/node-server/_shared/session-secret-store.js.map +1 -0
- package/dist/node-server/cdp-proxy/cdp-unmask.d.ts +48 -0
- package/dist/node-server/cdp-proxy/cdp-unmask.js +59 -0
- package/dist/node-server/cdp-proxy/session-url-tracker.d.ts +27 -0
- package/dist/node-server/cdp-proxy/session-url-tracker.js +153 -0
- package/dist/node-server/index.js +143 -4
- package/dist/node-server/secrets/proxy-manager.d.ts +11 -1
- package/dist/node-server/secrets/proxy-manager.js +15 -2
- package/dist/node-server/sudo/dialog-backends.d.ts +29 -0
- package/dist/node-server/sudo/dialog-backends.js +181 -0
- package/dist/node-server/sudo/electron-backend.d.ts +36 -0
- package/dist/node-server/sudo/electron-backend.js +76 -0
- package/dist/node-server/sudo/endpoint.d.ts +25 -0
- package/dist/node-server/sudo/endpoint.js +52 -0
- package/dist/node-server/sudo/select.d.ts +29 -0
- package/dist/node-server/sudo/select.js +59 -0
- package/dist/node-server/sudo/tty-backend.d.ts +17 -0
- package/dist/node-server/sudo/tty-backend.js +49 -0
- package/dist/node-server/sudo/types.d.ts +33 -0
- package/dist/node-server/sudo/types.js +11 -0
- package/dist/ui/assets/{adobe-BkKbqjN2.js → adobe-BuddmT1_.js} +1 -1
- package/dist/ui/assets/{adobe-EVDv-oJe.js → adobe-DwuDVWKR.js} +2 -2
- package/dist/ui/assets/{agent-bridge-C_uLyvTI.js → agent-bridge-CQ_WHXpS.js} +1 -1
- package/dist/ui/assets/{agent-message-to-chat-CeS0fVHu.js → agent-message-to-chat-Bk83dal6.js} +1 -1
- package/dist/ui/assets/anthropic-BgHKqajT.js +39 -0
- package/dist/ui/assets/{anthropic-CU0B0Pm9.js → anthropic-CtzKOYSY.js} +2 -2
- package/dist/ui/assets/{apps-Cr7y2pou.js → apps-DUrh4PEK.js} +2 -2
- package/dist/ui/assets/{azure-openai-BbQrZgL2.js → azure-openai-589UnBaE.js} +1 -1
- package/dist/ui/assets/{azure-openai-BkZHl52u.js → azure-openai-BVD3rRyh.js} +1 -1
- package/dist/ui/assets/azure-openai-responses-DDoPpQfz.js +1 -0
- package/dist/ui/assets/{azure-openai-responses-IwnQ3IBU.js → azure-openai-responses-DvPlhYRg.js} +1 -1
- package/dist/ui/assets/{biome_wasm-C3ncT0Zp.js → biome_wasm-2BIO-fFD.js} +1 -1
- package/dist/ui/assets/{bsh-watchdog-vMuNcim4.js → bsh-watchdog-x1NhC21S.js} +1 -1
- package/dist/ui/assets/{cdp-zqWeM9Fx.js → cdp-CIf67Kji.js} +3 -3
- package/dist/ui/assets/{cdp-ws-page-bridge-BccgQ_MP.js → cdp-ws-page-bridge-D48c5VHQ.js} +1 -1
- package/dist/ui/assets/{common-DZkhMfZN.js → common-DJglxtI9.js} +1 -1
- package/dist/ui/assets/{connect-surface-DEau8hB2.js → connect-surface-D4wcacvR.js} +1 -1
- package/dist/ui/assets/cost-command-Dqjx5BJ4.js +1 -0
- package/dist/ui/assets/{dist-BAWk6emk.js → dist-CU640e2s.js} +1 -1
- package/dist/ui/assets/{dist-DuRiHK77.js → dist-CUdWMJvw.js} +2 -2
- package/dist/ui/assets/{dist-F3PYJWK5.js → dist-CXh0a315.js} +4 -4
- package/dist/ui/assets/{dist-BEjMwuAO.js → dist-CrZ60vIK.js} +1 -1
- package/dist/ui/assets/{es-C7IOSTrK.js → es-BCqpNDbf.js} +1 -1
- package/dist/ui/assets/{esp32-l4qNjLi8.js → esp32-UFl3lGuU.js} +1 -1
- package/dist/ui/assets/{esp32-Bgz6pdUM.js → esp32-z35G3TbR.js} +1 -1
- package/dist/ui/assets/{esp32c2-BvojiH-8.js → esp32c2-gLxOsZif.js} +1 -1
- package/dist/ui/assets/{esp32c2-Cw-tOYX0.js → esp32c2-pl5qy6El.js} +1 -1
- package/dist/ui/assets/{esp32c3-B_2bJHNk.js → esp32c3-CtBZCzN8.js} +1 -1
- package/dist/ui/assets/{esp32c3-DY9pxlPN.js → esp32c3-P3fd2u0V.js} +1 -1
- package/dist/ui/assets/{esp32c5-D7qf04lj.js → esp32c5-B1WV7eXo.js} +1 -1
- package/dist/ui/assets/{esp32c5-FIUNaCuV.js → esp32c5-VtJmrubf.js} +1 -1
- package/dist/ui/assets/{esp32c6-BdBb7y38.js → esp32c6-B-u1dpSJ.js} +1 -1
- package/dist/ui/assets/{esp32c6-DUgdbovF.js → esp32c6-roW5XaV9.js} +1 -1
- package/dist/ui/assets/{esp32c61-DLeQhFdd.js → esp32c61-BEqxfS6j.js} +1 -1
- package/dist/ui/assets/{esp32c61-UDRWrpzb.js → esp32c61-e_DudgN9.js} +1 -1
- package/dist/ui/assets/{esp32h2-DB3fwjOh.js → esp32h2-BNSoMBaR.js} +1 -1
- package/dist/ui/assets/{esp32h2-JwDRtz-6.js → esp32h2-DfHWoI2F.js} +1 -1
- package/dist/ui/assets/{esp32p4-BREZajQ_.js → esp32p4-B28QO5xI.js} +1 -1
- package/dist/ui/assets/{esp32p4-DImm9rZq.js → esp32p4-oT03skoL.js} +1 -1
- package/dist/ui/assets/{esp32s2-BzUqmNUY.js → esp32s2-B4ccaXVM.js} +1 -1
- package/dist/ui/assets/{esp32s2-Dl_HOpu8.js → esp32s2-PvYKf6wY.js} +1 -1
- package/dist/ui/assets/{esp32s3-CVtlgvOB.js → esp32s3-BEGROUfT.js} +1 -1
- package/dist/ui/assets/{esp32s3-dQC1sCq-.js → esp32s3-BR5mq9LB.js} +1 -1
- package/dist/ui/assets/esp8266-Cg5dZq5p.js +1 -0
- package/dist/ui/assets/esp8266-MLobtggU.js +1 -0
- package/dist/ui/assets/{esptool-operations-Bqunmv8c.js → esptool-operations-BmdDP4Te.js} +2 -2
- package/dist/ui/assets/{esptool-operations-C_StTYge.js → esptool-operations-PyMOLbEo.js} +3 -3
- package/dist/ui/assets/{follower-sprinkle-bridge-BAwETPVw.js → follower-sprinkle-bridge-DhhhEoEw.js} +1 -1
- package/dist/ui/assets/{github-D__yuYPE.js → github-BmiOv8pZ.js} +1 -1
- package/dist/ui/assets/{github-BRvRXw7P.js → github-H8WCUoaG.js} +2 -2
- package/dist/ui/assets/{github-copilot-f_yTYAGH.js → github-copilot-CFrKRCIh.js} +2 -2
- package/dist/ui/assets/{github-copilot-CciTQvjp.js → github-copilot-LZq-2nbm.js} +1 -1
- package/dist/ui/assets/{google-z7G7cUTg.js → google-Bwhr3ElU.js} +1 -1
- package/dist/ui/assets/{google-DlsDPGgv.js → google-CDEKJo6s.js} +1 -1
- package/dist/ui/assets/{google-shared-CHBsSinA.js → google-shared-BqepQLFX.js} +1 -1
- package/dist/ui/assets/{google-shared-BgAGdoyv.js → google-shared-DUInnTRv.js} +1 -1
- package/dist/ui/assets/{google-vertex-BkQMSZWx.js → google-vertex-DOk_o4Vo.js} +1 -1
- package/dist/ui/assets/{google-vertex-DB0-2x4F.js → google-vertex-Dy07djME.js} +1 -1
- package/dist/ui/assets/{hosted-config-apply-C0EMBy-k.js → hosted-config-apply-CIYq4OE-.js} +1 -1
- package/dist/ui/assets/{intercepted-oauth-98jE6MdJ.js → intercepted-oauth-DYoA2kA8.js} +1 -1
- package/dist/ui/assets/{kernel-worker-C_bNzCH6.js → kernel-worker-xMdP33ug.js} +1185 -1096
- package/dist/ui/assets/lick-ws-bridge-DLXsmZ6H.js +1 -0
- package/dist/ui/assets/{local-llm-BWbSsi3a.js → local-llm-BSBAbQIB.js} +2 -2
- package/dist/ui/assets/{magick-wasm-Dtq-eXDu.js → magick-wasm-BpDug9Pm.js} +1 -1
- package/dist/ui/assets/{main-D7lo-Iw7.js → main-BxzufWem.js} +21 -21
- package/dist/ui/assets/{main-cherry-DA2Vwatj.js → main-cherry-CV5ItRlu.js} +1 -1
- package/dist/ui/assets/{migration-run-B828fX-Z.js → migration-run-195D_oov.js} +1 -1
- package/dist/ui/assets/{mistral-roBDzZtU.js → mistral-BgklU_Dp.js} +2 -2
- package/dist/ui/assets/{mistral-CDP7d9Q7.js → mistral-DzTfCccO.js} +1 -1
- package/dist/ui/assets/{nodejs-Bwix3RAJ.js → nodejs-156RsPtl.js} +1 -1
- package/dist/ui/assets/{nuke-command-vh4Y9o7P.js → nuke-command-B02fs5G-.js} +1 -1
- package/dist/ui/assets/{oauth-B6PLhGUg.js → oauth-DSEOvfNU.js} +1 -1
- package/dist/ui/assets/{oauth-bootstrap-Cr4B6L_c.js → oauth-bootstrap-CCTPtyS_.js} +2 -2
- package/dist/ui/assets/{oauth-service-D7FIq6-6.js → oauth-service-Ctr2_Obu.js} +1 -1
- package/dist/ui/assets/{oauth-service-BNaPQI8J.js → oauth-service-LEczdutD.js} +1 -1
- package/dist/ui/assets/{offscreen-client-Bfe0KuPj.js → offscreen-client-Dswx1Ljm.js} +1 -1
- package/dist/ui/assets/{onboarding-orchestrator-BYaZ0be3.js → onboarding-orchestrator-8SmCagx8.js} +1 -1
- package/dist/ui/assets/{openai-codex-DHgM74Sl.js → openai-codex-CYM3h5BG.js} +1 -1
- package/dist/ui/assets/{openai-codex-D1hjYfz1.js → openai-codex-D-QWKpWb.js} +1 -1
- package/dist/ui/assets/{openai-codex-responses-DayS7aDG.js → openai-codex-responses-CbtdwhQL.js} +5 -5
- package/dist/ui/assets/{openai-codex-responses-BimSBWEw.js → openai-codex-responses-CnQXtoLP.js} +1 -1
- package/dist/ui/assets/{openai-completions-VKddpnU6.js → openai-completions-CbUcQcuU.js} +3 -3
- package/dist/ui/assets/{openai-responses-D9HA45yW.js → openai-responses-DBGxMDFy.js} +1 -1
- package/dist/ui/assets/{openai-responses-aNm5t_ca.js → openai-responses-DomGQu-u.js} +1 -1
- package/dist/ui/assets/{openai-responses-shared-BZFLXrgF.js → openai-responses-shared-CsK-8CQH.js} +3 -3
- package/dist/ui/assets/{openai-responses-shared-DzI8rQQS.js → openai-responses-shared-DYSAljRs.js} +1 -1
- package/dist/ui/assets/{openrouter-OoruFe8v.js → openrouter-i7KtgZt3.js} +1 -1
- package/dist/ui/assets/panel-rpc-handlers-BeUo4K-9.js +2 -0
- package/dist/ui/assets/{provider-Ba1IsiDR.js → provider-CuOCGXmD.js} +1 -1
- package/dist/ui/assets/{provider-BMMzCthA.js → provider-U8Br2pQO.js} +2 -2
- package/dist/ui/assets/provider-store-access-CRMelzXC.js +1 -0
- package/dist/ui/assets/provider-store-access-D9JW2Z9f.js +1 -0
- package/dist/ui/assets/{proxied-fetch-Cn_CFESw.js → proxied-fetch-CW9YdsrT.js} +1 -1
- package/dist/ui/assets/{pyodide-Cpi0sKef.js → pyodide-BQVwxCA4.js} +2 -2
- package/dist/ui/assets/{remote-terminal-view-BYQH-0XJ.js → remote-terminal-view-ChqlFNm7.js} +3 -3
- package/dist/ui/assets/{remote-vfs-client-B4-lP0Zo.js → remote-vfs-client-Cc4yBMI0.js} +1 -1
- package/dist/ui/assets/{secret-env-D39KVeV6.js → secret-env-mFCaJWuD.js} +1 -1
- package/dist/ui/assets/{slicc-editor-BWgR4Xj3.js → slicc-editor-Bn_0-CZl.js} +1 -1
- package/dist/ui/assets/{spawn-MJ8-EjZE.js → spawn-7Vgp-lrm.js} +1 -1
- package/dist/ui/assets/{sql-wasm-Ulc3s55p.js → sql-wasm-BbdRW4or.js} +1 -1
- package/dist/ui/assets/{src-6t6EkdjL.js → src-BV-fJ2mM.js} +1 -1
- package/dist/ui/assets/{store-nrzYvE_Y.js → store-DUcHEhum.js} +1 -1
- package/dist/ui/assets/sudo-CYttizEB.js +4 -0
- package/dist/ui/assets/{tray-leave-runtime-mn_AtTiW.js → tray-leave-runtime-BYZH2LNU.js} +1 -1
- package/dist/ui/assets/{typescript-6K4Vreer.js → typescript-DY6vxmmv.js} +1 -1
- package/dist/ui/assets/{upgrade-detection-rDZlWMcK.js → upgrade-detection-BmNgOg4g.js} +1 -1
- package/dist/ui/assets/{web-C3ecTZIA.js → web-DRaGEaSq.js} +1 -1
- package/dist/ui/assets/{writable-vfs-client-NlEFPGwe.js → writable-vfs-client-lsN1qOSV.js} +1 -1
- package/dist/ui/assets/{ws-subscribers-DAPNffxG.js → ws-subscribers-CxhSakhG.js} +1 -1
- package/dist/ui/assets/{xai-grok-BDnhgMfk.js → xai-grok-C0UPkvUi.js} +1 -1
- package/dist/ui/assets/{xai-grok-B9fBrwRF.js → xai-grok-DEapxZue.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/ui/packages/webapp/index.html +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/anthropic-BGuKxqSF.js +0 -39
- package/dist/ui/assets/azure-openai-responses-BLuAUdUm.js +0 -1
- package/dist/ui/assets/cost-command-DLq7GqKn.js +0 -1
- package/dist/ui/assets/esp8266-BEpoAOn2.js +0 -1
- package/dist/ui/assets/esp8266-CqYRyoC9.js +0 -1
- package/dist/ui/assets/lick-ws-bridge-BBMzHt7o.js +0 -1
- package/dist/ui/assets/panel-rpc-handlers-CGWZd1To.js +0 -2
- package/dist/ui/assets/provider-store-access-CKu7KBid.js +0 -1
- package/dist/ui/assets/provider-store-access-CeJAwMVA.js +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, platform-agnostic helper that unmasks whole-token secret fields inside a
|
|
3
|
+
* parsed CDP command frame, gating on the target tab's hostname via the existing
|
|
4
|
+
* `SecretsPipeline` (no second masking implementation).
|
|
5
|
+
*
|
|
6
|
+
* Three CDP methods carry a single, whole masked token in one frame and are
|
|
7
|
+
* the only ones unmasked here (D1 in the feature spec):
|
|
8
|
+
* - `Runtime.callFunctionOn` → string entries in `params.arguments[].value`
|
|
9
|
+
* - `Runtime.evaluate` → `params.expression`
|
|
10
|
+
* - `Input.insertText` → `params.text`
|
|
11
|
+
*
|
|
12
|
+
* Per-frame domain gating reuses `SecretsPipeline.unmaskBody` semantics:
|
|
13
|
+
* on a domain mismatch (or missing secret) the value is left verbatim (no
|
|
14
|
+
* forbidden surface — masked values in conversation context are harmless).
|
|
15
|
+
*
|
|
16
|
+
* Returns `{ frame, changed }`. When nothing applies the original frame
|
|
17
|
+
* reference is returned untouched (no clone, no mutation).
|
|
18
|
+
*/
|
|
19
|
+
import type { SecretsPipeline } from './secrets-pipeline.js';
|
|
20
|
+
export interface CdpFrame {
|
|
21
|
+
method?: string;
|
|
22
|
+
params?: unknown;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface UnmaskCdpFrameResult {
|
|
26
|
+
frame: CdpFrame;
|
|
27
|
+
changed: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function unmaskCdpFrame(frame: CdpFrame, hostname: string, pipeline: SecretsPipeline): UnmaskCdpFrameResult;
|
|
30
|
+
//# sourceMappingURL=cdp-frame-unmask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp-frame-unmask.d.ts","sourceRoot":"","sources":["../src/cdp-frame-unmask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAWD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,eAAe,GACxB,oBAAoB,CAmDtB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, platform-agnostic helper that unmasks whole-token secret fields inside a
|
|
3
|
+
* parsed CDP command frame, gating on the target tab's hostname via the existing
|
|
4
|
+
* `SecretsPipeline` (no second masking implementation).
|
|
5
|
+
*
|
|
6
|
+
* Three CDP methods carry a single, whole masked token in one frame and are
|
|
7
|
+
* the only ones unmasked here (D1 in the feature spec):
|
|
8
|
+
* - `Runtime.callFunctionOn` → string entries in `params.arguments[].value`
|
|
9
|
+
* - `Runtime.evaluate` → `params.expression`
|
|
10
|
+
* - `Input.insertText` → `params.text`
|
|
11
|
+
*
|
|
12
|
+
* Per-frame domain gating reuses `SecretsPipeline.unmaskBody` semantics:
|
|
13
|
+
* on a domain mismatch (or missing secret) the value is left verbatim (no
|
|
14
|
+
* forbidden surface — masked values in conversation context are harmless).
|
|
15
|
+
*
|
|
16
|
+
* Returns `{ frame, changed }`. When nothing applies the original frame
|
|
17
|
+
* reference is returned untouched (no clone, no mutation).
|
|
18
|
+
*/
|
|
19
|
+
function unmaskString(pipeline, hostname, value) {
|
|
20
|
+
const { text } = pipeline.unmaskBody(value, hostname);
|
|
21
|
+
return { text, changed: text !== value };
|
|
22
|
+
}
|
|
23
|
+
export function unmaskCdpFrame(frame, hostname, pipeline) {
|
|
24
|
+
if (!frame || typeof frame !== 'object')
|
|
25
|
+
return { frame, changed: false };
|
|
26
|
+
if (!pipeline.hasSecrets())
|
|
27
|
+
return { frame, changed: false };
|
|
28
|
+
const method = frame.method;
|
|
29
|
+
const params = frame.params;
|
|
30
|
+
if (!params || typeof params !== 'object')
|
|
31
|
+
return { frame, changed: false };
|
|
32
|
+
if (method === 'Runtime.evaluate') {
|
|
33
|
+
const p = params;
|
|
34
|
+
if (typeof p.expression !== 'string')
|
|
35
|
+
return { frame, changed: false };
|
|
36
|
+
const { text, changed } = unmaskString(pipeline, hostname, p.expression);
|
|
37
|
+
if (!changed)
|
|
38
|
+
return { frame, changed: false };
|
|
39
|
+
return {
|
|
40
|
+
frame: { ...frame, params: { ...p, expression: text } },
|
|
41
|
+
changed: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (method === 'Input.insertText') {
|
|
45
|
+
const p = params;
|
|
46
|
+
if (typeof p.text !== 'string')
|
|
47
|
+
return { frame, changed: false };
|
|
48
|
+
const { text, changed } = unmaskString(pipeline, hostname, p.text);
|
|
49
|
+
if (!changed)
|
|
50
|
+
return { frame, changed: false };
|
|
51
|
+
return {
|
|
52
|
+
frame: { ...frame, params: { ...p, text } },
|
|
53
|
+
changed: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (method === 'Runtime.callFunctionOn') {
|
|
57
|
+
const p = params;
|
|
58
|
+
if (!Array.isArray(p.arguments))
|
|
59
|
+
return { frame, changed: false };
|
|
60
|
+
let argsChanged = false;
|
|
61
|
+
const nextArgs = p.arguments.map((arg) => {
|
|
62
|
+
if (!arg || typeof arg !== 'object')
|
|
63
|
+
return arg;
|
|
64
|
+
const a = arg;
|
|
65
|
+
if (typeof a.value !== 'string')
|
|
66
|
+
return arg;
|
|
67
|
+
const { text, changed } = unmaskString(pipeline, hostname, a.value);
|
|
68
|
+
if (!changed)
|
|
69
|
+
return arg;
|
|
70
|
+
argsChanged = true;
|
|
71
|
+
return { ...a, value: text };
|
|
72
|
+
});
|
|
73
|
+
if (!argsChanged)
|
|
74
|
+
return { frame, changed: false };
|
|
75
|
+
return {
|
|
76
|
+
frame: { ...frame, params: { ...p, arguments: nextArgs } },
|
|
77
|
+
changed: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return { frame, changed: false };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=cdp-frame-unmask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp-frame-unmask.js","sourceRoot":"","sources":["../src/cdp-frame-unmask.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Re-exports added in Task 1.2 (secret-masking) and Task 1.3 (secrets-pipeline).
|
|
2
|
+
export * from './cdp-frame-unmask.js';
|
|
2
3
|
export * from './oauth-extra-domains-storage.js';
|
|
3
4
|
export * from './secret-masking.js';
|
|
4
5
|
export * from './secrets-pipeline.js';
|
|
6
|
+
export * from './session-secret-store.js';
|
|
5
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SessionSecretStore } from './session-secret-store.js';
|
|
1
2
|
export interface FetchProxySecretSource {
|
|
2
3
|
get(name: string): Promise<string | undefined>;
|
|
3
4
|
listAll(): Promise<{
|
|
@@ -35,6 +36,13 @@ export interface ExtractedUrlCreds {
|
|
|
35
36
|
export interface SecretsPipelineOpts {
|
|
36
37
|
sessionId: string;
|
|
37
38
|
source: FetchProxySecretSource;
|
|
39
|
+
/**
|
|
40
|
+
* Optional in-memory session-secret store. Its entries are layered on top
|
|
41
|
+
* of `source` at every `reload()` so the fetch proxy can unmask session
|
|
42
|
+
* secrets like persisted ones. Persisted secrets win on a name collision
|
|
43
|
+
* (the agent cannot shadow a real persisted secret's masking).
|
|
44
|
+
*/
|
|
45
|
+
sessionStore?: SessionSecretStore;
|
|
38
46
|
}
|
|
39
47
|
/**
|
|
40
48
|
* Stateful unmask/scrub pipeline shared between node-server's /api/fetch-proxy
|
|
@@ -63,6 +71,7 @@ export interface SecretsPipelineOpts {
|
|
|
63
71
|
export declare class SecretsPipeline {
|
|
64
72
|
readonly sessionId: string;
|
|
65
73
|
private readonly source;
|
|
74
|
+
private readonly sessionStore?;
|
|
66
75
|
private maskedToSecret;
|
|
67
76
|
private scrubber;
|
|
68
77
|
constructor(opts: SecretsPipelineOpts);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets-pipeline.d.ts","sourceRoot":"","sources":["../src/secrets-pipeline.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secrets-pipeline.d.ts","sourceRoot":"","sources":["../src/secrets-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,16 +56,23 @@ function replaceAllBytes(haystack, needle, replacement) {
|
|
|
56
56
|
export class SecretsPipeline {
|
|
57
57
|
sessionId;
|
|
58
58
|
source;
|
|
59
|
+
sessionStore;
|
|
59
60
|
maskedToSecret = new Map();
|
|
60
61
|
scrubber = (t) => t;
|
|
61
62
|
constructor(opts) {
|
|
62
63
|
this.sessionId = opts.sessionId;
|
|
63
64
|
this.source = opts.source;
|
|
65
|
+
this.sessionStore = opts.sessionStore;
|
|
64
66
|
}
|
|
65
67
|
async reload() {
|
|
66
68
|
const all = await this.source.listAll();
|
|
69
|
+
// Layer session secrets on top of persisted ones; persisted wins on a
|
|
70
|
+
// name collision so a free session-set can't shadow a real secret.
|
|
71
|
+
const persistedNames = new Set(all.map((s) => s.name));
|
|
72
|
+
const session = (this.sessionStore?.listAll() ?? []).filter((s) => !persistedNames.has(s.name));
|
|
73
|
+
const merged = [...all, ...session];
|
|
67
74
|
const next = new Map();
|
|
68
|
-
for (const s of
|
|
75
|
+
for (const s of merged) {
|
|
69
76
|
const maskedValue = await cryptoMask(this.sessionId, s.name, s.value);
|
|
70
77
|
next.set(maskedValue, {
|
|
71
78
|
name: s.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets-pipeline.js","sourceRoot":"","sources":["../src/secrets-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,IAAI,IAAI,UAAU,EAClB,cAAc,GAEf,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"secrets-pipeline.js","sourceRoot":"","sources":["../src/secrets-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory, session-only secret store.
|
|
3
|
+
*
|
|
4
|
+
* Session secrets are set by the agent without approval and are NEVER
|
|
5
|
+
* persisted to disk / Keychain / chrome.storage — they live only for the
|
|
6
|
+
* lifetime of the process (node-server) or service-worker (extension) that
|
|
7
|
+
* owns the instance, and vanish on session end.
|
|
8
|
+
*
|
|
9
|
+
* The store is wired into {@link SecretsPipeline} (via `sessionStore`) so the
|
|
10
|
+
* fetch proxy can unmask session secrets exactly like persisted ones, while
|
|
11
|
+
* the `secret` shell command writes to it through the per-float transport.
|
|
12
|
+
*/
|
|
13
|
+
export interface SessionSecretRecord {
|
|
14
|
+
name: string;
|
|
15
|
+
value: string;
|
|
16
|
+
domains: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare class SessionSecretStore {
|
|
19
|
+
private readonly entries;
|
|
20
|
+
/** Create or replace a session secret. Domains default to empty. */
|
|
21
|
+
set(name: string, value: string, domains?: string[]): void;
|
|
22
|
+
/** Real value for `name`, or undefined when absent. */
|
|
23
|
+
get(name: string): string | undefined;
|
|
24
|
+
/** Full record (value + domains) for `name`, or undefined when absent. */
|
|
25
|
+
getRecord(name: string): SessionSecretRecord | undefined;
|
|
26
|
+
has(name: string): boolean;
|
|
27
|
+
/** Replace the allowed domains of an existing secret. No-op when absent. */
|
|
28
|
+
setDomains(name: string, domains: string[]): boolean;
|
|
29
|
+
delete(name: string): boolean;
|
|
30
|
+
/** All records including values (for pipeline reload). */
|
|
31
|
+
listAll(): SessionSecretRecord[];
|
|
32
|
+
/** Names + domains only (no values) for listing/management surfaces. */
|
|
33
|
+
list(): Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
domains: string[];
|
|
36
|
+
}>;
|
|
37
|
+
size(): number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build a partial, redacted preview of a secret value: the first and last
|
|
41
|
+
* `edge` characters with the middle elided. Always elides at least one
|
|
42
|
+
* character so the full value is never reconstructable from the preview.
|
|
43
|
+
*
|
|
44
|
+
* previewSecret('sk-proj-ABCDEFGH1234') → 'sk-p…1234'
|
|
45
|
+
* previewSecret('short') → 's…t'
|
|
46
|
+
*/
|
|
47
|
+
export declare function previewSecret(value: string, edge?: number): string;
|
|
48
|
+
//# sourceMappingURL=session-secret-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-secret-store.d.ts","sourceRoot":"","sources":["../src/session-secret-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0C;IAElE,oEAAoE;IACpE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,IAAI;IAI9D,uDAAuD;IACvD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIrC,0EAA0E;IAC1E,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAKxD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,4EAA4E;IAC5E,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO;IAOpD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI7B,0DAA0D;IAC1D,OAAO,IAAI,mBAAmB,EAAE;IAQhC,wEAAwE;IACxE,IAAI,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAOlD,IAAI,IAAI,MAAM;CAGf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,MAAM,CAM7D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory, session-only secret store.
|
|
3
|
+
*
|
|
4
|
+
* Session secrets are set by the agent without approval and are NEVER
|
|
5
|
+
* persisted to disk / Keychain / chrome.storage — they live only for the
|
|
6
|
+
* lifetime of the process (node-server) or service-worker (extension) that
|
|
7
|
+
* owns the instance, and vanish on session end.
|
|
8
|
+
*
|
|
9
|
+
* The store is wired into {@link SecretsPipeline} (via `sessionStore`) so the
|
|
10
|
+
* fetch proxy can unmask session secrets exactly like persisted ones, while
|
|
11
|
+
* the `secret` shell command writes to it through the per-float transport.
|
|
12
|
+
*/
|
|
13
|
+
export class SessionSecretStore {
|
|
14
|
+
entries = new Map();
|
|
15
|
+
/** Create or replace a session secret. Domains default to empty. */
|
|
16
|
+
set(name, value, domains = []) {
|
|
17
|
+
this.entries.set(name, { name, value, domains: [...domains] });
|
|
18
|
+
}
|
|
19
|
+
/** Real value for `name`, or undefined when absent. */
|
|
20
|
+
get(name) {
|
|
21
|
+
return this.entries.get(name)?.value;
|
|
22
|
+
}
|
|
23
|
+
/** Full record (value + domains) for `name`, or undefined when absent. */
|
|
24
|
+
getRecord(name) {
|
|
25
|
+
const r = this.entries.get(name);
|
|
26
|
+
return r ? { name: r.name, value: r.value, domains: [...r.domains] } : undefined;
|
|
27
|
+
}
|
|
28
|
+
has(name) {
|
|
29
|
+
return this.entries.has(name);
|
|
30
|
+
}
|
|
31
|
+
/** Replace the allowed domains of an existing secret. No-op when absent. */
|
|
32
|
+
setDomains(name, domains) {
|
|
33
|
+
const r = this.entries.get(name);
|
|
34
|
+
if (!r)
|
|
35
|
+
return false;
|
|
36
|
+
r.domains = [...domains];
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
delete(name) {
|
|
40
|
+
return this.entries.delete(name);
|
|
41
|
+
}
|
|
42
|
+
/** All records including values (for pipeline reload). */
|
|
43
|
+
listAll() {
|
|
44
|
+
return Array.from(this.entries.values()).map((r) => ({
|
|
45
|
+
name: r.name,
|
|
46
|
+
value: r.value,
|
|
47
|
+
domains: [...r.domains],
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
/** Names + domains only (no values) for listing/management surfaces. */
|
|
51
|
+
list() {
|
|
52
|
+
return Array.from(this.entries.values()).map((r) => ({
|
|
53
|
+
name: r.name,
|
|
54
|
+
domains: [...r.domains],
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
size() {
|
|
58
|
+
return this.entries.size;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Build a partial, redacted preview of a secret value: the first and last
|
|
63
|
+
* `edge` characters with the middle elided. Always elides at least one
|
|
64
|
+
* character so the full value is never reconstructable from the preview.
|
|
65
|
+
*
|
|
66
|
+
* previewSecret('sk-proj-ABCDEFGH1234') → 'sk-p…1234'
|
|
67
|
+
* previewSecret('short') → 's…t'
|
|
68
|
+
*/
|
|
69
|
+
export function previewSecret(value, edge = 4) {
|
|
70
|
+
const len = value.length;
|
|
71
|
+
if (len === 0)
|
|
72
|
+
return '';
|
|
73
|
+
if (len <= 2)
|
|
74
|
+
return '…';
|
|
75
|
+
const e = Math.min(Math.max(1, edge), Math.floor((len - 1) / 2));
|
|
76
|
+
return `${value.slice(0, e)}…${value.slice(len - e)}`;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=session-secret-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-secret-store.js","sourceRoot":"","sources":["../src/session-secret-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* applyCdpUnmask — Client→Chrome leg unmask gate for the CDP proxy.
|
|
3
|
+
*
|
|
4
|
+
* Parses the outbound CDP frame, looks up the per-session current URL
|
|
5
|
+
* via `CdpSessionUrlTracker`, and delegates whole-token unmasking to
|
|
6
|
+
* the pure `unmaskCdpFrame` helper from @slicc/shared-ts.
|
|
7
|
+
*
|
|
8
|
+
* Security invariants (HARD requirements):
|
|
9
|
+
* - Unmask is gated on the target tab's CURRENT URL. If the session's
|
|
10
|
+
* URL is unknown OR its hostname can't be parsed → FAIL CLOSED:
|
|
11
|
+
* forward the original bytes verbatim, no unmask.
|
|
12
|
+
* - Domain mismatch is handled inside `unmaskCdpFrame.unmaskBody`:
|
|
13
|
+
* the masked value passes through untouched.
|
|
14
|
+
* - Frames larger than `CDP_CLIENT_FRAME_MAX_BYTES` are forwarded
|
|
15
|
+
* verbatim — parsing a runaway frame to scan for secrets would
|
|
16
|
+
* amplify the same feedback-loop pressure the Chrome→Client leg
|
|
17
|
+
* already has to defend against.
|
|
18
|
+
* - JSON parse errors → forward verbatim. The CDP wire format is
|
|
19
|
+
* JSON-only in practice, but corrupted/non-JSON bytes are not the
|
|
20
|
+
* unmasker's problem to surface.
|
|
21
|
+
*/
|
|
22
|
+
import { type SecretsPipeline } from '../_shared/index.js';
|
|
23
|
+
import type { CdpSessionUrlTracker } from './session-url-tracker.js';
|
|
24
|
+
/**
|
|
25
|
+
* Hard cap on client→Chrome frames we'll attempt to parse + unmask.
|
|
26
|
+
* Real CDP commands originating from the cone are tiny (a few KB at most
|
|
27
|
+
* for `Runtime.evaluate` payloads); the cap is generous to cover oversize
|
|
28
|
+
* `Runtime.callFunctionOn` argument lists without burning cycles on
|
|
29
|
+
* pathological inputs.
|
|
30
|
+
*/
|
|
31
|
+
export declare const CDP_CLIENT_FRAME_MAX_BYTES: number;
|
|
32
|
+
export interface CdpUnmaskDeps {
|
|
33
|
+
tracker: CdpSessionUrlTracker;
|
|
34
|
+
pipeline: SecretsPipeline;
|
|
35
|
+
}
|
|
36
|
+
export interface CdpUnmaskResult {
|
|
37
|
+
/** Bytes to forward to Chrome. Same reference as `input` when nothing changed. */
|
|
38
|
+
output: string;
|
|
39
|
+
/** True iff the helper rewrote at least one whole-token field. */
|
|
40
|
+
changed: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Reason the frame was forwarded verbatim, when applicable. `undefined`
|
|
43
|
+
* means the frame was inspected (and possibly unmasked) successfully.
|
|
44
|
+
* Used by the proxy to emit a single deduped debug line per failure mode.
|
|
45
|
+
*/
|
|
46
|
+
skipped?: 'oversized' | 'parse-error' | 'no-method' | 'no-hostname' | 'no-secrets';
|
|
47
|
+
}
|
|
48
|
+
export declare function applyCdpUnmask(input: string, deps: CdpUnmaskDeps): CdpUnmaskResult;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* applyCdpUnmask — Client→Chrome leg unmask gate for the CDP proxy.
|
|
3
|
+
*
|
|
4
|
+
* Parses the outbound CDP frame, looks up the per-session current URL
|
|
5
|
+
* via `CdpSessionUrlTracker`, and delegates whole-token unmasking to
|
|
6
|
+
* the pure `unmaskCdpFrame` helper from @slicc/shared-ts.
|
|
7
|
+
*
|
|
8
|
+
* Security invariants (HARD requirements):
|
|
9
|
+
* - Unmask is gated on the target tab's CURRENT URL. If the session's
|
|
10
|
+
* URL is unknown OR its hostname can't be parsed → FAIL CLOSED:
|
|
11
|
+
* forward the original bytes verbatim, no unmask.
|
|
12
|
+
* - Domain mismatch is handled inside `unmaskCdpFrame.unmaskBody`:
|
|
13
|
+
* the masked value passes through untouched.
|
|
14
|
+
* - Frames larger than `CDP_CLIENT_FRAME_MAX_BYTES` are forwarded
|
|
15
|
+
* verbatim — parsing a runaway frame to scan for secrets would
|
|
16
|
+
* amplify the same feedback-loop pressure the Chrome→Client leg
|
|
17
|
+
* already has to defend against.
|
|
18
|
+
* - JSON parse errors → forward verbatim. The CDP wire format is
|
|
19
|
+
* JSON-only in practice, but corrupted/non-JSON bytes are not the
|
|
20
|
+
* unmasker's problem to surface.
|
|
21
|
+
*/
|
|
22
|
+
import { unmaskCdpFrame } from '../_shared/index.js';
|
|
23
|
+
/**
|
|
24
|
+
* Hard cap on client→Chrome frames we'll attempt to parse + unmask.
|
|
25
|
+
* Real CDP commands originating from the cone are tiny (a few KB at most
|
|
26
|
+
* for `Runtime.evaluate` payloads); the cap is generous to cover oversize
|
|
27
|
+
* `Runtime.callFunctionOn` argument lists without burning cycles on
|
|
28
|
+
* pathological inputs.
|
|
29
|
+
*/
|
|
30
|
+
export const CDP_CLIENT_FRAME_MAX_BYTES = 4 * 1024 * 1024;
|
|
31
|
+
export function applyCdpUnmask(input, deps) {
|
|
32
|
+
if (input.length > CDP_CLIENT_FRAME_MAX_BYTES) {
|
|
33
|
+
return { output: input, changed: false, skipped: 'oversized' };
|
|
34
|
+
}
|
|
35
|
+
if (!deps.pipeline.hasSecrets()) {
|
|
36
|
+
return { output: input, changed: false, skipped: 'no-secrets' };
|
|
37
|
+
}
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(input);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { output: input, changed: false, skipped: 'parse-error' };
|
|
44
|
+
}
|
|
45
|
+
if (!parsed || typeof parsed !== 'object' || typeof parsed.method !== 'string') {
|
|
46
|
+
return { output: input, changed: false, skipped: 'no-method' };
|
|
47
|
+
}
|
|
48
|
+
const sessionId = typeof parsed.sessionId === 'string' ? parsed.sessionId : undefined;
|
|
49
|
+
const hostname = deps.tracker.getHostname(sessionId);
|
|
50
|
+
if (!hostname) {
|
|
51
|
+
// FAIL CLOSED — without a resolvable hostname we cannot enforce
|
|
52
|
+
// the per-tab domain gate, so unmasking is not safe.
|
|
53
|
+
return { output: input, changed: false, skipped: 'no-hostname' };
|
|
54
|
+
}
|
|
55
|
+
const { frame, changed } = unmaskCdpFrame(parsed, hostname, deps.pipeline);
|
|
56
|
+
if (!changed)
|
|
57
|
+
return { output: input, changed: false };
|
|
58
|
+
return { output: JSON.stringify(frame), changed: true };
|
|
59
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CdpSessionUrlTracker — sniffs the Chrome→Client leg of the CDP WebSocket
|
|
3
|
+
* proxy and maintains a `sessionId -> currentUrl` map keyed the same way
|
|
4
|
+
* navigation-watcher.ts keys its session state. The map feeds the Client→
|
|
5
|
+
* Chrome unmask gate (cdp-unmask.ts) so per-frame unmasking is scoped to
|
|
6
|
+
* the target tab's actual current URL.
|
|
7
|
+
*
|
|
8
|
+
* Three CDP events feed the tracker:
|
|
9
|
+
* - `Target.attachedToTarget` → seed via `params.sessionId` + `params.targetInfo.url`
|
|
10
|
+
* - `Target.targetInfoChanged` → keyed by `params.targetInfo.targetId`; updates
|
|
11
|
+
* every session pointing at that target
|
|
12
|
+
* - `Page.frameNavigated` (root) → `sessionId` lives at the wire-frame top level;
|
|
13
|
+
* only the root frame (no parentId) updates the session url
|
|
14
|
+
*
|
|
15
|
+
* `Target.detachedFromTarget` clears the entry. Everything else is a no-op.
|
|
16
|
+
*
|
|
17
|
+
* Hostname resolution is done lazily via `getHostname(sessionId)`. Empty,
|
|
18
|
+
* un-parseable, or `about:blank`-style URLs fail closed (return null).
|
|
19
|
+
*/
|
|
20
|
+
export interface CdpSessionUrlTracker {
|
|
21
|
+
observeChromeToClient(frame: unknown): void;
|
|
22
|
+
getHostname(sessionId: string | undefined): string | null;
|
|
23
|
+
getUrl(sessionId: string | undefined): string | null;
|
|
24
|
+
size(): number;
|
|
25
|
+
clear(): void;
|
|
26
|
+
}
|
|
27
|
+
export declare function createCdpSessionUrlTracker(): CdpSessionUrlTracker;
|