@pensar/apex 2.5.0 → 2.6.1-canary.025b1ecf
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/README.md +38 -0
- package/bin/pensar.js +12 -4
- package/build/agent-b37fm1yh.js +13 -0
- package/build/{agent-m30a62kh.js → agent-f8rpt4sb.js} +48 -50
- package/build/agent-gqexqg2q.js +13 -0
- package/build/agent-qk30vqmf.js +15 -0
- package/build/agent-runs-nw7dwp1d.js +313 -0
- package/build/{apps-x4ef2gpc.js → apps-zeqbjbs4.js} +50 -58
- package/build/{auth-7ay8qgxm.js → auth-038hsg1s.js} +61 -68
- package/build/blackboxAgent-fjrv4q3d.js +13 -0
- package/build/blackboxPentest-6dtb7vnq.js +59 -0
- package/build/{cli-73k43t1r.js → cli-17ndymmb.js} +53 -78
- package/build/{cli-3py0a0wg.js → cli-1rwe9a9v.js} +206 -136
- package/build/{cli-y3dpm18e.js → cli-2tfnaeca.js} +75 -92
- package/build/{cli-ee3axgts.js → cli-3gt761d2.js} +7 -1
- package/build/cli-3qznjsnr.js +14 -0
- package/build/{cli-sx3jkv7p.js → cli-3w0mx2mv.js} +28872 -25951
- package/build/cli-5qq1655n.js +175 -0
- package/build/{cli-53rm0rrz.js → cli-8w8k4dph.js} +1 -1
- package/build/{cli-68260ckj.js → cli-91gs9whc.js} +1658 -1606
- package/build/cli-99gxp2yb.js +62 -0
- package/build/cli-ayqhdajr.js +22 -0
- package/build/{cli-knd276ed.js → cli-bb02pjt0.js} +31 -31
- package/build/{cli-p4r7q012.js → cli-bw31v3z7.js} +16743 -13352
- package/build/{cli-j54qa6tm.js → cli-c2k4xxaw.js} +42 -42
- package/build/{cli-z5c0ypg1.js → cli-czwr2xmh.js} +4 -4
- package/build/{cli-k71t434r.js → cli-ec2hwkv3.js} +34 -76
- package/build/{cli-vkbzcnw1.js → cli-fxmref08.js} +43 -40
- package/build/cli-g06s7edq.js +11 -0
- package/build/cli-gsaf4jk3.js +280 -0
- package/build/{cli-bc05qbss.js → cli-h6y3bt60.js} +13 -21
- package/build/cli-jdrx44ge.js +14 -0
- package/build/{cli-x92fkt2f.js → cli-m3btkdbx.js} +55 -97
- package/build/cli-mdk51kby.js +429 -0
- package/build/{cli-bw2ddttk.js → cli-mnpzhtg6.js} +4730 -267
- package/build/cli-mz5pk30x.js +5508 -0
- package/build/cli-pwm29ks7.js +6337 -0
- package/build/cli-retw3rw5.js +12 -0
- package/build/{cli-kff2bbq7.js → cli-rxj14t82.js} +43 -43
- package/build/cli-se8ae8z3.js +2250 -0
- package/build/cli-skedjgqy.js +186 -0
- package/build/{cli-dm0fc0bm.js → cli-v1sarr4y.js} +5 -9
- package/build/cli-vfzpbv3g.js +355 -0
- package/build/cli-xcy2vxj2.js +1732 -0
- package/build/{cli-zav1yx5k.js → cli-yn4sj3z1.js} +990 -632
- package/build/{cli-7vg06q5r.js → cli-zsq8kfgc.js} +135 -125
- package/build/cli.js +769 -195
- package/build/{config-4kzh88xz.js → config-4emx9c35.js} +16 -19
- package/build/{doctor-rz7sx6ev.js → doctor-z94afr10.js} +26 -15
- package/build/export-trajectory-rt4tf07k.js +112 -0
- package/build/{fastStrike-a54atjc8.js → fastStrike-mnn8g4ay.js} +56 -31
- package/build/{fixes-fv66yn1z.js → fixes-hm5569vq.js} +22 -30
- package/build/{getMachineId-bsd-xj3bn2fv.js → getMachineId-bsd-zr67nd9p.js} +5 -5
- package/build/{getMachineId-darwin-07jzjcx6.js → getMachineId-darwin-fd1d562d.js} +5 -5
- package/build/{getMachineId-linux-ahngynxd.js → getMachineId-linux-kjmg243j.js} +4 -4
- package/build/{getMachineId-unsupported-vy43b44z.js → getMachineId-unsupported-n4r58vke.js} +4 -4
- package/build/{getMachineId-win-8x66cynz.js → getMachineId-win-yzgpfsrb.js} +5 -5
- package/build/index-0yfxwj9h.js +25 -0
- package/build/{index-kyd1jm89.js → index-1qjwwg4x.js} +159 -169
- package/build/index-939ypn8a.js +12 -0
- package/build/index-a0bxw5zq.js +17477 -0
- package/build/{index-cbwn03kz.js → index-a2xycbjs.js} +12 -31
- package/build/{index-psqjpw5m.js → index-c1h0g35p.js} +11 -11
- package/build/{index-fpwr10qm.js → index-f2xpfw4x.js} +5106 -3803
- package/build/index-g9akqryt.js +9 -0
- package/build/index-mrrfbsyz.js +17 -0
- package/build/index-qnyevb6q.js +1563 -0
- package/build/index-ttwhf2se.js +36 -0
- package/build/index-vy2pm5zf.js +121 -0
- package/build/index-x8ab8x86.js +102 -0
- package/build/{issues-019678t0.js → issues-wxd3ca1d.js} +51 -47
- package/build/knowledge-rvcpbak8.js +139 -0
- package/build/lib/chunk-0y40tebt.js +102 -0
- package/build/lib/chunk-0ydfy4hq.js +510 -0
- package/build/lib/chunk-2njv7wz3.js +178 -0
- package/build/lib/chunk-3q89v4xv.js +21 -0
- package/build/lib/chunk-4p2n69vn.js +62 -0
- package/build/lib/chunk-7gjdygcx.js +171 -0
- package/build/lib/chunk-8d8w07a9.js +431 -0
- package/build/lib/chunk-8dqz8cwa.js +27 -0
- package/build/lib/chunk-8vhr65w3.js +272 -0
- package/build/lib/chunk-8xnzgfs0.js +56 -0
- package/build/lib/chunk-9nsrd4xg.js +12 -0
- package/build/lib/chunk-a3gxgj9r.js +317 -0
- package/build/lib/chunk-afef65e0.js +7150 -0
- package/build/lib/chunk-b8eq85d2.js +143 -0
- package/build/lib/chunk-bqrmw2tn.js +439 -0
- package/build/lib/chunk-bx94rwt5.js +24 -0
- package/build/lib/chunk-c2b0hxs7.js +143 -0
- package/build/lib/chunk-cwj17b1f.js +345 -0
- package/build/lib/chunk-cx7yrzh1.js +2429 -0
- package/build/lib/chunk-eb4h4k1f.js +213 -0
- package/build/lib/chunk-esymacwg.js +14 -0
- package/build/lib/chunk-fy3bbbqy.js +7896 -0
- package/build/lib/chunk-gdrv2h1p.js +11157 -0
- package/build/lib/chunk-ja7j565c.js +743 -0
- package/build/lib/chunk-jdjagvgr.js +85 -0
- package/build/lib/chunk-k4rz1yvj.js +31 -0
- package/build/lib/chunk-kfvq4m1s.js +685 -0
- package/build/lib/chunk-mgppdr6j.js +980 -0
- package/build/lib/chunk-mhxe717m.js +572 -0
- package/build/lib/chunk-mv74mq5n.js +59 -0
- package/build/lib/chunk-n0ba7khr.js +64 -0
- package/build/lib/chunk-q5e23acz.js +52 -0
- package/build/lib/chunk-q8bk9dys.js +922 -0
- package/build/lib/chunk-sgd2126b.js +9294 -0
- package/build/lib/chunk-t5bt5vn1.js +146 -0
- package/build/lib/chunk-v2q8anzw.js +120 -0
- package/build/lib/chunk-vd6hr8pm.js +212 -0
- package/build/lib/chunk-ve7m90fb.js +317 -0
- package/build/lib/chunk-vx228eeq.js +82 -0
- package/build/lib/chunk-wchtd611.js +186 -0
- package/build/lib/chunk-ws86wx87.js +1412 -0
- package/build/lib/chunk-xpfg2fbk.js +90 -0
- package/build/lib/chunk-zrbqn62x.js +697 -0
- package/build/lib/core/agents/agentRuntime.d.ts +47 -0
- package/build/lib/core/agents/defineAgent.d.ts +82 -0
- package/build/lib/core/agents/offSecAgent/index.d.ts +9 -0
- package/build/lib/core/agents/offSecAgent/index.js +225 -0
- package/build/lib/core/agents/offSecAgent/interruptedStepFinalization.d.ts +23 -0
- package/build/lib/core/agents/offSecAgent/interruptedStepMessages.d.ts +42 -0
- package/build/lib/core/agents/offSecAgent/messagePersistence.d.ts +39 -0
- package/build/lib/core/agents/offSecAgent/offensiveSecurityAgent.d.ts +233 -0
- package/build/lib/core/agents/offSecAgent/prompt.d.ts +35 -0
- package/build/lib/core/agents/offSecAgent/recordedTools.d.ts +11 -0
- package/build/lib/core/agents/offSecAgent/runtimeContext.d.ts +43 -0
- package/build/lib/core/agents/offSecAgent/streamDiagnostics.d.ts +67 -0
- package/build/lib/core/agents/offSecAgent/subagentSpawner.d.ts +223 -0
- package/build/lib/core/agents/offSecAgent/subagentSpawner.js +19 -0
- package/build/lib/core/agents/offSecAgent/toolLifecycle.d.ts +54 -0
- package/build/lib/core/agents/offSecAgent/tools/__tests__/sandboxScript.d.ts +1 -0
- package/build/lib/core/agents/offSecAgent/tools/addMemory.d.ts +16 -0
- package/build/lib/core/agents/offSecAgent/tools/agentScratch.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/applyPatch.d.ts +8 -0
- package/build/lib/core/agents/offSecAgent/tools/applyPatchImpl.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/askUserQuestions.d.ts +42 -0
- package/build/lib/core/agents/offSecAgent/tools/browserHeaderRouting.d.ts +9 -0
- package/build/lib/core/agents/offSecAgent/tools/browserToolFactories.d.ts +40 -0
- package/build/lib/core/agents/offSecAgent/tools/browserTools.d.ts +96 -0
- package/build/lib/core/agents/offSecAgent/tools/callbackListener.d.ts +212 -0
- package/build/lib/core/agents/offSecAgent/tools/camoufox.d.ts +106 -0
- package/build/lib/core/agents/offSecAgent/tools/checkpointState.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/completeAuthentication.d.ts +39 -0
- package/build/lib/core/agents/offSecAgent/tools/crawlAuthenticated.d.ts +36 -0
- package/build/lib/core/agents/offSecAgent/tools/createAttackSurfaceReport.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/createFile.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/createTask.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/delegateAuth.d.ts +72 -0
- package/build/lib/core/agents/offSecAgent/tools/deleteFile.d.ts +10 -0
- package/build/lib/core/agents/offSecAgent/tools/destructiveGuard.d.ts +94 -0
- package/build/lib/core/agents/offSecAgent/tools/detectAuthScheme.d.ts +72 -0
- package/build/lib/core/agents/offSecAgent/tools/documentApp.d.ts +38 -0
- package/build/lib/core/agents/offSecAgent/tools/documentEndpoint.d.ts +111 -0
- package/build/lib/core/agents/offSecAgent/tools/documentFinding.d.ts +285 -0
- package/build/lib/core/agents/offSecAgent/tools/email/adapters.d.ts +45 -0
- package/build/lib/core/agents/offSecAgent/tools/email/adapters.js +8 -0
- package/build/lib/core/agents/offSecAgent/tools/email/getAttachments.d.ts +33 -0
- package/build/lib/core/agents/offSecAgent/tools/email/getMessage.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/email/index.d.ts +145 -0
- package/build/lib/core/agents/offSecAgent/tools/email/listInboxes.d.ts +23 -0
- package/build/lib/core/agents/offSecAgent/tools/email/listMessages.d.ts +22 -0
- package/build/lib/core/agents/offSecAgent/tools/email/markRead.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/email/searchMessages.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/email/sendEmail.d.ts +28 -0
- package/build/lib/core/agents/offSecAgent/tools/email/types.d.ts +40 -0
- package/build/lib/core/agents/offSecAgent/tools/email/types.js +0 -0
- package/build/lib/core/agents/offSecAgent/tools/executeCommand.d.ts +84 -0
- package/build/lib/core/agents/offSecAgent/tools/extractJsEndpoints.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/fileWorkspace.d.ts +21 -0
- package/build/lib/core/agents/offSecAgent/tools/fileWorkspaceRemote.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/getMemory.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/getPage.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/gitDiff.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/gitStatus.d.ts +10 -0
- package/build/lib/core/agents/offSecAgent/tools/glob.d.ts +8 -0
- package/build/lib/core/agents/offSecAgent/tools/globImpl.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/globPattern.d.ts +7 -0
- package/build/lib/core/agents/offSecAgent/tools/grep.d.ts +10 -0
- package/build/lib/core/agents/offSecAgent/tools/grepImpl.d.ts +34 -0
- package/build/lib/core/agents/offSecAgent/tools/httpRequest.d.ts +70 -0
- package/build/lib/core/agents/offSecAgent/tools/index.d.ts +466 -0
- package/build/lib/core/agents/offSecAgent/tools/index.js +262 -0
- package/build/lib/core/agents/offSecAgent/tools/listFiles.d.ts +9 -0
- package/build/lib/core/agents/offSecAgent/tools/listFilesImpl.d.ts +27 -0
- package/build/lib/core/agents/offSecAgent/tools/listMemories.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/tools/listPromptInjections.d.ts +18 -0
- package/build/lib/core/agents/offSecAgent/tools/listTasks.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/patchApply.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/patchParse.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/perCommandShell.d.ts +82 -0
- package/build/lib/core/agents/offSecAgent/tools/playwrightMcp.d.ts +369 -0
- package/build/lib/core/agents/offSecAgent/tools/probeAuthEndpoints.d.ts +28 -0
- package/build/lib/core/agents/offSecAgent/tools/profileCodebase.d.ts +33 -0
- package/build/lib/core/agents/offSecAgent/tools/provideComparisonResults.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/queryWhiteboxCatalog.d.ts +17 -0
- package/build/lib/core/agents/offSecAgent/tools/readFile.d.ts +11 -0
- package/build/lib/core/agents/offSecAgent/tools/readFileImpl.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/readSkill.d.ts +15 -0
- package/build/lib/core/agents/offSecAgent/tools/reportError.d.ts +31 -0
- package/build/lib/core/agents/offSecAgent/tools/response.d.ts +15 -0
- package/build/lib/core/agents/offSecAgent/tools/runAttackSurface.d.ts +81 -0
- package/build/lib/core/agents/offSecAgent/tools/runCodeQuery.d.ts +44 -0
- package/build/lib/core/agents/offSecAgent/tools/runPentestWorkflow.d.ts +32 -0
- package/build/lib/core/agents/offSecAgent/tools/runWhiteboxScan.d.ts +52 -0
- package/build/lib/core/agents/offSecAgent/tools/sandbox.d.ts +30 -0
- package/build/lib/core/agents/offSecAgent/tools/sandboxPlaywright.d.ts +137 -0
- package/build/lib/core/agents/offSecAgent/tools/sandboxScript.d.ts +6 -0
- package/build/lib/core/agents/offSecAgent/tools/scopeGuard.d.ts +91 -0
- package/build/lib/core/agents/offSecAgent/tools/scriptSyntaxCheck.d.ts +45 -0
- package/build/lib/core/agents/offSecAgent/tools/smsInbox.d.ts +67 -0
- package/build/lib/core/agents/offSecAgent/tools/smsInbox.js +6 -0
- package/build/lib/core/agents/offSecAgent/tools/smsListMessages.d.ts +29 -0
- package/build/lib/core/agents/offSecAgent/tools/spawnCodingAgent.d.ts +43 -0
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestAgent.d.ts +51 -0
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestSwarm.d.ts +52 -0
- package/build/lib/core/agents/offSecAgent/tools/submitPlan.d.ts +12 -0
- package/build/lib/core/agents/offSecAgent/tools/testEndpointVariations.d.ts +34 -0
- package/build/lib/core/agents/offSecAgent/tools/threatModelGenerator.d.ts +32 -0
- package/build/lib/core/agents/offSecAgent/tools/toolOutput.d.ts +23 -0
- package/build/lib/core/agents/offSecAgent/tools/types.d.ts +215 -0
- package/build/lib/core/agents/offSecAgent/tools/updateFile.d.ts +14 -0
- package/build/lib/core/agents/offSecAgent/tools/updateTask.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/validateDiscovery.d.ts +24 -0
- package/build/lib/core/agents/offSecAgent/tools/webSearch.d.ts +16 -0
- package/build/lib/core/agents/offSecAgent/tools/whiteboxCandidates.d.ts +108 -0
- package/build/lib/core/agents/offSecAgent/tools/whiteboxJobs.d.ts +157 -0
- package/build/lib/core/agents/offSecAgent/tools/windowsCurl.d.ts +20 -0
- package/build/lib/core/agents/offSecAgent/tools/workspaceApps.d.ts +120 -0
- package/build/lib/core/agents/offSecAgent/tools/workspaceDomains.d.ts +22 -0
- package/build/lib/core/agents/offSecAgent/tools/workspaceFailure.d.ts +6 -0
- package/build/lib/core/agents/offSecAgent/tools/writePlan.d.ts +13 -0
- package/build/lib/core/agents/offSecAgent/trace.d.ts +268 -0
- package/build/lib/core/agents/offSecAgent/types.d.ts +543 -0
- package/build/lib/core/agents/offSecAgent/types.js +7 -0
- package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.d.ts +66 -0
- package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.js +33 -0
- package/build/lib/core/agents/specialized/attackSurface/blackboxRiskScoring.d.ts +30 -0
- package/build/lib/core/agents/specialized/attackSurface/grpcSchema.d.ts +93 -0
- package/build/lib/core/agents/specialized/attackSurface/jsExtraction.d.ts +42 -0
- package/build/lib/core/agents/specialized/attackSurface/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/attackSurface/schemas.d.ts +284 -0
- package/build/lib/core/agents/specialized/attackSurface/schemas.js +144 -0
- package/build/lib/core/agents/specialized/attackSurface/types.d.ts +32 -0
- package/build/lib/core/agents/specialized/authenticationAgent/agent.d.ts +73 -0
- package/build/lib/core/agents/specialized/authenticationAgent/index.d.ts +4 -0
- package/build/lib/core/agents/specialized/authenticationAgent/index.js +71 -0
- package/build/lib/core/agents/specialized/authenticationAgent/prompts.d.ts +10 -0
- package/build/lib/core/agents/specialized/authenticationAgent/types.d.ts +620 -0
- package/build/lib/core/agents/specialized/benchmark/comparisonAgent.d.ts +10 -0
- package/build/lib/core/agents/specialized/benchmark/docker-utils.d.ts +17 -0
- package/build/lib/core/agents/specialized/benchmark/flag-detector.d.ts +60 -0
- package/build/lib/core/agents/specialized/benchmark/index.d.ts +8 -0
- package/build/lib/core/agents/specialized/benchmark/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/benchmark/remote/circuit-breaker.d.ts +22 -0
- package/build/lib/core/agents/specialized/benchmark/remote/daytona-wrapper.d.ts +33 -0
- package/build/lib/core/agents/specialized/benchmark/remote/index.d.ts +2 -0
- package/build/lib/core/agents/specialized/benchmark/types.d.ts +92 -0
- package/build/lib/core/agents/specialized/benchmarkComparisonAgent.d.ts +27 -0
- package/build/lib/core/agents/specialized/codeAgent/agent.d.ts +50 -0
- package/build/lib/core/agents/specialized/codeAgent/agent.js +31 -0
- package/build/lib/core/agents/specialized/codeAgent/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/codeAgent/schemas.d.ts +11 -0
- package/build/lib/core/agents/specialized/codeAgent/schemas.js +10 -0
- package/build/lib/core/agents/specialized/cvssScorer/index.d.ts +56 -0
- package/build/lib/core/agents/specialized/environment/agent.d.ts +43 -0
- package/build/lib/core/agents/specialized/environment/index.d.ts +4 -0
- package/build/lib/core/agents/specialized/environment/prompts.d.ts +10 -0
- package/build/lib/core/agents/specialized/environment/types.d.ts +37 -0
- package/build/lib/core/agents/specialized/findingJudge/agent.d.ts +22 -0
- package/build/lib/core/agents/specialized/findingJudge/agent.js +224 -0
- package/build/lib/core/agents/specialized/findingJudge/index.d.ts +31 -0
- package/build/lib/core/agents/specialized/findingJudge/index.js +13 -0
- package/build/lib/core/agents/specialized/findingJudge/prompts.d.ts +3 -0
- package/build/lib/core/agents/specialized/findingJudge/types.d.ts +77 -0
- package/build/lib/core/agents/specialized/googleSignInPrompt.d.ts +4 -0
- package/build/lib/core/agents/specialized/mobileOtpPrompt.d.ts +1 -0
- package/build/lib/core/agents/specialized/patching/agent.d.ts +64 -0
- package/build/lib/core/agents/specialized/patching/index.d.ts +4 -0
- package/build/lib/core/agents/specialized/patching/index.js +44 -0
- package/build/lib/core/agents/specialized/patching/prompts.d.ts +17 -0
- package/build/lib/core/agents/specialized/patching/types.d.ts +40 -0
- package/build/lib/core/agents/specialized/pentest/agent.d.ts +172 -0
- package/build/lib/core/agents/specialized/pentest/agent.js +43 -0
- package/build/lib/core/agents/specialized/pentest/helperWorkspace.d.ts +16 -0
- package/build/lib/core/agents/specialized/pentest/planPrompt.d.ts +13 -0
- package/build/lib/core/agents/specialized/utils.d.ts +7 -0
- package/build/lib/core/agents/specialized/vulnerabilityReproduction/agent.d.ts +94 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/agent.d.ts +148 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.d.ts +61 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.d.ts +5 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.js +47 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/prompts.d.ts +34 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/types.d.ts +382 -0
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/types.js +21 -0
- package/build/lib/core/ai/ai.d.ts +342 -0
- package/build/lib/core/ai/ai.js +68 -0
- package/build/lib/core/ai/caching.d.ts +26 -0
- package/build/lib/core/ai/compactionEvidence.d.ts +15 -0
- package/build/lib/core/ai/compactionTelemetry.d.ts +55 -0
- package/build/lib/core/ai/contextManagement.d.ts +85 -0
- package/build/lib/core/ai/index.d.ts +10 -0
- package/build/lib/core/ai/index.js +72 -0
- package/build/lib/core/ai/inference-attempt/adapters.d.ts +15 -0
- package/build/lib/core/ai/inference-attempt/builder.d.ts +31 -0
- package/build/lib/core/ai/inference-attempt/envelope.d.ts +120 -0
- package/build/lib/core/ai/inference-attempt/errors.d.ts +6 -0
- package/build/lib/core/ai/inference-attempt/identity.d.ts +13 -0
- package/build/lib/core/ai/inference-attempt/index.d.ts +36 -0
- package/build/lib/core/ai/inference-attempt/project.d.ts +21 -0
- package/build/lib/core/ai/inference-attempt/recording.d.ts +23 -0
- package/build/lib/core/ai/inference-attempt/tokens.d.ts +13 -0
- package/build/lib/core/ai/inference-attempt/validate.d.ts +2 -0
- package/build/lib/core/ai/mantle.d.ts +28 -0
- package/build/lib/core/ai/model-history.d.ts +4 -0
- package/build/lib/core/ai/models/anthropic.d.ts +2 -0
- package/build/lib/core/ai/models/bedrock.d.ts +2 -0
- package/build/lib/core/ai/models/claude-capabilities.d.ts +7 -0
- package/build/lib/core/ai/models/concentrate.d.ts +2 -0
- package/build/lib/core/ai/models/google.d.ts +2 -0
- package/build/lib/core/ai/models/inception.d.ts +2 -0
- package/build/lib/core/ai/models/index.d.ts +29 -0
- package/build/lib/core/ai/models/mantle.d.ts +2 -0
- package/build/lib/core/ai/models/openai.d.ts +2 -0
- package/build/lib/core/ai/models/openrouter.d.ts +2 -0
- package/build/lib/core/ai/models/pensar.d.ts +2 -0
- package/build/lib/core/ai/native-rollout-evidence/capture.d.ts +31 -0
- package/build/lib/core/ai/native-rollout-evidence/content.d.ts +14 -0
- package/build/lib/core/ai/native-rollout-evidence/index.d.ts +9 -0
- package/build/lib/core/ai/native-rollout-evidence/provider-metadata.d.ts +15 -0
- package/build/lib/core/ai/native-rollout-evidence/schema.d.ts +554 -0
- package/build/lib/core/ai/native-rollout-evidence/validate.d.ts +8 -0
- package/build/lib/core/ai/providers/anthropic.d.ts +2 -0
- package/build/lib/core/ai/providers/concentrate.d.ts +9 -0
- package/build/lib/core/ai/providers/custom.d.ts +3 -0
- package/build/lib/core/ai/providers/hoonify.d.ts +6 -0
- package/build/lib/core/ai/providers/openai-pro-fetch.d.ts +2 -0
- package/build/lib/core/ai/providers/pensar.d.ts +34 -0
- package/build/lib/core/ai/providers/pensarFormatters.d.ts +2 -0
- package/build/lib/core/ai/providers/pensarResponsesStream.d.ts +15 -0
- package/build/lib/core/ai/providers/pensarSSE.d.ts +23 -0
- package/build/lib/core/ai/providers/pensarSigning.d.ts +1 -0
- package/build/lib/core/ai/providers/pensarStreamUsage.d.ts +19 -0
- package/build/lib/core/ai/streamTelemetry.d.ts +22 -0
- package/build/lib/core/ai/utils.d.ts +90 -0
- package/build/lib/core/ai/utils.js +22 -0
- package/build/lib/core/api/apiClient.d.ts +7 -0
- package/build/lib/core/api/apps.d.ts +213 -0
- package/build/lib/core/api/attackSurface.d.ts +14 -0
- package/build/lib/core/api/authentication.d.ts +3 -0
- package/build/lib/core/api/benchmark.d.ts +5 -0
- package/build/lib/core/api/blackboxPentest.d.ts +11 -0
- package/build/lib/core/api/clientIdentity.d.ts +10 -0
- package/build/lib/core/api/constants.d.ts +5 -0
- package/build/lib/core/api/domains.d.ts +19 -0
- package/build/lib/core/api/environment.d.ts +16 -0
- package/build/lib/core/api/index.d.ts +41 -0
- package/build/lib/core/api/index.js +187 -0
- package/build/lib/core/api/issues.d.ts +273 -0
- package/build/lib/core/api/knowledge.d.ts +33 -0
- package/build/lib/core/api/localWorker.d.ts +4 -0
- package/build/lib/core/api/offesecAgent.d.ts +34 -0
- package/build/lib/core/api/patching.d.ts +15 -0
- package/build/lib/core/api/recordedRun.d.ts +36 -0
- package/build/lib/core/api/targetedPentest.d.ts +15 -0
- package/build/lib/core/api/targetedPentest.js +32 -0
- package/build/lib/core/api/threatModel.d.ts +1 -0
- package/build/lib/core/api/trajectoryExport.d.ts +38 -0
- package/build/lib/core/api/vulnerabilityReproduction.d.ts +10 -0
- package/build/lib/core/assets/wordlists.d.ts +31 -0
- package/build/lib/core/atif/convert.d.ts +27 -0
- package/build/lib/core/atif/index.d.ts +7 -0
- package/build/lib/core/atif/schema.d.ts +459 -0
- package/build/lib/core/atif/serialize.d.ts +2 -0
- package/build/lib/core/atif/test-fixtures.d.ts +28 -0
- package/build/lib/core/atif/validate.d.ts +12 -0
- package/build/lib/core/auth/connection.d.ts +12 -0
- package/build/lib/core/auth/device-flow.d.ts +38 -0
- package/build/lib/core/auth/gateway.d.ts +25 -0
- package/build/lib/core/auth/index.d.ts +8 -0
- package/build/lib/core/auth/signing.d.ts +14 -0
- package/build/lib/core/auth/token.d.ts +17 -0
- package/build/lib/core/auth/types.d.ts +85 -0
- package/build/lib/core/auth/workspaces.d.ts +34 -0
- package/build/lib/core/benchmark/index.d.ts +3 -0
- package/build/lib/core/benchmark/report.d.ts +3 -0
- package/build/lib/core/benchmark/runner.d.ts +3 -0
- package/build/lib/core/benchmark/types.d.ts +80 -0
- package/build/lib/core/cli/logLevelArgs.d.ts +18 -0
- package/build/lib/core/cli/model.d.ts +9 -0
- package/build/lib/core/cli/pentestMode.d.ts +5 -0
- package/build/lib/core/cli/tuiArgs.d.ts +5 -0
- package/build/lib/core/config/config.d.ts +86 -0
- package/build/lib/core/config/customProviders.d.ts +62 -0
- package/build/lib/core/config/index.d.ts +6 -0
- package/build/lib/core/config/index.js +6 -0
- package/build/lib/core/credentials/index.d.ts +2 -0
- package/build/lib/core/credentials/manager.d.ts +85 -0
- package/build/lib/core/credentials/types.d.ts +79 -0
- package/build/lib/core/doctor.d.ts +1 -0
- package/build/lib/core/eventBus.d.ts +195 -0
- package/build/lib/core/eventBus.js +6 -0
- package/build/lib/core/findings/attackSurfaceRegistry.d.ts +88 -0
- package/build/lib/core/findings/attackSurfaceRegistry.js +6 -0
- package/build/lib/core/findings/registry.d.ts +177 -0
- package/build/lib/core/findings/registry.js +21 -0
- package/build/lib/core/history.d.ts +23 -0
- package/build/lib/core/hoonify.d.ts +8 -0
- package/build/lib/core/http/parse.d.ts +50 -0
- package/build/lib/core/http/redirects.d.ts +23 -0
- package/build/lib/core/http/targetHeaders.d.ts +30 -0
- package/build/lib/core/http/targetScope.d.ts +12 -0
- package/build/lib/core/http/types.d.ts +11 -0
- package/build/lib/core/id/id.d.ts +60 -0
- package/build/lib/core/id/id.js +28 -0
- package/build/lib/core/installation/index.d.ts +25 -0
- package/build/lib/core/integrations/herdr.d.ts +13 -0
- package/build/lib/core/integrations/surface/index.d.ts +37 -0
- package/build/lib/core/integrations/surface/types.d.ts +22 -0
- package/build/lib/core/integrations/wandb/client.d.ts +23 -0
- package/build/lib/core/integrations/wandb/upload.d.ts +36 -0
- package/build/lib/core/logger/index.d.ts +62 -0
- package/build/lib/core/logger/structured.d.ts +30 -0
- package/build/lib/core/memory/index.d.ts +92 -0
- package/build/lib/core/memory/index.js +21 -0
- package/build/lib/core/messages/types.d.ts +96 -0
- package/build/lib/core/obfuscation/engine.d.ts +51 -0
- package/build/lib/core/obfuscation/index.d.ts +20 -0
- package/build/lib/core/observability/active-root-spans.d.ts +5 -0
- package/build/lib/core/observability/active-spans.d.ts +22 -0
- package/build/lib/core/observability/index.d.ts +36 -0
- package/build/lib/core/observability/index.js +27 -0
- package/build/lib/core/observability/runtime.d.ts +63 -0
- package/build/lib/core/observability/telemetry.d.ts +52 -0
- package/build/lib/core/observability/testkit.d.ts +24 -0
- package/build/lib/core/operator/approvalGate.d.ts +61 -0
- package/build/lib/core/operator/index.d.ts +9 -0
- package/build/lib/core/operator/types.d.ts +167 -0
- package/build/lib/core/plan/index.d.ts +16 -0
- package/build/lib/core/prompt-injections/index.d.ts +111 -0
- package/build/lib/core/prompt-injections/index.js +24 -0
- package/build/lib/core/providers/index.d.ts +5 -0
- package/build/lib/core/providers/types.d.ts +13 -0
- package/build/lib/core/providers/utils.d.ts +15 -0
- package/build/lib/core/providers/verify.d.ts +11 -0
- package/build/lib/core/report/builder.d.ts +9 -0
- package/build/lib/core/report/index.d.ts +7 -0
- package/build/lib/core/report/renderers/json.d.ts +2 -0
- package/build/lib/core/report/renderers/markdown.d.ts +2 -0
- package/build/lib/core/report/schemas.d.ts +115 -0
- package/build/lib/core/runtime/agentExecution.d.ts +15 -0
- package/build/lib/core/runtime/launchLocalWorker.d.ts +33 -0
- package/build/lib/core/runtime/localRunLock.d.ts +9 -0
- package/build/lib/core/runtime/localRunWorker.d.ts +18 -0
- package/build/lib/core/runtime/localWorkerEndpoint.d.ts +14 -0
- package/build/lib/core/runtime/localWorkerProtocol.d.ts +294 -0
- package/build/lib/core/runtime/localWorkerTransport.d.ts +30 -0
- package/build/lib/core/runtime/persistenceError.d.ts +9 -0
- package/build/lib/core/runtime/recordedExecution.d.ts +6 -0
- package/build/lib/core/runtime/recordedRunClient.d.ts +34 -0
- package/build/lib/core/runtime/runCheckpointStore.d.ts +11 -0
- package/build/lib/core/runtime/runContext.d.ts +48 -0
- package/build/lib/core/runtime/runControl.d.ts +44 -0
- package/build/lib/core/runtime/runControlStore.d.ts +83 -0
- package/build/lib/core/runtime/runDeadline.d.ts +4 -0
- package/build/lib/core/runtime/runEvidence.d.ts +37 -0
- package/build/lib/core/runtime/runInference.d.ts +9 -0
- package/build/lib/core/runtime/runModelStore.d.ts +27 -0
- package/build/lib/core/runtime/runObservation.d.ts +19 -0
- package/build/lib/core/runtime/runRecoveryContext.d.ts +20 -0
- package/build/lib/core/runtime/runRecoveryPlan.d.ts +38 -0
- package/build/lib/core/runtime/runRecoveryStore.d.ts +77 -0
- package/build/lib/core/runtime/runStore.d.ts +133 -0
- package/build/lib/core/runtime/runStorePath.d.ts +1 -0
- package/build/lib/core/runtime/runToolStore.d.ts +50 -0
- package/build/lib/core/runtime/runTools.d.ts +16 -0
- package/build/lib/core/runtime/sqliteControlStore.d.ts +41 -0
- package/build/lib/core/runtime/sqliteModelStore.d.ts +20 -0
- package/build/lib/core/runtime/sqliteRecoveryStore.d.ts +35 -0
- package/build/lib/core/runtime/sqliteRunStore.d.ts +8 -0
- package/build/lib/core/runtime/sqliteToolStore.d.ts +30 -0
- package/build/lib/core/runtime/testfixtures/localWorkerChild.d.ts +1 -0
- package/build/lib/core/runtime/testfixtures/localWorkerLauncher.d.ts +1 -0
- package/build/lib/core/runtime/testfixtures/recoveryChild.d.ts +1 -0
- package/build/lib/core/services/rateLimiter/index.d.ts +36 -0
- package/build/lib/core/services/rateLimiter/types.d.ts +10 -0
- package/build/lib/core/session/execution-metrics.d.ts +37 -0
- package/build/lib/core/session/index.d.ts +586 -0
- package/build/lib/core/session/index.js +36 -0
- package/build/lib/core/session/loader.d.ts +30 -0
- package/build/lib/core/session/persistence.d.ts +215 -0
- package/build/lib/core/session/persistence.js +35 -0
- package/build/lib/core/session/types.d.ts +59 -0
- package/build/lib/core/session/usage.d.ts +37 -0
- package/build/lib/core/skills/builtins/index.d.ts +13 -0
- package/build/lib/core/skills/builtins/pentest.d.ts +19 -0
- package/build/lib/core/skills/builtins/promptInjection.d.ts +2 -0
- package/build/lib/core/skills/builtins/threatModel.d.ts +11 -0
- package/build/lib/core/skills/index.d.ts +5 -0
- package/build/lib/core/skills/parser.d.ts +11 -0
- package/build/lib/core/skills/registry.d.ts +30 -0
- package/build/lib/core/skills/scanner.d.ts +12 -0
- package/build/lib/core/skills/types.d.ts +44 -0
- package/build/lib/core/skills/utils.d.ts +6 -0
- package/build/lib/core/storage/index.d.ts +248 -0
- package/build/lib/core/tasks/index.d.ts +78 -0
- package/build/lib/core/tools/backends/capture.d.ts +10 -0
- package/build/lib/core/tools/backends/collectCommand.d.ts +9 -0
- package/build/lib/core/tools/backends/helpers.d.ts +43 -0
- package/build/lib/core/tools/backends/httpTransport.d.ts +18 -0
- package/build/lib/core/tools/backends/index.d.ts +8 -0
- package/build/lib/core/tools/backends/index.js +31 -0
- package/build/lib/core/tools/backends/local.d.ts +11 -0
- package/build/lib/core/tools/backends/policy.d.ts +39 -0
- package/build/lib/core/tools/backends/resolve.d.ts +25 -0
- package/build/lib/core/tools/backends/types.d.ts +240 -0
- package/build/lib/core/tools/backends/whitebox.d.ts +6 -0
- package/build/lib/core/tools/backends/whiteboxJobs.d.ts +18 -0
- package/build/lib/core/tools/backends/windowsProgram.d.ts +4 -0
- package/build/lib/core/tools/daytonaSandbox.d.ts +14 -0
- package/build/lib/core/toolset/index.d.ts +28 -0
- package/build/lib/core/util/lazyLogger.d.ts +16 -0
- package/build/lib/core/utils/concurrency.d.ts +16 -0
- package/build/lib/core/utils/prompt.d.ts +12 -0
- package/build/lib/core/whitebox/adapters.d.ts +29 -0
- package/build/lib/core/whitebox/artifacts.d.ts +32 -0
- package/build/lib/core/whitebox/boundedProcess.d.ts +35 -0
- package/build/lib/core/whitebox/candidates.d.ts +29 -0
- package/build/lib/core/whitebox/catalog.d.ts +10 -0
- package/build/lib/core/whitebox/index.d.ts +9 -0
- package/build/lib/core/whitebox/jobKernel.d.ts +33 -0
- package/build/lib/core/whitebox/jobSupervisor.d.ts +14 -0
- package/build/lib/core/whitebox/jobs.d.ts +17 -0
- package/build/lib/core/whitebox/paths.d.ts +22 -0
- package/build/lib/core/whitebox/profileTransport.d.ts +10 -0
- package/build/lib/core/whitebox/profiles.d.ts +3 -0
- package/build/lib/core/whitebox/repoProfile.d.ts +4 -0
- package/build/lib/core/whitebox/types.d.ts +108 -0
- package/build/lib/core/workflows/fastStrike.d.ts +4 -0
- package/build/lib/core/workflows/pentest.d.ts +167 -0
- package/build/lib/core/workflows/pentest.js +42 -0
- package/build/lib/core/workflows/seams.d.ts +102 -0
- package/build/lib/core/workflows/seams.js +37 -0
- package/build/lib/core/workflows/threatModel.d.ts +26 -0
- package/build/lib/core/workflows/whiteboxAttackSurface.d.ts +142 -0
- package/build/lib/core/workflows/whiteboxAttackSurface.js +36 -0
- package/build/lib/index.d.ts +26 -0
- package/build/lib/index.js +96 -0
- package/build/lib/lib/attack-path/types.d.ts +9 -0
- package/build/lib/lib/cvss/calculator.d.ts +31 -0
- package/build/lib/lib/cvss/index.d.ts +24 -0
- package/build/lib/lib/cvss/index.js +24 -0
- package/build/lib/lib/cvss/macrovector-scores.d.ts +59 -0
- package/build/lib/lib/cvss/types.d.ts +114 -0
- package/build/lib/lib/cvss/types.js +8 -0
- package/build/lib/lib/cwe/cwe-catalog.d.ts +13 -0
- package/build/lib/lib/cwe/types.d.ts +28 -0
- package/build/lib/lib/cwe/validate.d.ts +15 -0
- package/build/lib/lib/evidence/types.d.ts +12 -0
- package/build/lib/util/errors.d.ts +186 -0
- package/build/lib/util/lock.d.ts +2 -0
- package/build/lib/util/name.d.ts +14 -0
- package/build/lib/util/url.d.ts +40 -0
- package/build/{logs-wzr5176k.js → logs-v5503qqk.js} +22 -30
- package/build/{multipart-parser-g2xxkezz.js → multipart-parser-vjjdbpd1.js} +10 -10
- package/build/native-rollout-evidence-1qwze8nm.js +135 -0
- package/build/offesecAgent-w5a2r0wa.js +22 -0
- package/build/{parse-rtccymzn.js → parse-cqecqrc5.js} +0 -4
- package/build/pentest-fxya42cg.js +22 -0
- package/build/pentests-6qntz6wz.js +143 -0
- package/build/recordedRunClient-rtdeagzx.js +11 -0
- package/build/{targetedPentest-tdwtgmxm.js → targetedPentest-khnxcvmb.js} +22 -22
- package/build/{targets-763n91t7.js → targets-ty7dahv4.js} +24 -32
- package/build/threatModel-28ayxe0n.js +21 -0
- package/build/{token-3bbp59y6.js → token-mk7t8y0y.js} +2 -2
- package/build/{token-util-6xjme11b.js → token-util-vd776hrv.js} +1 -2
- package/build/{uninstall-d33159cz.js → uninstall-nrhvt32a.js} +3 -3
- package/build/{upload-9qj1kpt9.js → upload-sx9gth59.js} +8 -14
- package/build/{utils-t7gc2903.js → utils-qetcfvgg.js} +29 -29
- package/package.json +230 -5
- package/src/cli/agent-runs.attach.test.ts +359 -0
- package/src/cli/agent-runs.test.ts +1172 -0
- package/src/cli/agent-runs.ts +430 -0
- package/src/cli/apps.test.ts +63 -0
- package/src/cli/apps.ts +526 -0
- package/src/cli/auth.ts +375 -0
- package/src/cli/command-exit.test.ts +15 -0
- package/src/cli/command-exit.ts +3 -0
- package/src/cli/config.ts +210 -0
- package/src/cli/export-trajectory.test.ts +224 -0
- package/src/cli/export-trajectory.ts +119 -0
- package/src/cli/fixes.ts +56 -0
- package/src/cli/issues.test.ts +214 -0
- package/src/cli/issues.ts +242 -0
- package/src/cli/json-output.test.ts +62 -0
- package/src/cli/knowledge.test.ts +140 -0
- package/src/cli/knowledge.ts +146 -0
- package/src/cli/launcher.test.ts +81 -0
- package/src/cli/logs.ts +111 -0
- package/src/cli/native-rollout-evidence.test.ts +322 -0
- package/src/cli/native-rollout-evidence.ts +206 -0
- package/src/cli/pentests.test.ts +194 -0
- package/src/cli/pentests.ts +159 -0
- package/src/cli/resume.test.ts +107 -0
- package/src/cli/targets.ts +125 -0
- package/src/cli/uninstall.ts +302 -0
- package/src/cli.ts +882 -0
- package/src/core/agents/agentRuntime.test.ts +242 -0
- package/src/core/agents/agentRuntime.ts +120 -0
- package/src/core/agents/defineAgent.ts +134 -0
- package/src/core/agents/offSecAgent/index.ts +162 -0
- package/src/core/agents/offSecAgent/interruptedStepFinalization.test.ts +295 -0
- package/src/core/agents/offSecAgent/interruptedStepFinalization.ts +162 -0
- package/src/core/agents/offSecAgent/interruptedStepMessages.test.ts +296 -0
- package/src/core/agents/offSecAgent/interruptedStepMessages.ts +137 -0
- package/src/core/agents/offSecAgent/messagePersistence.test.ts +281 -0
- package/src/core/agents/offSecAgent/messagePersistence.ts +111 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.runtimeContext.test.ts +689 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.test.ts +2899 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.ts +1610 -0
- package/src/core/agents/offSecAgent/prompt.test.ts +72 -0
- package/src/core/agents/offSecAgent/prompt.ts +368 -0
- package/src/core/agents/offSecAgent/recordedTools.test.ts +580 -0
- package/src/core/agents/offSecAgent/recordedTools.ts +162 -0
- package/src/core/agents/offSecAgent/runtimeContext.test.ts +531 -0
- package/src/core/agents/offSecAgent/runtimeContext.ts +387 -0
- package/src/core/agents/offSecAgent/selectiveConstruction.publicPath.test.ts +295 -0
- package/src/core/agents/offSecAgent/selectiveConstruction.test.ts +498 -0
- package/src/core/agents/offSecAgent/streamDiagnostics.test.ts +310 -0
- package/src/core/agents/offSecAgent/streamDiagnostics.ts +237 -0
- package/src/core/agents/offSecAgent/subagentSpawner.hooks.test.ts +102 -0
- package/src/core/agents/offSecAgent/subagentSpawner.test.ts +384 -0
- package/src/core/agents/offSecAgent/subagentSpawner.ts +664 -0
- package/src/core/agents/offSecAgent/toolLifecycle.test.ts +199 -0
- package/src/core/agents/offSecAgent/toolLifecycle.ts +171 -0
- package/src/core/agents/offSecAgent/tools/__tests__/sandboxScript.ts +14 -0
- package/src/core/agents/offSecAgent/tools/addMemory.ts +87 -0
- package/src/core/agents/offSecAgent/tools/agentScratch.test.ts +36 -0
- package/src/core/agents/offSecAgent/tools/agentScratch.ts +23 -0
- package/src/core/agents/offSecAgent/tools/applyPatch.test.ts +546 -0
- package/src/core/agents/offSecAgent/tools/applyPatch.ts +58 -0
- package/src/core/agents/offSecAgent/tools/applyPatchImpl.ts +300 -0
- package/src/core/agents/offSecAgent/tools/askUserQuestions.ts +81 -0
- package/src/core/agents/offSecAgent/tools/authBackendStatus.test.ts +112 -0
- package/src/core/agents/offSecAgent/tools/browserHeaderRouting.test.ts +136 -0
- package/src/core/agents/offSecAgent/tools/browserHeaderRouting.ts +81 -0
- package/src/core/agents/offSecAgent/tools/browserToolFactories.ts +372 -0
- package/src/core/agents/offSecAgent/tools/browserTools.test.ts +243 -0
- package/src/core/agents/offSecAgent/tools/browserTools.ts +285 -0
- package/src/core/agents/offSecAgent/tools/callbackListener.test.ts +1011 -0
- package/src/core/agents/offSecAgent/tools/callbackListener.ts +1038 -0
- package/src/core/agents/offSecAgent/tools/camoufox.test.ts +119 -0
- package/src/core/agents/offSecAgent/tools/camoufox.ts +199 -0
- package/src/core/agents/offSecAgent/tools/checkpointState.ts +79 -0
- package/src/core/agents/offSecAgent/tools/codingTools.windows.test.ts +625 -0
- package/src/core/agents/offSecAgent/tools/completeAuthentication.ts +136 -0
- package/src/core/agents/offSecAgent/tools/crawlAuthenticated.test.ts +267 -0
- package/src/core/agents/offSecAgent/tools/crawlAuthenticated.ts +170 -0
- package/src/core/agents/offSecAgent/tools/createAttackSurfaceReport.ts +75 -0
- package/src/core/agents/offSecAgent/tools/createFile.test.ts +111 -0
- package/src/core/agents/offSecAgent/tools/createFile.ts +44 -0
- package/src/core/agents/offSecAgent/tools/createTask.ts +118 -0
- package/src/core/agents/offSecAgent/tools/delegateAuth.ts +391 -0
- package/src/core/agents/offSecAgent/tools/deleteFile.test.ts +102 -0
- package/src/core/agents/offSecAgent/tools/deleteFile.ts +39 -0
- package/src/core/agents/offSecAgent/tools/destructiveGuard.test.ts +827 -0
- package/src/core/agents/offSecAgent/tools/destructiveGuard.ts +747 -0
- package/src/core/agents/offSecAgent/tools/detectAuthScheme.ts +191 -0
- package/src/core/agents/offSecAgent/tools/documentApp.ts +242 -0
- package/src/core/agents/offSecAgent/tools/documentEndpoint.ts +291 -0
- package/src/core/agents/offSecAgent/tools/documentFinding.test.ts +2091 -0
- package/src/core/agents/offSecAgent/tools/documentFinding.ts +1240 -0
- package/src/core/agents/offSecAgent/tools/email/adapters.test.ts +279 -0
- package/src/core/agents/offSecAgent/tools/email/adapters.ts +1121 -0
- package/src/core/agents/offSecAgent/tools/email/getAttachments.ts +73 -0
- package/src/core/agents/offSecAgent/tools/email/getMessage.ts +56 -0
- package/src/core/agents/offSecAgent/tools/email/inboxBackend.test.ts +137 -0
- package/src/core/agents/offSecAgent/tools/email/index.ts +55 -0
- package/src/core/agents/offSecAgent/tools/email/listInboxes.ts +47 -0
- package/src/core/agents/offSecAgent/tools/email/listMessages.ts +67 -0
- package/src/core/agents/offSecAgent/tools/email/markRead.ts +57 -0
- package/src/core/agents/offSecAgent/tools/email/searchMessages.ts +76 -0
- package/src/core/agents/offSecAgent/tools/email/sendEmail.ts +165 -0
- package/src/core/agents/offSecAgent/tools/email/types.ts +45 -0
- package/src/core/agents/offSecAgent/tools/executeCommand.backends.test.ts +171 -0
- package/src/core/agents/offSecAgent/tools/executeCommand.test.ts +1153 -0
- package/src/core/agents/offSecAgent/tools/executeCommand.ts +604 -0
- package/src/core/agents/offSecAgent/tools/extractJsEndpoints.ts +44 -0
- package/src/core/agents/offSecAgent/tools/fileBackends.test.ts +66 -0
- package/src/core/agents/offSecAgent/tools/fileMutations.test.ts +159 -0
- package/src/core/agents/offSecAgent/tools/fileToolBackendPurity.test.ts +72 -0
- package/src/core/agents/offSecAgent/tools/fileWorkspace.test.ts +357 -0
- package/src/core/agents/offSecAgent/tools/fileWorkspace.ts +434 -0
- package/src/core/agents/offSecAgent/tools/fileWorkspaceRemote.ts +263 -0
- package/src/core/agents/offSecAgent/tools/getMemory.ts +69 -0
- package/src/core/agents/offSecAgent/tools/getPage.test.ts +1127 -0
- package/src/core/agents/offSecAgent/tools/getPage.ts +70 -0
- package/src/core/agents/offSecAgent/tools/gitDiff.ts +67 -0
- package/src/core/agents/offSecAgent/tools/gitStatus.ts +61 -0
- package/src/core/agents/offSecAgent/tools/gitTools.test.ts +237 -0
- package/src/core/agents/offSecAgent/tools/glob.test.ts +695 -0
- package/src/core/agents/offSecAgent/tools/glob.ts +51 -0
- package/src/core/agents/offSecAgent/tools/globImpl.ts +313 -0
- package/src/core/agents/offSecAgent/tools/globPattern.ts +203 -0
- package/src/core/agents/offSecAgent/tools/grep.test.ts +922 -0
- package/src/core/agents/offSecAgent/tools/grep.ts +73 -0
- package/src/core/agents/offSecAgent/tools/grepImpl.ts +718 -0
- package/src/core/agents/offSecAgent/tools/httpBackends.test.ts +534 -0
- package/src/core/agents/offSecAgent/tools/httpRequest.test.ts +2409 -0
- package/src/core/agents/offSecAgent/tools/httpRequest.ts +425 -0
- package/src/core/agents/offSecAgent/tools/index.ts +787 -0
- package/src/core/agents/offSecAgent/tools/listFiles.bounded.test.ts +514 -0
- package/src/core/agents/offSecAgent/tools/listFiles.public-counters.test.ts +163 -0
- package/src/core/agents/offSecAgent/tools/listFiles.test.ts +521 -0
- package/src/core/agents/offSecAgent/tools/listFiles.ts +49 -0
- package/src/core/agents/offSecAgent/tools/listFilesImpl.ts +351 -0
- package/src/core/agents/offSecAgent/tools/listMemories.ts +71 -0
- package/src/core/agents/offSecAgent/tools/listPromptInjections.test.ts +201 -0
- package/src/core/agents/offSecAgent/tools/listPromptInjections.ts +78 -0
- package/src/core/agents/offSecAgent/tools/listTasks.ts +100 -0
- package/src/core/agents/offSecAgent/tools/patchApply.test.ts +573 -0
- package/src/core/agents/offSecAgent/tools/patchApply.ts +430 -0
- package/src/core/agents/offSecAgent/tools/patchParse.test.ts +383 -0
- package/src/core/agents/offSecAgent/tools/patchParse.ts +354 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.drain.test.ts +109 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.test.ts +565 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.ts +516 -0
- package/src/core/agents/offSecAgent/tools/perCommandShell.windows.test.ts +142 -0
- package/src/core/agents/offSecAgent/tools/playwrightMcp.test.ts +778 -0
- package/src/core/agents/offSecAgent/tools/playwrightMcp.ts +1426 -0
- package/src/core/agents/offSecAgent/tools/probeAuthEndpoints.ts +262 -0
- package/src/core/agents/offSecAgent/tools/profileCodebase.ts +110 -0
- package/src/core/agents/offSecAgent/tools/provideComparisonResults.ts +106 -0
- package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.coalescing-cost.test.ts +108 -0
- package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.test.ts +183 -0
- package/src/core/agents/offSecAgent/tools/queryWhiteboxCatalog.ts +143 -0
- package/src/core/agents/offSecAgent/tools/readFile.test.ts +1242 -0
- package/src/core/agents/offSecAgent/tools/readFile.ts +89 -0
- package/src/core/agents/offSecAgent/tools/readFileImpl.ts +956 -0
- package/src/core/agents/offSecAgent/tools/readSkill.ts +38 -0
- package/src/core/agents/offSecAgent/tools/reportError.test.ts +48 -0
- package/src/core/agents/offSecAgent/tools/reportError.ts +65 -0
- package/src/core/agents/offSecAgent/tools/response.ts +27 -0
- package/src/core/agents/offSecAgent/tools/runAttackSurface.ts +198 -0
- package/src/core/agents/offSecAgent/tools/runCodeQuery.test.ts +82 -0
- package/src/core/agents/offSecAgent/tools/runCodeQuery.ts +237 -0
- package/src/core/agents/offSecAgent/tools/runPentestWorkflow.ts +122 -0
- package/src/core/agents/offSecAgent/tools/runWhiteboxScan.ts +189 -0
- package/src/core/agents/offSecAgent/tools/runtimeBackendConsumers.test.ts +143 -0
- package/src/core/agents/offSecAgent/tools/sandbox.ts +37 -0
- package/src/core/agents/offSecAgent/tools/sandboxPlaywright.test.ts +235 -0
- package/src/core/agents/offSecAgent/tools/sandboxPlaywright.ts +1029 -0
- package/src/core/agents/offSecAgent/tools/sandboxScript.test.ts +31 -0
- package/src/core/agents/offSecAgent/tools/sandboxScript.ts +60 -0
- package/src/core/agents/offSecAgent/tools/scopeGuard.test.ts +574 -0
- package/src/core/agents/offSecAgent/tools/scopeGuard.ts +317 -0
- package/src/core/agents/offSecAgent/tools/scriptSyntaxCheck.test.ts +566 -0
- package/src/core/agents/offSecAgent/tools/scriptSyntaxCheck.ts +240 -0
- package/src/core/agents/offSecAgent/tools/selectiveFactories.test.ts +476 -0
- package/src/core/agents/offSecAgent/tools/smsInbox.ts +130 -0
- package/src/core/agents/offSecAgent/tools/smsListMessages.test.ts +443 -0
- package/src/core/agents/offSecAgent/tools/smsListMessages.ts +123 -0
- package/src/core/agents/offSecAgent/tools/spawnCodingAgent.ts +229 -0
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.test.ts +413 -0
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.ts +266 -0
- package/src/core/agents/offSecAgent/tools/spawnPentestSwarm.ts +146 -0
- package/src/core/agents/offSecAgent/tools/submitPlan.ts +51 -0
- package/src/core/agents/offSecAgent/tools/testEndpointVariations.ts +127 -0
- package/src/core/agents/offSecAgent/tools/threatModelGenerator.ts +664 -0
- package/src/core/agents/offSecAgent/tools/toolOutput.test.ts +480 -0
- package/src/core/agents/offSecAgent/tools/toolOutput.ts +160 -0
- package/src/core/agents/offSecAgent/tools/types.ts +267 -0
- package/src/core/agents/offSecAgent/tools/updateFile.ts +121 -0
- package/src/core/agents/offSecAgent/tools/updateTask.ts +107 -0
- package/src/core/agents/offSecAgent/tools/validateDiscovery.ts +123 -0
- package/src/core/agents/offSecAgent/tools/webSearch.ts +265 -0
- package/src/core/agents/offSecAgent/tools/whiteboxCandidates.ts +197 -0
- package/src/core/agents/offSecAgent/tools/whiteboxJobs.ts +312 -0
- package/src/core/agents/offSecAgent/tools/windowsCurl.test.ts +801 -0
- package/src/core/agents/offSecAgent/tools/windowsCurl.ts +202 -0
- package/src/core/agents/offSecAgent/tools/workspaceApps.test.ts +257 -0
- package/src/core/agents/offSecAgent/tools/workspaceApps.ts +334 -0
- package/src/core/agents/offSecAgent/tools/workspaceDomains.test.ts +113 -0
- package/src/core/agents/offSecAgent/tools/workspaceDomains.ts +57 -0
- package/src/core/agents/offSecAgent/tools/workspaceFailure.ts +11 -0
- package/src/core/agents/offSecAgent/tools/writePlan.ts +65 -0
- package/src/core/agents/offSecAgent/trace.test.ts +796 -0
- package/src/core/agents/offSecAgent/trace.ts +633 -0
- package/src/core/agents/offSecAgent/types.test.ts +224 -0
- package/src/core/agents/offSecAgent/types.ts +676 -0
- package/src/core/agents/specialized/attackSurface/blackboxAgent.test.ts +31 -0
- package/src/core/agents/specialized/attackSurface/blackboxAgent.ts +272 -0
- package/src/core/agents/specialized/attackSurface/blackboxRiskScoring.ts +276 -0
- package/src/core/agents/specialized/attackSurface/grpcSchema.ts +142 -0
- package/src/core/agents/specialized/attackSurface/jsExtraction.test.ts +237 -0
- package/src/core/agents/specialized/attackSurface/jsExtraction.ts +174 -0
- package/src/core/agents/specialized/attackSurface/prompts.ts +349 -0
- package/src/core/agents/specialized/attackSurface/schemas.ts +300 -0
- package/src/core/agents/specialized/attackSurface/types.ts +100 -0
- package/src/core/agents/specialized/authenticationAgent/agent.test.ts +111 -0
- package/src/core/agents/specialized/authenticationAgent/agent.ts +300 -0
- package/src/core/agents/specialized/authenticationAgent/index.ts +74 -0
- package/src/core/agents/specialized/authenticationAgent/prompts.test.ts +36 -0
- package/src/core/agents/specialized/authenticationAgent/prompts.ts +645 -0
- package/src/core/agents/specialized/authenticationAgent/types.ts +833 -0
- package/src/core/agents/specialized/benchmark/comparisonAgent.ts +344 -0
- package/src/core/agents/specialized/benchmark/docker-utils.ts +257 -0
- package/src/core/agents/specialized/benchmark/flag-detector.ts +686 -0
- package/src/core/agents/specialized/benchmark/index.ts +28 -0
- package/src/core/agents/specialized/benchmark/prompts.ts +257 -0
- package/src/core/agents/specialized/benchmark/remote/circuit-breaker.ts +108 -0
- package/src/core/agents/specialized/benchmark/remote/daytona-wrapper.ts +1005 -0
- package/src/core/agents/specialized/benchmark/remote/index.ts +2 -0
- package/src/core/agents/specialized/benchmark/types.ts +98 -0
- package/src/core/agents/specialized/benchmarkComparisonAgent.test.ts +111 -0
- package/src/core/agents/specialized/benchmarkComparisonAgent.ts +203 -0
- package/src/core/agents/specialized/codeAgent/agent.test.ts +89 -0
- package/src/core/agents/specialized/codeAgent/agent.ts +134 -0
- package/src/core/agents/specialized/codeAgent/prompts.ts +48 -0
- package/src/core/agents/specialized/codeAgent/schemas.ts +33 -0
- package/src/core/agents/specialized/cvssScorer/index.test.ts +87 -0
- package/src/core/agents/specialized/cvssScorer/index.ts +546 -0
- package/src/core/agents/specialized/environment/agent.ts +75 -0
- package/src/core/agents/specialized/environment/index.ts +16 -0
- package/src/core/agents/specialized/environment/prompts.ts +194 -0
- package/src/core/agents/specialized/environment/types.ts +48 -0
- package/src/core/agents/specialized/findingJudge/agent.test.ts +114 -0
- package/src/core/agents/specialized/findingJudge/agent.ts +59 -0
- package/src/core/agents/specialized/findingJudge/index.test.ts +155 -0
- package/src/core/agents/specialized/findingJudge/index.ts +166 -0
- package/src/core/agents/specialized/findingJudge/prompts.ts +140 -0
- package/src/core/agents/specialized/findingJudge/types.ts +115 -0
- package/src/core/agents/specialized/googleSignInPrompt.test.ts +29 -0
- package/src/core/agents/specialized/googleSignInPrompt.ts +18 -0
- package/src/core/agents/specialized/mobileOtpPrompt.ts +9 -0
- package/src/core/agents/specialized/patching/agent.test.ts +220 -0
- package/src/core/agents/specialized/patching/agent.ts +146 -0
- package/src/core/agents/specialized/patching/index.ts +20 -0
- package/src/core/agents/specialized/patching/prompts.test.ts +172 -0
- package/src/core/agents/specialized/patching/prompts.ts +396 -0
- package/src/core/agents/specialized/patching/types.ts +49 -0
- package/src/core/agents/specialized/pentest/agent.test.ts +1046 -0
- package/src/core/agents/specialized/pentest/agent.ts +1482 -0
- package/src/core/agents/specialized/pentest/helperLifecycle.test.ts +425 -0
- package/src/core/agents/specialized/pentest/helperWorkspace.test.ts +84 -0
- package/src/core/agents/specialized/pentest/helperWorkspace.ts +33 -0
- package/src/core/agents/specialized/pentest/planPrompt.ts +68 -0
- package/src/core/agents/specialized/pentest/results.test.ts +198 -0
- package/src/core/agents/specialized/utils.test.ts +16 -0
- package/src/core/agents/specialized/utils.ts +28 -0
- package/src/core/agents/specialized/vulnerabilityReproduction/agent.test.ts +195 -0
- package/src/core/agents/specialized/vulnerabilityReproduction/agent.ts +159 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/agent.test.ts +39 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/agent.ts +227 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.concurrency.test.ts +138 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.test.ts +199 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.ts +330 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/index.ts +24 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/prompts.ts +345 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/types.test.ts +67 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/types.ts +234 -0
- package/src/core/ai/ai.contract.test.ts +43 -0
- package/src/core/ai/ai.durability-hooks.test.ts +527 -0
- package/src/core/ai/ai.effective-tools.test.ts +739 -0
- package/src/core/ai/ai.native-rollout-evidence.test.ts +373 -0
- package/src/core/ai/ai.outer-catch-recovery.test.ts +82 -0
- package/src/core/ai/ai.proactive-recovery.test.ts +69 -0
- package/src/core/ai/ai.recorded-attempts.test.ts +621 -0
- package/src/core/ai/ai.recorded-context.test.ts +448 -0
- package/src/core/ai/ai.recorded-tools.test.ts +850 -0
- package/src/core/ai/ai.request-retention.test.ts +296 -0
- package/src/core/ai/ai.test.ts +690 -0
- package/src/core/ai/ai.ts +2377 -0
- package/src/core/ai/caching.test.ts +179 -0
- package/src/core/ai/caching.ts +119 -0
- package/src/core/ai/compactionEvidence.test.ts +52 -0
- package/src/core/ai/compactionEvidence.ts +101 -0
- package/src/core/ai/compactionTelemetry.test.ts +621 -0
- package/src/core/ai/compactionTelemetry.ts +287 -0
- package/src/core/ai/concentrate.test.ts +28 -0
- package/src/core/ai/contextManagement.test.ts +350 -0
- package/src/core/ai/contextManagement.ts +594 -0
- package/src/core/ai/index.ts +73 -0
- package/src/core/ai/inference-attempt/adapters.test.ts +84 -0
- package/src/core/ai/inference-attempt/adapters.ts +391 -0
- package/src/core/ai/inference-attempt/attempt.test.ts +198 -0
- package/src/core/ai/inference-attempt/builder.ts +171 -0
- package/src/core/ai/inference-attempt/envelope.ts +120 -0
- package/src/core/ai/inference-attempt/errors.ts +15 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-cache-create.json +18 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-cache-read.json +18 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-incomplete.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-mixed.json +22 -0
- package/src/core/ai/inference-attempt/fixtures/anthropic-messages-non-cache.json +26 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-cache-create.json +18 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-cache-read.json +26 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-incomplete.json +19 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-mixed.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/bedrock-converse-non-cache.json +24 -0
- package/src/core/ai/inference-attempt/fixtures/openai-responses-cache-read.json +17 -0
- package/src/core/ai/inference-attempt/fixtures/openai-responses-incomplete.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/openai-responses-non-cache.json +23 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-rest-incomplete.json +21 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-rest-native.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-cache-create.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-cache-read.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-incomplete.json +16 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-mixed.json +21 -0
- package/src/core/ai/inference-attempt/fixtures/pensar-anthropic-stream-non-cache.json +19 -0
- package/src/core/ai/inference-attempt/fixtures/reject-cache-read-exceeds-inclusive.json +11 -0
- package/src/core/ai/inference-attempt/fixtures/reject-components-exceed-inclusive.json +12 -0
- package/src/core/ai/inference-attempt/fixtures/reject-identity-mismatch.json +13 -0
- package/src/core/ai/inference-attempt/fixtures/reject-negative-token.json +9 -0
- package/src/core/ai/inference-attempt/fixtures/reject-non-integer-token.json +8 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-cache-read.json +19 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-incomplete.json +15 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-mixed.json +20 -0
- package/src/core/ai/inference-attempt/fixtures/sdk-normalized-non-cache.json +16 -0
- package/src/core/ai/inference-attempt/identity.ts +25 -0
- package/src/core/ai/inference-attempt/index.ts +70 -0
- package/src/core/ai/inference-attempt/project.test.ts +118 -0
- package/src/core/ai/inference-attempt/project.ts +60 -0
- package/src/core/ai/inference-attempt/recording.ts +46 -0
- package/src/core/ai/inference-attempt/tokens.ts +165 -0
- package/src/core/ai/inference-attempt/validate.ts +20 -0
- package/src/core/ai/mantle.test.ts +50 -0
- package/src/core/ai/mantle.ts +45 -0
- package/src/core/ai/model-history.test.ts +53 -0
- package/src/core/ai/model-history.ts +38 -0
- package/src/core/ai/models/anthropic.ts +151 -0
- package/src/core/ai/models/bedrock.ts +618 -0
- package/src/core/ai/models/claude-capabilities.ts +43 -0
- package/src/core/ai/models/concentrate.ts +192 -0
- package/src/core/ai/models/google.ts +154 -0
- package/src/core/ai/models/inception.ts +10 -0
- package/src/core/ai/models/index.ts +253 -0
- package/src/core/ai/models/mantle.ts +14 -0
- package/src/core/ai/models/models.test.ts +313 -0
- package/src/core/ai/models/openai.ts +409 -0
- package/src/core/ai/models/openrouter.ts +342 -0
- package/src/core/ai/models/pensar.ts +66 -0
- package/src/core/ai/native-rollout-evidence/capture.test.ts +1836 -0
- package/src/core/ai/native-rollout-evidence/capture.ts +1572 -0
- package/src/core/ai/native-rollout-evidence/content.test.ts +55 -0
- package/src/core/ai/native-rollout-evidence/content.ts +129 -0
- package/src/core/ai/native-rollout-evidence/index.ts +68 -0
- package/src/core/ai/native-rollout-evidence/provider-metadata.test.ts +85 -0
- package/src/core/ai/native-rollout-evidence/provider-metadata.ts +129 -0
- package/src/core/ai/native-rollout-evidence/recording.test.ts +398 -0
- package/src/core/ai/native-rollout-evidence/schema.test.ts +210 -0
- package/src/core/ai/native-rollout-evidence/schema.ts +353 -0
- package/src/core/ai/native-rollout-evidence/validate.ts +141 -0
- package/src/core/ai/providers/anthropic-models.test.ts +348 -0
- package/src/core/ai/providers/anthropic.ts +73 -0
- package/src/core/ai/providers/bedrock-models.test.ts +81 -0
- package/src/core/ai/providers/concentrate.live.test.ts +71 -0
- package/src/core/ai/providers/concentrate.test.ts +160 -0
- package/src/core/ai/providers/concentrate.ts +145 -0
- package/src/core/ai/providers/custom.live.test.ts +42 -0
- package/src/core/ai/providers/custom.test.ts +474 -0
- package/src/core/ai/providers/custom.ts +70 -0
- package/src/core/ai/providers/gateway-models.test.ts +648 -0
- package/src/core/ai/providers/hoonify.live.test.ts +72 -0
- package/src/core/ai/providers/hoonify.test.ts +284 -0
- package/src/core/ai/providers/hoonify.ts +32 -0
- package/src/core/ai/providers/openai-models.test.ts +356 -0
- package/src/core/ai/providers/openai-pro-fetch.test.ts +64 -0
- package/src/core/ai/providers/openai-pro-fetch.ts +32 -0
- package/src/core/ai/providers/pensar.ts +645 -0
- package/src/core/ai/providers/pensarFormatters.test.ts +272 -0
- package/src/core/ai/providers/pensarFormatters.ts +533 -0
- package/src/core/ai/providers/pensarResponsesStream.test.ts +191 -0
- package/src/core/ai/providers/pensarResponsesStream.ts +294 -0
- package/src/core/ai/providers/pensarSSE.test.ts +83 -0
- package/src/core/ai/providers/pensarSSE.ts +128 -0
- package/src/core/ai/providers/pensarSigning.ts +2 -0
- package/src/core/ai/providers/pensarStreamUsage.test.ts +79 -0
- package/src/core/ai/providers/pensarStreamUsage.ts +62 -0
- package/src/core/ai/stepContext.test.ts +61 -0
- package/src/core/ai/streamIdleTimeout.test.ts +390 -0
- package/src/core/ai/streamTelemetry.ts +90 -0
- package/src/core/ai/usage-callback.test.ts +511 -0
- package/src/core/ai/utils.native-rollout-evidence.test.ts +135 -0
- package/src/core/ai/utils.pensar.test.ts +59 -0
- package/src/core/ai/utils.ts +795 -0
- package/src/core/api/apiClient.test.ts +58 -0
- package/src/core/api/apiClient.ts +73 -0
- package/src/core/api/apps.test.ts +78 -0
- package/src/core/api/apps.ts +388 -0
- package/src/core/api/attackSurface.test.ts +24 -0
- package/src/core/api/attackSurface.ts +89 -0
- package/src/core/api/authentication.ts +8 -0
- package/src/core/api/benchmark.ts +35 -0
- package/src/core/api/blackboxPentest.test.ts +89 -0
- package/src/core/api/blackboxPentest.ts +64 -0
- package/src/core/api/clientIdentity.test.ts +61 -0
- package/src/core/api/clientIdentity.ts +57 -0
- package/src/core/api/comments.test.ts +69 -0
- package/src/core/api/constants.ts +15 -0
- package/src/core/api/domains.test.ts +35 -0
- package/src/core/api/domains.ts +32 -0
- package/src/core/api/environment.ts +47 -0
- package/src/core/api/index.ts +219 -0
- package/src/core/api/issues.test.ts +82 -0
- package/src/core/api/issues.ts +439 -0
- package/src/core/api/knowledge.ts +70 -0
- package/src/core/api/localWorker.ts +29 -0
- package/src/core/api/offesecAgent.test.ts +289 -0
- package/src/core/api/offesecAgent.ts +77 -0
- package/src/core/api/patching.ts +44 -0
- package/src/core/api/recordedRun.control.test.ts +830 -0
- package/src/core/api/recordedRun.inference.test.ts +529 -0
- package/src/core/api/recordedRun.loop.test.ts +290 -0
- package/src/core/api/recordedRun.recovery.test.ts +651 -0
- package/src/core/api/recordedRun.test.ts +646 -0
- package/src/core/api/recordedRun.ts +542 -0
- package/src/core/api/targetedPentest.test.ts +177 -0
- package/src/core/api/targetedPentest.ts +83 -0
- package/src/core/api/threatModel.ts +5 -0
- package/src/core/api/trajectoryExport.test.ts +299 -0
- package/src/core/api/trajectoryExport.ts +362 -0
- package/src/core/api/vulnerabilityReproduction.test.ts +56 -0
- package/src/core/api/vulnerabilityReproduction.ts +54 -0
- package/src/core/assets/wordlists.test.ts +85 -0
- package/src/core/assets/wordlists.ts +111 -0
- package/src/core/atif/compatibility.test.ts +107 -0
- package/src/core/atif/convert.test.ts +815 -0
- package/src/core/atif/convert.ts +1658 -0
- package/src/core/atif/fixtures/portable-bundle-v1.json +813 -0
- package/src/core/atif/index.ts +34 -0
- package/src/core/atif/schema.ts +345 -0
- package/src/core/atif/serialize.test.ts +244 -0
- package/src/core/atif/serialize.ts +419 -0
- package/src/core/atif/test-fixtures.ts +184 -0
- package/src/core/atif/validate.test.ts +188 -0
- package/src/core/atif/validate.ts +289 -0
- package/src/core/auth/connection.ts +26 -0
- package/src/core/auth/device-flow.ts +203 -0
- package/src/core/auth/gateway.ts +66 -0
- package/src/core/auth/index.ts +29 -0
- package/src/core/auth/signing.ts +25 -0
- package/src/core/auth/token.ts +140 -0
- package/src/core/auth/types.ts +106 -0
- package/src/core/auth/workspaces.ts +192 -0
- package/src/core/benchmark/index.ts +11 -0
- package/src/core/benchmark/report.ts +257 -0
- package/src/core/benchmark/runner.ts +698 -0
- package/src/core/benchmark/types.ts +80 -0
- package/src/core/cli/logLevelArgs.test.ts +83 -0
- package/src/core/cli/logLevelArgs.ts +62 -0
- package/src/core/cli/model.ts +35 -0
- package/src/core/cli/pentestMode.test.ts +24 -0
- package/src/core/cli/pentestMode.ts +23 -0
- package/src/core/cli/tuiArgs.test.ts +58 -0
- package/src/core/cli/tuiArgs.ts +28 -0
- package/src/core/config/config.test.ts +183 -0
- package/src/core/config/config.ts +201 -0
- package/src/core/config/customProviders.test.ts +183 -0
- package/src/core/config/customProviders.ts +190 -0
- package/src/core/config/index.ts +7 -0
- package/src/core/credentials/index.ts +6 -0
- package/src/core/credentials/manager.ts +313 -0
- package/src/core/credentials/types.ts +112 -0
- package/src/core/doctor.ts +138 -0
- package/src/core/eventBus.test.ts +374 -0
- package/src/core/eventBus.ts +410 -0
- package/src/core/findings/attackSurfaceRegistry.ts +294 -0
- package/src/core/findings/registry.test.ts +1680 -0
- package/src/core/findings/registry.ts +800 -0
- package/src/core/history.ts +82 -0
- package/src/core/hoonify.test.ts +250 -0
- package/src/core/hoonify.ts +163 -0
- package/src/core/http/headers.contract.test.ts +1161 -0
- package/src/core/http/parse.ts +257 -0
- package/src/core/http/redirects.test.ts +207 -0
- package/src/core/http/redirects.ts +145 -0
- package/src/core/http/targetHeaders.ts +604 -0
- package/src/core/http/targetScope.ts +52 -0
- package/src/core/http/types.ts +39 -0
- package/src/core/id/id.test.ts +88 -0
- package/src/core/id/id.ts +138 -0
- package/src/core/installation/index.ts +222 -0
- package/src/core/installation/installation.test.ts +415 -0
- package/src/core/integrations/herdr.test.ts +335 -0
- package/src/core/integrations/herdr.ts +163 -0
- package/src/core/integrations/surface/index.test.ts +534 -0
- package/src/core/integrations/surface/index.ts +224 -0
- package/src/core/integrations/surface/types.ts +29 -0
- package/src/core/integrations/wandb/client.ts +167 -0
- package/src/core/integrations/wandb/upload.test.ts +415 -0
- package/src/core/integrations/wandb/upload.ts +76 -0
- package/src/core/logger/errorLog.test.ts +98 -0
- package/src/core/logger/index.ts +214 -0
- package/src/core/logger/structured.test.ts +212 -0
- package/src/core/logger/structured.ts +207 -0
- package/src/core/memory/backend.test.ts +186 -0
- package/src/core/memory/index.ts +279 -0
- package/src/core/memory/memory.test.ts +362 -0
- package/src/core/messages/types.ts +141 -0
- package/src/core/obfuscation/engine.test.ts +314 -0
- package/src/core/obfuscation/engine.ts +647 -0
- package/src/core/obfuscation/index.ts +27 -0
- package/src/core/observability/active-root-spans.ts +30 -0
- package/src/core/observability/active-spans.ts +80 -0
- package/src/core/observability/index.ts +91 -0
- package/src/core/observability/log-correlation.test.ts +276 -0
- package/src/core/observability/payload-capture.test.ts +59 -0
- package/src/core/observability/runtime.test.ts +743 -0
- package/src/core/observability/runtime.ts +371 -0
- package/src/core/observability/shutdown.test.ts +551 -0
- package/src/core/observability/telemetry.test.ts +895 -0
- package/src/core/observability/telemetry.ts +220 -0
- package/src/core/observability/testkit.test.ts +66 -0
- package/src/core/observability/testkit.ts +97 -0
- package/src/core/observability/trace-contract.test.ts +1031 -0
- package/src/core/observability.test.ts +135 -0
- package/src/core/operator/approvalGate.test.ts +300 -0
- package/src/core/operator/approvalGate.ts +287 -0
- package/src/core/operator/index.ts +30 -0
- package/src/core/operator/types.ts +355 -0
- package/src/core/plan/index.ts +44 -0
- package/src/core/prompt-injections/index.test.ts +248 -0
- package/src/core/prompt-injections/index.ts +350 -0
- package/src/core/providers/index.ts +5 -0
- package/src/core/providers/types.ts +87 -0
- package/src/core/providers/utils.test.ts +189 -0
- package/src/core/providers/utils.ts +183 -0
- package/src/core/providers/verify.test.ts +49 -0
- package/src/core/providers/verify.ts +198 -0
- package/src/core/report/builder.test.ts +229 -0
- package/src/core/report/builder.ts +58 -0
- package/src/core/report/index.ts +13 -0
- package/src/core/report/renderers/json.test.ts +76 -0
- package/src/core/report/renderers/json.ts +5 -0
- package/src/core/report/renderers/markdown.test.ts +366 -0
- package/src/core/report/renderers/markdown.ts +133 -0
- package/src/core/report/schemas.ts +48 -0
- package/src/core/runtime/agentExecution.test.ts +94 -0
- package/src/core/runtime/agentExecution.ts +27 -0
- package/src/core/runtime/launchLocalWorker.test.ts +707 -0
- package/src/core/runtime/launchLocalWorker.ts +273 -0
- package/src/core/runtime/localRunLock.ts +118 -0
- package/src/core/runtime/localRunWorker.test.ts +381 -0
- package/src/core/runtime/localRunWorker.ts +287 -0
- package/src/core/runtime/localWorker.acceptance.test.ts +548 -0
- package/src/core/runtime/localWorkerEndpoint.test.ts +145 -0
- package/src/core/runtime/localWorkerEndpoint.ts +82 -0
- package/src/core/runtime/localWorkerProtocol.ts +176 -0
- package/src/core/runtime/localWorkerTransport.test.ts +841 -0
- package/src/core/runtime/localWorkerTransport.ts +434 -0
- package/src/core/runtime/persistenceError.ts +14 -0
- package/src/core/runtime/recordedExecution.ts +43 -0
- package/src/core/runtime/recordedRunClient.integration.test.ts +106 -0
- package/src/core/runtime/recordedRunClient.test.ts +677 -0
- package/src/core/runtime/recordedRunClient.ts +303 -0
- package/src/core/runtime/runCheckpointStore.ts +23 -0
- package/src/core/runtime/runContext.test.ts +445 -0
- package/src/core/runtime/runContext.ts +184 -0
- package/src/core/runtime/runControl.test.ts +923 -0
- package/src/core/runtime/runControl.ts +419 -0
- package/src/core/runtime/runControlStore.ts +106 -0
- package/src/core/runtime/runDeadline.test.ts +44 -0
- package/src/core/runtime/runDeadline.ts +28 -0
- package/src/core/runtime/runEvidence.test.ts +384 -0
- package/src/core/runtime/runEvidence.ts +267 -0
- package/src/core/runtime/runInference.test.ts +408 -0
- package/src/core/runtime/runInference.ts +125 -0
- package/src/core/runtime/runModelStore.ts +55 -0
- package/src/core/runtime/runObservation.ts +24 -0
- package/src/core/runtime/runRecoveryContext.test.ts +602 -0
- package/src/core/runtime/runRecoveryContext.ts +195 -0
- package/src/core/runtime/runRecoveryPlan.test.ts +851 -0
- package/src/core/runtime/runRecoveryPlan.ts +540 -0
- package/src/core/runtime/runRecoveryStore.ts +78 -0
- package/src/core/runtime/runStore.ts +148 -0
- package/src/core/runtime/runStorePath.ts +13 -0
- package/src/core/runtime/runToolStore.ts +66 -0
- package/src/core/runtime/runTools.crash.test.ts +414 -0
- package/src/core/runtime/runTools.test.ts +689 -0
- package/src/core/runtime/runTools.ts +208 -0
- package/src/core/runtime/sqliteControlStore.test.ts +917 -0
- package/src/core/runtime/sqliteControlStore.ts +555 -0
- package/src/core/runtime/sqliteModelStore.test.ts +619 -0
- package/src/core/runtime/sqliteModelStore.ts +286 -0
- package/src/core/runtime/sqliteRecoveryStore.public.test.ts +374 -0
- package/src/core/runtime/sqliteRecoveryStore.test.ts +836 -0
- package/src/core/runtime/sqliteRecoveryStore.ts +435 -0
- package/src/core/runtime/sqliteRunContext.test.ts +1000 -0
- package/src/core/runtime/sqliteRunObservation.test.ts +432 -0
- package/src/core/runtime/sqliteRunStore.test.ts +698 -0
- package/src/core/runtime/sqliteRunStore.ts +593 -0
- package/src/core/runtime/sqliteToolStore.test.ts +1231 -0
- package/src/core/runtime/sqliteToolStore.ts +419 -0
- package/src/core/runtime/testfixtures/localWorkerChild.ts +254 -0
- package/src/core/runtime/testfixtures/localWorkerLauncher.ts +15 -0
- package/src/core/runtime/testfixtures/recoveryChild.ts +159 -0
- package/src/core/services/rateLimiter/index.test.ts +106 -0
- package/src/core/services/rateLimiter/index.ts +157 -0
- package/src/core/services/rateLimiter/types.ts +10 -0
- package/src/core/session/admitted-config.test.ts +50 -0
- package/src/core/session/deprecated-headers-shim.test.ts +111 -0
- package/src/core/session/execution-metrics.test.ts +297 -0
- package/src/core/session/execution-metrics.ts +176 -0
- package/src/core/session/index.ts +1085 -0
- package/src/core/session/loader.ts +212 -0
- package/src/core/session/persistence.test.ts +1210 -0
- package/src/core/session/persistence.ts +1076 -0
- package/src/core/session/rehydrate.test.ts +393 -0
- package/src/core/session/types.ts +139 -0
- package/src/core/session/usage.test.ts +99 -0
- package/src/core/session/usage.ts +84 -0
- package/src/core/skills/builtins/index.ts +22 -0
- package/src/core/skills/builtins/pentest.ts +135 -0
- package/src/core/skills/builtins/promptInjection.ts +44 -0
- package/src/core/skills/builtins/threatModel.ts +336 -0
- package/src/core/skills/index.ts +15 -0
- package/src/core/skills/parser.test.ts +120 -0
- package/src/core/skills/parser.ts +106 -0
- package/src/core/skills/registry.test.ts +202 -0
- package/src/core/skills/registry.ts +109 -0
- package/src/core/skills/scanner.test.ts +157 -0
- package/src/core/skills/scanner.ts +115 -0
- package/src/core/skills/types.ts +45 -0
- package/src/core/skills/utils.ts +16 -0
- package/src/core/storage/index.ts +150 -0
- package/src/core/tasks/index.ts +242 -0
- package/src/core/tools/backends/capture.ts +38 -0
- package/src/core/tools/backends/collectCommand.test.ts +33 -0
- package/src/core/tools/backends/collectCommand.ts +28 -0
- package/src/core/tools/backends/helpers.ts +140 -0
- package/src/core/tools/backends/httpTransport.ts +534 -0
- package/src/core/tools/backends/index.ts +61 -0
- package/src/core/tools/backends/local.test.ts +307 -0
- package/src/core/tools/backends/local.ts +820 -0
- package/src/core/tools/backends/policy.test.ts +137 -0
- package/src/core/tools/backends/policy.ts +129 -0
- package/src/core/tools/backends/resolve.test.ts +309 -0
- package/src/core/tools/backends/resolve.ts +152 -0
- package/src/core/tools/backends/types.ts +279 -0
- package/src/core/tools/backends/whitebox.test.ts +275 -0
- package/src/core/tools/backends/whitebox.ts +14 -0
- package/src/core/tools/backends/whiteboxJobs.test.ts +375 -0
- package/src/core/tools/backends/whiteboxJobs.ts +157 -0
- package/src/core/tools/backends/windowsProgram.ts +36 -0
- package/src/core/tools/daytonaSandbox.test.ts +491 -0
- package/src/core/tools/daytonaSandbox.ts +232 -0
- package/src/core/toolset/index.ts +583 -0
- package/src/core/util/lazyLogger.ts +32 -0
- package/src/core/utils/concurrency.test.ts +204 -0
- package/src/core/utils/concurrency.ts +75 -0
- package/src/core/utils/prompt.ts +28 -0
- package/src/core/whitebox/adapters.ts +277 -0
- package/src/core/whitebox/artifacts.ts +128 -0
- package/src/core/whitebox/boundedProcess.ts +265 -0
- package/src/core/whitebox/candidates.ts +268 -0
- package/src/core/whitebox/catalog.ts +82 -0
- package/src/core/whitebox/index.ts +53 -0
- package/src/core/whitebox/jobKernel.test.ts +91 -0
- package/src/core/whitebox/jobKernel.ts +347 -0
- package/src/core/whitebox/jobSupervisor.ts +264 -0
- package/src/core/whitebox/jobs.ts +21 -0
- package/src/core/whitebox/paths.ts +94 -0
- package/src/core/whitebox/profileTransport.ts +225 -0
- package/src/core/whitebox/profiles.ts +294 -0
- package/src/core/whitebox/repoProfile.test.ts +217 -0
- package/src/core/whitebox/repoProfile.ts +256 -0
- package/src/core/whitebox/types.ts +189 -0
- package/src/core/whitebox/whitebox.test.ts +789 -0
- package/src/core/workflows/fastStrike.seams.test.ts +217 -0
- package/src/core/workflows/fastStrike.test.ts +29 -0
- package/src/core/workflows/fastStrike.ts +239 -0
- package/src/core/workflows/pentest.test.ts +575 -0
- package/src/core/workflows/pentest.ts +1022 -0
- package/src/core/workflows/seams.test.ts +386 -0
- package/src/core/workflows/seams.ts +276 -0
- package/src/core/workflows/threatModel.ts +108 -0
- package/src/core/workflows/usage-forwarding.test.ts +203 -0
- package/src/core/workflows/whiteboxAttackSurface.test.ts +695 -0
- package/src/core/workflows/whiteboxAttackSurface.ts +1740 -0
- package/src/index.ts +49 -0
- package/src/lib/attack-path/types.ts +13 -0
- package/src/lib/cvss/calculator.test.ts +2090 -0
- package/src/lib/cvss/calculator.ts +643 -0
- package/src/lib/cvss/index.ts +65 -0
- package/src/lib/cvss/macrovector-scores.ts +402 -0
- package/src/lib/cvss/types.ts +241 -0
- package/src/lib/cwe/cwe-catalog.ts +444 -0
- package/src/lib/cwe/types.test.ts +142 -0
- package/src/lib/cwe/types.ts +37 -0
- package/src/lib/cwe/validate.test.ts +110 -0
- package/src/lib/cwe/validate.ts +53 -0
- package/src/lib/evidence/types.ts +9 -0
- package/src/tests/agentWorkingDirectory.test.ts +175 -0
- package/src/tests/attackSurface.test.ts +35 -0
- package/src/tests/auth.test.ts +196 -0
- package/src/tests/authCookieExport.test.ts +143 -0
- package/src/tests/authPentestHandoff.test.ts +231 -0
- package/src/tests/browserCookies.test.ts +128 -0
- package/src/tests/credentialManager.test.ts +657 -0
- package/src/tests/data/console.openapi.json +1037 -0
- package/src/tests/data/console.sitemap.xml +348 -0
- package/src/tests/delegateAuthMerge.test.ts +48 -0
- package/src/tui/auto-copy.ts +36 -0
- package/src/tui/clipboard.ts +65 -0
- package/src/tui/command-registry.test.ts +124 -0
- package/src/tui/command-registry.ts +645 -0
- package/src/tui/command-router.ts +81 -0
- package/src/tui/components/agent-display.tsx +480 -0
- package/src/tui/components/ascii-art.tsx +225 -0
- package/src/tui/components/chat/approval-inline.tsx +51 -0
- package/src/tui/components/chat/config-view.tsx +279 -0
- package/src/tui/components/chat/home-view.tsx +288 -0
- package/src/tui/components/chat/index.tsx +161 -0
- package/src/tui/components/chat/input-area.tsx +529 -0
- package/src/tui/components/chat/lib/play-core/num.ts +102 -0
- package/src/tui/components/chat/lib/wave-simulation.ts +124 -0
- package/src/tui/components/chat/loading-indicator.test.ts +33 -0
- package/src/tui/components/chat/loading-indicator.tsx +131 -0
- package/src/tui/components/chat/message-list.tsx +265 -0
- package/src/tui/components/chat/petri-animation.tsx +175 -0
- package/src/tui/components/chat/plan-review-message.tsx +49 -0
- package/src/tui/components/chat/questions-form.tsx +756 -0
- package/src/tui/components/commands/__tests__/recorded-runs-lifecycle.tsx +907 -0
- package/src/tui/components/commands/advanced-settings.tsx +94 -0
- package/src/tui/components/commands/api-key-input.tsx +122 -0
- package/src/tui/components/commands/auth-flow-logic.test.ts +58 -0
- package/src/tui/components/commands/auth-flow-logic.ts +30 -0
- package/src/tui/components/commands/auth-flow.tsx +702 -0
- package/src/tui/components/commands/credits-flow.tsx +210 -0
- package/src/tui/components/commands/help-dialog.tsx +238 -0
- package/src/tui/components/commands/models-display.tsx +111 -0
- package/src/tui/components/commands/operator-wizard.tsx +328 -0
- package/src/tui/components/commands/provider-manager.tsx +241 -0
- package/src/tui/components/commands/provider-selection.tsx +129 -0
- package/src/tui/components/commands/recorded-runs.test.ts +40 -0
- package/src/tui/components/commands/recorded-runs.tsx +793 -0
- package/src/tui/components/commands/sessions-display.tsx +365 -0
- package/src/tui/components/commands/shortcuts-dialog.tsx +52 -0
- package/src/tui/components/commands/skills-dialog.tsx +308 -0
- package/src/tui/components/commands/theme-picker.tsx +177 -0
- package/src/tui/components/commands/web-wizard.tsx +965 -0
- package/src/tui/components/dialog-layout.tsx +73 -0
- package/src/tui/components/error-boundary.tsx +82 -0
- package/src/tui/components/footer.tsx +101 -0
- package/src/tui/components/input.tsx +43 -0
- package/src/tui/components/loaders.tsx +784 -0
- package/src/tui/components/model-picker/ModelPicker.tsx +907 -0
- package/src/tui/components/model-picker/ModelPickerDialog.tsx +75 -0
- package/src/tui/components/model-picker/index.ts +2 -0
- package/src/tui/components/model-picker/model-navigation.test.ts +102 -0
- package/src/tui/components/model-picker/model-navigation.ts +54 -0
- package/src/tui/components/model-picker/model-search.test.ts +62 -0
- package/src/tui/components/model-picker/model-search.ts +42 -0
- package/src/tui/components/model-picker/model-visibility.test.ts +65 -0
- package/src/tui/components/model-picker/model-visibility.ts +59 -0
- package/src/tui/components/operator-dashboard/conversation.test.ts +431 -0
- package/src/tui/components/operator-dashboard/conversation.ts +179 -0
- package/src/tui/components/operator-dashboard/display-state.test.ts +369 -0
- package/src/tui/components/operator-dashboard/display-state.ts +163 -0
- package/src/tui/components/operator-dashboard/herdr-state.test.ts +162 -0
- package/src/tui/components/operator-dashboard/herdr-state.ts +81 -0
- package/src/tui/components/operator-dashboard/index.tsx +2044 -0
- package/src/tui/components/operator-dashboard/logic.test.ts +753 -0
- package/src/tui/components/operator-dashboard/logic.ts +465 -0
- package/src/tui/components/operator-dashboard/queue.test.ts +147 -0
- package/src/tui/components/operator-dashboard/queue.ts +55 -0
- package/src/tui/components/operator-dashboard/queued-messages.tsx +50 -0
- package/src/tui/components/operator-dashboard/run-events.test.ts +915 -0
- package/src/tui/components/operator-dashboard/run-events.ts +507 -0
- package/src/tui/components/operator-dashboard/run-tracing.test.ts +206 -0
- package/src/tui/components/operator-dashboard/run-tracing.ts +105 -0
- package/src/tui/components/operator-dashboard/subagent-detail-view.tsx +51 -0
- package/src/tui/components/operator-dashboard/subagent-dialog.tsx +142 -0
- package/src/tui/components/operator-dashboard/subagent-hub.test.ts +162 -0
- package/src/tui/components/operator-dashboard/subagent-hub.tsx +266 -0
- package/src/tui/components/operator-dashboard/subagent-state.test.ts +431 -0
- package/src/tui/components/operator-dashboard/subagent-state.ts +404 -0
- package/src/tui/components/operator-dashboard/subagent-status-bar.tsx +80 -0
- package/src/tui/components/operator-dashboard/tool-argument-buffer.test.ts +317 -0
- package/src/tui/components/operator-dashboard/tool-arguments.perf.test.ts +121 -0
- package/src/tui/components/operator-dashboard/welcome-logo.tsx +79 -0
- package/src/tui/components/operator-dashboard/workflow-data.test.ts +291 -0
- package/src/tui/components/operator-dashboard/workflow-data.ts +130 -0
- package/src/tui/components/report-viewer-dialog.tsx +98 -0
- package/src/tui/components/responsible-use-disclosure.tsx +55 -0
- package/src/tui/components/screenshot-modal.tsx +204 -0
- package/src/tui/components/shared/__tests__/prompt-input-lifecycle.tsx +64 -0
- package/src/tui/components/shared/__tests__/tool-renderer-lifecycle.tsx +87 -0
- package/src/tui/components/shared/action-label.test.ts +142 -0
- package/src/tui/components/shared/action-label.ts +18 -0
- package/src/tui/components/shared/ascii-spinner.tsx +40 -0
- package/src/tui/components/shared/compacting-icon.tsx +18 -0
- package/src/tui/components/shared/dialog-controls.tsx +76 -0
- package/src/tui/components/shared/index.ts +38 -0
- package/src/tui/components/shared/markdown-viewer.tsx +188 -0
- package/src/tui/components/shared/markdown.ts +239 -0
- package/src/tui/components/shared/message-renderer.tsx +178 -0
- package/src/tui/components/shared/message-utils.ts +175 -0
- package/src/tui/components/shared/pentest-workflow-display.tsx +330 -0
- package/src/tui/components/shared/prompt-input-lifecycle.test.ts +22 -0
- package/src/tui/components/shared/prompt-input-logic.test.ts +782 -0
- package/src/tui/components/shared/prompt-input-logic.ts +423 -0
- package/src/tui/components/shared/prompt-input.tsx +782 -0
- package/src/tui/components/shared/result-registry.test.ts +90 -0
- package/src/tui/components/shared/result-registry.ts +900 -0
- package/src/tui/components/shared/syntax-highlight.ts +242 -0
- package/src/tui/components/shared/tool-registry.test.ts +59 -0
- package/src/tui/components/shared/tool-registry.ts +280 -0
- package/src/tui/components/shared/tool-renderer.test.ts +13 -0
- package/src/tui/components/shared/tool-renderer.tsx +237 -0
- package/src/tui/components/shared/type-guards.ts +64 -0
- package/src/tui/components/shared/use-paste-extmarks.ts +109 -0
- package/src/tui/components/switch.tsx +81 -0
- package/src/tui/components/terminal-focus-handler.tsx +34 -0
- package/src/tui/components/toast.tsx +82 -0
- package/src/tui/components/usage-labels.test.ts +191 -0
- package/src/tui/components/usage-labels.ts +78 -0
- package/src/tui/console-theme.ts +59 -0
- package/src/tui/context/agent.tsx +251 -0
- package/src/tui/context/command.tsx +291 -0
- package/src/tui/context/config.tsx +59 -0
- package/src/tui/context/dialog.tsx +206 -0
- package/src/tui/context/dimensions.tsx +31 -0
- package/src/tui/context/focus-ownership.test.ts +26 -0
- package/src/tui/context/focus-ownership.ts +12 -0
- package/src/tui/context/focus.tsx +86 -0
- package/src/tui/context/herdr.tsx +28 -0
- package/src/tui/context/input.tsx +45 -0
- package/src/tui/context/keybinding.tsx +92 -0
- package/src/tui/context/obfuscation.tsx +114 -0
- package/src/tui/context/route.tsx +127 -0
- package/src/tui/context/session-usage.test.ts +295 -0
- package/src/tui/context/session-usage.ts +204 -0
- package/src/tui/context/session.tsx +62 -0
- package/src/tui/context/toast.tsx +66 -0
- package/src/tui/generated-ascii-art.json +1 -0
- package/src/tui/generated-ascii-art.json.d.ts +2 -0
- package/src/tui/herdr-startup.test.ts +157 -0
- package/src/tui/hooks/use-sessions-list.ts +165 -0
- package/src/tui/index.tsx +838 -0
- package/src/tui/keybindings/index.ts +126 -0
- package/src/tui/keybindings/registry.ts +146 -0
- package/src/tui/keybindings-registry.ts +43 -0
- package/src/tui/obfuscation/patch.ts +139 -0
- package/src/tui/terminal-focus.ts +218 -0
- package/src/tui/theme/colors.ts +43 -0
- package/src/tui/theme/context.tsx +137 -0
- package/src/tui/theme/detect-mode.ts +56 -0
- package/src/tui/theme/index.ts +75 -0
- package/src/tui/theme/registry.ts +29 -0
- package/src/tui/theme/themes/apex.ts +190 -0
- package/src/tui/theme/themes/ayu.ts +189 -0
- package/src/tui/theme/themes/catppuccin.ts +189 -0
- package/src/tui/theme/themes/dracula.ts +190 -0
- package/src/tui/theme/themes/everforest.ts +189 -0
- package/src/tui/theme/themes/flexoki.ts +190 -0
- package/src/tui/theme/themes/github.ts +189 -0
- package/src/tui/theme/themes/gruvbox.ts +189 -0
- package/src/tui/theme/themes/index.ts +54 -0
- package/src/tui/theme/themes/kanagawa.ts +189 -0
- package/src/tui/theme/themes/material.ts +190 -0
- package/src/tui/theme/themes/monokai.ts +190 -0
- package/src/tui/theme/themes/nightfox.ts +189 -0
- package/src/tui/theme/themes/nord.ts +190 -0
- package/src/tui/theme/themes/onedark.ts +190 -0
- package/src/tui/theme/themes/rose-pine.ts +189 -0
- package/src/tui/theme/themes/solarized.ts +189 -0
- package/src/tui/theme/themes/tokyonight.ts +189 -0
- package/src/tui/theme/themes/vesper.ts +191 -0
- package/src/tui/theme/types.ts +143 -0
- package/src/tui/utils/command-flags.test.ts +269 -0
- package/src/tui/utils/command-flags.ts +377 -0
- package/src/tui/utils/kitty-graphics.ts +76 -0
- package/src/tui/utils/open-file.ts +37 -0
- package/src/tui/utils/open-report.ts +34 -0
- package/src/tui/utils/open-url.ts +39 -0
- package/src/tui/utils/paste.ts +8 -0
- package/src/tui/utils/scroll.ts +81 -0
- package/src/util/errors.ts +58 -0
- package/src/util/lock.ts +100 -0
- package/src/util/name.ts +148 -0
- package/src/util/url.test.ts +162 -0
- package/src/util/url.ts +107 -0
- package/build/agent-13rrhp8d.js +0 -20
- package/build/agent-zbj2331s.js +0 -30
- package/build/authentication-f4j3w5vs.js +0 -20
- package/build/blackboxAgent-v2vx9ws4.js +0 -20
- package/build/blackboxPentest-w5nwzpvk.js +0 -70
- package/build/cli-5wemv37a.js +0 -194
- package/build/cli-7s062hr6.js +0 -22
- package/build/cli-9qbxkhye.js +0 -55
- package/build/cli-avmhkjtv.js +0 -22961
- package/build/cli-g3czc3jz.js +0 -204
- package/build/cli-ww7hbazg.js +0 -88
- package/build/index-18vyy6mj.js +0 -19
- package/build/index-5wh7gq37.js +0 -12858
- package/build/index-e23zc8g4.js +0 -34
- package/build/index-hnwhswqj.js +0 -213
- package/build/index-wkmnr4nm.js +0 -39
- package/build/index-ywmfnd30.js +0 -12
- package/build/offesecAgent-c97pqzcn.js +0 -27
- package/build/pentest-4p5jt7gj.js +0 -30
- package/build/pentests-v98eg8n3.js +0 -92
- package/build/threatModel-81d4rcbk.js +0 -29
- /package/build/{cli-c8131c4q.js → cli-0wsh8j2t.js} +0 -0
- /package/build/{cli-9pbk8m32.js → cli-ag6jtndp.js} +0 -0
- /package/build/{cli-e08r86zk.js → cli-b3dvxjgk.js} +0 -0
- /package/build/{cli-fw5r7pfj.js → cli-q126f6ef.js} +0 -0
- /package/build/{cli-9fsre5pt.js → cli-qba2x69h.js} +0 -0
- /package/build/{cli-7q3ae3ft.js → cli-z82n3qk1.js} +0 -0
|
@@ -0,0 +1,1426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright MCP Browser Tools
|
|
3
|
+
*
|
|
4
|
+
* Provides browser automation via Playwright MCP server.
|
|
5
|
+
*
|
|
6
|
+
* Two modes:
|
|
7
|
+
* - "pentest": Automated pentesting agent - XSS validation, form-based attacks, evidence collection
|
|
8
|
+
* - "operator": User-driven operator mode - SPA reconnaissance, authenticated flows, attack surface mapping
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { randomUUID } from "node:crypto";
|
|
12
|
+
import {
|
|
13
|
+
existsSync,
|
|
14
|
+
mkdirSync,
|
|
15
|
+
readdirSync,
|
|
16
|
+
readFileSync,
|
|
17
|
+
writeFileSync,
|
|
18
|
+
} from "node:fs";
|
|
19
|
+
import { createRequire } from "node:module";
|
|
20
|
+
import { dirname, join } from "node:path";
|
|
21
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
22
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
23
|
+
import type { BrowserBackend } from "../../../tools/backends/types";
|
|
24
|
+
import {
|
|
25
|
+
type BrowserHeaderPolicy,
|
|
26
|
+
browserHeaderRouteFunction,
|
|
27
|
+
} from "./browserHeaderRouting";
|
|
28
|
+
import {
|
|
29
|
+
type BrowserToolMode,
|
|
30
|
+
createBackendBrowserToolFactories,
|
|
31
|
+
} from "./browserToolFactories";
|
|
32
|
+
|
|
33
|
+
export type { BrowserToolMode } from "./browserToolFactories";
|
|
34
|
+
|
|
35
|
+
import type { Logger } from "../../../logger";
|
|
36
|
+
import {
|
|
37
|
+
type CamoufoxLaunchOptions,
|
|
38
|
+
COMPUTER_USE_VIEWPORT_SIZE,
|
|
39
|
+
ENDPOINT_DISPLAY_BASE,
|
|
40
|
+
ENDPOINT_VIEWPORT_SIZE,
|
|
41
|
+
ensureCamoufox,
|
|
42
|
+
parseDisplayNumber,
|
|
43
|
+
parseViewportSize,
|
|
44
|
+
resolveCamoufoxLaunchOptions,
|
|
45
|
+
} from "./camoufox";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Playwright `BrowserContext.storageState()` shape — the JSON-serialisable
|
|
49
|
+
* snapshot of cookies + per-origin storage that Playwright uses to round-trip
|
|
50
|
+
* authentication state between contexts.
|
|
51
|
+
*/
|
|
52
|
+
export interface BrowserStorageState {
|
|
53
|
+
cookies: Array<{
|
|
54
|
+
name: string;
|
|
55
|
+
value: string;
|
|
56
|
+
domain: string;
|
|
57
|
+
path: string;
|
|
58
|
+
expires?: number;
|
|
59
|
+
httpOnly?: boolean;
|
|
60
|
+
secure?: boolean;
|
|
61
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
62
|
+
}>;
|
|
63
|
+
origins: Array<{
|
|
64
|
+
origin: string;
|
|
65
|
+
localStorage: Array<{ name: string; value: string }>;
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Types for tool results
|
|
70
|
+
export interface BrowserNavigateResult {
|
|
71
|
+
success: boolean;
|
|
72
|
+
url: string;
|
|
73
|
+
title?: string;
|
|
74
|
+
result?: unknown;
|
|
75
|
+
error?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface BrowserScreenshotResult {
|
|
79
|
+
success: boolean;
|
|
80
|
+
path?: string;
|
|
81
|
+
message?: string;
|
|
82
|
+
error?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface BrowserClickResult {
|
|
86
|
+
success: boolean;
|
|
87
|
+
element?: string;
|
|
88
|
+
result?: unknown;
|
|
89
|
+
error?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface BrowserFillResult {
|
|
93
|
+
success: boolean;
|
|
94
|
+
element?: string;
|
|
95
|
+
result?: unknown;
|
|
96
|
+
error?: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface BrowserEvaluateResult {
|
|
100
|
+
success: boolean;
|
|
101
|
+
script?: string;
|
|
102
|
+
result?: unknown;
|
|
103
|
+
error?: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface BrowserConsoleResult {
|
|
107
|
+
success: boolean;
|
|
108
|
+
messages?: Array<{ type: string; text: string }>;
|
|
109
|
+
result?: unknown;
|
|
110
|
+
error?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const MCP_CONNECT_TIMEOUT_MS = 30_000;
|
|
114
|
+
const MCP_TOOL_CALL_TIMEOUT_MS = 60_000;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Transform a user-provided script into a function expression for Playwright's browser_evaluate.
|
|
118
|
+
*
|
|
119
|
+
* Handles three cases:
|
|
120
|
+
* 1. Plain expressions: `document.cookie` → `() => (document.cookie)`
|
|
121
|
+
* 2. Function expressions: `() => document.cookie` → unchanged
|
|
122
|
+
* 3. IIFEs: `(() => { ... })()` → `() => { ... }`
|
|
123
|
+
*
|
|
124
|
+
* IIFEs are problematic because they evaluate to a value, not a function,
|
|
125
|
+
* causing "result is not a function" errors when Playwright tries to call them.
|
|
126
|
+
*
|
|
127
|
+
* @internal Exported for testing
|
|
128
|
+
*/
|
|
129
|
+
export function transformScriptToFunction(script: string): string {
|
|
130
|
+
const trimmed = script.trim();
|
|
131
|
+
|
|
132
|
+
// Detect IIFE pattern: (function...)() or (() => ...)() or (async () => ...)()
|
|
133
|
+
// Must start with ( followed by (async )?(function or () and end with ()
|
|
134
|
+
const iifeTrailing = /\(\s*\)\s*;?\s*$/.test(trimmed);
|
|
135
|
+
const iifeLeading = /^\s*\((?:async\s+)?(?:function|\()/.test(trimmed);
|
|
136
|
+
|
|
137
|
+
if (iifeLeading && iifeTrailing) {
|
|
138
|
+
// This is an IIFE - extract the function without the trailing invocation ()
|
|
139
|
+
let extracted = trimmed.replace(/\(\s*\)\s*;?\s*$/, "").trim();
|
|
140
|
+
// Remove the outer wrapping parentheses: (fn) -> fn
|
|
141
|
+
if (extracted.startsWith("(") && extracted.endsWith(")")) {
|
|
142
|
+
extracted = extracted.slice(1, -1).trim();
|
|
143
|
+
}
|
|
144
|
+
return extracted;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Regular function expression or plain expression
|
|
148
|
+
const isFunction =
|
|
149
|
+
/^\s*(async\s+)?\(/.test(script) ||
|
|
150
|
+
/^\s*(async\s+)?function\s*\(/.test(script);
|
|
151
|
+
return isFunction ? script : `() => (${script})`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Parse the response payload from `browser_run_code` returning a
|
|
156
|
+
* `BrowserContext.storageState()` JSON object. Playwright MCP wraps results
|
|
157
|
+
* as `### Result\n<value>\n\n### Ran Playwright code\n...` strings, so we
|
|
158
|
+
* strip the prefix/suffix and JSON-parse the middle. Falls back to a JSON
|
|
159
|
+
* object regex extract for older MCP variants. Returns `null` for any
|
|
160
|
+
* shape we can't decode rather than throwing.
|
|
161
|
+
*
|
|
162
|
+
* @internal Exported for testing.
|
|
163
|
+
*/
|
|
164
|
+
export function parseStorageStateResult(
|
|
165
|
+
result: unknown,
|
|
166
|
+
): BrowserStorageState | null {
|
|
167
|
+
if (!result) return null;
|
|
168
|
+
|
|
169
|
+
if (typeof result === "string") {
|
|
170
|
+
const stripped = result
|
|
171
|
+
.replace(/^###\s*Result\s*\n?/, "")
|
|
172
|
+
.replace(/\n\n###[\s\S]*$/, "")
|
|
173
|
+
.trim();
|
|
174
|
+
try {
|
|
175
|
+
const parsed = JSON.parse(stripped);
|
|
176
|
+
if (parsed && typeof parsed === "object" && "cookies" in parsed) {
|
|
177
|
+
return parsed as BrowserStorageState;
|
|
178
|
+
}
|
|
179
|
+
if (typeof parsed === "string") {
|
|
180
|
+
const inner = JSON.parse(parsed);
|
|
181
|
+
if (inner && typeof inner === "object" && "cookies" in inner) {
|
|
182
|
+
return inner as BrowserStorageState;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
} catch {
|
|
186
|
+
const jsonMatch = stripped.match(/\{[\s\S]*\}/);
|
|
187
|
+
if (jsonMatch) {
|
|
188
|
+
try {
|
|
189
|
+
const inner = JSON.parse(jsonMatch[0]);
|
|
190
|
+
if (inner && typeof inner === "object" && "cookies" in inner) {
|
|
191
|
+
return inner as BrowserStorageState;
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
194
|
+
/* fall through */
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (typeof result === "object" && "cookies" in (result as object)) {
|
|
202
|
+
return result as BrowserStorageState;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Race a promise against a timeout. Rejects with a descriptive error
|
|
210
|
+
* if the timeout fires first.
|
|
211
|
+
*/
|
|
212
|
+
function withTimeout<T>(
|
|
213
|
+
promise: Promise<T>,
|
|
214
|
+
ms: number,
|
|
215
|
+
message: string,
|
|
216
|
+
): Promise<T> {
|
|
217
|
+
let timer: ReturnType<typeof setTimeout>;
|
|
218
|
+
const timeout = new Promise<never>((_, reject) => {
|
|
219
|
+
timer = setTimeout(() => reject(new Error(message)), ms);
|
|
220
|
+
});
|
|
221
|
+
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Collect every descendant PID of `rootPid` by walking `/proc` parent links
|
|
226
|
+
* (Linux only). Returns `[]` on platforms without `/proc` (e.g. macOS dev),
|
|
227
|
+
* where the process-group SIGKILL path is relied on instead.
|
|
228
|
+
*
|
|
229
|
+
* Used to reap the Chromium browser tree a Playwright MCP `node` child
|
|
230
|
+
* launches. `StdioClientTransport` does not spawn that `node` as a
|
|
231
|
+
* process-group leader, so `process.kill(-pid)` fails and only the `node`
|
|
232
|
+
* dies — orphaning Chromium (reparented to init) and leaking ~0.5GB per
|
|
233
|
+
* completed endpoint until the sandbox OOMs. Enumerating descendants lets us
|
|
234
|
+
* SIGKILL the browser explicitly. Must be called BEFORE the parent is killed:
|
|
235
|
+
* once it dies its children reparent to init and are no longer reachable via
|
|
236
|
+
* its pid.
|
|
237
|
+
*/
|
|
238
|
+
/** `/proc/<pid>/stat` starttime (field 22) — used to refuse PID-reuse kills. */
|
|
239
|
+
function readProcStartTime(pid: number): number | null {
|
|
240
|
+
try {
|
|
241
|
+
const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
242
|
+
const afterComm = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
|
|
243
|
+
const starttime = Number(afterComm[19]);
|
|
244
|
+
return Number.isFinite(starttime) ? starttime : null;
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function collectDescendantPids(rootPid: number): number[] {
|
|
251
|
+
let entries: string[];
|
|
252
|
+
try {
|
|
253
|
+
entries = readdirSync("/proc");
|
|
254
|
+
} catch {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const childrenByPpid = new Map<number, number[]>();
|
|
259
|
+
for (const name of entries) {
|
|
260
|
+
if (!/^\d+$/.test(name)) continue;
|
|
261
|
+
const pid = Number(name);
|
|
262
|
+
let ppid: number;
|
|
263
|
+
try {
|
|
264
|
+
// /proc/<pid>/stat: "pid (comm) state ppid ...". comm can contain spaces
|
|
265
|
+
// and parens, so parse the ppid from after the final ')'.
|
|
266
|
+
const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
267
|
+
const afterComm = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
|
|
268
|
+
ppid = Number(afterComm[1]);
|
|
269
|
+
} catch {
|
|
270
|
+
continue; // process exited between readdir and read
|
|
271
|
+
}
|
|
272
|
+
if (!Number.isFinite(ppid)) continue;
|
|
273
|
+
const list = childrenByPpid.get(ppid);
|
|
274
|
+
if (list) list.push(pid);
|
|
275
|
+
else childrenByPpid.set(ppid, [pid]);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const descendants: number[] = [];
|
|
279
|
+
const seen = new Set<number>([rootPid]);
|
|
280
|
+
const stack = [rootPid];
|
|
281
|
+
while (stack.length > 0) {
|
|
282
|
+
const pid = stack.pop()!;
|
|
283
|
+
for (const child of childrenByPpid.get(pid) ?? []) {
|
|
284
|
+
if (seen.has(child)) continue;
|
|
285
|
+
seen.add(child);
|
|
286
|
+
descendants.push(child);
|
|
287
|
+
stack.push(child);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return descendants;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Per-launch UUID inherited by the node child, Camoufox, and its content
|
|
295
|
+
* processes. Lets teardown find the tree by identity rather than ancestry,
|
|
296
|
+
* which breaks the moment the node dies and its browser reparents to init.
|
|
297
|
+
*/
|
|
298
|
+
const BROWSER_LAUNCH_ENV = "PENSAR_BROWSER_LAUNCH_ID";
|
|
299
|
+
|
|
300
|
+
/** Live pids stamped with `key=value`; `/proc/<pid>/environ` is fixed at exec. */
|
|
301
|
+
export function collectPidsByEnvMarker(key: string, value: string): number[] {
|
|
302
|
+
let entries: string[];
|
|
303
|
+
try {
|
|
304
|
+
entries = readdirSync("/proc");
|
|
305
|
+
} catch {
|
|
306
|
+
return [];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const needle = `${key}=${value}`;
|
|
310
|
+
const pids: number[] = [];
|
|
311
|
+
for (const name of entries) {
|
|
312
|
+
if (!/^\d+$/.test(name)) continue;
|
|
313
|
+
const pid = Number(name);
|
|
314
|
+
if (pid === process.pid) continue;
|
|
315
|
+
try {
|
|
316
|
+
if (
|
|
317
|
+
readFileSync(`/proc/${pid}/environ`, "utf8")
|
|
318
|
+
.split("\0")
|
|
319
|
+
.includes(needle)
|
|
320
|
+
) {
|
|
321
|
+
pids.push(pid);
|
|
322
|
+
}
|
|
323
|
+
} catch {
|
|
324
|
+
// exited, or not ours to inspect
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return pids;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// ---------------------------------------------------------------------------
|
|
331
|
+
// Module-level defaults (used when not explicitly provided)
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
|
|
334
|
+
let defaultHeadless = true;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Default User-Agent string for new browser sessions.
|
|
338
|
+
*
|
|
339
|
+
* Playwright MCP's Chromium default advertises `HeadlessChrome/…`, which is
|
|
340
|
+
* the single most common trigger for nginx / Cloudflare / generic-WAF 403s
|
|
341
|
+
* on targets we're otherwise authorised to test. Override the default to a
|
|
342
|
+
* real desktop Chrome UA so the browser isn't immediately fingerprinted as
|
|
343
|
+
* a headless bot at the edge.
|
|
344
|
+
*/
|
|
345
|
+
let defaultUserAgent: string | undefined =
|
|
346
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Hard floor for viewport size — used when both the explicit constructor
|
|
350
|
+
* arg and the module-level default are `undefined`, and the session is not
|
|
351
|
+
* on an endpoint-tier display. Guarantees that `new PlaywrightMcpSession()`
|
|
352
|
+
* always launches at a real desktop resolution and never silently falls
|
|
353
|
+
* back to Chromium's tiny built-in just because someone called
|
|
354
|
+
* `setViewportSize(undefined)`. Must match computer-use Xvfb (Console shim).
|
|
355
|
+
*
|
|
356
|
+
* The only way to opt out is to pass `null` explicitly to the constructor.
|
|
357
|
+
*/
|
|
358
|
+
const HARDCODED_VIEWPORT_FALLBACK = COMPUTER_USE_VIEWPORT_SIZE;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Default viewport size (format: `WIDTH,HEIGHT`) for new browser sessions.
|
|
362
|
+
* 1920x1080 matches computer-use desktops; endpoint displays (`:10+`) override
|
|
363
|
+
* to 1280x720 in the constructor so Camoufox fills the streamed Xvfb.
|
|
364
|
+
*/
|
|
365
|
+
let defaultViewportSize: string | undefined = HARDCODED_VIEWPORT_FALLBACK;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Configure the default headless mode for new browser sessions.
|
|
369
|
+
* Call this BEFORE any browser tools are created.
|
|
370
|
+
* Default is headless=true for normal operation.
|
|
371
|
+
*/
|
|
372
|
+
export function setHeadlessMode(headless: boolean): void {
|
|
373
|
+
defaultHeadless = headless;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Configure the default User-Agent for new browser sessions.
|
|
378
|
+
* Pass `undefined` to fall back to Chromium's built-in UA.
|
|
379
|
+
*/
|
|
380
|
+
export function setUserAgent(userAgent: string | undefined): void {
|
|
381
|
+
defaultUserAgent = userAgent;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Configure the default viewport size for new browser sessions.
|
|
386
|
+
* Format is `"WIDTH,HEIGHT"`, e.g. `"1920,1080"`.
|
|
387
|
+
* Pass `undefined` to fall back to Chromium's default viewport.
|
|
388
|
+
*/
|
|
389
|
+
export function setViewportSize(viewportSize: string | undefined): void {
|
|
390
|
+
defaultViewportSize = viewportSize;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export type BrowserEngine = "camoufox" | "chrome";
|
|
394
|
+
|
|
395
|
+
export interface PlaywrightMcpSessionOptions {
|
|
396
|
+
readonly headless?: boolean;
|
|
397
|
+
readonly userAgent?: string | null;
|
|
398
|
+
readonly viewportSize?: string | null;
|
|
399
|
+
readonly headerPolicy?: BrowserHeaderPolicy;
|
|
400
|
+
/**
|
|
401
|
+
* Browser to launch. Camoufox (Firefox) is the default for pentest traffic.
|
|
402
|
+
* Chrome is required for Sign in with Google — Google blocks Camoufox.
|
|
403
|
+
*/
|
|
404
|
+
readonly engine?: BrowserEngine;
|
|
405
|
+
/**
|
|
406
|
+
* X display for this session's spawned browser (e.g. `":11"`). Overrides
|
|
407
|
+
* `process.env.DISPLAY` for THIS session only. Required for per-agent display
|
|
408
|
+
* isolation: when several headed sessions run in one process (e.g. concurrent
|
|
409
|
+
* per-endpoint pentests), a single process-wide `DISPLAY` env can't separate
|
|
410
|
+
* them, so each is given its own display explicitly.
|
|
411
|
+
*/
|
|
412
|
+
readonly display?: string;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Isolated MCP browser session.
|
|
417
|
+
*
|
|
418
|
+
* Each instance owns its own Playwright MCP child-process and browser.
|
|
419
|
+
* Create one per agent so concurrent agents never collide on the same
|
|
420
|
+
* browser context.
|
|
421
|
+
*
|
|
422
|
+
* Incorporates all robustness features: connection timeouts, force-kill
|
|
423
|
+
* of stuck processes, dead-transport detection, and per-call abort
|
|
424
|
+
* signal + timeout support.
|
|
425
|
+
*/
|
|
426
|
+
export class PlaywrightMcpSession {
|
|
427
|
+
private mcpClient: Client | null = null;
|
|
428
|
+
private mcpTransport: StdioClientTransport | null = null;
|
|
429
|
+
private mcpProcess: import("child_process").ChildProcess | null = null;
|
|
430
|
+
private connectionPromise: Promise<Client> | null = null;
|
|
431
|
+
private disconnecting = false;
|
|
432
|
+
private readonly headless: boolean;
|
|
433
|
+
private readonly userAgent: string | undefined;
|
|
434
|
+
private readonly viewportSize: string | undefined;
|
|
435
|
+
private readonly headerPolicy: BrowserHeaderPolicy | undefined;
|
|
436
|
+
/** X display for the spawned browser; overrides `process.env.DISPLAY`. */
|
|
437
|
+
private readonly display: string | undefined;
|
|
438
|
+
readonly engine: BrowserEngine;
|
|
439
|
+
/** Temp config file written for MCP launch — deleted on disconnect. */
|
|
440
|
+
private mcpConfigPath: string | null = null;
|
|
441
|
+
/** Cached Camoufox launch options — resolved once, reused on reconnect. */
|
|
442
|
+
private cachedCamouOptions: CamoufoxLaunchOptions | null = null;
|
|
443
|
+
/**
|
|
444
|
+
* Deliberately NOT cleared by `resetState()` — `disconnect()` resets before
|
|
445
|
+
* it kills, so clearing there would blind the sweep. A new launch overwrites.
|
|
446
|
+
*/
|
|
447
|
+
private currentLaunchId: string | null = null;
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Each option is three-state: `undefined` → module default, value → use it,
|
|
451
|
+
* `null` → opt out of the default and let Chromium pick. Viewport has a
|
|
452
|
+
* hard floor of `HARDCODED_VIEWPORT_FALLBACK` to avoid Chromium's tiny built-in.
|
|
453
|
+
*/
|
|
454
|
+
constructor(options: PlaywrightMcpSessionOptions = {}) {
|
|
455
|
+
const { headless, userAgent, viewportSize, headerPolicy, display, engine } =
|
|
456
|
+
options;
|
|
457
|
+
this.engine = engine ?? "camoufox";
|
|
458
|
+
|
|
459
|
+
// An explicit `display` option wins over the process-wide env (needed when
|
|
460
|
+
// concurrent headed sessions each need their own display); fall back to
|
|
461
|
+
// `process.env.DISPLAY`.
|
|
462
|
+
this.display = display ?? process.env.DISPLAY ?? undefined;
|
|
463
|
+
|
|
464
|
+
// An explicit option always wins. Otherwise, if a virtual display is
|
|
465
|
+
// present (an explicit one, or a Daytona computer-use desktop on
|
|
466
|
+
// `process.env.DISPLAY`), default to headed — Camoufox is far less
|
|
467
|
+
// detectable headful and the display lets the session be streamed/observed.
|
|
468
|
+
// With no display we keep the module default (headless). Mirrors the
|
|
469
|
+
// `DISPLAY`-aware policy already used on the sandbox-executor path
|
|
470
|
+
// (`sandboxPlaywright.ts`).
|
|
471
|
+
this.headless = headless ?? (this.display ? false : defaultHeadless);
|
|
472
|
+
this.userAgent =
|
|
473
|
+
userAgent === null ? undefined : (userAgent ?? defaultUserAgent);
|
|
474
|
+
// Viewport resolution:
|
|
475
|
+
// 1. explicit `viewportSize` / `null` opt-out
|
|
476
|
+
// 2. endpoint-tier display (`:10+`) → 1280x720 (matches Console Xvfb)
|
|
477
|
+
// 3. module default / 1920x1080 floor (matches computer-use `:0`–`:9`)
|
|
478
|
+
// `ENDPOINT_DISPLAY_BASE` must stay aligned with Console desktopSession.ts
|
|
479
|
+
// and the agent-image Xvfb shim.
|
|
480
|
+
if (viewportSize === null) {
|
|
481
|
+
this.viewportSize = undefined;
|
|
482
|
+
} else if (viewportSize !== undefined) {
|
|
483
|
+
this.viewportSize = viewportSize;
|
|
484
|
+
} else {
|
|
485
|
+
const displayNum = parseDisplayNumber(this.display);
|
|
486
|
+
this.viewportSize =
|
|
487
|
+
displayNum !== undefined && displayNum >= ENDPOINT_DISPLAY_BASE
|
|
488
|
+
? ENDPOINT_VIEWPORT_SIZE
|
|
489
|
+
: (defaultViewportSize ?? HARDCODED_VIEWPORT_FALLBACK);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
this.headerPolicy =
|
|
493
|
+
headerPolicy &&
|
|
494
|
+
headerPolicy.allowedHosts.length > 0 &&
|
|
495
|
+
Object.keys(headerPolicy.headers).length > 0
|
|
496
|
+
? {
|
|
497
|
+
allowedHosts: [...headerPolicy.allowedHosts],
|
|
498
|
+
headers: { ...headerPolicy.headers },
|
|
499
|
+
}
|
|
500
|
+
: undefined;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Immediately reset all instance state and schedule best-effort cleanup
|
|
505
|
+
* of the temp MCP config file (if one exists). The file unlink is async
|
|
506
|
+
* but fire-and-forget so this method stays non-blocking.
|
|
507
|
+
*/
|
|
508
|
+
private resetState(): void {
|
|
509
|
+
this.cleanupConfigFile();
|
|
510
|
+
this.mcpClient = null;
|
|
511
|
+
this.mcpTransport = null;
|
|
512
|
+
this.mcpProcess = null;
|
|
513
|
+
this.connectionPromise = null;
|
|
514
|
+
this.disconnecting = false;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/** Best-effort async unlink of the current temp config file. */
|
|
518
|
+
private cleanupConfigFile(): void {
|
|
519
|
+
const configPath = this.mcpConfigPath;
|
|
520
|
+
if (!configPath) return;
|
|
521
|
+
this.mcpConfigPath = null;
|
|
522
|
+
void (async () => {
|
|
523
|
+
try {
|
|
524
|
+
const fsp = await import("fs/promises");
|
|
525
|
+
await fsp.unlink(configPath);
|
|
526
|
+
} catch {
|
|
527
|
+
// already-deleted or inaccessible — fine
|
|
528
|
+
}
|
|
529
|
+
})();
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Force-kill the MCP child process. Sends SIGKILL directly — no graceful
|
|
534
|
+
* shutdown, no waiting. Used during disconnect and error recovery so the
|
|
535
|
+
* agent is never blocked on a hung Playwright process.
|
|
536
|
+
*/
|
|
537
|
+
private forceKillProcess(
|
|
538
|
+
proc: import("child_process").ChildProcess | null = this.mcpProcess,
|
|
539
|
+
// Bind the sweep to a specific launch. `onclose` passes its own generation
|
|
540
|
+
// so a relaunch that has already overwritten `currentLaunchId` can never
|
|
541
|
+
// have its fresh browser killed by the previous generation's teardown.
|
|
542
|
+
launchId: string | null = this.currentLaunchId,
|
|
543
|
+
): void {
|
|
544
|
+
// Was an early `return`, which skipped the sweep below in exactly the case
|
|
545
|
+
// that needs it — a node that already exited.
|
|
546
|
+
if (proc && proc.exitCode === null) {
|
|
547
|
+
// Snapshot descendants BEFORE the node dies; afterwards they reparent to
|
|
548
|
+
// init. The group-kill misses them because the node isn't a group leader.
|
|
549
|
+
const rootPid = proc.pid ?? null;
|
|
550
|
+
const descendants = rootPid != null ? collectDescendantPids(rootPid) : [];
|
|
551
|
+
// Snapshot starttimes before kill so we refuse PID-reuse kills after reparent.
|
|
552
|
+
const descendantStarts = new Map<number, number | null>();
|
|
553
|
+
for (const pid of descendants) {
|
|
554
|
+
descendantStarts.set(pid, readProcStartTime(pid));
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
try {
|
|
558
|
+
if (rootPid != null) {
|
|
559
|
+
try {
|
|
560
|
+
process.kill(-rootPid, "SIGKILL");
|
|
561
|
+
} catch {
|
|
562
|
+
proc.kill("SIGKILL");
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
proc.kill("SIGKILL");
|
|
566
|
+
}
|
|
567
|
+
} catch {
|
|
568
|
+
// Already dead — fine
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
for (const pid of descendants) {
|
|
572
|
+
// An unverifiable starttime can't rule out PID reuse, so decline the
|
|
573
|
+
// kill; the marker sweep below covers anything skipped here.
|
|
574
|
+
const expected = descendantStarts.get(pid);
|
|
575
|
+
const now = readProcStartTime(pid);
|
|
576
|
+
if (expected == null || now == null || now !== expected) continue;
|
|
577
|
+
try {
|
|
578
|
+
process.kill(pid, "SIGKILL");
|
|
579
|
+
} catch {
|
|
580
|
+
// Already gone — fine
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
this.reapLaunchedProcesses(launchId);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* SIGKILL anything still carrying the given launch's marker. Idempotent, and
|
|
590
|
+
* can only ever target processes this session launched.
|
|
591
|
+
*/
|
|
592
|
+
private reapLaunchedProcesses(launchId: string | null): void {
|
|
593
|
+
if (!launchId) return;
|
|
594
|
+
for (const pid of collectPidsByEnvMarker(BROWSER_LAUNCH_ENV, launchId)) {
|
|
595
|
+
try {
|
|
596
|
+
process.kill(pid, "SIGKILL");
|
|
597
|
+
} catch {
|
|
598
|
+
// Already gone — fine
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
private async buildMcpLaunch(launchId: string): Promise<{
|
|
604
|
+
cfg: unknown;
|
|
605
|
+
env: Record<string, string>;
|
|
606
|
+
}> {
|
|
607
|
+
const env: Record<string, string> = { [BROWSER_LAUNCH_ENV]: launchId };
|
|
608
|
+
if (this.display) env.DISPLAY = this.display;
|
|
609
|
+
|
|
610
|
+
if (this.engine === "chrome") {
|
|
611
|
+
const parsed = this.viewportSize
|
|
612
|
+
? parseViewportSize(this.viewportSize)
|
|
613
|
+
: undefined;
|
|
614
|
+
const viewport = parsed
|
|
615
|
+
? { width: parsed[0], height: parsed[1] }
|
|
616
|
+
: undefined;
|
|
617
|
+
return {
|
|
618
|
+
cfg: {
|
|
619
|
+
browser: {
|
|
620
|
+
browserName: "chromium",
|
|
621
|
+
launchOptions: {
|
|
622
|
+
channel: "chrome",
|
|
623
|
+
headless: this.headless,
|
|
624
|
+
// Sandbox images run as root, where Chrome refuses to start sandboxed.
|
|
625
|
+
chromiumSandbox: false,
|
|
626
|
+
args: ["--disable-dev-shm-usage"],
|
|
627
|
+
},
|
|
628
|
+
contextOptions: {
|
|
629
|
+
...(viewport ? { viewport } : {}),
|
|
630
|
+
},
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
env,
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// Drive an anti-detect Camoufox (Firefox) instead of vanilla Chromium.
|
|
638
|
+
// camoufox-js produces the executablePath / args / firefoxUserPrefs / env
|
|
639
|
+
// that carry the fingerprint; MCP drives that browser through the same
|
|
640
|
+
// tool API. We pass these via a temp config file rather than CLI flags.
|
|
641
|
+
// Resolve once per session lifetime so reconnects keep the same fingerprint.
|
|
642
|
+
await ensureCamoufox();
|
|
643
|
+
if (!this.cachedCamouOptions) {
|
|
644
|
+
// Apply viewportSize as Camoufox `window` so the headed browser fills
|
|
645
|
+
// the bound Xvfb desktop (previously stored but never forwarded —
|
|
646
|
+
// Camoufox randomised the window and overflowed 720p endpoint streams).
|
|
647
|
+
const window = this.viewportSize
|
|
648
|
+
? parseViewportSize(this.viewportSize)
|
|
649
|
+
: undefined;
|
|
650
|
+
this.cachedCamouOptions = await resolveCamoufoxLaunchOptions(
|
|
651
|
+
this.headless,
|
|
652
|
+
window ? { window } : undefined,
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
const camou = this.cachedCamouOptions;
|
|
656
|
+
return {
|
|
657
|
+
cfg: {
|
|
658
|
+
browser: {
|
|
659
|
+
browserName: "firefox",
|
|
660
|
+
launchOptions: {
|
|
661
|
+
executablePath: camou.executablePath,
|
|
662
|
+
args: camou.args,
|
|
663
|
+
firefoxUserPrefs: camou.firefoxUserPrefs,
|
|
664
|
+
headless: camou.headless,
|
|
665
|
+
},
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
env: {
|
|
669
|
+
...Object.fromEntries(
|
|
670
|
+
Object.entries(camou.env).map(([k, v]) => [k, String(v)]),
|
|
671
|
+
),
|
|
672
|
+
...env,
|
|
673
|
+
},
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
private async installHeaderRoute(client: Client): Promise<void> {
|
|
678
|
+
if (!this.headerPolicy) return;
|
|
679
|
+
await withTimeout(
|
|
680
|
+
client.callTool({
|
|
681
|
+
name: "browser_run_code",
|
|
682
|
+
arguments: {
|
|
683
|
+
code: browserHeaderRouteFunction(this.headerPolicy),
|
|
684
|
+
},
|
|
685
|
+
}),
|
|
686
|
+
MCP_TOOL_CALL_TIMEOUT_MS,
|
|
687
|
+
"Browser header route installation timed out",
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Initialize or return existing MCP client connection for this session.
|
|
693
|
+
* Handles race conditions when multiple tools within the same agent
|
|
694
|
+
* try to connect simultaneously. Detects dead transports and
|
|
695
|
+
* auto-reconnects.
|
|
696
|
+
*/
|
|
697
|
+
async initialize(): Promise<Client> {
|
|
698
|
+
if (this.mcpClient) {
|
|
699
|
+
if ((this.mcpClient as unknown as { transport?: unknown }).transport) {
|
|
700
|
+
return this.mcpClient;
|
|
701
|
+
}
|
|
702
|
+
this.forceKillProcess();
|
|
703
|
+
this.resetState();
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (this.connectionPromise) {
|
|
707
|
+
return this.connectionPromise;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
this.connectionPromise = (async () => {
|
|
711
|
+
try {
|
|
712
|
+
const require_ = createRequire(import.meta.url);
|
|
713
|
+
const mcpPkgJsonPath = require_.resolve("@playwright/mcp/package.json");
|
|
714
|
+
const cliPath = join(dirname(mcpPkgJsonPath), "cli.js");
|
|
715
|
+
|
|
716
|
+
const args = [cliPath, "--isolated"];
|
|
717
|
+
|
|
718
|
+
const os = await import("node:os");
|
|
719
|
+
const fsp = await import("node:fs/promises");
|
|
720
|
+
const launchId = randomUUID();
|
|
721
|
+
this.currentLaunchId = launchId;
|
|
722
|
+
|
|
723
|
+
const { cfg, env } = await this.buildMcpLaunch(launchId);
|
|
724
|
+
this.mcpConfigPath = join(
|
|
725
|
+
os.tmpdir(),
|
|
726
|
+
`pensar-mcp-${process.pid}-${Date.now()}.json`,
|
|
727
|
+
);
|
|
728
|
+
await fsp.writeFile(this.mcpConfigPath, JSON.stringify(cfg), {
|
|
729
|
+
encoding: "utf-8",
|
|
730
|
+
mode: 0o600,
|
|
731
|
+
});
|
|
732
|
+
args.push("--config", this.mcpConfigPath);
|
|
733
|
+
|
|
734
|
+
const transport = new StdioClientTransport({
|
|
735
|
+
command: "node",
|
|
736
|
+
args,
|
|
737
|
+
stderr: "pipe",
|
|
738
|
+
env,
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
const client = new Client({
|
|
742
|
+
name: "apex-browser-agent",
|
|
743
|
+
version: "1.0.0",
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
// Hook into transport to capture the child process reference
|
|
747
|
+
const origStart = transport.start.bind(transport);
|
|
748
|
+
transport.start = async () => {
|
|
749
|
+
await origStart();
|
|
750
|
+
this.mcpProcess =
|
|
751
|
+
(
|
|
752
|
+
transport as unknown as {
|
|
753
|
+
_process?: import("child_process").ChildProcess;
|
|
754
|
+
}
|
|
755
|
+
)._process ?? null;
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
await withTimeout(
|
|
759
|
+
client.connect(transport),
|
|
760
|
+
MCP_CONNECT_TIMEOUT_MS,
|
|
761
|
+
"MCP client connection timed out",
|
|
762
|
+
);
|
|
763
|
+
await this.installHeaderRoute(client);
|
|
764
|
+
|
|
765
|
+
this.mcpClient = client;
|
|
766
|
+
this.mcpTransport = transport;
|
|
767
|
+
|
|
768
|
+
client.onclose = () => {
|
|
769
|
+
if (this.mcpClient === client) {
|
|
770
|
+
// Must run before resetState() nulls the handle. This path used to
|
|
771
|
+
// drop it without killing anything, stranding one Camoufox each time.
|
|
772
|
+
this.forceKillProcess(this.mcpProcess, launchId);
|
|
773
|
+
this.resetState();
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
return client;
|
|
778
|
+
} catch (error) {
|
|
779
|
+
this.forceKillProcess();
|
|
780
|
+
this.resetState();
|
|
781
|
+
throw error;
|
|
782
|
+
}
|
|
783
|
+
})();
|
|
784
|
+
|
|
785
|
+
return this.connectionPromise;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* Disconnect and cleanup this session's MCP client and browser.
|
|
790
|
+
*
|
|
791
|
+
* Designed to NEVER hang: resets state synchronously, then kills
|
|
792
|
+
* the transport and process. Does NOT call browser_close (which
|
|
793
|
+
* could block for 60 s if the server is hung).
|
|
794
|
+
*/
|
|
795
|
+
async disconnect(): Promise<void> {
|
|
796
|
+
if (this.disconnecting) return;
|
|
797
|
+
this.disconnecting = true;
|
|
798
|
+
|
|
799
|
+
const transport = this.mcpTransport;
|
|
800
|
+
const client = this.mcpClient;
|
|
801
|
+
// Capture the child BEFORE resetState() nulls it — otherwise the kill
|
|
802
|
+
// below is a no-op (the original bug).
|
|
803
|
+
const proc = this.mcpProcess;
|
|
804
|
+
|
|
805
|
+
this.resetState();
|
|
806
|
+
this.disconnecting = true; // re-set because resetState clears it
|
|
807
|
+
|
|
808
|
+
// SIGKILL the MCP child FIRST. Previously this ran *after* the awaited
|
|
809
|
+
// client/transport.close() calls AND read the already-nulled
|
|
810
|
+
// this.mcpProcess, so it never actually killed anything: disconnect relied
|
|
811
|
+
// entirely on close() to end the child. When the Playwright MCP child is
|
|
812
|
+
// wedged, transport.close() blocks indefinitely — so disconnect() (and any
|
|
813
|
+
// caller awaiting it, e.g. the agent's consume() teardown) hung forever,
|
|
814
|
+
// stranding an endpoint that had already finished its run. Killing the
|
|
815
|
+
// child up front makes the stdio transport observe EOF so close() resolves
|
|
816
|
+
// promptly, and guarantees disconnect() honors its "never hangs" contract.
|
|
817
|
+
this.forceKillProcess(proc);
|
|
818
|
+
|
|
819
|
+
// Graceful close is best-effort cleanup and must never block the caller —
|
|
820
|
+
// bound it so a stuck client/transport can't re-introduce the hang.
|
|
821
|
+
const CLOSE_TIMEOUT_MS = 5_000;
|
|
822
|
+
let closeTimer: ReturnType<typeof setTimeout> | undefined;
|
|
823
|
+
await Promise.race([
|
|
824
|
+
(async () => {
|
|
825
|
+
try {
|
|
826
|
+
await client?.close();
|
|
827
|
+
} catch {
|
|
828
|
+
// Ignore — may already be closed
|
|
829
|
+
}
|
|
830
|
+
try {
|
|
831
|
+
await transport?.close();
|
|
832
|
+
} catch {
|
|
833
|
+
// Ignore — may already be closed
|
|
834
|
+
}
|
|
835
|
+
})(),
|
|
836
|
+
new Promise<void>((resolve) => {
|
|
837
|
+
closeTimer = setTimeout(resolve, CLOSE_TIMEOUT_MS);
|
|
838
|
+
}),
|
|
839
|
+
]);
|
|
840
|
+
if (closeTimer) clearTimeout(closeTimer);
|
|
841
|
+
|
|
842
|
+
this.cleanupConfigFile();
|
|
843
|
+
|
|
844
|
+
this.disconnecting = false;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/** Check if this session's client is currently connected. */
|
|
848
|
+
isConnected(): boolean {
|
|
849
|
+
return this.mcpClient !== null;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* Snapshot this session's full Playwright storage state (cookies + per-origin
|
|
854
|
+
* localStorage) by invoking `BrowserContext.storageState()` through the
|
|
855
|
+
* MCP `browser_run_code` tool.
|
|
856
|
+
*
|
|
857
|
+
* Returns `null` when the session has never been initialised (no Chromium
|
|
858
|
+
* to ask), when no page is open, or when the call / response parse fails.
|
|
859
|
+
* Callers should treat a `null` result as "no auth state to clone" and
|
|
860
|
+
* proceed with an unseeded session.
|
|
861
|
+
*
|
|
862
|
+
* Cheap to call repeatedly — the underlying MCP call is a few KB of JSON.
|
|
863
|
+
*/
|
|
864
|
+
async captureStorageState(): Promise<BrowserStorageState | null> {
|
|
865
|
+
if (!this.isConnected()) return null;
|
|
866
|
+
|
|
867
|
+
try {
|
|
868
|
+
const result = await this.callTool("browser_run_code", {
|
|
869
|
+
code: `async (page) => { return await page.context().storageState(); }`,
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
return parseStorageStateResult(result);
|
|
873
|
+
} catch {
|
|
874
|
+
return null;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Seed this session's browser context with a previously-captured
|
|
880
|
+
* {@link BrowserStorageState}. Initialises the session if it hasn't been
|
|
881
|
+
* connected yet, then injects:
|
|
882
|
+
*
|
|
883
|
+
* - cookies, immediately, via `BrowserContext.addCookies()`
|
|
884
|
+
* - per-origin localStorage, lazily, via `BrowserContext.addInitScript()`
|
|
885
|
+
* so the values are written into `localStorage` whenever a page from
|
|
886
|
+
* that origin loads
|
|
887
|
+
*
|
|
888
|
+
* The init-script approach means localStorage is restored on the next
|
|
889
|
+
* `browser_navigate` call — calling `browser_evaluate` on `about:blank`
|
|
890
|
+
* before navigating won't see the seeded values (those live on the
|
|
891
|
+
* target origin). Cookies are visible immediately and will be sent on
|
|
892
|
+
* the first navigation.
|
|
893
|
+
*
|
|
894
|
+
* Best-effort: errors are swallowed so a seeding failure never blocks
|
|
895
|
+
* the worker from running with an unauthenticated session.
|
|
896
|
+
*/
|
|
897
|
+
async seedStorageState(state: BrowserStorageState): Promise<void> {
|
|
898
|
+
await this.initialize();
|
|
899
|
+
|
|
900
|
+
const code = `async (page) => {
|
|
901
|
+
const ctx = page.context();
|
|
902
|
+
const state = ${JSON.stringify(state)};
|
|
903
|
+
if (state.cookies && state.cookies.length > 0) {
|
|
904
|
+
try { await ctx.addCookies(state.cookies); } catch (e) {}
|
|
905
|
+
}
|
|
906
|
+
if (state.origins && state.origins.length > 0) {
|
|
907
|
+
const parts = [];
|
|
908
|
+
for (const o of state.origins) {
|
|
909
|
+
if (!o.localStorage || o.localStorage.length === 0) continue;
|
|
910
|
+
const setters = o.localStorage.map(function(it) {
|
|
911
|
+
return 'try{localStorage.setItem(' + JSON.stringify(it.name) + ',' + JSON.stringify(it.value) + ');}catch(e){}';
|
|
912
|
+
}).join('');
|
|
913
|
+
parts.push('if (location.origin === ' + JSON.stringify(o.origin) + ') {' + setters + '}');
|
|
914
|
+
}
|
|
915
|
+
if (parts.length > 0) {
|
|
916
|
+
try { await ctx.addInitScript({ content: parts.join('\\n') }); } catch (e) {}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return { ok: true, cookies: (state.cookies||[]).length, origins: (state.origins||[]).length };
|
|
920
|
+
}`;
|
|
921
|
+
|
|
922
|
+
try {
|
|
923
|
+
await this.callTool("browser_run_code", { code });
|
|
924
|
+
} catch {
|
|
925
|
+
// Best-effort — proceed even if seeding partially or fully failed.
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* Call a tool on this session's MCP server and extract the result.
|
|
931
|
+
*
|
|
932
|
+
* Each call is guarded by:
|
|
933
|
+
* 1. The SDK's native abort signal (properly cancels the request)
|
|
934
|
+
* 2. An outer timeout (in case the SDK's cancellation gets stuck)
|
|
935
|
+
* 3. Auto-reconnection on transport errors
|
|
936
|
+
*/
|
|
937
|
+
async callTool(
|
|
938
|
+
toolName: string,
|
|
939
|
+
args: Record<string, unknown>,
|
|
940
|
+
abortSignal?: AbortSignal,
|
|
941
|
+
): Promise<unknown> {
|
|
942
|
+
if (abortSignal?.aborted) {
|
|
943
|
+
throw new Error("Browser tool call aborted");
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
let client: Client;
|
|
947
|
+
try {
|
|
948
|
+
client = await withTimeout(
|
|
949
|
+
this.initialize(),
|
|
950
|
+
MCP_CONNECT_TIMEOUT_MS,
|
|
951
|
+
"MCP client initialization timed out",
|
|
952
|
+
);
|
|
953
|
+
} catch (error) {
|
|
954
|
+
this.forceKillProcess();
|
|
955
|
+
this.resetState();
|
|
956
|
+
throw error;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
const callController = new AbortController();
|
|
960
|
+
let abortCleanup: (() => void) | undefined;
|
|
961
|
+
|
|
962
|
+
if (abortSignal) {
|
|
963
|
+
const handler = () => callController.abort(abortSignal.reason);
|
|
964
|
+
if (abortSignal.aborted) {
|
|
965
|
+
callController.abort(abortSignal.reason);
|
|
966
|
+
} else {
|
|
967
|
+
abortSignal.addEventListener("abort", handler, { once: true });
|
|
968
|
+
abortCleanup = () => abortSignal.removeEventListener("abort", handler);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
const timeoutTimer = setTimeout(
|
|
973
|
+
() =>
|
|
974
|
+
callController.abort(
|
|
975
|
+
new Error(
|
|
976
|
+
`Browser tool "${toolName}" timed out after ${MCP_TOOL_CALL_TIMEOUT_MS / 1000}s`,
|
|
977
|
+
),
|
|
978
|
+
),
|
|
979
|
+
MCP_TOOL_CALL_TIMEOUT_MS,
|
|
980
|
+
);
|
|
981
|
+
|
|
982
|
+
try {
|
|
983
|
+
const result = await client.callTool(
|
|
984
|
+
{ name: toolName, arguments: args },
|
|
985
|
+
undefined,
|
|
986
|
+
{ signal: callController.signal },
|
|
987
|
+
);
|
|
988
|
+
|
|
989
|
+
if (result && "content" in result && Array.isArray(result.content)) {
|
|
990
|
+
const imageContent = result.content.find(
|
|
991
|
+
(c: { type: string }) => c.type === "image",
|
|
992
|
+
);
|
|
993
|
+
if (imageContent && "data" in imageContent) {
|
|
994
|
+
return { type: "image", data: imageContent.data };
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
const textContent = result.content.find(
|
|
998
|
+
(c: { type: string }) => c.type === "text",
|
|
999
|
+
);
|
|
1000
|
+
if (textContent && "text" in textContent) {
|
|
1001
|
+
try {
|
|
1002
|
+
return JSON.parse(textContent.text as string);
|
|
1003
|
+
} catch {
|
|
1004
|
+
return textContent.text;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return result.content;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
return result;
|
|
1011
|
+
} catch (error) {
|
|
1012
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
1013
|
+
const isConnectionDead =
|
|
1014
|
+
msg.includes("Not connected") ||
|
|
1015
|
+
msg.includes("Connection closed") ||
|
|
1016
|
+
msg.includes("EPIPE") ||
|
|
1017
|
+
msg.includes("write after end");
|
|
1018
|
+
|
|
1019
|
+
if (isConnectionDead && this.mcpClient === client) {
|
|
1020
|
+
this.forceKillProcess();
|
|
1021
|
+
this.resetState();
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
throw error;
|
|
1025
|
+
} finally {
|
|
1026
|
+
clearTimeout(timeoutTimer);
|
|
1027
|
+
abortCleanup?.();
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
export function createPlaywrightBrowserBackend(
|
|
1033
|
+
evidenceDir: string,
|
|
1034
|
+
logger?: Logger,
|
|
1035
|
+
abortSignal?: AbortSignal,
|
|
1036
|
+
headless?: boolean,
|
|
1037
|
+
userAgent?: string | null,
|
|
1038
|
+
viewportSize?: string | null,
|
|
1039
|
+
existingSession?: PlaywrightMcpSession,
|
|
1040
|
+
headerPolicy?: BrowserHeaderPolicy,
|
|
1041
|
+
): BrowserBackend {
|
|
1042
|
+
let session: PlaywrightMcpSession;
|
|
1043
|
+
|
|
1044
|
+
if (existingSession) {
|
|
1045
|
+
session = existingSession;
|
|
1046
|
+
// Owner manages disconnect — do NOT register an abort handler here,
|
|
1047
|
+
// otherwise an inheriting sub-agent finishing first would tear down
|
|
1048
|
+
// the parent's browser mid-flight.
|
|
1049
|
+
} else {
|
|
1050
|
+
// PlaywrightMcpSession's constructor folds in the module-level
|
|
1051
|
+
// defaults (1920x1080 viewport, desktop Chrome UA, headless=true)
|
|
1052
|
+
// when these options are undefined — pass them through verbatim.
|
|
1053
|
+
session = new PlaywrightMcpSession({
|
|
1054
|
+
headless,
|
|
1055
|
+
userAgent,
|
|
1056
|
+
viewportSize,
|
|
1057
|
+
headerPolicy,
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
if (abortSignal) {
|
|
1061
|
+
const onAbort = () => session.disconnect().catch(() => {});
|
|
1062
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
// Ensure evidence directory exists
|
|
1067
|
+
if (!existsSync(evidenceDir)) {
|
|
1068
|
+
mkdirSync(evidenceDir, { recursive: true });
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
return {
|
|
1072
|
+
navigate: async (url) => {
|
|
1073
|
+
try {
|
|
1074
|
+
const result = await session.callTool(
|
|
1075
|
+
"browser_navigate",
|
|
1076
|
+
{ url },
|
|
1077
|
+
abortSignal,
|
|
1078
|
+
);
|
|
1079
|
+
return {
|
|
1080
|
+
success: true,
|
|
1081
|
+
url,
|
|
1082
|
+
result,
|
|
1083
|
+
};
|
|
1084
|
+
} catch (error: unknown) {
|
|
1085
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1086
|
+
logger?.error(`browser_navigate failed: ${message}`);
|
|
1087
|
+
return { success: false, url, error: message };
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
screenshot: async ({ filename }) => {
|
|
1091
|
+
try {
|
|
1092
|
+
const result = await session.callTool(
|
|
1093
|
+
"browser_take_screenshot",
|
|
1094
|
+
{},
|
|
1095
|
+
abortSignal,
|
|
1096
|
+
);
|
|
1097
|
+
|
|
1098
|
+
// Extract base64 image data from various response formats
|
|
1099
|
+
let base64Data: string | undefined;
|
|
1100
|
+
|
|
1101
|
+
if (result && typeof result === "object") {
|
|
1102
|
+
const r = result as Record<string, unknown>;
|
|
1103
|
+
|
|
1104
|
+
// Format 1: { type: "image", data: "<base64>" } — from callTool's image extraction
|
|
1105
|
+
if ("data" in r && typeof r.data === "string") {
|
|
1106
|
+
base64Data = r.data;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
// Format 2: Raw MCP content array — [{type:"image", data:"...", mimeType:"..."}]
|
|
1110
|
+
if (!base64Data && Array.isArray(result)) {
|
|
1111
|
+
const imgItem = (result as Array<Record<string, unknown>>).find(
|
|
1112
|
+
(c) => c.type === "image" && typeof c.data === "string",
|
|
1113
|
+
);
|
|
1114
|
+
if (imgItem) {
|
|
1115
|
+
base64Data = imgItem.data as string;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
if (base64Data) {
|
|
1121
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
1122
|
+
const screenshotFilename = `${filename}_${timestamp}.png`;
|
|
1123
|
+
const screenshotPath = join(evidenceDir, screenshotFilename);
|
|
1124
|
+
const dir = dirname(screenshotPath);
|
|
1125
|
+
if (!existsSync(dir)) {
|
|
1126
|
+
mkdirSync(dir, { recursive: true });
|
|
1127
|
+
}
|
|
1128
|
+
writeFileSync(screenshotPath, Buffer.from(base64Data, "base64"));
|
|
1129
|
+
return {
|
|
1130
|
+
success: true,
|
|
1131
|
+
path: screenshotPath,
|
|
1132
|
+
message: `Screenshot saved to ${screenshotPath}`,
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
// Log the actual response shape to aid debugging
|
|
1137
|
+
const resultShape =
|
|
1138
|
+
result === null
|
|
1139
|
+
? "null"
|
|
1140
|
+
: Array.isArray(result)
|
|
1141
|
+
? `array(${(result as unknown[]).length})`
|
|
1142
|
+
: typeof result === "object"
|
|
1143
|
+
? `object(${Object.keys(result as Record<string, unknown>).join(",")})`
|
|
1144
|
+
: typeof result;
|
|
1145
|
+
return {
|
|
1146
|
+
success: false,
|
|
1147
|
+
error: `No screenshot data returned (response type: ${resultShape})`,
|
|
1148
|
+
};
|
|
1149
|
+
} catch (error: unknown) {
|
|
1150
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1151
|
+
logger?.error(`browser_screenshot failed: ${message}`);
|
|
1152
|
+
return { success: false, error: message };
|
|
1153
|
+
}
|
|
1154
|
+
},
|
|
1155
|
+
snapshot: async () => {
|
|
1156
|
+
try {
|
|
1157
|
+
const result = await session.callTool(
|
|
1158
|
+
"browser_snapshot",
|
|
1159
|
+
{},
|
|
1160
|
+
abortSignal,
|
|
1161
|
+
);
|
|
1162
|
+
return {
|
|
1163
|
+
success: true,
|
|
1164
|
+
snapshot:
|
|
1165
|
+
typeof result === "string"
|
|
1166
|
+
? result
|
|
1167
|
+
: JSON.stringify(result, null, 2),
|
|
1168
|
+
};
|
|
1169
|
+
} catch (error: unknown) {
|
|
1170
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1171
|
+
logger?.error(`browser_snapshot failed: ${message}`);
|
|
1172
|
+
return { success: false, error: message };
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
click: async ({ element, ref }) => {
|
|
1176
|
+
try {
|
|
1177
|
+
const args: Record<string, unknown> = { element };
|
|
1178
|
+
if (ref) {
|
|
1179
|
+
args.ref = ref;
|
|
1180
|
+
}
|
|
1181
|
+
const result = await session.callTool(
|
|
1182
|
+
"browser_click",
|
|
1183
|
+
args,
|
|
1184
|
+
abortSignal,
|
|
1185
|
+
);
|
|
1186
|
+
return { success: true, element, result };
|
|
1187
|
+
} catch (error: unknown) {
|
|
1188
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1189
|
+
logger?.error(`browser_click failed: ${message}`);
|
|
1190
|
+
return { success: false, error: message };
|
|
1191
|
+
}
|
|
1192
|
+
},
|
|
1193
|
+
fill: async ({ element, ref, value }) => {
|
|
1194
|
+
try {
|
|
1195
|
+
// Note: Playwright MCP uses "browser_type" for filling fields
|
|
1196
|
+
const args: Record<string, unknown> = { element, text: value };
|
|
1197
|
+
if (ref) {
|
|
1198
|
+
args.ref = ref;
|
|
1199
|
+
}
|
|
1200
|
+
const result = await session.callTool(
|
|
1201
|
+
"browser_type",
|
|
1202
|
+
args,
|
|
1203
|
+
abortSignal,
|
|
1204
|
+
);
|
|
1205
|
+
return { success: true, element, result };
|
|
1206
|
+
} catch (error: unknown) {
|
|
1207
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1208
|
+
logger?.error(`browser_fill failed: ${message}`);
|
|
1209
|
+
return { success: false, error: message };
|
|
1210
|
+
}
|
|
1211
|
+
},
|
|
1212
|
+
evaluate: async ({ script }) => {
|
|
1213
|
+
try {
|
|
1214
|
+
const fnScript = transformScriptToFunction(script);
|
|
1215
|
+
|
|
1216
|
+
const result = await session.callTool(
|
|
1217
|
+
"browser_evaluate",
|
|
1218
|
+
{ function: fnScript },
|
|
1219
|
+
abortSignal,
|
|
1220
|
+
);
|
|
1221
|
+
return { success: true, script, result };
|
|
1222
|
+
} catch (error: unknown) {
|
|
1223
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1224
|
+
logger?.error(`browser_evaluate failed: ${message}`);
|
|
1225
|
+
return { success: false, error: message };
|
|
1226
|
+
}
|
|
1227
|
+
},
|
|
1228
|
+
console: async () => {
|
|
1229
|
+
try {
|
|
1230
|
+
const result = await session.callTool(
|
|
1231
|
+
"browser_console_messages",
|
|
1232
|
+
{},
|
|
1233
|
+
abortSignal,
|
|
1234
|
+
);
|
|
1235
|
+
|
|
1236
|
+
// Parse console messages if they're in JSON format
|
|
1237
|
+
let messages: Array<{ type: string; text: string }> | undefined;
|
|
1238
|
+
if (typeof result === "string") {
|
|
1239
|
+
try {
|
|
1240
|
+
messages = JSON.parse(result);
|
|
1241
|
+
} catch {
|
|
1242
|
+
messages = [{ type: "log", text: result }];
|
|
1243
|
+
}
|
|
1244
|
+
} else if (Array.isArray(result)) {
|
|
1245
|
+
messages = result as Array<{ type: string; text: string }>;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
return { success: true, messages, result };
|
|
1249
|
+
} catch (error: unknown) {
|
|
1250
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1251
|
+
logger?.error(`browser_console failed: ${message}`);
|
|
1252
|
+
return { success: false, error: message };
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
1255
|
+
getCookies: async ({ urls } = {}) => {
|
|
1256
|
+
try {
|
|
1257
|
+
// Playwright MCP doesn't expose a dedicated cookie tool, so we use
|
|
1258
|
+
// browser_run_code to call the Playwright context API directly.
|
|
1259
|
+
// This gets ALL cookies including httpOnly ones.
|
|
1260
|
+
const urlFilter =
|
|
1261
|
+
urls && urls.length > 0 ? JSON.stringify(urls) : "undefined";
|
|
1262
|
+
const code = `async (page) => { const cookies = await page.context().cookies(${urlFilter === "undefined" ? "" : urlFilter}); return cookies; }`;
|
|
1263
|
+
|
|
1264
|
+
const result = await session.callTool(
|
|
1265
|
+
"browser_run_code",
|
|
1266
|
+
{ code },
|
|
1267
|
+
abortSignal,
|
|
1268
|
+
);
|
|
1269
|
+
|
|
1270
|
+
let cookies: Array<{
|
|
1271
|
+
name: string;
|
|
1272
|
+
value: string;
|
|
1273
|
+
domain: string;
|
|
1274
|
+
path: string;
|
|
1275
|
+
httpOnly: boolean;
|
|
1276
|
+
secure: boolean;
|
|
1277
|
+
}> = [];
|
|
1278
|
+
|
|
1279
|
+
if (typeof result === "string") {
|
|
1280
|
+
// Playwright MCP wraps results as "### Result\n<value>\n\n### Ran Playwright code\n...".
|
|
1281
|
+
// Strip the prefix and any trailing Playwright output sections.
|
|
1282
|
+
const stripped = result
|
|
1283
|
+
.replace(/^###\s*Result\s*\n?/, "")
|
|
1284
|
+
.replace(/\n\n###[\s\S]*$/, "")
|
|
1285
|
+
.trim();
|
|
1286
|
+
try {
|
|
1287
|
+
const parsed = JSON.parse(stripped);
|
|
1288
|
+
if (Array.isArray(parsed)) {
|
|
1289
|
+
cookies = parsed;
|
|
1290
|
+
} else if (typeof parsed === "string") {
|
|
1291
|
+
cookies = JSON.parse(parsed);
|
|
1292
|
+
}
|
|
1293
|
+
} catch {
|
|
1294
|
+
const jsonMatch = stripped.match(/\[[\s\S]*\]/);
|
|
1295
|
+
if (jsonMatch) {
|
|
1296
|
+
try {
|
|
1297
|
+
cookies = JSON.parse(jsonMatch[0]);
|
|
1298
|
+
} catch {
|
|
1299
|
+
// Could not parse
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
} else if (Array.isArray(result)) {
|
|
1304
|
+
cookies = result as typeof cookies;
|
|
1305
|
+
} else if (
|
|
1306
|
+
result &&
|
|
1307
|
+
typeof result === "object" &&
|
|
1308
|
+
"cookies" in result
|
|
1309
|
+
) {
|
|
1310
|
+
cookies = (result as { cookies: typeof cookies }).cookies;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
const cookieHeader = cookies
|
|
1314
|
+
.map((c) => `${c.name}=${c.value}`)
|
|
1315
|
+
.join("; ");
|
|
1316
|
+
|
|
1317
|
+
return {
|
|
1318
|
+
success: true,
|
|
1319
|
+
cookies,
|
|
1320
|
+
cookieHeader,
|
|
1321
|
+
};
|
|
1322
|
+
} catch (error: unknown) {
|
|
1323
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1324
|
+
logger?.error(`browser_get_cookies failed: ${message}`);
|
|
1325
|
+
return { success: false, error: message };
|
|
1326
|
+
}
|
|
1327
|
+
},
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* Create browser automation tools backed by a **dedicated** Playwright MCP
|
|
1333
|
+
* session. Every invocation spins up its own MCP child-process / browser so
|
|
1334
|
+
* that concurrent agents never share a browser context.
|
|
1335
|
+
*
|
|
1336
|
+
* @param targetUrl - Base target URL for context in descriptions
|
|
1337
|
+
* @param evidenceDir - Directory to save screenshots
|
|
1338
|
+
* @param mode - "pentest" for automated pentesting, "operator" for user-driven reconnaissance, "auth" for authentication flows
|
|
1339
|
+
* @param logger - Optional logger for error reporting
|
|
1340
|
+
* @param abortSignal - Optional abort signal for cleanup
|
|
1341
|
+
* @param headless - Override headless mode for this session (defaults to the
|
|
1342
|
+
* value set by {@link setHeadlessMode}, which itself defaults to `true`)
|
|
1343
|
+
* @param userAgent - Override User-Agent for this session (defaults to the
|
|
1344
|
+
* value set by {@link setUserAgent}). Passing `null` forces Chromium's
|
|
1345
|
+
* built-in UA (useful if the default anti-bot UA is counter-productive).
|
|
1346
|
+
* @param viewportSize - Override viewport size (format `"WIDTH,HEIGHT"`) for
|
|
1347
|
+
* this session (defaults to the value set by {@link setViewportSize}).
|
|
1348
|
+
* Passing `null` forces Chromium's default viewport.
|
|
1349
|
+
* @param existingSession - When provided, browser tools reuse this
|
|
1350
|
+
* already-constructed session instead of creating a new MCP child-process
|
|
1351
|
+
* / Chromium instance. Used by sub-agents (e.g. workers spawned via
|
|
1352
|
+
* `spawn_pentest_agent`) to inherit a parent's authenticated browser
|
|
1353
|
+
* context. Headless / userAgent / viewportSize are ignored when an
|
|
1354
|
+
* existing session is passed — those are baked into the session at
|
|
1355
|
+
* construction time. Lifecycle: the caller that originally constructed
|
|
1356
|
+
* the session owns disconnect, so `abortSignal` is NOT wired to disconnect
|
|
1357
|
+
* when reusing a session.
|
|
1358
|
+
*/
|
|
1359
|
+
/**
|
|
1360
|
+
* Lazy per-member browser tool factories. Shared state (the MCP session,
|
|
1361
|
+
* evidence dir, mode descriptions) is built once per call; each member's
|
|
1362
|
+
* tool object is constructed only when its factory is invoked, so a
|
|
1363
|
+
* selection of one member never allocates sibling tool schemas.
|
|
1364
|
+
*/
|
|
1365
|
+
export function createBrowserToolFactories(
|
|
1366
|
+
targetUrl: string,
|
|
1367
|
+
evidenceDir: string,
|
|
1368
|
+
mode: BrowserToolMode = "pentest",
|
|
1369
|
+
logger?: Logger,
|
|
1370
|
+
abortSignal?: AbortSignal,
|
|
1371
|
+
headless?: boolean,
|
|
1372
|
+
userAgent?: string | null,
|
|
1373
|
+
viewportSize?: string | null,
|
|
1374
|
+
existingSession?: PlaywrightMcpSession,
|
|
1375
|
+
headerPolicy?: BrowserHeaderPolicy,
|
|
1376
|
+
) {
|
|
1377
|
+
return createBackendBrowserToolFactories(
|
|
1378
|
+
createPlaywrightBrowserBackend(
|
|
1379
|
+
evidenceDir,
|
|
1380
|
+
logger,
|
|
1381
|
+
abortSignal,
|
|
1382
|
+
headless,
|
|
1383
|
+
userAgent,
|
|
1384
|
+
viewportSize,
|
|
1385
|
+
existingSession,
|
|
1386
|
+
headerPolicy,
|
|
1387
|
+
),
|
|
1388
|
+
{ targetUrl, mode },
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
export function createBrowserTools(
|
|
1393
|
+
targetUrl: string,
|
|
1394
|
+
evidenceDir: string,
|
|
1395
|
+
mode: BrowserToolMode = "pentest",
|
|
1396
|
+
logger?: Logger,
|
|
1397
|
+
abortSignal?: AbortSignal,
|
|
1398
|
+
headless?: boolean,
|
|
1399
|
+
userAgent?: string | null,
|
|
1400
|
+
viewportSize?: string | null,
|
|
1401
|
+
existingSession?: PlaywrightMcpSession,
|
|
1402
|
+
headerPolicy?: BrowserHeaderPolicy,
|
|
1403
|
+
) {
|
|
1404
|
+
const factories = createBrowserToolFactories(
|
|
1405
|
+
targetUrl,
|
|
1406
|
+
evidenceDir,
|
|
1407
|
+
mode,
|
|
1408
|
+
logger,
|
|
1409
|
+
abortSignal,
|
|
1410
|
+
headless,
|
|
1411
|
+
userAgent,
|
|
1412
|
+
viewportSize,
|
|
1413
|
+
existingSession,
|
|
1414
|
+
headerPolicy,
|
|
1415
|
+
);
|
|
1416
|
+
return {
|
|
1417
|
+
browser_navigate: factories.browser_navigate(),
|
|
1418
|
+
browser_snapshot: factories.browser_snapshot(),
|
|
1419
|
+
browser_screenshot: factories.browser_screenshot(),
|
|
1420
|
+
browser_click: factories.browser_click(),
|
|
1421
|
+
browser_fill: factories.browser_fill(),
|
|
1422
|
+
browser_evaluate: factories.browser_evaluate(),
|
|
1423
|
+
browser_console: factories.browser_console(),
|
|
1424
|
+
browser_get_cookies: factories.browser_get_cookies(),
|
|
1425
|
+
};
|
|
1426
|
+
}
|