@pensar/apex 2.5.0 → 2.6.1-canary.0cc77dcc
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-6mzhkzxj.js +13 -0
- package/build/agent-9ymr36jt.js +13 -0
- package/build/{agent-m30a62kh.js → agent-fb1d2x2a.js} +48 -50
- package/build/agent-h8z7zb26.js +15 -0
- package/build/agent-runs-awgj4sat.js +313 -0
- package/build/{apps-x4ef2gpc.js → apps-d50kkp3g.js} +50 -58
- package/build/{auth-7ay8qgxm.js → auth-396rc66q.js} +61 -68
- package/build/blackboxAgent-j3ncq55f.js +13 -0
- package/build/blackboxPentest-aw69ect4.js +59 -0
- package/build/cli-0ym9qz7r.js +175 -0
- package/build/{cli-zav1yx5k.js → cli-2dqvgkh8.js} +990 -632
- package/build/cli-38j2jc0m.js +62 -0
- package/build/{cli-ee3axgts.js → cli-3gt761d2.js} +7 -1
- package/build/{cli-sx3jkv7p.js → cli-3p4gyc9m.js} +28872 -25951
- package/build/cli-3qznjsnr.js +14 -0
- package/build/cli-5ppxe6qz.js +355 -0
- package/build/cli-691cfgdy.js +186 -0
- package/build/{cli-x92fkt2f.js → cli-6y2mzdz2.js} +55 -97
- package/build/{cli-73k43t1r.js → cli-8s4ew1hv.js} +53 -78
- package/build/{cli-53rm0rrz.js → cli-8w8k4dph.js} +1 -1
- package/build/{cli-68260ckj.js → cli-91gs9whc.js} +1658 -1606
- package/build/{cli-7vg06q5r.js → cli-9s7snz6x.js} +135 -125
- package/build/{cli-bw2ddttk.js → cli-a1m3pmke.js} +4730 -267
- package/build/{cli-knd276ed.js → cli-bb02pjt0.js} +31 -31
- package/build/{cli-p4r7q012.js → cli-c0ha5wh1.js} +16072 -12743
- package/build/{cli-j54qa6tm.js → cli-c2k4xxaw.js} +42 -42
- package/build/{cli-k71t434r.js → cli-ec2hwkv3.js} +34 -76
- package/build/{cli-vkbzcnw1.js → cli-fapvkkbh.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-z5c0ypg1.js → cli-jp6wytx1.js} +4 -4
- package/build/cli-mz5pk30x.js +5508 -0
- package/build/{cli-kff2bbq7.js → cli-nmg32cfd.js} +43 -43
- package/build/cli-pckpvwbd.js +22 -0
- package/build/cli-pwm29ks7.js +6337 -0
- package/build/cli-retw3rw5.js +12 -0
- package/build/cli-se8ae8z3.js +2250 -0
- package/build/{cli-dm0fc0bm.js → cli-v1sarr4y.js} +5 -9
- package/build/cli-v9rrvh12.js +429 -0
- package/build/{cli-3py0a0wg.js → cli-vfta27tv.js} +206 -136
- package/build/cli-xcy2vxj2.js +1732 -0
- package/build/{cli-y3dpm18e.js → cli-xn12g67s.js} +75 -92
- package/build/cli.js +769 -195
- package/build/{config-4kzh88xz.js → config-hddxxr27.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-mgws2nav.js} +56 -31
- package/build/{fixes-fv66yn1z.js → fixes-9qtsvwxx.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-0d05xcz4.js +25 -0
- package/build/index-0ef0j7yp.js +12 -0
- package/build/index-557xary4.js +121 -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-cfbd4zej.js +17 -0
- package/build/index-mqaw1ac6.js +9 -0
- package/build/{index-kyd1jm89.js → index-nfhetcq8.js} +159 -169
- package/build/index-qnyevb6q.js +1563 -0
- package/build/{index-fpwr10qm.js → index-wyn4g2c1.js} +5048 -3786
- package/build/index-zbq3rvwx.js +36 -0
- package/build/index-zhr65sg3.js +102 -0
- package/build/{issues-019678t0.js → issues-9zdszfq8.js} +51 -47
- package/build/knowledge-r6rmer3d.js +139 -0
- package/build/lib/chunk-02awpt3c.js +431 -0
- package/build/lib/chunk-0me4mrrd.js +7150 -0
- package/build/lib/chunk-2j49k090.js +922 -0
- package/build/lib/chunk-2njv7wz3.js +178 -0
- package/build/lib/chunk-2t65f749.js +1412 -0
- package/build/lib/chunk-3502z798.js +9232 -0
- package/build/lib/chunk-3q89v4xv.js +21 -0
- package/build/lib/chunk-3w05jmk6.js +685 -0
- package/build/lib/chunk-48zms2q1.js +572 -0
- package/build/lib/chunk-4ydrmwd9.js +980 -0
- package/build/lib/chunk-517rf135.js +143 -0
- package/build/lib/chunk-5cp1fp0x.js +186 -0
- package/build/lib/chunk-7gjdygcx.js +171 -0
- package/build/lib/chunk-8vhr65w3.js +272 -0
- package/build/lib/chunk-9nsrd4xg.js +12 -0
- package/build/lib/chunk-asbemhm5.js +56 -0
- package/build/lib/chunk-b8eq85d2.js +143 -0
- package/build/lib/chunk-bx94rwt5.js +24 -0
- package/build/lib/chunk-eb4h4k1f.js +213 -0
- package/build/lib/chunk-ebkq3bcq.js +102 -0
- package/build/lib/chunk-esymacwg.js +14 -0
- package/build/lib/chunk-f04pr76h.js +317 -0
- package/build/lib/chunk-fy3bbbqy.js +7896 -0
- package/build/lib/chunk-g8d2x00m.js +2429 -0
- package/build/lib/chunk-ja7j565c.js +743 -0
- package/build/lib/chunk-jah67hkt.js +120 -0
- package/build/lib/chunk-jdjagvgr.js +85 -0
- package/build/lib/chunk-k5m5rasy.js +439 -0
- package/build/lib/chunk-mp1czx2y.js +510 -0
- package/build/lib/chunk-mrjbsaf4.js +31 -0
- package/build/lib/chunk-mv74mq5n.js +59 -0
- package/build/lib/chunk-n0ba7khr.js +64 -0
- package/build/lib/chunk-ngp6p527.js +317 -0
- package/build/lib/chunk-q5e23acz.js +52 -0
- package/build/lib/chunk-sk8xnywf.js +212 -0
- package/build/lib/chunk-t5bt5vn1.js +146 -0
- package/build/lib/chunk-tsnk2k9x.js +345 -0
- package/build/lib/chunk-vt9spgd1.js +62 -0
- package/build/lib/chunk-vx228eeq.js +82 -0
- package/build/lib/chunk-wr6ke041.js +11157 -0
- package/build/lib/chunk-xcdtrzk5.js +27 -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 +332 -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 +6 -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-1r7nkzhg.js} +22 -30
- package/build/{multipart-parser-g2xxkezz.js → multipart-parser-vjjdbpd1.js} +10 -10
- package/build/native-rollout-evidence-y0vdtjje.js +135 -0
- package/build/offesecAgent-dfj42jkj.js +22 -0
- package/build/{parse-rtccymzn.js → parse-cqecqrc5.js} +0 -4
- package/build/pentest-n8k0dd5q.js +22 -0
- package/build/pentests-jh9az51h.js +143 -0
- package/build/recordedRunClient-mvendk9n.js +11 -0
- package/build/{targetedPentest-tdwtgmxm.js → targetedPentest-rgffxsgd.js} +22 -22
- package/build/{targets-763n91t7.js → targets-wn0gmdhe.js} +24 -32
- package/build/threatModel-6efzjpbv.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-cmv057jn.js} +3 -3
- package/build/{upload-9qj1kpt9.js → upload-vkkj6h54.js} +8 -14
- package/build/{utils-t7gc2903.js → utils-b1kae4f3.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 +636 -0
- package/src/core/ai/ai.ts +2349 -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 +145 -0
- package/src/core/ai/models/bedrock.ts +600 -0
- package/src/core/ai/models/claude-capabilities.ts +22 -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 +250 -0
- package/src/core/ai/models/mantle.ts +14 -0
- package/src/core/ai/models/models.test.ts +290 -0
- package/src/core/ai/models/openai.ts +409 -0
- package/src/core/ai/models/openrouter.ts +336 -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 +289 -0
- package/src/core/ai/providers/anthropic.ts +73 -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 +638 -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 +796 -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 +115 -0
- package/src/tui/components/chat/message-list.tsx +264 -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 +913 -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 +69 -0
- package/src/tui/components/shared/action-label.test.ts +133 -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/dialog-controls.tsx +76 -0
- package/src/tui/components/shared/index.ts +37 -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 +279 -0
- package/src/tui/components/shared/tool-renderer.test.ts +13 -0
- package/src/tui/components/shared/tool-renderer.tsx +223 -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,1740 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import {
|
|
4
|
+
existsSync,
|
|
5
|
+
mkdirSync,
|
|
6
|
+
readdirSync,
|
|
7
|
+
readFileSync,
|
|
8
|
+
statSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import type { StreamTextOnStepFinishCallback, ToolSet } from "ai";
|
|
13
|
+
import pLimit from "p-limit";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import type { AgentHooks } from "../agents/offSecAgent";
|
|
16
|
+
import {
|
|
17
|
+
inProcessSubagentSpawner,
|
|
18
|
+
type SubagentSpawner,
|
|
19
|
+
} from "../agents/offSecAgent/subagentSpawner";
|
|
20
|
+
import type { DocumentedEndpointRecord } from "../agents/specialized/attackSurface/schemas";
|
|
21
|
+
import { CodeAgent } from "../agents/specialized/codeAgent/agent";
|
|
22
|
+
import {
|
|
23
|
+
type App,
|
|
24
|
+
type AppInfo,
|
|
25
|
+
AppInfoSchema,
|
|
26
|
+
type AppsDiscoveryResult,
|
|
27
|
+
AppsDiscoveryResultSchema,
|
|
28
|
+
type DiscoverySummary,
|
|
29
|
+
DiscoverySummarySchema,
|
|
30
|
+
type Endpoint,
|
|
31
|
+
EndpointSchema,
|
|
32
|
+
WHITEBOX_APPS_DISCOVERY_SYSTEM_PROMPT,
|
|
33
|
+
WHITEBOX_DISCOVERY_SYSTEM_PROMPT,
|
|
34
|
+
type WhiteboxAttackSurfaceResult,
|
|
35
|
+
} from "../agents/specialized/whiteboxAttackSurface";
|
|
36
|
+
import {
|
|
37
|
+
type AgentConcurrencyLimiter,
|
|
38
|
+
runAppEndpointDocumentation,
|
|
39
|
+
} from "../agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent";
|
|
40
|
+
import type {
|
|
41
|
+
AIAuthConfig,
|
|
42
|
+
AIModel,
|
|
43
|
+
CacheMetrics,
|
|
44
|
+
OpenAIReasoningEffort,
|
|
45
|
+
ThinkingEffort,
|
|
46
|
+
} from "../ai";
|
|
47
|
+
import type { AgentEventBus } from "../eventBus";
|
|
48
|
+
import { mapAppWithSurface } from "../integrations/surface";
|
|
49
|
+
import { createLogger } from "../logger/structured";
|
|
50
|
+
import type { SessionInfo } from "../session";
|
|
51
|
+
import { collectCommand } from "../tools/backends/collectCommand";
|
|
52
|
+
import type { ToolBackends } from "../tools/backends/types";
|
|
53
|
+
import { scopedLogger } from "../util/lazyLogger";
|
|
54
|
+
import {
|
|
55
|
+
assertDepth,
|
|
56
|
+
inProcessSeams,
|
|
57
|
+
resolveItemHooks,
|
|
58
|
+
type WorkflowSeams,
|
|
59
|
+
} from "./seams";
|
|
60
|
+
|
|
61
|
+
const log = scopedLogger(() => createLogger("whitebox-workflow"));
|
|
62
|
+
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Constants
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
const DEFAULT_CONCURRENCY = 5;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Hard ceiling on CodeAgents running concurrently across ALL apps and their
|
|
71
|
+
* endpoints. Previously the app-level cap (`DEFAULT_CONCURRENCY` = 5) and the
|
|
72
|
+
* per-app endpoint cap (`ENDPOINT_DOCUMENTATION_CONCURRENCY` = 10) multiplied,
|
|
73
|
+
* so a repo with many apps could run ~50 agents at once — the dominant memory
|
|
74
|
+
* driver in the 8 GiB recon sandbox. A single shared `p-limit` gate makes the
|
|
75
|
+
* cap independent of app/endpoint counts. Override via
|
|
76
|
+
* `WhiteboxAttackSurfaceWorkflowInput.maxConcurrentAgents`.
|
|
77
|
+
*/
|
|
78
|
+
const MAX_CONCURRENT_AGENTS = 12;
|
|
79
|
+
|
|
80
|
+
type DiscoveryTaskType = "pages" | "apiEndpoints" | "cloudResourceEndpoints";
|
|
81
|
+
|
|
82
|
+
// Sibling cards under an app share the app name from their parent;
|
|
83
|
+
// label children by what they *do* instead.
|
|
84
|
+
const TASK_TYPE_LABELS = {
|
|
85
|
+
pages: "Pages",
|
|
86
|
+
apiEndpoints: "API Endpoints",
|
|
87
|
+
cloudResourceEndpoints: "Cloud Resources",
|
|
88
|
+
} as const satisfies Record<DiscoveryTaskType, string>;
|
|
89
|
+
|
|
90
|
+
// App types surface doesn't enumerate — these always use the specialized
|
|
91
|
+
// cloud-resource objective, regardless of `surfaceIntegrationEnabled`.
|
|
92
|
+
const NON_SERVICE_TYPES = ["cloud_resource", "storage", "database"];
|
|
93
|
+
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Helpers
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
function sanitizeName(name: string): string {
|
|
99
|
+
return name.toLowerCase().replace(/[^a-z0-9-_.]/g, "_");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Shape persisted to <app>/app.json. Equivalent to AppInfo — kept as a Pick
|
|
103
|
+
// so the field list can't drift out of sync with the schema.
|
|
104
|
+
type AppMetadata = Pick<
|
|
105
|
+
AppInfo,
|
|
106
|
+
"name" | "type" | "framework" | "description" | "location"
|
|
107
|
+
>;
|
|
108
|
+
|
|
109
|
+
function toAppMetadata(
|
|
110
|
+
app: Pick<App, "name" | "type" | "framework" | "description" | "location">,
|
|
111
|
+
): AppMetadata {
|
|
112
|
+
return {
|
|
113
|
+
name: app.name,
|
|
114
|
+
type: app.type,
|
|
115
|
+
framework: app.framework,
|
|
116
|
+
description: app.description,
|
|
117
|
+
location: app.location,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// System prompts and intermediate schemas live in
|
|
122
|
+
// `src/core/agents/specialized/whiteboxAttackSurface/{prompts,types}.ts`.
|
|
123
|
+
// This file is the orchestration layer that consumes them.
|
|
124
|
+
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Input types
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
export interface WhiteboxAttackSurfaceWorkflowInput {
|
|
130
|
+
/** Preloaded owned-backend artifacts; absent preserves full discovery. */
|
|
131
|
+
incremental?: {
|
|
132
|
+
diffPath: string;
|
|
133
|
+
assetsPath: string;
|
|
134
|
+
existingResult: WhiteboxAttackSurfaceResult;
|
|
135
|
+
};
|
|
136
|
+
codebasePath: string;
|
|
137
|
+
model: AIModel;
|
|
138
|
+
session: SessionInfo;
|
|
139
|
+
authConfig?: AIAuthConfig;
|
|
140
|
+
abortSignal?: AbortSignal;
|
|
141
|
+
eventBus?: AgentEventBus;
|
|
142
|
+
attackSurfaceRegistry?: import("../findings/attackSurfaceRegistry").AttackSurfaceRegistry;
|
|
143
|
+
onStepFinish?: StreamTextOnStepFinishCallback<ToolSet>;
|
|
144
|
+
onCacheMetrics?: (metrics: CacheMetrics) => void;
|
|
145
|
+
openAIReasoningEffort?: OpenAIReasoningEffort | null;
|
|
146
|
+
/** Enable extended thinking for supported models (Anthropic Claude 3.7+). */
|
|
147
|
+
enableThinking?: boolean;
|
|
148
|
+
/** Adaptive-thinking effort hint (Anthropic Opus/Sonnet 4.6+); ignored elsewhere. */
|
|
149
|
+
thinkingEffort?: ThinkingEffort | null;
|
|
150
|
+
/** Known domains associated with the project — agents can map discovered apps to these. */
|
|
151
|
+
domains?: string[];
|
|
152
|
+
/** Project-level threat model content (e.g. from .pensar/threat_model.md), if found */
|
|
153
|
+
projectThreatModel?: string;
|
|
154
|
+
/** Deployment environment names (e.g. ["production", "staging"]) from project settings. */
|
|
155
|
+
environments?: string[];
|
|
156
|
+
/**
|
|
157
|
+
* When false, Phase 2 skips the deterministic `@pensar/surface` path and
|
|
158
|
+
* always runs the legacy pages + apiEndpoints discovery agent pair for
|
|
159
|
+
* service apps. Defaults to `true`.
|
|
160
|
+
*/
|
|
161
|
+
surfaceIntegrationEnabled?: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Hard ceiling on CodeAgents running concurrently across all apps/endpoints.
|
|
164
|
+
* Defaults to {@link MAX_CONCURRENT_AGENTS}. Bounds total agent fan-out so it
|
|
165
|
+
* doesn't scale with the number of apps in the repo.
|
|
166
|
+
*/
|
|
167
|
+
maxConcurrentAgents?: number;
|
|
168
|
+
/** Fan-out spawner. Defaults to the in-process spawner. */
|
|
169
|
+
subagentSpawner?: SubagentSpawner;
|
|
170
|
+
/**
|
|
171
|
+
* The caller's full {@link AgentHooks}, forwarded to every CodeAgent this
|
|
172
|
+
* workflow constructs (Phase 1 apps discovery, Phase 2 per-app/per-endpoint
|
|
173
|
+
* documentation). A per-app override can come from `seams.hooksForItem`
|
|
174
|
+
* (`./seams.ts`).
|
|
175
|
+
*/
|
|
176
|
+
hooks?: AgentHooks;
|
|
177
|
+
/**
|
|
178
|
+
* Fan-out / id / hook seams (`./seams.ts`). Defaults to
|
|
179
|
+
* {@link inProcessSeams}, matching today's in-process behavior.
|
|
180
|
+
*/
|
|
181
|
+
seams?: WorkflowSeams;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface IncrementalWhiteboxInput extends WhiteboxAttackSurfaceWorkflowInput {
|
|
185
|
+
previousCommitSha: string;
|
|
186
|
+
currentCommitSha: string;
|
|
187
|
+
existingResult: WhiteboxAttackSurfaceResult;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Phase 2 per-app worker
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Explicit, serializable-by-the-caller input for {@link runWhiteboxAttackSurfaceApp}
|
|
196
|
+
* — everything one app's Phase-2 worker reads, with no reads of
|
|
197
|
+
* `runWhiteboxAttackSurfaceWorkflow`'s own local scope. A durable caller
|
|
198
|
+
* rebuilds `hooks`, `seams`, `mintChildId` and `agentLimiter` on its own side
|
|
199
|
+
* and runs the app as a separate child workflow.
|
|
200
|
+
*/
|
|
201
|
+
export interface WhiteboxAttackSurfaceAppInput {
|
|
202
|
+
codebasePath: string;
|
|
203
|
+
model: AIModel;
|
|
204
|
+
session: SessionInfo;
|
|
205
|
+
authConfig?: AIAuthConfig;
|
|
206
|
+
abortSignal?: AbortSignal;
|
|
207
|
+
eventBus?: AgentEventBus;
|
|
208
|
+
attackSurfaceRegistry?: import("../findings/attackSurfaceRegistry").AttackSurfaceRegistry;
|
|
209
|
+
onStepFinish?: StreamTextOnStepFinishCallback<ToolSet>;
|
|
210
|
+
onCacheMetrics?: (metrics: CacheMetrics) => void;
|
|
211
|
+
openAIReasoningEffort?: OpenAIReasoningEffort | null;
|
|
212
|
+
enableThinking?: boolean;
|
|
213
|
+
thinkingEffort?: ThinkingEffort | null;
|
|
214
|
+
projectThreatModel?: string;
|
|
215
|
+
environments?: string[];
|
|
216
|
+
surfaceIntegrationEnabled: boolean;
|
|
217
|
+
/** `serviceApps.length === 1` at the time Phase 2 started — forwarded to `mapAppWithSurface`. */
|
|
218
|
+
isSingleAppRepo: boolean;
|
|
219
|
+
/** Parent id for this app's own subagent-complete event — the Phase-1 umbrella node. */
|
|
220
|
+
umbrellaId: string;
|
|
221
|
+
/** Mints IDs for discovery and per-endpoint documentation children. */
|
|
222
|
+
mintChildId: (name: string) => string;
|
|
223
|
+
/** Bounds total concurrent CodeAgents across the whole workflow (Phase 1 + every app). */
|
|
224
|
+
agentLimiter: AgentConcurrencyLimiter;
|
|
225
|
+
/** Fan-out spawner forwarded to `runAppEndpointDocumentation`'s own per-endpoint fan-out. */
|
|
226
|
+
subagentSpawner?: SubagentSpawner;
|
|
227
|
+
hooks: AgentHooks;
|
|
228
|
+
seams: WorkflowSeams;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* One Phase-2 app: pages/API-endpoints discovery (surface-driven or legacy
|
|
233
|
+
* fallback) or cloud-resource documentation, then this app's own
|
|
234
|
+
* subagent-complete event. Closure-free extraction of
|
|
235
|
+
* `runWhiteboxAttackSurfaceWorkflow`'s per-app worker so a durable caller can
|
|
236
|
+
* run it as a separate child workflow. Returns whether the app failed.
|
|
237
|
+
*/
|
|
238
|
+
export async function runWhiteboxAttackSurfaceApp(
|
|
239
|
+
app: AppInfo,
|
|
240
|
+
appIndex: number,
|
|
241
|
+
input: WhiteboxAttackSurfaceAppInput,
|
|
242
|
+
): Promise<boolean> {
|
|
243
|
+
const {
|
|
244
|
+
codebasePath,
|
|
245
|
+
model,
|
|
246
|
+
session,
|
|
247
|
+
authConfig,
|
|
248
|
+
abortSignal,
|
|
249
|
+
eventBus,
|
|
250
|
+
attackSurfaceRegistry,
|
|
251
|
+
onStepFinish,
|
|
252
|
+
onCacheMetrics,
|
|
253
|
+
openAIReasoningEffort,
|
|
254
|
+
enableThinking,
|
|
255
|
+
thinkingEffort,
|
|
256
|
+
projectThreatModel,
|
|
257
|
+
environments,
|
|
258
|
+
surfaceIntegrationEnabled,
|
|
259
|
+
isSingleAppRepo,
|
|
260
|
+
umbrellaId,
|
|
261
|
+
mintChildId,
|
|
262
|
+
agentLimiter,
|
|
263
|
+
subagentSpawner,
|
|
264
|
+
hooks: sharedHooks,
|
|
265
|
+
seams,
|
|
266
|
+
} = input;
|
|
267
|
+
|
|
268
|
+
const appNodeId = `app:${sanitizeName(app.name)}`;
|
|
269
|
+
// Per-app AgentHooks: seams.hooksForItem can give this one app (and every
|
|
270
|
+
// endpoint documented under it) different hooks than its siblings;
|
|
271
|
+
// otherwise it inherits sharedHooks as-is.
|
|
272
|
+
const hooksForApp = resolveItemHooks(sharedHooks, seams, app, appIndex);
|
|
273
|
+
let failed = false;
|
|
274
|
+
|
|
275
|
+
const spawnDiscoveryAgent = async (
|
|
276
|
+
type: DiscoveryTaskType,
|
|
277
|
+
objective: string,
|
|
278
|
+
): Promise<void> => {
|
|
279
|
+
const subagentId = mintChildId(TASK_TYPE_LABELS[type]);
|
|
280
|
+
|
|
281
|
+
log.debug(
|
|
282
|
+
`Phase 2: spawning agent id="${subagentId}" parent="${appNodeId}" (app="${app.name}", type=${type}, appType=${app.type})`,
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
const spawner = subagentSpawner ?? inProcessSubagentSpawner;
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
await agentLimiter(() =>
|
|
289
|
+
spawner.spawn<DiscoverySummary>({
|
|
290
|
+
spec: {
|
|
291
|
+
type: "code",
|
|
292
|
+
codebasePath,
|
|
293
|
+
objective,
|
|
294
|
+
system: WHITEBOX_DISCOVERY_SYSTEM_PROMPT,
|
|
295
|
+
excludeTools: ["document_app"],
|
|
296
|
+
responseSchema: DiscoverySummarySchema,
|
|
297
|
+
projectThreatModel,
|
|
298
|
+
attackSurfaceRegistry,
|
|
299
|
+
},
|
|
300
|
+
runtime: {
|
|
301
|
+
model,
|
|
302
|
+
session,
|
|
303
|
+
authConfig,
|
|
304
|
+
abortSignal,
|
|
305
|
+
enableThinking,
|
|
306
|
+
thinkingEffort,
|
|
307
|
+
openAIReasoningEffort,
|
|
308
|
+
onStepFinish,
|
|
309
|
+
onCacheMetrics,
|
|
310
|
+
backends: hooksForApp.backends,
|
|
311
|
+
sandbox: hooksForApp.sandbox,
|
|
312
|
+
languageModelMiddleware: hooksForApp.languageModelMiddleware,
|
|
313
|
+
usageRecorder: hooksForApp.usageRecorder,
|
|
314
|
+
streamIdFactory: hooksForApp.streamIdFactory,
|
|
315
|
+
},
|
|
316
|
+
subagentId,
|
|
317
|
+
subagentName: TASK_TYPE_LABELS[type],
|
|
318
|
+
parentBus: eventBus,
|
|
319
|
+
parentSubagentId: appNodeId,
|
|
320
|
+
lifecycleInput: { app: app.name, type },
|
|
321
|
+
}),
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
log.debug(`Phase 2: agent "${subagentId}" completed`);
|
|
325
|
+
} catch (error) {
|
|
326
|
+
log.error(
|
|
327
|
+
`Phase 2: agent "${subagentId}" FAILED`,
|
|
328
|
+
error instanceof Error ? error : undefined,
|
|
329
|
+
{ error: String(error) },
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
failed = true;
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const spawnPagesAgent = (): Promise<void> =>
|
|
337
|
+
spawnDiscoveryAgent(
|
|
338
|
+
"pages",
|
|
339
|
+
buildPagesDiscoveryObjective(codebasePath, app),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const spawnApiEndpointsAgent = (): Promise<void> =>
|
|
343
|
+
spawnDiscoveryAgent(
|
|
344
|
+
"apiEndpoints",
|
|
345
|
+
buildApiEndpointsDiscoveryObjective(codebasePath, app),
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
const spawnCloudResourceAgent = (): Promise<void> =>
|
|
349
|
+
spawnDiscoveryAgent(
|
|
350
|
+
"cloudResourceEndpoints",
|
|
351
|
+
buildCloudResourceEndpointsObjective(codebasePath, app, environments),
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
try {
|
|
355
|
+
if (NON_SERVICE_TYPES.includes(app.type)) {
|
|
356
|
+
// Cloud resources: surface doesn't enumerate these — always fallback.
|
|
357
|
+
await spawnCloudResourceAgent();
|
|
358
|
+
} else if (!surfaceIntegrationEnabled) {
|
|
359
|
+
log.debug(`${app.name}: legacy (surfaceIntegrationEnabled=false)`);
|
|
360
|
+
await Promise.all([spawnPagesAgent(), spawnApiEndpointsAgent()]);
|
|
361
|
+
} else {
|
|
362
|
+
const surfaceResult = mapAppWithSurface(
|
|
363
|
+
join(codebasePath, app.location),
|
|
364
|
+
codebasePath,
|
|
365
|
+
{ isSingleAppRepo },
|
|
366
|
+
);
|
|
367
|
+
if (surfaceResult.mode === "surface") {
|
|
368
|
+
log.debug(
|
|
369
|
+
`${app.name}: surface-driven (${surfaceResult.endpoints.length} endpoints, frameworks=${surfaceResult.frameworks.join(",")})`,
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
await runAppEndpointDocumentation({
|
|
373
|
+
codebasePath,
|
|
374
|
+
app,
|
|
375
|
+
endpoints: surfaceResult.endpoints,
|
|
376
|
+
frameworks: surfaceResult.frameworks,
|
|
377
|
+
model,
|
|
378
|
+
session,
|
|
379
|
+
authConfig,
|
|
380
|
+
abortSignal,
|
|
381
|
+
eventBus,
|
|
382
|
+
attackSurfaceRegistry,
|
|
383
|
+
onStepFinish,
|
|
384
|
+
onCacheMetrics,
|
|
385
|
+
openAIReasoningEffort,
|
|
386
|
+
enableThinking,
|
|
387
|
+
thinkingEffort,
|
|
388
|
+
projectThreatModel,
|
|
389
|
+
parentSubagentId: appNodeId,
|
|
390
|
+
agentLimiter,
|
|
391
|
+
subagentSpawner,
|
|
392
|
+
hooks: hooksForApp,
|
|
393
|
+
mintChildId,
|
|
394
|
+
});
|
|
395
|
+
} else {
|
|
396
|
+
log.debug(`${app.name}: fallback (${surfaceResult.reason})`);
|
|
397
|
+
await Promise.all([spawnPagesAgent(), spawnApiEndpointsAgent()]);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
} catch {
|
|
401
|
+
failed = true;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
eventBus?.emit("subagent-complete", {
|
|
405
|
+
subagentId: appNodeId,
|
|
406
|
+
status: failed ? "failed" : "completed",
|
|
407
|
+
parentSubagentId: umbrellaId,
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
return failed;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// ---------------------------------------------------------------------------
|
|
414
|
+
// Workflow
|
|
415
|
+
// ---------------------------------------------------------------------------
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Deterministic whitebox attack surface workflow.
|
|
419
|
+
*
|
|
420
|
+
* Phase 1: Spawn a single CodeAgent to identify all apps in the repo.
|
|
421
|
+
* Phase 1.5: Create app folders with app.json metadata.
|
|
422
|
+
* Phase 2: Per-app dispatch. When `surfaceIntegrationEnabled` (default), service
|
|
423
|
+
* apps run `mapAppWithSurface`; on `surface` mode a per-endpoint
|
|
424
|
+
* endpoint-documentation CodeAgent documents the deterministic list,
|
|
425
|
+
* on `fallback` the legacy pages+apiEndpoints agent pair runs. When
|
|
426
|
+
* `surfaceIntegrationEnabled` is false, every service app uses the
|
|
427
|
+
* legacy pair directly. Cloud resources always use the specialized
|
|
428
|
+
* cloud-resource agent. Threat models and risk scores are generated
|
|
429
|
+
* inline by document_endpoint.
|
|
430
|
+
* Phase 3: Read the assets directory to build endpoint data.
|
|
431
|
+
* Phase 4: Final assembly.
|
|
432
|
+
*/
|
|
433
|
+
export async function runWhiteboxAttackSurfaceWorkflow(
|
|
434
|
+
input: WhiteboxAttackSurfaceWorkflowInput,
|
|
435
|
+
): Promise<WhiteboxAttackSurfaceResult> {
|
|
436
|
+
const {
|
|
437
|
+
codebasePath,
|
|
438
|
+
model,
|
|
439
|
+
session,
|
|
440
|
+
authConfig,
|
|
441
|
+
abortSignal,
|
|
442
|
+
eventBus,
|
|
443
|
+
attackSurfaceRegistry,
|
|
444
|
+
onStepFinish,
|
|
445
|
+
onCacheMetrics,
|
|
446
|
+
openAIReasoningEffort,
|
|
447
|
+
enableThinking,
|
|
448
|
+
thinkingEffort,
|
|
449
|
+
domains,
|
|
450
|
+
projectThreatModel,
|
|
451
|
+
environments,
|
|
452
|
+
surfaceIntegrationEnabled = true,
|
|
453
|
+
maxConcurrentAgents = MAX_CONCURRENT_AGENTS,
|
|
454
|
+
subagentSpawner,
|
|
455
|
+
hooks,
|
|
456
|
+
seams: inputSeams,
|
|
457
|
+
} = input;
|
|
458
|
+
|
|
459
|
+
const seams = inputSeams ?? inProcessSeams();
|
|
460
|
+
// The shared AgentHooks every CodeAgent in this workflow gets unless
|
|
461
|
+
// `seams.hooksForItem` overrides it for a given app.
|
|
462
|
+
const sharedHooks: AgentHooks = { subagentSpawner, ...hooks };
|
|
463
|
+
// Every child id this workflow mints goes through one monotonic ordinal —
|
|
464
|
+
// the umbrella node is ordinal 0, everything spawned under it follows in
|
|
465
|
+
// dispatch order.
|
|
466
|
+
let nextChildOrdinal = 0;
|
|
467
|
+
const mintChildId = (name: string): string =>
|
|
468
|
+
seams.ids.newSessionId(name, nextChildOrdinal++);
|
|
469
|
+
|
|
470
|
+
// Single shared gate for every CodeAgent run in this workflow (Phase 1
|
|
471
|
+
// discovery, Phase 2 per-app discovery, and per-endpoint documentation). This
|
|
472
|
+
// is what makes total concurrency independent of app count: the nested
|
|
473
|
+
// app-level (`DEFAULT_CONCURRENCY`) and per-app endpoint-level
|
|
474
|
+
// (`ENDPOINT_DOCUMENTATION_CONCURRENCY`) loops still control scheduling, but
|
|
475
|
+
// the number of agents actually running at once can never exceed this.
|
|
476
|
+
const agentSlots = pLimit(Math.max(1, maxConcurrentAgents));
|
|
477
|
+
const agentLimiter = <T>(fn: () => Promise<T>): Promise<T> => agentSlots(fn);
|
|
478
|
+
|
|
479
|
+
// =========================================================================
|
|
480
|
+
// Phase 1: Identify all apps in the repository
|
|
481
|
+
// =========================================================================
|
|
482
|
+
|
|
483
|
+
// Umbrella node — real `ses_` id so the appsAgent span and its agent_sessions
|
|
484
|
+
// row share one id; also the parent for per-app nodes (held open until Phase 2).
|
|
485
|
+
const WORKFLOW_UMBRELLA_ID = mintChildId("whitebox-apps-discovery");
|
|
486
|
+
|
|
487
|
+
if (input.incremental && !hooks?.backends)
|
|
488
|
+
throw new Error("Incremental recon requires owned artifact backends");
|
|
489
|
+
|
|
490
|
+
const appsAgent = new CodeAgent<AppsDiscoveryResult>({
|
|
491
|
+
codebasePath,
|
|
492
|
+
objective: input.incremental
|
|
493
|
+
? buildIncrementalObjective(
|
|
494
|
+
codebasePath,
|
|
495
|
+
input.incremental.diffPath,
|
|
496
|
+
input.incremental.assetsPath,
|
|
497
|
+
input.incremental.existingResult,
|
|
498
|
+
domains,
|
|
499
|
+
environments,
|
|
500
|
+
).replace(
|
|
501
|
+
"- **Non-route changes** (e.g. utility functions, configs, tests) → skip",
|
|
502
|
+
"- **Shared-library/configuration changes** → trace affected consumers and update only impacted endpoint assets; skip unrelated changes",
|
|
503
|
+
) +
|
|
504
|
+
"\nTrace changed shared libraries, deleted files, and root/build/deployment configuration to the applications that consume them. A path outside an application directory does not prove that application is unaffected. Leave unrelated endpoint artifacts unchanged."
|
|
505
|
+
: buildAppsDiscoveryObjective(codebasePath, domains, environments),
|
|
506
|
+
// Phase 1 uses an apps-only system prompt (no document_endpoint guidance)
|
|
507
|
+
// paired with `excludeTools: ["document_endpoint"]`. The shared
|
|
508
|
+
// WHITEBOX_DISCOVERY_SYSTEM_PROMPT instructs every agent to call
|
|
509
|
+
// document_endpoint per route — strong enough that Phase 1 would
|
|
510
|
+
// improvise by abusing document_app for individual routes if the prompt
|
|
511
|
+
// mentioned the tool at all. The variant below removes those mentions.
|
|
512
|
+
system: input.incremental
|
|
513
|
+
? WHITEBOX_DISCOVERY_SYSTEM_PROMPT
|
|
514
|
+
: WHITEBOX_APPS_DISCOVERY_SYSTEM_PROMPT,
|
|
515
|
+
model,
|
|
516
|
+
session,
|
|
517
|
+
authConfig,
|
|
518
|
+
attackSurfaceRegistry,
|
|
519
|
+
eventBus,
|
|
520
|
+
subagentId: WORKFLOW_UMBRELLA_ID,
|
|
521
|
+
subagentName: "Whitebox Apps Discovery",
|
|
522
|
+
onStepFinish: (event) => onStepFinish?.(event),
|
|
523
|
+
onCacheMetrics,
|
|
524
|
+
openAIReasoningEffort,
|
|
525
|
+
enableThinking,
|
|
526
|
+
thinkingEffort,
|
|
527
|
+
responseSchema: input.incremental
|
|
528
|
+
? IncrementalReconResultSchema
|
|
529
|
+
: AppsDiscoveryResultSchema,
|
|
530
|
+
projectThreatModel,
|
|
531
|
+
// Reserved for Phase 2's per-app task agents. Inline documentation
|
|
532
|
+
// here would flatten the UI hierarchy under Phase 1.
|
|
533
|
+
excludeTools: input.incremental ? [] : ["document_endpoint"],
|
|
534
|
+
...sharedHooks,
|
|
535
|
+
...(input.incremental
|
|
536
|
+
? { attackSurfaceArtifactsPath: input.incremental.assetsPath }
|
|
537
|
+
: {}),
|
|
538
|
+
abortSignal,
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
log.info(
|
|
542
|
+
`Phase 1: discovering apps in ${codebasePath}${domains?.length ? ` (${domains.length} known domains)` : ""}`,
|
|
543
|
+
);
|
|
544
|
+
|
|
545
|
+
eventBus?.emit("subagent-spawn", {
|
|
546
|
+
subagentId: WORKFLOW_UMBRELLA_ID,
|
|
547
|
+
name: "Whitebox Apps Discovery",
|
|
548
|
+
input: { codebasePath },
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
const appsResult = await agentLimiter(() => appsAgent.consume());
|
|
552
|
+
|
|
553
|
+
if (input.incremental) {
|
|
554
|
+
if (!hooks?.backends)
|
|
555
|
+
throw new Error("Incremental recon requires owned artifact backends");
|
|
556
|
+
const result = await readIncrementalReconAssets(
|
|
557
|
+
hooks.backends,
|
|
558
|
+
input.incremental.assetsPath,
|
|
559
|
+
input.incremental.existingResult,
|
|
560
|
+
abortSignal,
|
|
561
|
+
);
|
|
562
|
+
eventBus?.emit("subagent-complete", {
|
|
563
|
+
subagentId: WORKFLOW_UMBRELLA_ID,
|
|
564
|
+
status: "completed",
|
|
565
|
+
});
|
|
566
|
+
return result;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
log.info(
|
|
570
|
+
`Phase 1 complete: ${appsResult?.apps.length ?? 0} apps discovered` +
|
|
571
|
+
(appsResult
|
|
572
|
+
? ` (repoType=${appsResult.repoType}, packageManager=${appsResult.packageManager})`
|
|
573
|
+
: " (no result returned)"),
|
|
574
|
+
);
|
|
575
|
+
|
|
576
|
+
if (appsResult?.apps.length) {
|
|
577
|
+
for (const app of appsResult.apps) {
|
|
578
|
+
log.debug(
|
|
579
|
+
`app: "${app.name}" type=${app.type} framework="${app.framework}" location="${app.location}"`,
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
if (!appsResult || appsResult.apps.length === 0) {
|
|
585
|
+
eventBus?.emit("subagent-complete", {
|
|
586
|
+
subagentId: WORKFLOW_UMBRELLA_ID,
|
|
587
|
+
status: "completed",
|
|
588
|
+
});
|
|
589
|
+
return {
|
|
590
|
+
repoType: appsResult?.repoType ?? "unknown",
|
|
591
|
+
packageManager: appsResult?.packageManager ?? "unknown",
|
|
592
|
+
apps: [],
|
|
593
|
+
summary: {
|
|
594
|
+
totalApps: 0,
|
|
595
|
+
totalPages: 0,
|
|
596
|
+
totalApiEndpoints: 0,
|
|
597
|
+
totalPentestObjectives: 0,
|
|
598
|
+
},
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// =========================================================================
|
|
603
|
+
// Phase 1.5: Create app folders with app.json metadata
|
|
604
|
+
// =========================================================================
|
|
605
|
+
|
|
606
|
+
const assetsPath = join(session.rootPath, "assets");
|
|
607
|
+
mkdirSync(assetsPath, { recursive: true });
|
|
608
|
+
|
|
609
|
+
for (const app of appsResult.apps) {
|
|
610
|
+
const appDir = join(assetsPath, sanitizeName(app.name));
|
|
611
|
+
mkdirSync(appDir, { recursive: true });
|
|
612
|
+
writeFileSync(
|
|
613
|
+
join(appDir, "app.json"),
|
|
614
|
+
JSON.stringify(toAppMetadata(app), null, 2),
|
|
615
|
+
"utf-8",
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// =========================================================================
|
|
620
|
+
// Phase 2: Per-app dispatch — surface-driven documentation vs. fallback.
|
|
621
|
+
// When `surfaceIntegrationEnabled` is true, service apps try
|
|
622
|
+
// `mapAppWithSurface`; on `surface` mode run a per-endpoint
|
|
623
|
+
// endpoint-documentation CodeAgent against the deterministic list,
|
|
624
|
+
// on `fallback` run the legacy pages+apiEndpoints CodeAgent pair.
|
|
625
|
+
// When `surfaceIntegrationEnabled` is false, every service app
|
|
626
|
+
// uses the legacy pair directly — pre-PR behavior.
|
|
627
|
+
// Cloud resources always take the specialized objective — surface
|
|
628
|
+
// is HTTP-route-focused and doesn't enumerate cloud assets.
|
|
629
|
+
// =========================================================================
|
|
630
|
+
|
|
631
|
+
log.info(`Phase 2: surfaceIntegrationEnabled=${surfaceIntegrationEnabled}`);
|
|
632
|
+
|
|
633
|
+
const serviceApps = appsResult.apps.filter(
|
|
634
|
+
(app) => !NON_SERVICE_TYPES.includes(app.type),
|
|
635
|
+
);
|
|
636
|
+
const cloudApps = appsResult.apps.filter((app) =>
|
|
637
|
+
NON_SERVICE_TYPES.includes(app.type),
|
|
638
|
+
);
|
|
639
|
+
|
|
640
|
+
log.info(
|
|
641
|
+
`Phase 2: ${serviceApps.length} service apps (surface or fallback per app), ${cloudApps.length} cloud resources → ${appsResult.apps.length} total apps`,
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
const totalApps = appsResult.apps.length;
|
|
645
|
+
let completedAppCount = 0;
|
|
646
|
+
|
|
647
|
+
eventBus?.emit("app-analysis-progress", {
|
|
648
|
+
totalApps,
|
|
649
|
+
completedApps: 0,
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
// Synthetic grouping nodes between the umbrella and per-task agents,
|
|
653
|
+
// so the UI nests pages/api/endpoint-doc agents under their app.
|
|
654
|
+
for (const app of appsResult.apps) {
|
|
655
|
+
eventBus?.emit("subagent-spawn", {
|
|
656
|
+
subagentId: `app:${sanitizeName(app.name)}`,
|
|
657
|
+
name: app.name,
|
|
658
|
+
input: { app: app.name, type: app.type, framework: app.framework },
|
|
659
|
+
parentSubagentId: WORKFLOW_UMBRELLA_ID,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const appWorkerInput: WhiteboxAttackSurfaceAppInput = {
|
|
664
|
+
codebasePath,
|
|
665
|
+
model,
|
|
666
|
+
session,
|
|
667
|
+
authConfig,
|
|
668
|
+
abortSignal,
|
|
669
|
+
eventBus,
|
|
670
|
+
attackSurfaceRegistry,
|
|
671
|
+
onStepFinish,
|
|
672
|
+
onCacheMetrics,
|
|
673
|
+
openAIReasoningEffort,
|
|
674
|
+
enableThinking,
|
|
675
|
+
thinkingEffort,
|
|
676
|
+
projectThreatModel,
|
|
677
|
+
environments,
|
|
678
|
+
surfaceIntegrationEnabled,
|
|
679
|
+
isSingleAppRepo: serviceApps.length === 1,
|
|
680
|
+
umbrellaId: WORKFLOW_UMBRELLA_ID,
|
|
681
|
+
mintChildId,
|
|
682
|
+
agentLimiter,
|
|
683
|
+
subagentSpawner,
|
|
684
|
+
hooks: sharedHooks,
|
|
685
|
+
seams,
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
assertDepth(1, seams.limits);
|
|
689
|
+
await seams.fanOut.spawnMany(
|
|
690
|
+
appsResult.apps,
|
|
691
|
+
async (app, appIndex) => {
|
|
692
|
+
await runWhiteboxAttackSurfaceApp(app, appIndex, appWorkerInput);
|
|
693
|
+
|
|
694
|
+
completedAppCount++;
|
|
695
|
+
|
|
696
|
+
eventBus?.emit("app-analysis-progress", {
|
|
697
|
+
totalApps,
|
|
698
|
+
completedApps: completedAppCount,
|
|
699
|
+
appName: app.name,
|
|
700
|
+
});
|
|
701
|
+
},
|
|
702
|
+
{ concurrency: DEFAULT_CONCURRENCY },
|
|
703
|
+
);
|
|
704
|
+
|
|
705
|
+
eventBus?.emit("subagent-complete", {
|
|
706
|
+
subagentId: WORKFLOW_UMBRELLA_ID,
|
|
707
|
+
status: "completed",
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
// =========================================================================
|
|
711
|
+
// Phase 3: Read assets directory to build endpoint data
|
|
712
|
+
// =========================================================================
|
|
713
|
+
|
|
714
|
+
log.info(`Phase 3: reading assets from ${assetsPath}`);
|
|
715
|
+
|
|
716
|
+
const {
|
|
717
|
+
apps: parsedApps,
|
|
718
|
+
repoType,
|
|
719
|
+
packageManager,
|
|
720
|
+
} = readAppsFromAssetsDirectory(assetsPath, appsResult);
|
|
721
|
+
|
|
722
|
+
for (const app of parsedApps) {
|
|
723
|
+
log.debug(
|
|
724
|
+
`Phase 3: "${app.name}" → ${app.pages.length} pages, ${app.apiEndpoints.length} API endpoints`,
|
|
725
|
+
);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// =========================================================================
|
|
729
|
+
// Phase 4: Final assembly (risk scores are already attached inline
|
|
730
|
+
// by document_endpoint during Phase 2)
|
|
731
|
+
// =========================================================================
|
|
732
|
+
|
|
733
|
+
const apps: App[] = parsedApps;
|
|
734
|
+
|
|
735
|
+
const totalPages = apps.reduce((sum, a) => sum + a.pages.length, 0);
|
|
736
|
+
const totalApiEndpoints = apps.reduce(
|
|
737
|
+
(sum, a) => sum + a.apiEndpoints.length,
|
|
738
|
+
0,
|
|
739
|
+
);
|
|
740
|
+
const totalPentestObjectives = apps.reduce(
|
|
741
|
+
(sum, a) =>
|
|
742
|
+
sum +
|
|
743
|
+
[...a.pages, ...a.apiEndpoints].reduce(
|
|
744
|
+
(s, ep) => s + ep.pentestObjectives.length,
|
|
745
|
+
0,
|
|
746
|
+
),
|
|
747
|
+
0,
|
|
748
|
+
);
|
|
749
|
+
|
|
750
|
+
return {
|
|
751
|
+
repoType,
|
|
752
|
+
packageManager,
|
|
753
|
+
apps,
|
|
754
|
+
summary: {
|
|
755
|
+
totalApps: apps.length,
|
|
756
|
+
totalPages,
|
|
757
|
+
totalApiEndpoints,
|
|
758
|
+
totalPentestObjectives,
|
|
759
|
+
},
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// ---------------------------------------------------------------------------
|
|
764
|
+
// Assets directory reader
|
|
765
|
+
// ---------------------------------------------------------------------------
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Read app folders and their asset files from the assets directory.
|
|
769
|
+
*
|
|
770
|
+
* Expected structure:
|
|
771
|
+
* assets/
|
|
772
|
+
* <app-name>/
|
|
773
|
+
* app.json — app metadata (name, framework, description, location)
|
|
774
|
+
* asset_*.json — endpoint assets written by document_endpoint
|
|
775
|
+
*
|
|
776
|
+
* Each asset file is a {@link DocumentedEndpointRecord}. Endpoints are classified
|
|
777
|
+
* as pages (method contains "PAGE") or API endpoints (everything else).
|
|
778
|
+
*/
|
|
779
|
+
function readAppsFromAssetsDirectory(
|
|
780
|
+
assetsPath: string,
|
|
781
|
+
appsDiscovery?: AppsDiscoveryResult,
|
|
782
|
+
): {
|
|
783
|
+
apps: App[];
|
|
784
|
+
repoType: string;
|
|
785
|
+
packageManager: string;
|
|
786
|
+
} {
|
|
787
|
+
const repoType = appsDiscovery?.repoType ?? "unknown";
|
|
788
|
+
const packageManager = appsDiscovery?.packageManager ?? "unknown";
|
|
789
|
+
|
|
790
|
+
if (!existsSync(assetsPath)) {
|
|
791
|
+
log.debug(`readAssets: assets directory does not exist: ${assetsPath}`);
|
|
792
|
+
return { apps: [], repoType, packageManager };
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const entries = readdirSync(assetsPath);
|
|
796
|
+
log.debug(
|
|
797
|
+
`readAssets: found ${entries.length} entries in ${assetsPath}: [${entries.join(", ")}]`,
|
|
798
|
+
);
|
|
799
|
+
const apps: App[] = [];
|
|
800
|
+
|
|
801
|
+
for (const entry of entries) {
|
|
802
|
+
const entryPath = join(assetsPath, entry);
|
|
803
|
+
if (!statSync(entryPath).isDirectory()) {
|
|
804
|
+
log.debug(`readAssets: skipping non-directory: ${entry}`);
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
const appJsonPath = join(entryPath, "app.json");
|
|
809
|
+
let metadata: AppMetadata;
|
|
810
|
+
|
|
811
|
+
if (existsSync(appJsonPath)) {
|
|
812
|
+
try {
|
|
813
|
+
metadata = JSON.parse(
|
|
814
|
+
readFileSync(appJsonPath, "utf-8"),
|
|
815
|
+
) as AppMetadata;
|
|
816
|
+
} catch {
|
|
817
|
+
log.warn(
|
|
818
|
+
`readAssets: skipping app folder with unreadable app.json: ${entry}`,
|
|
819
|
+
);
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
} else {
|
|
823
|
+
log.debug(`readAssets: skipping folder without app.json: ${entry}`);
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const pages: Endpoint[] = [];
|
|
828
|
+
const apiEndpoints: Endpoint[] = [];
|
|
829
|
+
|
|
830
|
+
const assetFiles = readdirSync(entryPath).filter(
|
|
831
|
+
(f) => f.endsWith(".json") && f !== "app.json",
|
|
832
|
+
);
|
|
833
|
+
|
|
834
|
+
log.debug(
|
|
835
|
+
`readAssets: app "${metadata.name}" (${entry}): ${assetFiles.length} asset files`,
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
let parseFailed = 0;
|
|
839
|
+
for (const file of assetFiles) {
|
|
840
|
+
try {
|
|
841
|
+
const raw = readFileSync(join(entryPath, file), "utf-8");
|
|
842
|
+
const data = JSON.parse(raw) as DocumentedEndpointRecord;
|
|
843
|
+
|
|
844
|
+
const endpoint = assetRecordToEndpoint(data);
|
|
845
|
+
if (!endpoint) {
|
|
846
|
+
log.debug(
|
|
847
|
+
`readAssets: ${file}: failed schema validation (assetRecordToEndpoint returned null)`,
|
|
848
|
+
);
|
|
849
|
+
parseFailed++;
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
if (isPageEndpoint(data)) {
|
|
854
|
+
pages.push(endpoint);
|
|
855
|
+
} else {
|
|
856
|
+
apiEndpoints.push(endpoint);
|
|
857
|
+
}
|
|
858
|
+
} catch {
|
|
859
|
+
log.warn(
|
|
860
|
+
`readAssets: skipping unreadable asset file: ${entry}/${file}`,
|
|
861
|
+
);
|
|
862
|
+
parseFailed++;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
log.debug(
|
|
867
|
+
`readAssets: app "${metadata.name}": ${pages.length} pages, ${apiEndpoints.length} API endpoints, ${parseFailed} failed`,
|
|
868
|
+
);
|
|
869
|
+
|
|
870
|
+
apps.push({
|
|
871
|
+
name: metadata.name,
|
|
872
|
+
type: (metadata.type as App["type"]) ?? "web_application",
|
|
873
|
+
framework: metadata.framework,
|
|
874
|
+
description: metadata.description,
|
|
875
|
+
location: metadata.location,
|
|
876
|
+
pages,
|
|
877
|
+
apiEndpoints,
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
return { apps, repoType, packageManager };
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Convert a {@link DocumentedEndpointRecord} (from document_endpoint) to an
|
|
886
|
+
* {@link Endpoint} (for the whitebox result schema).
|
|
887
|
+
*/
|
|
888
|
+
function assetRecordToEndpoint(
|
|
889
|
+
record: DocumentedEndpointRecord,
|
|
890
|
+
): Endpoint | null {
|
|
891
|
+
const rawMethod = record.method;
|
|
892
|
+
const method = Array.isArray(rawMethod)
|
|
893
|
+
? rawMethod.join(", ")
|
|
894
|
+
: (rawMethod ?? "UNKNOWN");
|
|
895
|
+
|
|
896
|
+
const path = record.routePath;
|
|
897
|
+
const file = record.file ?? "";
|
|
898
|
+
|
|
899
|
+
const parsed = EndpointSchema.safeParse({
|
|
900
|
+
method,
|
|
901
|
+
path,
|
|
902
|
+
handler: record.handler,
|
|
903
|
+
file,
|
|
904
|
+
line: record.line,
|
|
905
|
+
authRequired: record.authRequired,
|
|
906
|
+
description: record.description,
|
|
907
|
+
pentestObjectives: record.pentestObjectives ?? [],
|
|
908
|
+
riskScore: record.riskScore,
|
|
909
|
+
threatModel: record.threatModel,
|
|
910
|
+
transport: record.transport,
|
|
911
|
+
grpc: record.grpc,
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
return parsed.success ? parsed.data : null;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Determine whether a documented endpoint record represents a web page
|
|
919
|
+
* (as opposed to an API endpoint).
|
|
920
|
+
*/
|
|
921
|
+
function isPageEndpoint(record: DocumentedEndpointRecord): boolean {
|
|
922
|
+
const method = record.method;
|
|
923
|
+
if (typeof method === "string") {
|
|
924
|
+
return method.toUpperCase() === "PAGE";
|
|
925
|
+
}
|
|
926
|
+
if (Array.isArray(method)) {
|
|
927
|
+
return method.length === 1 && method[0].toUpperCase() === "PAGE";
|
|
928
|
+
}
|
|
929
|
+
return false;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// ---------------------------------------------------------------------------
|
|
933
|
+
// Objective builders
|
|
934
|
+
// ---------------------------------------------------------------------------
|
|
935
|
+
|
|
936
|
+
function buildAppsDiscoveryObjective(
|
|
937
|
+
codebasePath: string,
|
|
938
|
+
domains?: string[],
|
|
939
|
+
environments?: string[],
|
|
940
|
+
): string {
|
|
941
|
+
const domainSection = domains?.length
|
|
942
|
+
? `\n## Known Domains\nThe following domains are associated with this project. When you document an application, set the \`domain\` field on \`document_app\` if you can determine which domain the app is served from:\n${domains.map((d) => `- ${d}`).join("\n")}\n`
|
|
943
|
+
: "";
|
|
944
|
+
|
|
945
|
+
const environmentsSection = environments?.length
|
|
946
|
+
? `\n## Target Environments\nThis project is deployed to the following environments:\n${environments.map((e) => `- **${e}**`).join("\n")}\n
|
|
947
|
+
**Per-environment app creation:** When infrastructure-as-code or configuration defines resources that are dynamically named per environment (e.g. environment-prefixed S3 buckets, stage-scoped databases, per-environment API endpoints), you MUST create a **separate app entry for each environment**. Use the environment name as a prefix in the app name (e.g. \`${environments[0]}-user-uploads-bucket\`, \`${environments.length > 1 ? environments[1] : "staging"}-api-gateway\`).
|
|
948
|
+
|
|
949
|
+
**How to identify environment-scoped resources:**
|
|
950
|
+
- IaC that interpolates a stage/environment variable into resource names (e.g. \`\${stage}-my-bucket\`, \`\${env}-api\`, \`$app.$stage.example.com\`)
|
|
951
|
+
- Separate config blocks, Terraform workspaces, SST stages, or CDK stacks per environment
|
|
952
|
+
- Environment variables or config files that change resource identifiers per stage
|
|
953
|
+
|
|
954
|
+
**For each environment** (${environments.join(", ")}), create an app entry with:
|
|
955
|
+
- **name**: \`<environment>-<resource-name>\` (e.g. \`${environments[0]}-data-bucket\`)
|
|
956
|
+
- **domain**: Substitute the environment name into the IaC naming pattern to derive the environment-specific URL (e.g. IaC has \`\${stage}-data\` → \`https://${environments[0]}-data.s3.amazonaws.com\`). Omit if no naming pattern exists in the code.
|
|
957
|
+
|
|
958
|
+
**Shared resources:** If a resource is clearly shared across all environments (e.g. a single CDN distribution, a shared auth service), document it once without an environment prefix.\n`
|
|
959
|
+
: "";
|
|
960
|
+
|
|
961
|
+
return `# Identify All Applications in the Repository
|
|
962
|
+
|
|
963
|
+
## Phase scope — read this first
|
|
964
|
+
This objective is **Phase 1: app discovery only**. Your job is to enumerate
|
|
965
|
+
applications and call \`document_app\` for each. **Do NOT call
|
|
966
|
+
\`document_endpoint\` in this phase** — endpoints are documented in a later
|
|
967
|
+
phase by per-app subagents. The \`document_endpoint\` tool is intentionally
|
|
968
|
+
unavailable here. Ignore any general guidance in the system prompt that
|
|
969
|
+
tells you to call it; that guidance applies only to later phases.
|
|
970
|
+
|
|
971
|
+
## Codebase
|
|
972
|
+
- **Path:** ${codebasePath}
|
|
973
|
+
${domainSection}${environmentsSection}
|
|
974
|
+
## Task
|
|
975
|
+
Analyze the repository structure and identify every **deployed application or service** (APIs, web apps, microservices) defined within it. Also discover **cloud resources and external services** referenced in the code that are owned by the target (e.g. S3 buckets, cloud storage, CDN origins, message queues).
|
|
976
|
+
|
|
977
|
+
**IMPORTANT: Only include deployable apps, services, and owned cloud resources.** Exclude:
|
|
978
|
+
- Libraries, SDKs, and shared packages that are consumed by other code but not deployed on their own
|
|
979
|
+
- Git submodules (external dependencies)
|
|
980
|
+
- Build tools, scripts, CLI utilities, and dev tooling
|
|
981
|
+
- Test suites, fixtures, and test helpers
|
|
982
|
+
- Documentation packages
|
|
983
|
+
- Third-party SaaS services not owned by the target (e.g. Stripe, auth providers)
|
|
984
|
+
- **Individual API routes, web pages, or HTTP endpoints.** Endpoint enumeration is handled by a separate phase that runs after this one. Even if you discover route files (\`page.tsx\`, \`route.ts\`, controller methods) while navigating the codebase, do NOT call \`document_app\` for them. Each \`document_app\` call must represent a deployable application or cloud resource, never a single endpoint. The \`document_endpoint\` tool is intentionally not available to you.
|
|
985
|
+
|
|
986
|
+
An app/service qualifies if it **listens on a port, serves HTTP traffic, or runs as a deployed process** (e.g. an Express server, a Next.js app, a Django project, a FastAPI service, a background worker with an API).
|
|
987
|
+
|
|
988
|
+
A **cloud resource** qualifies if it is an **owned infrastructure resource** referenced in the code — S3 buckets, GCS buckets, Azure Blob Storage, CloudFront distributions, Redis/ElastiCache instances, SQS queues, etc. These are part of the attack surface because they may have misconfigured permissions, public access, or sensitive data.
|
|
989
|
+
|
|
990
|
+
### Steps
|
|
991
|
+
1. List the root directory and read top-level config files (package.json, requirements.txt, Cargo.toml, go.mod, etc.)
|
|
992
|
+
2. **Check for git submodules** — run \`git submodule status\` or check for a \`.gitmodules\` file. Exclude all submodule directories.
|
|
993
|
+
3. Determine the **repo type**: monorepo (workspaces), single-app, multi-package, etc.
|
|
994
|
+
4. Determine the **package manager**: npm, yarn, pnpm, pip, cargo, go modules, etc.
|
|
995
|
+
5. Identify all **deployable** applications/services (ignoring submodules, libraries, and shared packages):
|
|
996
|
+
- For monorepos: look at workspace packages that have their own server entry point, Dockerfile, or deploy config — skip packages that are libraries/utilities consumed by other packages
|
|
997
|
+
- For multi-service repos: look at separate service directories with their own server startup
|
|
998
|
+
- For single apps: the root is the app
|
|
999
|
+
6. **Discover cloud resources** referenced in the codebase:
|
|
1000
|
+
- Search for S3 bucket references (\`s3://\`, \`new S3Client\`, \`boto3.client('s3')\`, bucket name strings in config)
|
|
1001
|
+
- Search for cloud storage URLs (e.g. \`*.s3.amazonaws.com\`, \`storage.googleapis.com\`)
|
|
1002
|
+
- Search for CDN/distribution configs (CloudFront, Cloudflare, etc.)
|
|
1003
|
+
- Search for message queue references (SQS, SNS, RabbitMQ, etc.)
|
|
1004
|
+
- Search for cache/database endpoints (ElastiCache, Redis, DynamoDB, etc.)
|
|
1005
|
+
- Check infrastructure-as-code files (Terraform, CloudFormation, CDK, Pulumi, SST, serverless.yml)
|
|
1006
|
+
- Document each cloud resource as an app with \`appType: "cloud_resource"\` or \`appType: "storage"\`
|
|
1007
|
+
7. For each app/resource, determine:
|
|
1008
|
+
- **name**: the application or service name
|
|
1009
|
+
- **framework**: the web framework or cloud service (e.g. "AWS S3", "CloudFront", "Express")
|
|
1010
|
+
- **description**: brief summary of what it does
|
|
1011
|
+
- **location**: path relative to the repository root (for code) or the resource identifier (for cloud resources)
|
|
1012
|
+
- **type**: classify as \`"web_application"\` for frontend-only apps, \`"api"\` for backend API services, \`"full_stack"\` for frameworks serving both UI and API (Next.js, Remix, Nuxt, SvelteKit, Django with templates, Rails), \`"database"\` for databases, \`"cloud_resource"\` for owned cloud infra (SQS, CDN, etc.), \`"storage"\` for S3/GCS/blob storage.
|
|
1013
|
+
|
|
1014
|
+
### Setting the \`domain\` field on \`document_app\` — CRITICAL
|
|
1015
|
+
|
|
1016
|
+
**Only set \`domain\` when you can deterministically derive it from evidence** — Known Domains list, IaC resource definitions, configuration files, environment variables, or route definitions. Substituting a known environment/stage name into an IaC naming pattern IS deterministic (e.g. IaC defines \`\${stage}-bucket\` and the target environments include "production" → \`https://production-bucket.s3.amazonaws.com\` is valid). However, do NOT invent domains with no supporting evidence — if no domain can be derived from the source, **omit the \`domain\` field entirely**. A missing domain is far better than a hallucinated one.
|
|
1017
|
+
|
|
1018
|
+
When you CAN determine the domain, each resource must have its OWN unique, resource-specific domain. Never reuse a generic domain or another application's domain.
|
|
1019
|
+
|
|
1020
|
+
**For web apps and API services:** Use the public-facing URL from the Known Domains list, route configuration, or infrastructure definition (e.g., \`https://console.pensar.dev\`, \`https://api.example.com\`).
|
|
1021
|
+
|
|
1022
|
+
**For S3 / GCS / blob storage buckets:** Derive the **actual bucket name** from the infrastructure-as-code. The bucket name is defined in the IaC resource definition (e.g., SST \`new sst.aws.Bucket("ProjectData")\` produces a bucket with a name like \`console-staging-projectdata-abc123\`). Set domain to \`https://{actual-bucket-name}.s3.amazonaws.com\`. If the IaC uses a stage/environment variable in the name, substitute the known environment name (e.g. \`\${stage}-projectdata\` with environment "production" → \`https://production-projectdata.s3.amazonaws.com\`). **NEVER use \`https://s3.amazonaws.com\`** — that is the S3 service, not a bucket. If you cannot determine the bucket name at all, omit the domain.
|
|
1023
|
+
|
|
1024
|
+
**For databases (RDS, Aurora, DynamoDB):** Use the cluster/instance endpoint from IaC. If the exact endpoint isn't determinable, omit the domain.
|
|
1025
|
+
|
|
1026
|
+
**For Redis / ElastiCache:** Use the cache cluster endpoint if determinable, otherwise omit.
|
|
1027
|
+
|
|
1028
|
+
**For SQS queues:** Use \`https://sqs.{region}.amazonaws.com/{account}/{queue-name}\` if determinable, otherwise omit.
|
|
1029
|
+
|
|
1030
|
+
**For Lambda functions:** Use the Lambda Function URL or the API Gateway route — NOT a generic API domain shared by all functions. If no concrete URL is determinable, omit.
|
|
1031
|
+
|
|
1032
|
+
**For CloudFront / CDN:** Use the distribution domain or custom domain alias if determinable, otherwise omit.
|
|
1033
|
+
|
|
1034
|
+
**For WebSocket APIs:** Use the WebSocket endpoint URL if determinable, otherwise omit.
|
|
1035
|
+
|
|
1036
|
+
When finished, call the \`response\` tool with your structured findings. Do not call \`document_app\` for individual routes, pages, or endpoints — that is a separate phase's responsibility.`;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
function buildPagesDiscoveryObjective(
|
|
1040
|
+
codebasePath: string,
|
|
1041
|
+
appInfo: AppInfo,
|
|
1042
|
+
): string {
|
|
1043
|
+
return `# Find All Web Pages in ${appInfo.name}
|
|
1044
|
+
|
|
1045
|
+
## Codebase
|
|
1046
|
+
- **Repository root:** ${codebasePath}
|
|
1047
|
+
- **App location:** ${appInfo.location}
|
|
1048
|
+
- **Framework:** ${appInfo.framework}
|
|
1049
|
+
|
|
1050
|
+
## Scope — CRITICAL
|
|
1051
|
+
**Only document pages/views that are DEFINED within this application (\`${appInfo.location}\`).** A page belongs to this app if its route definition or component file lives inside \`${appInfo.location}\`.
|
|
1052
|
+
|
|
1053
|
+
Do NOT document:
|
|
1054
|
+
- Routes defined in other applications or packages (even if this app imports/calls them)
|
|
1055
|
+
- External URLs or cloud resource endpoints that this app links to or fetches from
|
|
1056
|
+
- API endpoints (those are handled separately)
|
|
1057
|
+
|
|
1058
|
+
## Task
|
|
1059
|
+
Find ALL web pages, views, and routes that render HTML or serve client-side UI **defined in this application's source code**.
|
|
1060
|
+
|
|
1061
|
+
### What to look for (by framework)
|
|
1062
|
+
- **React/Next.js**: pages/ or app/ directory, route components, layout files
|
|
1063
|
+
- **Express**: res.render(), res.sendFile(), static file serving, template routes
|
|
1064
|
+
- **Django**: urls.py patterns pointing to template views, class-based views with template_name
|
|
1065
|
+
- **Rails**: routes.rb entries pointing to controller actions that render views
|
|
1066
|
+
- **Vue/Nuxt**: pages/ directory, router definitions
|
|
1067
|
+
- **FastAPI**: routes returning HTMLResponse, Jinja2 template responses
|
|
1068
|
+
- **Spring**: @Controller methods returning view names, Thymeleaf templates
|
|
1069
|
+
|
|
1070
|
+
### How to document each page
|
|
1071
|
+
For each page, call \`document_endpoint\` with:
|
|
1072
|
+
- **appName**: \`${appInfo.name}\`
|
|
1073
|
+
- **endpointType**: \`"web-endpoint"\`
|
|
1074
|
+
- **description**: Brief description of what this page shows
|
|
1075
|
+
- **routePath**: The HTTP route this page serves (e.g., \`/dashboard\`). This is the URL path a client requests — it is the endpoint's identity. NOT a file path.
|
|
1076
|
+
- **method**: \`"PAGE"\`
|
|
1077
|
+
- **file**: Source-code file where this page is defined (e.g., \`src/pages/dashboard.tsx\`). Must be inside \`${appInfo.location}\`. This is NOT the route.
|
|
1078
|
+
- **line**: Line number (if determinable)
|
|
1079
|
+
- **handler**: Component or handler name
|
|
1080
|
+
- **authRequired**: Whether the page requires authentication
|
|
1081
|
+
- **riskLevel**: CRITICAL for admin/auth pages, HIGH for user data, MEDIUM for general, LOW for static/public
|
|
1082
|
+
|
|
1083
|
+
### Required workflow — NO MANIFESTS, NO BATCHING
|
|
1084
|
+
**You MUST call \`document_endpoint\` directly, one page at a time, the moment you identify a route.** It is a hard error to:
|
|
1085
|
+
- Build a JSON file, array, or list of pages-to-document and then "process" it (e.g. \`cat > /tmp/pages.json << EOF [...] EOF\`).
|
|
1086
|
+
- Write a Python or shell script that emits \`document_endpoint\` calls.
|
|
1087
|
+
- Defer documentation until "the end" or until "you have the full picture."
|
|
1088
|
+
- Stop early because the calls feel repetitive or because you've documented "the important ones."
|
|
1089
|
+
|
|
1090
|
+
These patterns hit per-message output-token limits and silently drop pages — usually the alphabetically-later ones. The only correct loop is: identify route → call \`document_endpoint\` → identify next route → call \`document_endpoint\` → ...
|
|
1091
|
+
|
|
1092
|
+
You may use \`list_files\`, \`grep\`, or \`execute_command\` (e.g. \`find ... -name page.tsx\`) to **enumerate** the routes that exist. That enumeration step is fine and encouraged. What is not allowed is using a script to **emit the documentation calls themselves** — those must come directly from you, one tool call per route.
|
|
1093
|
+
|
|
1094
|
+
Be thorough — examine every route file, every page directory, every template **within \`${appInfo.location}\`**. Every page surfaced by your enumeration must result in its own \`document_endpoint\` call. Repetitive calls are expected; do not summarize, deduplicate to "interesting" routes, or skip any.
|
|
1095
|
+
|
|
1096
|
+
When finished, call \`response\` with a summary of how many pages you documented. The reported count must equal the number of successful \`document_endpoint\` calls you made.`;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
function buildApiEndpointsDiscoveryObjective(
|
|
1100
|
+
codebasePath: string,
|
|
1101
|
+
appInfo: AppInfo,
|
|
1102
|
+
): string {
|
|
1103
|
+
return `# Find All API Endpoints in ${appInfo.name}
|
|
1104
|
+
|
|
1105
|
+
## Codebase
|
|
1106
|
+
- **Repository root:** ${codebasePath}
|
|
1107
|
+
- **App location:** ${appInfo.location}
|
|
1108
|
+
- **Framework:** ${appInfo.framework}
|
|
1109
|
+
|
|
1110
|
+
## Scope — CRITICAL
|
|
1111
|
+
**Only document API routes that are DEFINED within this application (\`${appInfo.location}\`).** An endpoint belongs to this app if its route handler or route definition file lives inside \`${appInfo.location}\`.
|
|
1112
|
+
|
|
1113
|
+
Do NOT document:
|
|
1114
|
+
- Routes defined in other applications or packages
|
|
1115
|
+
- External API calls this app makes to third-party services or other internal services
|
|
1116
|
+
- S3 bucket URLs, cloud resource endpoints, or CDN URLs that this app interacts with — those belong to the cloud resource, not this API
|
|
1117
|
+
- Web pages/views (those are handled separately)
|
|
1118
|
+
|
|
1119
|
+
## Task
|
|
1120
|
+
Find ALL API endpoints **whose route definitions live in this application's source code**.
|
|
1121
|
+
|
|
1122
|
+
### What to look for (by framework)
|
|
1123
|
+
- **Express**: app.get(), app.post(), router.get(), router.post(), router.put(), router.delete(), etc.
|
|
1124
|
+
- **Next.js**: app/api/ or pages/api/ route handlers (GET, POST, PUT, DELETE exports)
|
|
1125
|
+
- **Django**: urls.py patterns pointing to API views, DRF viewsets, routers, @api_view decorators
|
|
1126
|
+
- **FastAPI**: @app.get(), @app.post(), @app.put(), @app.delete() decorators
|
|
1127
|
+
- **Rails**: routes.rb API namespaces, resources, controller actions
|
|
1128
|
+
- **Spring**: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @RequestMapping
|
|
1129
|
+
- **Go**: http.HandleFunc, mux.Handle, gin router methods
|
|
1130
|
+
- **gRPC**: \`.proto\` service definitions (\`service X { rpc Method (Req) returns (Resp); }\`), \`buf.yaml\`/\`buf.gen.yaml\`, or generated gRPC stubs
|
|
1131
|
+
|
|
1132
|
+
### gRPC / Connect services — do NOT flatten into HTTP paths
|
|
1133
|
+
A gRPC method looks like a path (\`/package.Service/Method\`) but is NOT an HTTP route. When this app defines gRPC/Connect services, document **one \`document_endpoint\` per \`rpc\` method** with:
|
|
1134
|
+
- **endpointType**: \`"api-endpoint"\` (a gRPC method is still an API endpoint)
|
|
1135
|
+
- **transport**: \`"grpc"\` (or \`"grpc_web"\` / \`"connect"\` if the service is served that way)
|
|
1136
|
+
- **routePath**: the wire path \`/package.Service/Method\` (e.g. \`/account.v1.AccountService/GetAccount\`) — do NOT prepend a host
|
|
1137
|
+
- **grpc**: \`{ serviceFqn, method, streamingType, schemaSource: "proto" }\` where \`serviceFqn\` is the fully-qualified service (\`account.v1.AccountService\`), \`method\` is the rpc name, and \`streamingType\` is one of \`unary | server_stream | client_stream | bidi\` (based on the \`stream\` keywords in the rpc signature). Set \`reflectionAvailable: true\` if the server registers the gRPC reflection service.
|
|
1138
|
+
- If a REST/GraphQL gateway (e.g. grpc-gateway annotations, a GraphQL resolver, a Connect handler) maps to this rpc, set \`grpc.frontingGatewayOperation\` — prefer marking this whenever a gateway mapping exists, since it's what lets us later compute "shadow" methods (proto methods reachable directly but NOT exposed via the gateway, where auth checks usually live).
|
|
1139
|
+
|
|
1140
|
+
### How to document each endpoint
|
|
1141
|
+
For each **unique route path**, call \`document_endpoint\` with:
|
|
1142
|
+
- **appName**: \`${appInfo.name}\`
|
|
1143
|
+
- **endpointType**: \`"api-endpoint"\`
|
|
1144
|
+
- **description**: Brief description of what this endpoint does across all its methods
|
|
1145
|
+
- **routePath**: The HTTP route (e.g., \`/api/users\`, \`/api/orders/:id\`). This is the URL path a client requests — it is the endpoint's identity. NOT a source-file path.
|
|
1146
|
+
- **method**: Array of ALL HTTP methods this path supports (e.g., \`["GET", "POST"]\`). **Do NOT create separate entries for each method — consolidate them.**
|
|
1147
|
+
- **file**: Source-code file where the endpoint is defined (e.g., \`src/routes/users.ts\`). Must be inside \`${appInfo.location}\`. This is NOT the route.
|
|
1148
|
+
- **line**: Line number (if determinable)
|
|
1149
|
+
- **handler**: Handler function name (comma-separate if multiple handlers for different methods)
|
|
1150
|
+
- **authRequired**: Whether the endpoint requires authentication (true if ANY method requires it)
|
|
1151
|
+
- **riskLevel**: CRITICAL for auth/payment/admin, HIGH for user data mutations, MEDIUM for general, LOW for read-only public
|
|
1152
|
+
- **transport / grpc**: for gRPC / Connect / gRPC-Web methods, this checklist is not enough — ALSO pass the \`transport\` and \`grpc\` fields exactly as described in the "gRPC / Connect services" section above. Never document an \`rpc\` as a plain HTTP route.
|
|
1153
|
+
|
|
1154
|
+
**CRITICAL: ONE entry per route path.** If \`/api/products\` has GET (list) and POST (create), document it as ONE entry with \`method: ["GET", "POST"]\`. Do NOT create two separate entries.
|
|
1155
|
+
|
|
1156
|
+
**IMPORTANT — Method consolidation for document_endpoint:** When using the \`document_endpoint\` tool, do NOT create separate entries for different HTTP methods on the same route path. For example, if \`/api/users\` supports GET, POST, and DELETE, document it as ONE entry with \`method: ["GET", "POST", "DELETE"]\` and include pentest objectives covering all methods.
|
|
1157
|
+
|
|
1158
|
+
### Required workflow — NO MANIFESTS, NO BATCHING
|
|
1159
|
+
**You MUST call \`document_endpoint\` directly, one route at a time, the moment you identify it.** It is a hard error to:
|
|
1160
|
+
- Build a JSON file, array, or list of endpoints-to-document and then "process" it (e.g. \`cat > /tmp/endpoints.json << EOF [...] EOF\`).
|
|
1161
|
+
- Write a Python or shell script that emits \`document_endpoint\` calls.
|
|
1162
|
+
- Defer documentation until you've "mapped everything out."
|
|
1163
|
+
- Stop early because the calls feel repetitive or because you've covered "the important ones."
|
|
1164
|
+
|
|
1165
|
+
These patterns hit per-message output-token limits and silently drop endpoints — usually the alphabetically-later ones. The only correct loop is: identify route → call \`document_endpoint\` → identify next route → call \`document_endpoint\` → ...
|
|
1166
|
+
|
|
1167
|
+
You may use \`list_files\`, \`grep\`, or \`execute_command\` to **enumerate** routes (e.g. extracting all route registrations into a list to read). That enumeration step is fine. What is not allowed is using a script to **emit the documentation calls themselves** — those must come directly from you, one tool call per unique route path.
|
|
1168
|
+
|
|
1169
|
+
Be thorough — trace through all route registrations, middleware chains, and controller files **within \`${appInfo.location}\`**. Every unique route path your enumeration surfaces must result in its own \`document_endpoint\` call.
|
|
1170
|
+
|
|
1171
|
+
When finished, call \`response\` with a summary of how many endpoints you documented. The reported count must equal the number of successful \`document_endpoint\` calls you made.`;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
function buildCloudResourceEndpointsObjective(
|
|
1175
|
+
codebasePath: string,
|
|
1176
|
+
appInfo: AppInfo,
|
|
1177
|
+
environments?: string[],
|
|
1178
|
+
): string {
|
|
1179
|
+
const envNote = environments?.length
|
|
1180
|
+
? `\n## Target Environments\nThis resource may exist in the following environments: ${environments.join(", ")}. When documenting entry points, use the **environment-specific resource identifiers** (e.g. environment-prefixed bucket names, stage-scoped queue URLs, per-environment ARNs). If the app name already includes an environment prefix, use that environment's resource names in the endpoints.\n`
|
|
1181
|
+
: "";
|
|
1182
|
+
|
|
1183
|
+
return `# Document Entry Points for Cloud Resource: ${appInfo.name}
|
|
1184
|
+
|
|
1185
|
+
## Codebase
|
|
1186
|
+
- **Repository root:** ${codebasePath}
|
|
1187
|
+
- **Resource location:** ${appInfo.location}
|
|
1188
|
+
- **Service:** ${appInfo.framework}
|
|
1189
|
+
${envNote}
|
|
1190
|
+
## Context — Application Domain
|
|
1191
|
+
The parent application for this cloud resource already has a domain/URL associated with it (set via \`document_app\`). **Do NOT create endpoints that simply repeat the base domain URL.** The domain is already stored on the application record — endpoints should document **distinct access patterns** that go beyond the base domain.
|
|
1192
|
+
|
|
1193
|
+
## Scope — CRITICAL
|
|
1194
|
+
You are documenting the **distinct access patterns and resource identifiers** for this cloud resource — specific ways the resource can be accessed that are NOT just its base domain URL.
|
|
1195
|
+
|
|
1196
|
+
Do NOT document:
|
|
1197
|
+
- The base domain URL of the resource (e.g. \`https://bucket-name.s3.amazonaws.com\`) — this is already the application's domain
|
|
1198
|
+
- Code locations where the app calls/uses this resource (e.g. "line 42 of api.ts calls S3.putObject" is NOT an endpoint)
|
|
1199
|
+
- API routes from other apps that happen to interact with this resource
|
|
1200
|
+
- Internal SDK calls or client instantiations
|
|
1201
|
+
|
|
1202
|
+
DO document:
|
|
1203
|
+
- **Specific access patterns** beyond the base domain (e.g. pre-signed URL patterns, static website hosting paths, object key patterns)
|
|
1204
|
+
- **Resource ARNs** that represent programmatic access points (e.g. \`arn:aws:s3:::bucket-name\`, \`arn:aws:sqs:region:account:queue-name\`)
|
|
1205
|
+
- **Alternative access URLs** (e.g. CDN distribution URL, static website hosting URL, regional endpoint variants)
|
|
1206
|
+
- **Queue/topic URLs** for message-based resources
|
|
1207
|
+
|
|
1208
|
+
## Task
|
|
1209
|
+
Find the **distinct access patterns and resource identifiers** for this cloud resource by reading infrastructure-as-code and configuration.
|
|
1210
|
+
|
|
1211
|
+
### Where to find entry point information
|
|
1212
|
+
1. **Infrastructure-as-code** — Terraform (*.tf), CloudFormation (*.yaml/*.json), CDK constructs, SST components (sst.config.ts, infra/), Pulumi, serverless.yml — these define the resource and its access configuration
|
|
1213
|
+
2. **Configuration files** — .env files, config modules, environment variable definitions that contain resource URLs
|
|
1214
|
+
3. **Resource policies** — bucket policies, CORS configs, access control settings that reveal how the resource is exposed
|
|
1215
|
+
|
|
1216
|
+
### What qualifies as an entry point (by resource type)
|
|
1217
|
+
- **S3 / GCS / Blob Storage**: Pre-signed URL patterns (e.g. \`/{objectKey}?X-Amz-Signature={sig}\`), static website hosting URL, ARN. Do NOT include the plain bucket HTTPS endpoint — that's the app domain.
|
|
1218
|
+
- **CloudFront / CDN**: Custom domain aliases, origin access patterns
|
|
1219
|
+
- **SQS / SNS / Message Queues**: Queue URL, topic ARN
|
|
1220
|
+
- **Lambda / Cloud Functions**: Function URL, API Gateway integration URL
|
|
1221
|
+
- **DynamoDB / ElastiCache / Redis**: Connection endpoint URL, ARN
|
|
1222
|
+
|
|
1223
|
+
### How to document each entry point
|
|
1224
|
+
For each entry point, call \`document_endpoint\` with:
|
|
1225
|
+
- **appName**: \`${appInfo.name}\`
|
|
1226
|
+
- **endpointType**: \`"asset"\`
|
|
1227
|
+
- **description**: What this entry point exposes (e.g., "Pre-signed HTTP URLs for temporary read access to objects", "AWS resource ARN for programmatic access through IAM policies")
|
|
1228
|
+
- **routePath**: The specific access pattern, path template, or ARN — this is the endpoint's identity. NOT the base domain URL. Examples: \`/{objectKey}?X-Amz-Signature={signature}&X-Amz-Credential={credential}\`, \`arn:aws:s3:::bucket-name\`, \`https://sqs.region.amazonaws.com/account/queue-name\`
|
|
1229
|
+
- **method**: Access methods on the resource (e.g., \`["GET", "PUT"]\` for S3, \`["SendMessage", "ReceiveMessage"]\` for SQS, \`["READ", "WRITE"]\` for generic)
|
|
1230
|
+
- **file**: Infrastructure or config file where this resource is defined (e.g., \`infra/storage.ts\`). NOT application code that calls it.
|
|
1231
|
+
- **line**: Line number if determinable
|
|
1232
|
+
- **authRequired**: Whether external access requires authentication
|
|
1233
|
+
- **riskLevel**: CRITICAL for publicly accessible storage with write access or sensitive data, HIGH for resources with broad IAM permissions, MEDIUM for internal resources, LOW for read-only public assets
|
|
1234
|
+
|
|
1235
|
+
### Required workflow — NO MANIFESTS, NO BATCHING
|
|
1236
|
+
**You MUST call \`document_endpoint\` directly, one entry point at a time, the moment you identify it.** Do not build a JSON file or list of entry points to "process later," and do not write a script that emits \`document_endpoint\` calls. Those patterns hit per-message output-token limits and silently drop entries. The only correct loop is: identify entry point → call \`document_endpoint\` → identify next → call \`document_endpoint\` → ...
|
|
1237
|
+
|
|
1238
|
+
When finished, call \`response\` with a summary of how many entry points you documented. The reported count must equal the number of successful \`document_endpoint\` calls you made.`;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
// ---------------------------------------------------------------------------
|
|
1242
|
+
// Incremental whitebox attack surface workflow
|
|
1243
|
+
// ---------------------------------------------------------------------------
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* Incremental whitebox attack surface workflow for commit-triggered recon.
|
|
1247
|
+
*
|
|
1248
|
+
* Instead of scanning the entire codebase:
|
|
1249
|
+
* 1. Run `git diff` between the two commits and write the output to a file.
|
|
1250
|
+
* 2. Serialize existing assets into the session's assets directory (app folder structure).
|
|
1251
|
+
* 3. Spawn a CodeAgent to analyze the diff and update assets in-place.
|
|
1252
|
+
* New endpoints get risk scores inline via document_endpoint.
|
|
1253
|
+
* 4. Read the final assets directory and reconstruct the result.
|
|
1254
|
+
* 5. Carry forward existing risk scores for unchanged endpoints.
|
|
1255
|
+
*/
|
|
1256
|
+
export async function runIncrementalWhiteboxAttackSurfaceWorkflow(
|
|
1257
|
+
input: IncrementalWhiteboxInput,
|
|
1258
|
+
): Promise<WhiteboxAttackSurfaceResult> {
|
|
1259
|
+
const {
|
|
1260
|
+
codebasePath,
|
|
1261
|
+
previousCommitSha,
|
|
1262
|
+
currentCommitSha,
|
|
1263
|
+
existingResult,
|
|
1264
|
+
model,
|
|
1265
|
+
session,
|
|
1266
|
+
authConfig,
|
|
1267
|
+
abortSignal,
|
|
1268
|
+
eventBus,
|
|
1269
|
+
attackSurfaceRegistry,
|
|
1270
|
+
onStepFinish,
|
|
1271
|
+
projectThreatModel,
|
|
1272
|
+
seams: inputSeams,
|
|
1273
|
+
} = input;
|
|
1274
|
+
|
|
1275
|
+
const seams = inputSeams ?? inProcessSeams();
|
|
1276
|
+
|
|
1277
|
+
// =========================================================================
|
|
1278
|
+
// Phase 1: Generate diff file
|
|
1279
|
+
// =========================================================================
|
|
1280
|
+
|
|
1281
|
+
const diffPath = join(session.rootPath, "diff-output.txt");
|
|
1282
|
+
try {
|
|
1283
|
+
const diff = execFileSync(
|
|
1284
|
+
"git",
|
|
1285
|
+
["diff", `${previousCommitSha}..${currentCommitSha}`],
|
|
1286
|
+
{ cwd: codebasePath, maxBuffer: 50 * 1024 * 1024, encoding: "utf-8" },
|
|
1287
|
+
);
|
|
1288
|
+
writeFileSync(diffPath, diff, "utf-8");
|
|
1289
|
+
} catch (error) {
|
|
1290
|
+
log.error(
|
|
1291
|
+
"Failed to generate git diff, falling back to full recon",
|
|
1292
|
+
error instanceof Error ? error : undefined,
|
|
1293
|
+
{ error: String(error) },
|
|
1294
|
+
);
|
|
1295
|
+
return runWhiteboxAttackSurfaceWorkflow(input);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// =========================================================================
|
|
1299
|
+
// Phase 2: Serialize existing assets to session's assets directory
|
|
1300
|
+
// (app folder structure: assets/<app>/app.json + endpoint files)
|
|
1301
|
+
// =========================================================================
|
|
1302
|
+
|
|
1303
|
+
const assetsPath = join(session.rootPath, "assets");
|
|
1304
|
+
mkdirSync(assetsPath, { recursive: true });
|
|
1305
|
+
|
|
1306
|
+
let preloadedCount = 0;
|
|
1307
|
+
|
|
1308
|
+
for (const app of existingResult.apps) {
|
|
1309
|
+
const appDir = join(assetsPath, sanitizeName(app.name));
|
|
1310
|
+
mkdirSync(appDir, { recursive: true });
|
|
1311
|
+
|
|
1312
|
+
writeFileSync(
|
|
1313
|
+
join(appDir, "app.json"),
|
|
1314
|
+
JSON.stringify(toAppMetadata(app), null, 2),
|
|
1315
|
+
"utf-8",
|
|
1316
|
+
);
|
|
1317
|
+
|
|
1318
|
+
// Write endpoint assets
|
|
1319
|
+
for (const ep of [...app.pages, ...app.apiEndpoints]) {
|
|
1320
|
+
const isPage = app.pages.includes(ep);
|
|
1321
|
+
const rawKey = `${app.name}__${ep.path}`.toLowerCase();
|
|
1322
|
+
const hash = createHash("sha256")
|
|
1323
|
+
.update(rawKey)
|
|
1324
|
+
.digest("hex")
|
|
1325
|
+
.slice(0, 8);
|
|
1326
|
+
const sanitizedPath = sanitizeName(ep.path);
|
|
1327
|
+
const filename = `asset_${sanitizedPath}_${hash}.json`;
|
|
1328
|
+
|
|
1329
|
+
const { riskScore: _staleScore, threatModel, ...epWithoutMeta } = ep;
|
|
1330
|
+
const assetData: Record<string, unknown> = {
|
|
1331
|
+
assetName: ep.path,
|
|
1332
|
+
assetType: "endpoint",
|
|
1333
|
+
appName: app.name,
|
|
1334
|
+
description: ep.description ?? `${ep.method} ${ep.path}`,
|
|
1335
|
+
details: {
|
|
1336
|
+
url: ep.path,
|
|
1337
|
+
method: isPage ? "PAGE" : ep.method,
|
|
1338
|
+
file: ep.file,
|
|
1339
|
+
line: ep.line,
|
|
1340
|
+
handler: ep.handler,
|
|
1341
|
+
authRequired: ep.authRequired,
|
|
1342
|
+
},
|
|
1343
|
+
riskLevel: "MEDIUM",
|
|
1344
|
+
pentestObjectives: epWithoutMeta.pentestObjectives ?? [],
|
|
1345
|
+
...(threatModel ? { threatModel } : {}),
|
|
1346
|
+
discoveredAt: new Date().toISOString(),
|
|
1347
|
+
sessionId: session.id,
|
|
1348
|
+
target: "",
|
|
1349
|
+
};
|
|
1350
|
+
writeFileSync(
|
|
1351
|
+
join(appDir, filename),
|
|
1352
|
+
JSON.stringify(assetData, null, 2),
|
|
1353
|
+
"utf-8",
|
|
1354
|
+
);
|
|
1355
|
+
preloadedCount++;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
log.info(
|
|
1360
|
+
`Incremental recon: wrote ${preloadedCount} existing endpoint assets to ${assetsPath}`,
|
|
1361
|
+
);
|
|
1362
|
+
|
|
1363
|
+
// =========================================================================
|
|
1364
|
+
// Phase 3: Agent analyzes diff and updates asset files
|
|
1365
|
+
// =========================================================================
|
|
1366
|
+
|
|
1367
|
+
const IncrementalResultSchema = z.object({
|
|
1368
|
+
repoType: z.string(),
|
|
1369
|
+
packageManager: z.string(),
|
|
1370
|
+
changedApps: z
|
|
1371
|
+
.array(z.string())
|
|
1372
|
+
.describe("Names of applications that were affected by the diff"),
|
|
1373
|
+
addedEndpoints: z.number().describe("Count of new endpoints added"),
|
|
1374
|
+
modifiedEndpoints: z
|
|
1375
|
+
.number()
|
|
1376
|
+
.describe("Count of existing endpoints modified"),
|
|
1377
|
+
removedEndpoints: z.number().describe("Count of endpoints removed"),
|
|
1378
|
+
summary: z.string().describe("Brief summary of what changed"),
|
|
1379
|
+
});
|
|
1380
|
+
|
|
1381
|
+
type IncrementalResult = z.infer<typeof IncrementalResultSchema>;
|
|
1382
|
+
|
|
1383
|
+
const objective = buildIncrementalObjective(
|
|
1384
|
+
codebasePath,
|
|
1385
|
+
diffPath,
|
|
1386
|
+
assetsPath,
|
|
1387
|
+
existingResult,
|
|
1388
|
+
input.domains,
|
|
1389
|
+
input.environments,
|
|
1390
|
+
);
|
|
1391
|
+
|
|
1392
|
+
const incrementalSubagentId = seams.ids.newSessionId("incremental-recon", 0);
|
|
1393
|
+
const agent = new CodeAgent<IncrementalResult>({
|
|
1394
|
+
codebasePath,
|
|
1395
|
+
objective,
|
|
1396
|
+
system: WHITEBOX_DISCOVERY_SYSTEM_PROMPT,
|
|
1397
|
+
model,
|
|
1398
|
+
session,
|
|
1399
|
+
authConfig,
|
|
1400
|
+
attackSurfaceRegistry,
|
|
1401
|
+
eventBus,
|
|
1402
|
+
subagentId: incrementalSubagentId,
|
|
1403
|
+
subagentName: "Incremental Recon",
|
|
1404
|
+
onStepFinish: (event) => onStepFinish?.(event),
|
|
1405
|
+
openAIReasoningEffort: input.openAIReasoningEffort,
|
|
1406
|
+
enableThinking: input.enableThinking,
|
|
1407
|
+
thinkingEffort: input.thinkingEffort,
|
|
1408
|
+
responseSchema: IncrementalResultSchema,
|
|
1409
|
+
projectThreatModel,
|
|
1410
|
+
subagentSpawner: input.subagentSpawner,
|
|
1411
|
+
...input.hooks,
|
|
1412
|
+
abortSignal,
|
|
1413
|
+
});
|
|
1414
|
+
|
|
1415
|
+
eventBus?.emit("subagent-spawn", {
|
|
1416
|
+
subagentId: incrementalSubagentId,
|
|
1417
|
+
name: "Incremental Recon",
|
|
1418
|
+
input: { codebasePath },
|
|
1419
|
+
});
|
|
1420
|
+
|
|
1421
|
+
let agentResult: IncrementalResult;
|
|
1422
|
+
try {
|
|
1423
|
+
agentResult = await agent.consume();
|
|
1424
|
+
eventBus?.emit("subagent-complete", {
|
|
1425
|
+
subagentId: incrementalSubagentId,
|
|
1426
|
+
status: "completed",
|
|
1427
|
+
});
|
|
1428
|
+
} catch (e) {
|
|
1429
|
+
eventBus?.emit("subagent-complete", {
|
|
1430
|
+
subagentId: incrementalSubagentId,
|
|
1431
|
+
status: "failed",
|
|
1432
|
+
});
|
|
1433
|
+
throw e;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
log.info(
|
|
1437
|
+
`Incremental agent finished: ${agentResult?.summary ?? "no summary"}`,
|
|
1438
|
+
);
|
|
1439
|
+
|
|
1440
|
+
// =========================================================================
|
|
1441
|
+
// Phase 4: Read final assets directory and reconstruct result
|
|
1442
|
+
// =========================================================================
|
|
1443
|
+
|
|
1444
|
+
const { apps: parsedApps } = readAppsFromAssetsDirectory(assetsPath);
|
|
1445
|
+
|
|
1446
|
+
// =========================================================================
|
|
1447
|
+
// Phase 5: Carry forward existing risk scores for endpoints that were
|
|
1448
|
+
// not re-created via document_endpoint (i.e. modified via
|
|
1449
|
+
// execute_command or unchanged). New endpoints already have
|
|
1450
|
+
// inline risk scores from document_endpoint.
|
|
1451
|
+
// =========================================================================
|
|
1452
|
+
|
|
1453
|
+
const existingEndpointMap = new Map<string, Endpoint>();
|
|
1454
|
+
for (const existingApp of existingResult.apps) {
|
|
1455
|
+
for (const ep of [...existingApp.pages, ...existingApp.apiEndpoints]) {
|
|
1456
|
+
existingEndpointMap.set(`${ep.method}:${ep.file}:${ep.path}`, ep);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
function carryForwardRiskScore(ep: Endpoint): Endpoint {
|
|
1461
|
+
if (ep.riskScore) return ep;
|
|
1462
|
+
const key = `${ep.method}:${ep.file}:${ep.path}`;
|
|
1463
|
+
const existing = existingEndpointMap.get(key);
|
|
1464
|
+
return existing?.riskScore ? { ...ep, riskScore: existing.riskScore } : ep;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
const apps: App[] = parsedApps.map((app) => ({
|
|
1468
|
+
...app,
|
|
1469
|
+
pages: app.pages.map(carryForwardRiskScore),
|
|
1470
|
+
apiEndpoints: app.apiEndpoints.map(carryForwardRiskScore),
|
|
1471
|
+
}));
|
|
1472
|
+
|
|
1473
|
+
const totalPages = apps.reduce((sum, a) => sum + a.pages.length, 0);
|
|
1474
|
+
const totalApiEndpoints = apps.reduce(
|
|
1475
|
+
(sum, a) => sum + a.apiEndpoints.length,
|
|
1476
|
+
0,
|
|
1477
|
+
);
|
|
1478
|
+
const totalPentestObjectives = apps.reduce(
|
|
1479
|
+
(sum, a) =>
|
|
1480
|
+
sum +
|
|
1481
|
+
[...a.pages, ...a.apiEndpoints].reduce(
|
|
1482
|
+
(s, ep) => s + ep.pentestObjectives.length,
|
|
1483
|
+
0,
|
|
1484
|
+
),
|
|
1485
|
+
0,
|
|
1486
|
+
);
|
|
1487
|
+
|
|
1488
|
+
return {
|
|
1489
|
+
repoType: existingResult.repoType,
|
|
1490
|
+
packageManager: existingResult.packageManager,
|
|
1491
|
+
apps,
|
|
1492
|
+
summary: {
|
|
1493
|
+
totalApps: apps.length,
|
|
1494
|
+
totalPages,
|
|
1495
|
+
totalApiEndpoints,
|
|
1496
|
+
totalPentestObjectives,
|
|
1497
|
+
},
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
// ---------------------------------------------------------------------------
|
|
1502
|
+
// Incremental objective builder
|
|
1503
|
+
// ---------------------------------------------------------------------------
|
|
1504
|
+
|
|
1505
|
+
function buildIncrementalObjective(
|
|
1506
|
+
codebasePath: string,
|
|
1507
|
+
diffPath: string,
|
|
1508
|
+
assetsPath: string,
|
|
1509
|
+
existingResult: WhiteboxAttackSurfaceResult,
|
|
1510
|
+
domains?: string[],
|
|
1511
|
+
environments?: string[],
|
|
1512
|
+
): string {
|
|
1513
|
+
const appsSummary = existingResult.apps
|
|
1514
|
+
.map((app) => {
|
|
1515
|
+
const epCount = app.pages.length + app.apiEndpoints.length;
|
|
1516
|
+
return ` - **${app.name}** (${app.framework}) at \`${app.location}\` — ${epCount} endpoints`;
|
|
1517
|
+
})
|
|
1518
|
+
.join("\n");
|
|
1519
|
+
|
|
1520
|
+
const domainSection = domains?.length
|
|
1521
|
+
? `\n## Known Domains\nThe following domains are associated with this project. When documenting new apps, set the \`domain\` field on \`document_app\` if you can determine which domain serves the app:\n${domains.map((d) => `- ${d}`).join("\n")}\n`
|
|
1522
|
+
: "";
|
|
1523
|
+
|
|
1524
|
+
const environmentsSection = environments?.length
|
|
1525
|
+
? `\n## Target Environments\nThis project is deployed to: ${environments.join(", ")}. When the diff introduces new dynamically-named resources (e.g. environment-prefixed S3 buckets, stage-scoped databases), create a **separate app entry per environment** using the environment name as a prefix (e.g. \`${environments[0]}-<resource>\`). Use environment-specific identifiers in domains and endpoints.\n`
|
|
1526
|
+
: "";
|
|
1527
|
+
|
|
1528
|
+
return `# Incremental Attack Surface Update
|
|
1529
|
+
|
|
1530
|
+
## Context
|
|
1531
|
+
You are updating the attack surface map for a repository after a new commit. Rather than analyzing the entire codebase, you will analyze only the **changed files** and update the existing endpoint assets accordingly. Also check for any new cloud resources (S3 buckets, storage, CDN origins, etc.) introduced in the diff.
|
|
1532
|
+
|
|
1533
|
+
## Codebase
|
|
1534
|
+
- **Path:** ${codebasePath}
|
|
1535
|
+
- **Diff file:** ${diffPath} (contains \`git diff\` output between the previous and current commit)
|
|
1536
|
+
- **Existing assets directory:** ${assetsPath}
|
|
1537
|
+
${domainSection}${environmentsSection}
|
|
1538
|
+
## Directory Structure
|
|
1539
|
+
The assets directory uses app-scoped folders:
|
|
1540
|
+
\`\`\`
|
|
1541
|
+
assets/
|
|
1542
|
+
<app-name>/
|
|
1543
|
+
app.json — app metadata (name, framework, description, location)
|
|
1544
|
+
asset_*.json — one file per endpoint (written by document_endpoint)
|
|
1545
|
+
\`\`\`
|
|
1546
|
+
|
|
1547
|
+
## Existing Applications
|
|
1548
|
+
${appsSummary}
|
|
1549
|
+
|
|
1550
|
+
## Task
|
|
1551
|
+
|
|
1552
|
+
### Step 1: Read and understand the diff
|
|
1553
|
+
Read the diff file at \`${diffPath}\`. If it's very large, read it in chunks. Identify which files were added, modified, or deleted.
|
|
1554
|
+
|
|
1555
|
+
### Step 2: Determine impact on the attack surface
|
|
1556
|
+
For each changed file, determine if it affects any endpoints:
|
|
1557
|
+
- **New route/endpoint definitions** → use \`document_endpoint\` with the appropriate \`appName\`
|
|
1558
|
+
- **Modified route handlers** → read the existing asset file, then use \`execute_command\` to update it
|
|
1559
|
+
- **Deleted route files or endpoint definitions** → delete the corresponding asset file
|
|
1560
|
+
- **Non-route changes** (e.g. utility functions, configs, tests) → skip
|
|
1561
|
+
|
|
1562
|
+
### Step 3: Update assets
|
|
1563
|
+
For new endpoints, use \`document_endpoint\` with:
|
|
1564
|
+
- \`appName\` set to the correct application name
|
|
1565
|
+
- \`routePath\` set to the HTTP route (e.g., \`/api/users\`) — this is NOT a file path
|
|
1566
|
+
- \`method\` as an array of ALL HTTP methods the path supports
|
|
1567
|
+
- \`file\` set to the source-code file (e.g., \`src/routes/users.ts\`) — this is NOT the route
|
|
1568
|
+
- \`line\`, \`handler\`, \`authRequired\` filled in
|
|
1569
|
+
|
|
1570
|
+
For modified endpoints, update the existing JSON file via \`execute_command\`.
|
|
1571
|
+
For removed endpoints, delete the file via \`execute_command\`.
|
|
1572
|
+
|
|
1573
|
+
**IMPORTANT: ONE entry per route path.** Do NOT create separate entries for different HTTP methods on the same path.
|
|
1574
|
+
|
|
1575
|
+
**IMPORTANT: NO MANIFESTS, NO BATCHING.** Call \`document_endpoint\` directly, one new endpoint at a time, the moment you identify it. Do not build a JSON file or list of endpoints-to-document and process it later, and do not write a script that emits \`document_endpoint\` calls — that pattern hits output-token limits and silently drops endpoints.
|
|
1576
|
+
|
|
1577
|
+
### Step 4: Report
|
|
1578
|
+
When finished, call the \`response\` tool with a summary of your changes.
|
|
1579
|
+
|
|
1580
|
+
**IMPORTANT:** Be conservative. Only add/modify/remove endpoints that are clearly affected by the diff. Do not re-analyze the entire codebase.`;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
const IncrementalReconResultSchema = z.object({
|
|
1584
|
+
repoType: z.string(),
|
|
1585
|
+
packageManager: z.string(),
|
|
1586
|
+
changedApps: z
|
|
1587
|
+
.array(z.string())
|
|
1588
|
+
.describe("Names of applications that were affected by the diff"),
|
|
1589
|
+
addedEndpoints: z.number().describe("Count of new endpoints added"),
|
|
1590
|
+
modifiedEndpoints: z
|
|
1591
|
+
.number()
|
|
1592
|
+
.describe("Count of existing endpoints modified"),
|
|
1593
|
+
removedEndpoints: z.number().describe("Count of endpoints removed"),
|
|
1594
|
+
summary: z.string().describe("Brief summary of what changed"),
|
|
1595
|
+
});
|
|
1596
|
+
|
|
1597
|
+
async function readIncrementalReconAssets(
|
|
1598
|
+
backends: ToolBackends,
|
|
1599
|
+
assetsPath: string,
|
|
1600
|
+
existing: WhiteboxAttackSurfaceResult,
|
|
1601
|
+
abortSignal?: AbortSignal,
|
|
1602
|
+
): Promise<WhiteboxAttackSurfaceResult> {
|
|
1603
|
+
const fs = backends.fs;
|
|
1604
|
+
const list = async (path: string) => {
|
|
1605
|
+
abortSignal?.throwIfAborted();
|
|
1606
|
+
const result = await fs.list(path);
|
|
1607
|
+
if (!result.success)
|
|
1608
|
+
throw new Error(`Incomplete recon asset listing: ${path}`);
|
|
1609
|
+
if (!result.truncated) return result.files;
|
|
1610
|
+
const files: string[] = [];
|
|
1611
|
+
let total: number | undefined;
|
|
1612
|
+
for (let offset = 0; ; ) {
|
|
1613
|
+
abortSignal?.throwIfAborted();
|
|
1614
|
+
const quote = (value: string) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
1615
|
+
const output = await collectCommand(
|
|
1616
|
+
backends.command.run(
|
|
1617
|
+
`python3 -c ${quote(RECON_ARTIFACT_PAGE_SCRIPT)} ${quote(assetsPath)} ${quote(path)} ${offset}`,
|
|
1618
|
+
{ timeoutSeconds: 30, abortSignal },
|
|
1619
|
+
),
|
|
1620
|
+
);
|
|
1621
|
+
if (output.exitCode !== 0 || output.timedOut || output.stdoutTruncated)
|
|
1622
|
+
throw new Error(`Recon artifact enumeration failed: ${path}`);
|
|
1623
|
+
const page = z
|
|
1624
|
+
.object({
|
|
1625
|
+
files: z.array(z.string()).max(64),
|
|
1626
|
+
total: z.number().int().min(0).max(100000),
|
|
1627
|
+
next: z.number().int().min(1).nullable(),
|
|
1628
|
+
})
|
|
1629
|
+
.parse(JSON.parse(output.stdout));
|
|
1630
|
+
total ??= page.total;
|
|
1631
|
+
if (
|
|
1632
|
+
page.total !== total ||
|
|
1633
|
+
(page.next !== null && page.next !== offset + page.files.length) ||
|
|
1634
|
+
(page.next !== null && (page.files.length === 0 || page.next >= total))
|
|
1635
|
+
)
|
|
1636
|
+
throw new Error(
|
|
1637
|
+
"Recon artifact enumeration did not advance consistently",
|
|
1638
|
+
);
|
|
1639
|
+
files.push(...page.files);
|
|
1640
|
+
if (page.next === null) {
|
|
1641
|
+
if (files.length !== total || new Set(files).size !== total)
|
|
1642
|
+
throw new Error("Incomplete recon artifact pagination");
|
|
1643
|
+
return files;
|
|
1644
|
+
}
|
|
1645
|
+
offset = page.next;
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1648
|
+
const read = async (path: string): Promise<unknown> => {
|
|
1649
|
+
abortSignal?.throwIfAborted();
|
|
1650
|
+
const result = await fs.readRaw(path);
|
|
1651
|
+
if (!result.success) throw new Error(`Recon artifact read failed: ${path}`);
|
|
1652
|
+
return JSON.parse(result.content);
|
|
1653
|
+
};
|
|
1654
|
+
const apps: App[] = [];
|
|
1655
|
+
for (const directory of await list(assetsPath)) {
|
|
1656
|
+
if (!directory.endsWith("/")) continue;
|
|
1657
|
+
if (
|
|
1658
|
+
directory === "../" ||
|
|
1659
|
+
directory === "./" ||
|
|
1660
|
+
directory.slice(0, -1).includes("/")
|
|
1661
|
+
)
|
|
1662
|
+
throw new Error("Invalid recon artifact directory");
|
|
1663
|
+
const appPath = join(assetsPath, directory);
|
|
1664
|
+
const metadata = AppInfoSchema.parse(await read(join(appPath, "app.json")));
|
|
1665
|
+
const previousApp = existing.apps.find((app) => app.name === metadata.name);
|
|
1666
|
+
const app: App = {
|
|
1667
|
+
...previousApp,
|
|
1668
|
+
...metadata,
|
|
1669
|
+
pages: [],
|
|
1670
|
+
apiEndpoints: [],
|
|
1671
|
+
};
|
|
1672
|
+
for (const file of await list(appPath)) {
|
|
1673
|
+
if (file === "app.json" || !file.endsWith(".json")) continue;
|
|
1674
|
+
if (file.includes("/") || file === "..")
|
|
1675
|
+
throw new Error("Invalid recon artifact filename");
|
|
1676
|
+
const raw = await read(join(appPath, file));
|
|
1677
|
+
const record = z
|
|
1678
|
+
.object({
|
|
1679
|
+
method: z.union([z.string(), z.array(z.string())]),
|
|
1680
|
+
routePath: z.string(),
|
|
1681
|
+
})
|
|
1682
|
+
.passthrough()
|
|
1683
|
+
.parse(raw) as DocumentedEndpointRecord;
|
|
1684
|
+
const endpoint = assetRecordToEndpoint(record);
|
|
1685
|
+
if (!endpoint)
|
|
1686
|
+
throw new Error(`Invalid recon endpoint artifact: ${file}`);
|
|
1687
|
+
const previous =
|
|
1688
|
+
previousApp &&
|
|
1689
|
+
[...previousApp.pages, ...previousApp.apiEndpoints].find(
|
|
1690
|
+
(ep) =>
|
|
1691
|
+
ep.method === endpoint.method &&
|
|
1692
|
+
ep.file === endpoint.file &&
|
|
1693
|
+
ep.path === endpoint.path,
|
|
1694
|
+
);
|
|
1695
|
+
const restored = {
|
|
1696
|
+
...previous,
|
|
1697
|
+
...endpoint,
|
|
1698
|
+
...(endpoint.riskScore
|
|
1699
|
+
? {}
|
|
1700
|
+
: previous?.riskScore
|
|
1701
|
+
? { riskScore: previous.riskScore }
|
|
1702
|
+
: {}),
|
|
1703
|
+
};
|
|
1704
|
+
(isPageEndpoint(record) ? app.pages : app.apiEndpoints).push(restored);
|
|
1705
|
+
}
|
|
1706
|
+
apps.push(app);
|
|
1707
|
+
}
|
|
1708
|
+
return {
|
|
1709
|
+
...existing,
|
|
1710
|
+
apps,
|
|
1711
|
+
summary: {
|
|
1712
|
+
totalApps: apps.length,
|
|
1713
|
+
totalPages: apps.reduce((sum, app) => sum + app.pages.length, 0),
|
|
1714
|
+
totalApiEndpoints: apps.reduce(
|
|
1715
|
+
(sum, app) => sum + app.apiEndpoints.length,
|
|
1716
|
+
0,
|
|
1717
|
+
),
|
|
1718
|
+
totalPentestObjectives: apps.reduce(
|
|
1719
|
+
(sum, app) =>
|
|
1720
|
+
sum +
|
|
1721
|
+
[...app.pages, ...app.apiEndpoints].reduce(
|
|
1722
|
+
(count, ep) => count + ep.pentestObjectives.length,
|
|
1723
|
+
0,
|
|
1724
|
+
),
|
|
1725
|
+
0,
|
|
1726
|
+
),
|
|
1727
|
+
},
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
const RECON_ARTIFACT_PAGE_SCRIPT = `import os,sys,json,itertools
|
|
1732
|
+
base=os.path.realpath(sys.argv[1]); directory=os.path.realpath(sys.argv[2]); offset=int(sys.argv[3])
|
|
1733
|
+
if os.path.commonpath([base,directory]) != base: raise ValueError("Artifact directory escaped root")
|
|
1734
|
+
with os.scandir(directory) as scan:
|
|
1735
|
+
entries=list(itertools.islice(scan,100001))
|
|
1736
|
+
if len(entries)>100000: raise ValueError("Artifact inventory exceeds limit")
|
|
1737
|
+
if any(entry.is_symlink() for entry in entries): raise ValueError("Artifact links are not supported")
|
|
1738
|
+
files=sorted(entry.name+("/" if entry.is_dir() else "") for entry in entries)
|
|
1739
|
+
end=min(len(files),offset+64)
|
|
1740
|
+
print(json.dumps({"files":files[offset:end],"total":len(files),"next":end if end<len(files) else None}))`;
|