@pensar/apex 2.6.1 → 2.7.0-canary.1572d9a4
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/build/{agent-ayreaj6z.js → agent-3g1b578v.js} +6 -5
- package/build/{agent-yby11zaq.js → agent-p8cezgbb.js} +7 -6
- package/build/{agent-runs-g37vkrjr.js → agent-runs-f86emmgg.js} +23 -20
- package/build/agent-vaq31je6.js +14 -0
- package/build/agent-vvdqga09.js +14 -0
- package/build/{apps-xn6km9yn.js → apps-3stwnmen.js} +16 -13
- package/build/{auth-d105wc64.js → auth-7md9kwda.js} +16 -13
- package/build/blackboxAgent-ct8bejef.js +14 -0
- package/build/{blackboxPentest-ps78v3w7.js → blackboxPentest-w2nr4md3.js} +21 -15
- package/build/{cli-c05y640n.js → cli-1j28cbhy.js} +1 -1
- package/build/{cli-d37a42dc.js → cli-2jz2jz06.js} +206 -90
- package/build/{cli-az3xq70v.js → cli-4a8dsz2k.js} +4 -4
- package/build/{cli-qgz1q9g5.js → cli-58781vcf.js} +1192 -1473
- package/build/{cli-gx71jcke.js → cli-7067zzeb.js} +1 -1
- package/build/{cli-3sp6nd8d.js → cli-81smmd5w.js} +5 -5
- package/build/{cli-k2nwxta0.js → cli-8b25dhky.js} +2 -2
- package/build/{cli-fy6vh2a7.js → cli-8sw5zpqz.js} +1 -1
- package/build/{cli-709rvekb.js → cli-cg3ypx5n.js} +14 -7
- package/build/{cli-dpsw2fe6.js → cli-e9v6zg6h.js} +40941 -40172
- package/build/cli-fjxmphg1.js +36 -0
- package/build/{cli-7eea4e2y.js → cli-gzb6qrzh.js} +31 -60
- package/build/{cli-65g6rcat.js → cli-khnf5xrf.js} +2 -1
- package/build/{cli-1ve18npr.js → cli-mdzt2e8j.js} +4 -2
- package/build/{cli-n2en7j5b.js → cli-n8mmw4c4.js} +1 -1
- package/build/cli-pndb7mh9.js +1193 -0
- package/build/cli-px6ehzqx.js +54 -0
- package/build/{cli-xtc2t6me.js → cli-qs4msn6x.js} +111 -47
- package/build/{cli-kb21qhvm.js → cli-rvybdhgn.js} +4 -3
- package/build/{cli-ae8jqxqr.js → cli-v739h7hb.js} +2 -2
- package/build/{cli-ngq9dr8n.js → cli-wm8ech0x.js} +3 -3
- package/build/cli.js +170 -51
- package/build/{config-zpqkd5cz.js → config-e5v1bkh1.js} +1 -1
- package/build/{fastStrike-mcjdvwez.js → fastStrike-efp0rjs3.js} +74 -17
- package/build/{fixes-kytx5dmj.js → fixes-926cw1ej.js} +16 -13
- package/build/{index-n65z6v7b.js → index-3t41p258.js} +7 -6
- package/build/{index-qv4cc65p.js → index-bv09af6g.js} +19 -15
- package/build/{index-je6hcsqr.js → index-bv6dtwse.js} +1 -1
- package/build/{index-4vqdgb42.js → index-jt52ffgn.js} +1657 -1400
- package/build/{index-ns4m4s01.js → index-np405b9e.js} +11 -7
- package/build/{index-r9yjkfrv.js → index-qys178kp.js} +5 -4
- package/build/{index-wqetp6gq.js → index-tpyzq2wq.js} +42 -11
- package/build/{index-fv64eb32.js → index-vrcdyebh.js} +2 -2
- package/build/{index-dr3tg1w3.js → index-z1g8vbtm.js} +1 -1
- package/build/{issues-eb3q9d3a.js → issues-sncyqh14.js} +16 -13
- package/build/{knowledge-fqsvtx0f.js → knowledge-esgvy5ws.js} +16 -13
- package/build/lance-sacfgs1z.js +232 -0
- package/build/lib/{chunk-9yksqgzr.js → chunk-4aevegnc.js} +77 -45
- package/build/lib/{chunk-9tt2021m.js → chunk-4kf4a15q.js} +13 -13
- package/build/lib/{chunk-fy3bbbqy.js → chunk-5avnedwm.js} +7 -1
- package/build/lib/{chunk-bb0ekhkw.js → chunk-5nz5tk3p.js} +76 -22
- package/build/lib/{chunk-4hwzqthr.js → chunk-7s8e5wrd.js} +3 -2
- package/build/lib/{chunk-yrnrbjes.js → chunk-85kpxwzs.js} +4 -2
- package/build/lib/{chunk-mg03jdmt.js → chunk-9jkzk9nc.js} +1 -1
- package/build/lib/{chunk-r4j8ybn9.js → chunk-9wwts6r6.js} +824 -77
- package/build/lib/{chunk-nhfax4gb.js → chunk-bxznzxdy.js} +5 -1
- package/build/lib/{chunk-r2dkp4tb.js → chunk-cqxm95md.js} +1 -1
- package/build/lib/{chunk-w66ce82a.js → chunk-e3agqspc.js} +12 -4
- package/build/lib/{chunk-ba41jh41.js → chunk-eh5yw385.js} +1137 -333
- package/build/lib/{chunk-1azdancq.js → chunk-ewc9r84m.js} +5 -1
- package/build/lib/{chunk-2njv7wz3.js → chunk-hbyxyxdc.js} +4 -0
- package/build/lib/{chunk-e8yy2k73.js → chunk-jhhwts6w.js} +28 -2
- package/build/lib/{chunk-1jvwqnem.js → chunk-kbxbd1kn.js} +108 -44
- package/build/lib/{chunk-7pwa92rn.js → chunk-mph5fvk7.js} +1 -1
- package/build/lib/chunk-psc23epq.js +107 -0
- package/build/lib/{chunk-acgbyf5h.js → chunk-qxad7qjd.js} +4 -2
- package/build/lib/{chunk-3c00n0cy.js → chunk-r0v3vvgm.js} +54 -33
- package/build/lib/{chunk-1yct6cra.js → chunk-rt13120a.js} +1 -1
- package/build/lib/{chunk-v3dk9j7k.js → chunk-sgya016v.js} +93 -22
- package/build/lib/{chunk-1fy8azee.js → chunk-txef92hq.js} +1 -1
- package/build/lib/{chunk-2qsq76xq.js → chunk-vcd90qrn.js} +189 -90
- package/build/lib/{chunk-7gjdygcx.js → chunk-vwr9w3ab.js} +2 -0
- package/build/lib/{chunk-z137x08b.js → chunk-wf6ak0m3.js} +92 -70
- package/build/lib/{chunk-xhdpgpkm.js → chunk-xft0ms9j.js} +2 -2
- package/build/lib/core/agents/agentRuntime.d.ts +3 -1
- package/build/lib/core/agents/defineAgent.d.ts +3 -2
- package/build/lib/core/agents/lance.d.ts +153 -0
- package/build/lib/core/agents/lanceJudge.d.ts +3 -0
- package/build/lib/core/agents/offSecAgent/index.d.ts +3 -1
- package/build/lib/core/agents/offSecAgent/index.js +16 -14
- package/build/lib/core/agents/offSecAgent/offensiveSecurityAgent.d.ts +4 -0
- package/build/lib/core/agents/offSecAgent/prompt.d.ts +3 -1
- package/build/lib/core/agents/offSecAgent/subagentSpawner.d.ts +18 -2
- package/build/lib/core/agents/offSecAgent/subagentSpawner.js +10 -8
- package/build/lib/core/agents/offSecAgent/toolExecutionContext.d.ts +3 -0
- package/build/lib/core/agents/offSecAgent/toolLifecycle.d.ts +1 -0
- package/build/lib/core/agents/offSecAgent/tools/index.js +10 -6
- package/build/lib/core/agents/offSecAgent/tools/listMemories.d.ts +11 -1
- package/build/lib/core/agents/offSecAgent/tools/reportError.d.ts +2 -1
- package/build/lib/core/agents/offSecAgent/tools/runPentestWorkflow.d.ts +20 -1
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestAgent.d.ts +4 -7
- package/build/lib/core/agents/offSecAgent/tools/spawnPentestSwarm.d.ts +7 -1
- package/build/lib/core/agents/offSecAgent/tools/types.d.ts +6 -3
- package/build/lib/core/agents/offSecAgent/tools/whiteboxCandidates.d.ts +2 -2
- package/build/lib/core/agents/offSecAgent/types.d.ts +19 -3
- package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.js +13 -13
- package/build/lib/core/agents/specialized/attackSurface/schemas.js +12 -12
- package/build/lib/core/agents/specialized/authenticationAgent/index.js +14 -14
- package/build/lib/core/agents/specialized/codeAgent/agent.js +13 -13
- package/build/lib/core/agents/specialized/codeAgent/prompts.d.ts +1 -0
- package/build/lib/core/agents/specialized/cvssScorer/index.d.ts +2 -1
- package/build/lib/core/agents/specialized/findingJudge/agent.js +11 -11
- package/build/lib/core/agents/specialized/findingJudge/index.d.ts +2 -1
- package/build/lib/core/agents/specialized/findingJudge/index.js +4 -4
- package/build/lib/core/agents/specialized/patching/index.js +14 -14
- package/build/lib/core/agents/specialized/pentest/agent.d.ts +18 -4
- package/build/lib/core/agents/specialized/pentest/agent.js +15 -13
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.d.ts +2 -1
- package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.js +13 -13
- package/build/lib/core/ai/ai.d.ts +29 -70
- package/build/lib/core/ai/ai.js +5 -3
- package/build/lib/core/ai/index.d.ts +1 -0
- package/build/lib/core/ai/index.js +16 -4
- package/build/lib/core/ai/models/claude-capabilities.d.ts +3 -2
- package/build/lib/core/ai/models/concentrate.d.ts +1 -0
- package/build/lib/core/ai/models/index.d.ts +1 -1
- package/build/lib/core/ai/providers/concentrate.d.ts +1 -0
- package/build/lib/core/ai/reasoning.d.ts +44 -0
- package/build/lib/core/ai/utils.d.ts +2 -0
- package/build/lib/core/ai/utils.js +5 -3
- package/build/lib/core/api/index.d.ts +6 -0
- package/build/lib/core/api/index.js +32 -23
- package/build/lib/core/api/lance.d.ts +6 -0
- package/build/lib/core/api/offesecAgent.d.ts +1 -0
- package/build/lib/core/api/reasoning.d.ts +12 -0
- package/build/lib/core/api/targetedPentest.d.ts +1 -0
- package/build/lib/core/api/targetedPentest.js +14 -14
- package/build/lib/core/cli/reasoning.d.ts +4 -0
- package/build/lib/core/config/config.d.ts +10 -2
- package/build/lib/core/config/customProviders.d.ts +11 -0
- package/build/lib/core/config/index.js +1 -1
- package/build/lib/core/eventBus.js +1 -1
- package/build/lib/core/findings/registry.d.ts +3 -1
- package/build/lib/core/findings/registry.js +4 -4
- package/build/lib/core/observability/index.js +1 -1
- package/build/lib/core/observability/telemetry.d.ts +4 -0
- package/build/lib/core/session/index.d.ts +47 -0
- package/build/lib/core/session/index.js +6 -4
- package/build/lib/core/session/persistence.d.ts +7 -0
- package/build/lib/core/session/persistence.js +8 -4
- package/build/lib/core/tools/backends/index.js +1 -1
- package/build/lib/core/tools/backends/resolve.d.ts +1 -0
- package/build/lib/core/workflows/fastStrike.d.ts +3 -1
- package/build/lib/core/workflows/pentest.d.ts +12 -2
- package/build/lib/core/workflows/pentest.js +19 -19
- package/build/lib/core/workflows/seams.js +5 -5
- package/build/lib/core/workflows/threatModel.d.ts +1 -0
- package/build/lib/core/workflows/whiteboxAttackSurface.d.ts +6 -4
- package/build/lib/core/workflows/whiteboxAttackSurface.js +15 -15
- package/build/lib/index.js +25 -25
- package/build/{logs-x62b7hk1.js → logs-bcbjpjp6.js} +16 -13
- package/build/{native-rollout-evidence-c9yhfqcs.js → native-rollout-evidence-rph1774m.js} +5 -5
- package/build/offesecAgent-81h1p6ee.js +32 -0
- package/build/pentest-2q20q6n1.js +23 -0
- package/build/{pentests-e0f32aqx.js → pentests-jgw031mc.js} +16 -13
- package/build/recordedRunClient-6axj6fba.js +11 -0
- package/build/subagentSpawner-a861gvt0.js +12 -0
- package/build/targetedPentest-6yxznt7s.js +91 -0
- package/build/{targets-xj9g3q0z.js → targets-bjah19dp.js} +16 -13
- package/build/threatModel-739kpexm.js +24 -0
- package/build/{uninstall-7s784q4a.js → uninstall-yxrn9edt.js} +1 -1
- package/build/{upload-4gvhwmvr.js → upload-34ewrjp5.js} +4 -4
- package/build/{utils-cjrz64pc.js → utils-fzm66efw.js} +5 -5
- package/package.json +2 -1
- package/src/cli/issues.test.ts +17 -1
- package/src/cli/lance-verifier.test.ts +57 -0
- package/src/cli/lance-verifier.ts +73 -0
- package/src/cli/lance.test.ts +71 -0
- package/src/cli/lance.ts +48 -0
- package/src/cli.ts +109 -19
- package/src/core/agents/agentRuntime.test.ts +42 -0
- package/src/core/agents/agentRuntime.ts +7 -2
- package/src/core/agents/defineAgent.ts +3 -1
- package/src/core/agents/lance.test.ts +421 -0
- package/src/core/agents/lance.ts +701 -0
- package/src/core/agents/lanceJudge.test.ts +166 -0
- package/src/core/agents/lanceJudge.ts +115 -0
- package/src/core/agents/offSecAgent/index.ts +3 -0
- package/src/core/agents/offSecAgent/interruptedStepFinalization.test.ts +51 -0
- package/src/core/agents/offSecAgent/lance.test.ts +188 -0
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.test.ts +92 -5
- package/src/core/agents/offSecAgent/offensiveSecurityAgent.ts +244 -41
- package/src/core/agents/offSecAgent/prompt.test.ts +46 -0
- package/src/core/agents/offSecAgent/prompt.ts +52 -8
- package/src/core/agents/offSecAgent/selectiveConstruction.publicPath.test.ts +38 -0
- package/src/core/agents/offSecAgent/selectiveConstruction.test.ts +64 -0
- package/src/core/agents/offSecAgent/subagentSpawner.hooks.test.ts +11 -3
- package/src/core/agents/offSecAgent/subagentSpawner.reasoning.test.ts +167 -0
- package/src/core/agents/offSecAgent/subagentSpawner.ts +82 -28
- package/src/core/agents/offSecAgent/toolExecutionContext.test.ts +230 -0
- package/src/core/agents/offSecAgent/toolExecutionContext.ts +56 -0
- package/src/core/agents/offSecAgent/toolLifecycle.ts +2 -0
- package/src/core/agents/offSecAgent/tools/delegateAuth.ts +4 -2
- package/src/core/agents/offSecAgent/tools/documentFinding.test.ts +9 -4
- package/src/core/agents/offSecAgent/tools/documentFinding.ts +10 -9
- package/src/core/agents/offSecAgent/tools/listMemories.test.ts +230 -0
- package/src/core/agents/offSecAgent/tools/listMemories.ts +73 -6
- package/src/core/agents/offSecAgent/tools/reportError.test.ts +6 -0
- package/src/core/agents/offSecAgent/tools/reportError.ts +10 -2
- package/src/core/agents/offSecAgent/tools/runAttackSurface.ts +7 -4
- package/src/core/agents/offSecAgent/tools/runPentestWorkflow.test.ts +57 -0
- package/src/core/agents/offSecAgent/tools/runPentestWorkflow.ts +21 -1
- package/src/core/agents/offSecAgent/tools/runWhiteboxScan.ts +5 -2
- package/src/core/agents/offSecAgent/tools/spawnCodingAgent.ts +50 -67
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.test.ts +79 -3
- package/src/core/agents/offSecAgent/tools/spawnPentestAgent.ts +36 -16
- package/src/core/agents/offSecAgent/tools/spawnPentestSwarm.ts +28 -5
- package/src/core/agents/offSecAgent/tools/threatModelGenerator.ts +4 -3
- package/src/core/agents/offSecAgent/tools/types.ts +12 -2
- package/src/core/agents/offSecAgent/tools/updateTask.ts +5 -1
- package/src/core/agents/offSecAgent/tools/whiteboxCandidates.ts +11 -4
- package/src/core/agents/offSecAgent/types.ts +22 -1
- package/src/core/agents/specialized/codeAgent/agent.test.ts +7 -0
- package/src/core/agents/specialized/codeAgent/agent.ts +9 -2
- package/src/core/agents/specialized/codeAgent/prompts.ts +6 -0
- package/src/core/agents/specialized/cvssScorer/index.test.ts +2 -1
- package/src/core/agents/specialized/cvssScorer/index.ts +3 -0
- package/src/core/agents/specialized/findingJudge/index.ts +6 -0
- package/src/core/agents/specialized/pentest/agent.test.ts +155 -0
- package/src/core/agents/specialized/pentest/agent.ts +181 -52
- package/src/core/agents/specialized/pentest/results.test.ts +59 -4
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.concurrency.test.ts +59 -2
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.hooks.test.ts +127 -0
- package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.ts +74 -68
- package/src/core/ai/ai.durability-hooks.test.ts +25 -7
- package/src/core/ai/ai.lance.test.ts +581 -0
- package/src/core/ai/ai.operator-context.bench.test.ts +1390 -0
- package/src/core/ai/ai.recorded-context.test.ts +89 -8
- package/src/core/ai/ai.test.ts +81 -59
- package/src/core/ai/ai.ts +453 -327
- package/src/core/ai/compactionTelemetry.test.ts +69 -17
- package/src/core/ai/index.ts +11 -0
- package/src/core/ai/models/anthropic.ts +6 -0
- package/src/core/ai/models/bedrock.ts +18 -0
- package/src/core/ai/models/claude-capabilities.ts +29 -8
- package/src/core/ai/models/concentrate.ts +52 -0
- package/src/core/ai/models/index.ts +25 -4
- package/src/core/ai/models/models.test.ts +179 -7
- package/src/core/ai/models/openrouter-reasoning.json +219 -0
- package/src/core/ai/models/openrouter.ts +43 -1
- package/src/core/ai/providers/anthropic-models.test.ts +60 -1
- package/src/core/ai/providers/bedrock-models.test.ts +81 -0
- package/src/core/ai/providers/concentrate.test.ts +31 -0
- package/src/core/ai/providers/concentrate.ts +11 -0
- package/src/core/ai/providers/custom.test.ts +74 -0
- package/src/core/ai/providers/custom.ts +3 -1
- package/src/core/ai/providers/gateway-models.test.ts +16 -6
- package/src/core/ai/providers/pensarFormatters.ts +8 -1
- package/src/core/ai/reasoning.test.ts +313 -0
- package/src/core/ai/reasoning.ts +500 -0
- package/src/core/ai/streamIdleTimeout.test.ts +21 -0
- package/src/core/ai/utils.native-rollout-evidence.test.ts +21 -8
- package/src/core/ai/utils.ts +269 -163
- package/src/core/api/attackSurface.ts +1 -0
- package/src/core/api/blackboxPentest.ts +9 -1
- package/src/core/api/index.ts +17 -0
- package/src/core/api/lance.ts +23 -0
- package/src/core/api/offesecAgent.test.ts +51 -0
- package/src/core/api/offesecAgent.ts +15 -1
- package/src/core/api/reasoning.test.ts +213 -0
- package/src/core/api/reasoning.ts +44 -0
- package/src/core/api/recordedRun.loop.test.ts +5 -1
- package/src/core/api/targetedPentest.test.ts +14 -2
- package/src/core/api/targetedPentest.ts +52 -5
- package/src/core/cli/reasoning.test.ts +149 -0
- package/src/core/cli/reasoning.ts +95 -0
- package/src/core/config/config.test.ts +35 -0
- package/src/core/config/config.ts +11 -0
- package/src/core/config/customProviders.ts +21 -2
- package/src/core/eventBus.ts +1 -0
- package/src/core/findings/registry.test.ts +9 -1
- package/src/core/findings/registry.ts +6 -0
- package/src/core/observability/telemetry.test.ts +131 -79
- package/src/core/observability/telemetry.ts +5 -0
- package/src/core/runtime/sqliteRunObservation.test.ts +1 -1
- package/src/core/session/index.ts +38 -0
- package/src/core/session/persistence.test.ts +62 -0
- package/src/core/session/persistence.ts +56 -0
- package/src/core/tools/backends/resolve.ts +7 -0
- package/src/core/tools/backends/whiteboxJobs.test.ts +9 -8
- package/src/core/workflows/fastStrike.seams.test.ts +149 -0
- package/src/core/workflows/fastStrike.test.ts +18 -1
- package/src/core/workflows/fastStrike.ts +106 -11
- package/src/core/workflows/pentest.test.ts +104 -0
- package/src/core/workflows/pentest.ts +128 -7
- package/src/core/workflows/seams.test.ts +13 -0
- package/src/core/workflows/seams.ts +5 -1
- package/src/core/workflows/threatModel.ts +2 -0
- package/src/core/workflows/whiteboxAttackSurface.test.ts +74 -2
- package/src/core/workflows/whiteboxAttackSurface.ts +102 -73
- package/src/tui/command-registry.test.ts +12 -0
- package/src/tui/command-registry.ts +10 -0
- package/src/tui/components/chat/config-view.tsx +6 -10
- package/src/tui/components/chat/home-view.tsx +2 -2
- package/src/tui/components/chat/input-area.tsx +2 -2
- package/src/tui/components/chat/loading-indicator.tsx +20 -4
- package/src/tui/components/chat/message-list.tsx +1 -0
- package/src/tui/components/commands/__tests__/advanced-settings-lifecycle.tsx +164 -0
- package/src/tui/components/commands/advanced-settings.test.ts +34 -0
- package/src/tui/components/commands/advanced-settings.tsx +220 -31
- package/src/tui/components/commands/models-display.tsx +7 -1
- package/src/tui/components/model-picker/ModelPicker.tsx +65 -103
- package/src/tui/components/model-picker/ModelPickerDialog.tsx +8 -14
- package/src/tui/components/model-picker/__tests__/reasoning-control.tsx +162 -0
- package/src/tui/components/model-picker/reasoning-control.test.ts +15 -0
- package/src/tui/components/operator-dashboard/index.tsx +166 -50
- package/src/tui/components/operator-dashboard/logic.test.ts +144 -2
- package/src/tui/components/operator-dashboard/logic.ts +54 -3
- package/src/tui/components/operator-dashboard/run-events.test.ts +3 -1
- package/src/tui/components/shared/__tests__/tool-renderer-lifecycle.tsx +18 -0
- package/src/tui/components/shared/action-label.test.ts +9 -0
- package/src/tui/components/shared/compacting-icon.tsx +18 -0
- package/src/tui/components/shared/index.ts +1 -0
- package/src/tui/components/shared/tool-registry.ts +1 -0
- package/src/tui/components/shared/tool-renderer.tsx +21 -7
- package/src/tui/context/agent.tsx +32 -79
- package/src/tui/context/route.tsx +2 -0
- package/src/tui/index.tsx +1 -0
- package/src/tui/keybindings/registry.ts +2 -0
- package/build/agent-6w7egcf1.js +0 -13
- package/build/agent-9zx75feh.js +0 -13
- package/build/blackboxAgent-s56sgx9b.js +0 -13
- package/build/cli-g06s7edq.js +0 -11
- package/build/lib/chunk-z96pbjhd.js +0 -56
- package/build/offesecAgent-5whnpeta.js +0 -22
- package/build/pentest-e61hc38s.js +0 -22
- package/build/recordedRunClient-dp032c32.js +0 -11
- package/build/targetedPentest-rcbs4nvp.js +0 -57
- package/build/threatModel-jkxfa40s.js +0 -21
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getSavedReasoning } from "../../../core/cli/reasoning";
|
|
1
2
|
/**
|
|
2
3
|
* Operator Dashboard
|
|
3
4
|
*
|
|
@@ -29,14 +30,13 @@ import {
|
|
|
29
30
|
type AgentMode,
|
|
30
31
|
ALL_TOOL_NAMES,
|
|
31
32
|
ASK_USER_QUESTIONS_TOOL_NAME,
|
|
33
|
+
type FindingPolicy,
|
|
32
34
|
PLAN_MODE_TOOL_NAMES,
|
|
33
35
|
SKILL_TOOL_NAMES,
|
|
34
36
|
} from "../../../core/agents/offSecAgent";
|
|
35
37
|
import {
|
|
36
38
|
buildAuthConfig,
|
|
37
39
|
getContextWindow,
|
|
38
|
-
modelSupportsOpenAIReasoning,
|
|
39
|
-
modelSupportsThinking,
|
|
40
40
|
normalizeStepUsage,
|
|
41
41
|
} from "../../../core/ai";
|
|
42
42
|
import {
|
|
@@ -108,12 +108,15 @@ import {
|
|
|
108
108
|
type DashboardStatus,
|
|
109
109
|
filterOperatorAutocomplete,
|
|
110
110
|
resolveAbortAction,
|
|
111
|
+
resolveActiveFindingPolicy,
|
|
111
112
|
resolveInputFocused,
|
|
112
113
|
resolveKeyboardShortcut,
|
|
113
114
|
resolveOperatorAgentMode,
|
|
115
|
+
resolveOperatorFindingPolicy,
|
|
114
116
|
resolveOperatorStrikeMode,
|
|
115
117
|
resolveSubmit,
|
|
116
118
|
routeCommand,
|
|
119
|
+
shouldHandleQueuedMessageKey,
|
|
117
120
|
} from "./logic";
|
|
118
121
|
import {
|
|
119
122
|
createQueuedMessage,
|
|
@@ -159,6 +162,8 @@ export default function OperatorDashboard({
|
|
|
159
162
|
target?: string;
|
|
160
163
|
operatorMode?: OperatorMode;
|
|
161
164
|
strikeMode?: boolean;
|
|
165
|
+
lanceMode?: boolean;
|
|
166
|
+
findingPolicy?: FindingPolicy;
|
|
162
167
|
sandbox?: boolean;
|
|
163
168
|
taskDriven?: boolean;
|
|
164
169
|
headers?: Record<string, string>;
|
|
@@ -177,8 +182,8 @@ export default function OperatorDashboard({
|
|
|
177
182
|
usageStore,
|
|
178
183
|
markExecuted,
|
|
179
184
|
setSessionCwd,
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
reasoning: preferredReasoning,
|
|
186
|
+
setReasoning,
|
|
182
187
|
} = useAgent();
|
|
183
188
|
const {
|
|
184
189
|
autocompleteOptions: allAutocompleteOptions,
|
|
@@ -198,6 +203,11 @@ export default function OperatorDashboard({
|
|
|
198
203
|
const { refocusPromptIfNoActiveEditor } = useFocus();
|
|
199
204
|
const herdr = useHerdr();
|
|
200
205
|
const { enabled: obfuscateEnabled } = useObfuscation();
|
|
206
|
+
const [lanceMode, setLanceMode] = useState(
|
|
207
|
+
sessionId
|
|
208
|
+
? false
|
|
209
|
+
: (initialConfig?.lanceMode ?? config.data.lanceMode ?? false),
|
|
210
|
+
);
|
|
201
211
|
const initialStrikeModeRef = useRef(
|
|
202
212
|
resolveOperatorStrikeMode({
|
|
203
213
|
resuming: !!sessionId,
|
|
@@ -206,18 +216,36 @@ export default function OperatorDashboard({
|
|
|
206
216
|
}),
|
|
207
217
|
);
|
|
208
218
|
const [strikeMode, setStrikeMode] = useState(initialStrikeModeRef.current);
|
|
219
|
+
const initialFindingPolicyRef = useRef(
|
|
220
|
+
resolveOperatorFindingPolicy({
|
|
221
|
+
resuming: !!sessionId,
|
|
222
|
+
strikeMode: initialStrikeModeRef.current,
|
|
223
|
+
lanceMode,
|
|
224
|
+
routeOverride: initialConfig?.findingPolicy,
|
|
225
|
+
persistedDefault: config.data.findingPolicy,
|
|
226
|
+
}),
|
|
227
|
+
);
|
|
228
|
+
const [findingPolicy, setFindingPolicy] = useState(
|
|
229
|
+
initialFindingPolicyRef.current,
|
|
230
|
+
);
|
|
209
231
|
|
|
210
232
|
// biome-ignore lint/correctness/useExhaustiveDependencies: `skillsVersion` is an intentional cache-buster — forces recomputation when skills are refreshed even though `skillsRegistry` (stable ref) hasn't changed.
|
|
211
233
|
const autocompleteOptions = useMemo(() => {
|
|
212
234
|
const commandOptions = filterOperatorAutocomplete(
|
|
213
235
|
allAutocompleteOptions,
|
|
214
|
-
).filter(
|
|
236
|
+
).filter(
|
|
237
|
+
(option) =>
|
|
238
|
+
(!strikeMode || option.value !== "/pentest") &&
|
|
239
|
+
(!lanceMode ||
|
|
240
|
+
!["/pentest", "/plan", "/skills"].includes(option.value)),
|
|
241
|
+
);
|
|
215
242
|
const skillOptions = skillsRegistry
|
|
216
243
|
.list()
|
|
217
244
|
.filter(
|
|
218
245
|
(skill) =>
|
|
219
|
-
!
|
|
220
|
-
(
|
|
246
|
+
!lanceMode &&
|
|
247
|
+
(!strikeMode ||
|
|
248
|
+
(skill.slug !== "pentest" && skill.slug !== "threat-model")),
|
|
221
249
|
)
|
|
222
250
|
.map((skill) => {
|
|
223
251
|
const slug = `/${skill.slug}`;
|
|
@@ -235,7 +263,13 @@ export default function OperatorDashboard({
|
|
|
235
263
|
},
|
|
236
264
|
];
|
|
237
265
|
return [...commandOptions, ...operatorOnlyOptions, ...skillOptions];
|
|
238
|
-
}, [
|
|
266
|
+
}, [
|
|
267
|
+
allAutocompleteOptions,
|
|
268
|
+
skillsRegistry,
|
|
269
|
+
skillsVersion,
|
|
270
|
+
strikeMode,
|
|
271
|
+
lanceMode,
|
|
272
|
+
]);
|
|
239
273
|
|
|
240
274
|
// Session state
|
|
241
275
|
const [session, setSession] = useState<SessionInfo | null>(null);
|
|
@@ -360,6 +394,11 @@ export default function OperatorDashboard({
|
|
|
360
394
|
const agentMode: AgentMode = resolveOperatorAgentMode(
|
|
361
395
|
operatorMode,
|
|
362
396
|
strikeMode,
|
|
397
|
+
lanceMode,
|
|
398
|
+
);
|
|
399
|
+
const activeFindingPolicy = resolveActiveFindingPolicy(
|
|
400
|
+
agentMode,
|
|
401
|
+
findingPolicy,
|
|
363
402
|
);
|
|
364
403
|
const requireApproval = operatorMode === "manual";
|
|
365
404
|
// Plan mode review state
|
|
@@ -418,6 +457,32 @@ export default function OperatorDashboard({
|
|
|
418
457
|
};
|
|
419
458
|
}, []);
|
|
420
459
|
|
|
460
|
+
const restoredReasoningSession = useRef<string | null>(null);
|
|
461
|
+
const savedReasoning = session?.config?.modelReasoning;
|
|
462
|
+
const restoredPreference =
|
|
463
|
+
savedReasoning?.model === model.id
|
|
464
|
+
? getSavedReasoning(model.id, {
|
|
465
|
+
customProviders: config.data.customProviders,
|
|
466
|
+
modelReasoning: { [model.id]: savedReasoning.setting },
|
|
467
|
+
})
|
|
468
|
+
: undefined;
|
|
469
|
+
// An auto-started resumed turn can precede the preference write completing.
|
|
470
|
+
const reasoning =
|
|
471
|
+
session && restoredReasoningSession.current !== session.id
|
|
472
|
+
? (restoredPreference ?? preferredReasoning)
|
|
473
|
+
: preferredReasoning;
|
|
474
|
+
useEffect(() => {
|
|
475
|
+
if (!session || restoredReasoningSession.current === session.id) return;
|
|
476
|
+
if (
|
|
477
|
+
restoredPreference !== undefined &&
|
|
478
|
+
restoredPreference !== preferredReasoning
|
|
479
|
+
) {
|
|
480
|
+
setReasoning(restoredPreference);
|
|
481
|
+
} else {
|
|
482
|
+
restoredReasoningSession.current = session.id;
|
|
483
|
+
}
|
|
484
|
+
}, [session, restoredPreference, preferredReasoning, setReasoning]);
|
|
485
|
+
|
|
421
486
|
// Load existing session or initialise operator state for a new one.
|
|
422
487
|
// New sessions are created lazily by the agent on the first runAgent call.
|
|
423
488
|
useEffect(() => {
|
|
@@ -426,11 +491,22 @@ export default function OperatorDashboard({
|
|
|
426
491
|
if (sessionId) {
|
|
427
492
|
const s = await sessions.get(sessionId);
|
|
428
493
|
setSession(s);
|
|
494
|
+
setLanceMode(
|
|
495
|
+
existsSync(join(s.rootPath, "lance-result.json")) ||
|
|
496
|
+
(s.config?.operatorSettings?.lanceMode ?? false),
|
|
497
|
+
);
|
|
429
498
|
setSessionCwd(s.rootPath);
|
|
430
|
-
|
|
431
|
-
|
|
499
|
+
const resumedStrikeMode = resolveOperatorStrikeMode({
|
|
500
|
+
resuming: true,
|
|
501
|
+
savedSessionValue: s.config?.operatorSettings?.strikeMode,
|
|
502
|
+
});
|
|
503
|
+
setStrikeMode(resumedStrikeMode);
|
|
504
|
+
setFindingPolicy(
|
|
505
|
+
resolveOperatorFindingPolicy({
|
|
432
506
|
resuming: true,
|
|
433
|
-
|
|
507
|
+
strikeMode: resumedStrikeMode,
|
|
508
|
+
lanceMode: s.config?.operatorSettings?.lanceMode,
|
|
509
|
+
savedSessionValue: s.config?.operatorSettings?.findingPolicy,
|
|
434
510
|
}),
|
|
435
511
|
);
|
|
436
512
|
|
|
@@ -516,6 +592,7 @@ export default function OperatorDashboard({
|
|
|
516
592
|
// New session — just set up operator config; the agent creates the
|
|
517
593
|
// session on the first runAgent call.
|
|
518
594
|
setStrikeMode(initialStrikeModeRef.current);
|
|
595
|
+
setFindingPolicy(initialFindingPolicyRef.current);
|
|
519
596
|
const newMode = initialConfig?.operatorMode ?? "manual";
|
|
520
597
|
setOperatorMode(newMode);
|
|
521
598
|
const requireApproval = newMode === "manual";
|
|
@@ -855,7 +932,9 @@ export default function OperatorDashboard({
|
|
|
855
932
|
handlers: runEventProjections.handlers,
|
|
856
933
|
});
|
|
857
934
|
|
|
858
|
-
const skillsCatalog =
|
|
935
|
+
const skillsCatalog = lanceMode
|
|
936
|
+
? undefined
|
|
937
|
+
: skillsRegistry.buildCatalog() || undefined;
|
|
859
938
|
|
|
860
939
|
const commonInput = {
|
|
861
940
|
prompt: prompt ?? "",
|
|
@@ -871,14 +950,13 @@ export default function OperatorDashboard({
|
|
|
871
950
|
...SKILL_TOOL_NAMES,
|
|
872
951
|
] as string[],
|
|
873
952
|
mode: agentMode,
|
|
953
|
+
lance: lanceMode ? { interactive: true } : undefined,
|
|
954
|
+
findingPolicy: activeFindingPolicy,
|
|
874
955
|
authConfig: buildAuthConfig(config.data),
|
|
875
956
|
approvalGate: approvalGateRef.current,
|
|
876
957
|
commandCancelHandle: cancelHandleRef.current,
|
|
877
958
|
skillsRegistry,
|
|
878
|
-
|
|
879
|
-
openAIReasoningEffort: modelSupportsOpenAIReasoning(model.id)
|
|
880
|
-
? openAIReasoningEffort
|
|
881
|
-
: undefined,
|
|
959
|
+
reasoning,
|
|
882
960
|
surfaceIntegrationEnabled: config.data?.surfaceIntegrationEnabled,
|
|
883
961
|
promptInjectionLibrarySource:
|
|
884
962
|
initialConfig?.promptInjectionLibrarySource ??
|
|
@@ -905,34 +983,37 @@ export default function OperatorDashboard({
|
|
|
905
983
|
try {
|
|
906
984
|
let agentResult: RunAgentResult;
|
|
907
985
|
|
|
908
|
-
const systemPrompt =
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
986
|
+
const systemPrompt = lanceMode
|
|
987
|
+
? undefined
|
|
988
|
+
: buildOperatorSystemPrompt(
|
|
989
|
+
initialConfig?.target,
|
|
990
|
+
operatorState,
|
|
991
|
+
agentMode,
|
|
992
|
+
{
|
|
993
|
+
requireApproval,
|
|
994
|
+
sandboxMode: !!initialConfig?.sandbox,
|
|
995
|
+
skillsCatalog,
|
|
996
|
+
planFilePath: sessionRef.current
|
|
997
|
+
? getPlanFilePath(sessionRef.current.rootPath)
|
|
998
|
+
: undefined,
|
|
999
|
+
existingPlanContent:
|
|
1000
|
+
agentMode === "plan" &&
|
|
1001
|
+
planRejectedRef.current &&
|
|
1002
|
+
sessionRef.current
|
|
1003
|
+
? readPlan(sessionRef.current.rootPath)
|
|
1004
|
+
: null,
|
|
1005
|
+
approvedPlanContent:
|
|
1006
|
+
agentMode !== "plan" ? approvedPlanRef.current : null,
|
|
1007
|
+
taskDriven:
|
|
1008
|
+
session?.config?.taskDriven ?? initialConfig?.taskDriven,
|
|
1009
|
+
findingPolicy: activeFindingPolicy,
|
|
1010
|
+
},
|
|
1011
|
+
);
|
|
931
1012
|
|
|
932
1013
|
if (session) {
|
|
933
1014
|
agentResult = await agentClient.run({
|
|
934
1015
|
...commonInput,
|
|
935
|
-
system: systemPrompt,
|
|
1016
|
+
...(lanceMode ? {} : { system: systemPrompt }),
|
|
936
1017
|
session,
|
|
937
1018
|
});
|
|
938
1019
|
} else {
|
|
@@ -945,6 +1026,8 @@ export default function OperatorDashboard({
|
|
|
945
1026
|
requireApproval,
|
|
946
1027
|
enableSuggestions: true,
|
|
947
1028
|
strikeMode,
|
|
1029
|
+
lanceMode,
|
|
1030
|
+
findingPolicy,
|
|
948
1031
|
},
|
|
949
1032
|
agentCwd: initialConfig?.sandbox ? undefined : process.cwd(),
|
|
950
1033
|
codebasePath: initialConfig?.sandbox ? undefined : process.cwd(),
|
|
@@ -960,7 +1043,7 @@ export default function OperatorDashboard({
|
|
|
960
1043
|
};
|
|
961
1044
|
agentResult = await agentClient.run({
|
|
962
1045
|
...commonInput,
|
|
963
|
-
system: systemPrompt,
|
|
1046
|
+
...(lanceMode ? {} : { system: systemPrompt }),
|
|
964
1047
|
sessionConfig,
|
|
965
1048
|
onNameGenerated: (name: string) => {
|
|
966
1049
|
pendingNameRef.current = name;
|
|
@@ -977,6 +1060,18 @@ export default function OperatorDashboard({
|
|
|
977
1060
|
setSessionCwd(created.rootPath);
|
|
978
1061
|
}
|
|
979
1062
|
|
|
1063
|
+
const lanceResult = agentResult.lance;
|
|
1064
|
+
if (lanceResult && lanceResult.outcome !== "awaiting_input") {
|
|
1065
|
+
setMessages((prev) => [
|
|
1066
|
+
...prev,
|
|
1067
|
+
{
|
|
1068
|
+
role: "system",
|
|
1069
|
+
content: `Lance: ${lanceResult.outcome}. ${lanceResult.reason}`,
|
|
1070
|
+
createdAt: new Date(),
|
|
1071
|
+
},
|
|
1072
|
+
]);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
980
1075
|
// Sync conversationRef from the agent's persisted state.
|
|
981
1076
|
// messages.json is the single source of truth — after summarization
|
|
982
1077
|
// the agent discards stale history, so reading back avoids
|
|
@@ -1082,13 +1177,15 @@ export default function OperatorDashboard({
|
|
|
1082
1177
|
initialConfig?.headers,
|
|
1083
1178
|
initialConfig?.promptInjectionLibrarySource,
|
|
1084
1179
|
strikeMode,
|
|
1180
|
+
lanceMode,
|
|
1181
|
+
findingPolicy,
|
|
1182
|
+
activeFindingPolicy,
|
|
1085
1183
|
route.data,
|
|
1086
1184
|
setSessionCwd,
|
|
1087
1185
|
skillsRegistry.buildCatalog,
|
|
1088
1186
|
requireApproval,
|
|
1089
1187
|
skillsRegistry,
|
|
1090
|
-
|
|
1091
|
-
openAIReasoningEffort,
|
|
1188
|
+
reasoning,
|
|
1092
1189
|
usageStore,
|
|
1093
1190
|
markExecuted,
|
|
1094
1191
|
],
|
|
@@ -1365,6 +1462,15 @@ This three-phase flow is specific to the TUI \`/threat-model\` command. The same
|
|
|
1365
1462
|
async (command: string) => {
|
|
1366
1463
|
const action = routeCommand(command, resolveSkillContent);
|
|
1367
1464
|
|
|
1465
|
+
if (
|
|
1466
|
+
lanceMode &&
|
|
1467
|
+
["run-skill", "show-plan", "execute-command"].includes(action.type)
|
|
1468
|
+
) {
|
|
1469
|
+
addSystemMessage(
|
|
1470
|
+
"Lance accepts direct objectives only. Start a new session to use production workflows.",
|
|
1471
|
+
);
|
|
1472
|
+
return;
|
|
1473
|
+
}
|
|
1368
1474
|
switch (action.type) {
|
|
1369
1475
|
case "show-models":
|
|
1370
1476
|
showModelPicker();
|
|
@@ -1449,6 +1555,7 @@ This three-phase flow is specific to the TUI \`/threat-model\` command. The same
|
|
|
1449
1555
|
addSystemMessage,
|
|
1450
1556
|
handleHeadersSlash,
|
|
1451
1557
|
strikeMode,
|
|
1558
|
+
lanceMode,
|
|
1452
1559
|
],
|
|
1453
1560
|
);
|
|
1454
1561
|
|
|
@@ -1634,11 +1741,16 @@ This three-phase flow is specific to the TUI \`/threat-model\` command. The same
|
|
|
1634
1741
|
|
|
1635
1742
|
// Keyboard shortcuts
|
|
1636
1743
|
useKeyboard((key) => {
|
|
1744
|
+
const dialogOpen =
|
|
1745
|
+
stack.length > 0 || externalDialogOpen || !!pendingQuestions;
|
|
1637
1746
|
// Queue navigation: handle before general shortcuts
|
|
1638
1747
|
if (
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1748
|
+
shouldHandleQueuedMessageKey(
|
|
1749
|
+
status,
|
|
1750
|
+
queuedMessages.length,
|
|
1751
|
+
inputValue,
|
|
1752
|
+
dialogOpen,
|
|
1753
|
+
)
|
|
1642
1754
|
) {
|
|
1643
1755
|
if (key.name === "up") {
|
|
1644
1756
|
key.preventDefault?.();
|
|
@@ -1765,9 +1877,6 @@ This three-phase flow is specific to the TUI \`/threat-model\` command. The same
|
|
|
1765
1877
|
|
|
1766
1878
|
// Treat the questions form as a dialog so that dashboard-level shortcuts
|
|
1767
1879
|
// (Shift+Tab cycle-mode, etc.) don't fire while the form owns the keyboard.
|
|
1768
|
-
const dialogOpen =
|
|
1769
|
-
stack.length > 0 || externalDialogOpen || !!pendingQuestions;
|
|
1770
|
-
|
|
1771
1880
|
// Ctrl+A to open subagent dialog (skip if another dialog is open)
|
|
1772
1881
|
if (
|
|
1773
1882
|
key.ctrl &&
|
|
@@ -1925,7 +2034,14 @@ This three-phase flow is specific to the TUI \`/threat-model\` command. The same
|
|
|
1925
2034
|
>
|
|
1926
2035
|
<box flexDirection="row" gap={2}>
|
|
1927
2036
|
<text fg={colors.text}>{session?.name ?? "New Session"}</text>
|
|
1928
|
-
{
|
|
2037
|
+
{lanceMode ? (
|
|
2038
|
+
<text fg={colors.warning}>LANCE</text>
|
|
2039
|
+
) : (
|
|
2040
|
+
strikeMode && <text fg={colors.warning}>STRIKE</text>
|
|
2041
|
+
)}
|
|
2042
|
+
{activeFindingPolicy === "external" && (
|
|
2043
|
+
<text fg={colors.textMuted}>JUDGE OFF</text>
|
|
2044
|
+
)}
|
|
1929
2045
|
{(session?.targets[0] || initialConfig?.target) && (
|
|
1930
2046
|
<>
|
|
1931
2047
|
<text fg={colors.textMuted}>•</text>
|
|
@@ -6,12 +6,15 @@ import {
|
|
|
6
6
|
type DashboardStatus,
|
|
7
7
|
filterOperatorAutocomplete,
|
|
8
8
|
resolveAbortAction,
|
|
9
|
+
resolveActiveFindingPolicy,
|
|
9
10
|
resolveInputFocused,
|
|
10
11
|
resolveKeyboardShortcut,
|
|
11
12
|
resolveOperatorAgentMode,
|
|
13
|
+
resolveOperatorFindingPolicy,
|
|
12
14
|
resolveOperatorStrikeMode,
|
|
13
15
|
resolveSubmit,
|
|
14
16
|
routeCommand,
|
|
17
|
+
shouldHandleQueuedMessageKey,
|
|
15
18
|
} from "./logic";
|
|
16
19
|
|
|
17
20
|
// ---------------------------------------------------------------------------
|
|
@@ -23,6 +26,7 @@ const allOptions: AutocompleteOption[] = [
|
|
|
23
26
|
{ value: "/pentest", label: "/pentest", description: "Run a pentest" },
|
|
24
27
|
{ value: "/help", label: "/help", description: "Show help" },
|
|
25
28
|
{ value: "/models", label: "/models", description: "Switch model" },
|
|
29
|
+
{ value: "/effort", label: "/effort", description: "Adjust model effort" },
|
|
26
30
|
{ value: "/skills", label: "/skills", description: "View skills" },
|
|
27
31
|
{
|
|
28
32
|
value: "/advanced",
|
|
@@ -36,10 +40,11 @@ const allOptions: AutocompleteOption[] = [
|
|
|
36
40
|
// ---------------------------------------------------------------------------
|
|
37
41
|
|
|
38
42
|
describe("filterOperatorAutocomplete", () => {
|
|
39
|
-
it("includes allowed commands (/models, /skills, /advanced)", () => {
|
|
43
|
+
it("includes allowed commands (/models, /effort, /skills, /advanced)", () => {
|
|
40
44
|
const result = filterOperatorAutocomplete(allOptions);
|
|
41
45
|
const values = result.map((o) => o.value);
|
|
42
46
|
expect(values).toContain("/models");
|
|
47
|
+
expect(values).toContain("/effort");
|
|
43
48
|
expect(values).toContain("/skills");
|
|
44
49
|
expect(values).toContain("/advanced");
|
|
45
50
|
});
|
|
@@ -52,7 +57,7 @@ describe("filterOperatorAutocomplete", () => {
|
|
|
52
57
|
|
|
53
58
|
it("returns only allowed commands", () => {
|
|
54
59
|
const result = filterOperatorAutocomplete(allOptions);
|
|
55
|
-
expect(result).toHaveLength(
|
|
60
|
+
expect(result).toHaveLength(6);
|
|
56
61
|
});
|
|
57
62
|
|
|
58
63
|
it("preserves description on allowed commands", () => {
|
|
@@ -130,6 +135,115 @@ describe("resolveOperatorStrikeMode", () => {
|
|
|
130
135
|
});
|
|
131
136
|
});
|
|
132
137
|
|
|
138
|
+
describe("resolveOperatorFindingPolicy", () => {
|
|
139
|
+
it("defaults new sessions to Apex finding review", () => {
|
|
140
|
+
expect(
|
|
141
|
+
resolveOperatorFindingPolicy({ resuming: false, strikeMode: true }),
|
|
142
|
+
).toBe("native");
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("uses the saved preference for new Strike sessions", () => {
|
|
146
|
+
expect(
|
|
147
|
+
resolveOperatorFindingPolicy({
|
|
148
|
+
resuming: false,
|
|
149
|
+
strikeMode: true,
|
|
150
|
+
persistedDefault: "external",
|
|
151
|
+
}),
|
|
152
|
+
).toBe("external");
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("lets an explicit workflow override the saved preference", () => {
|
|
156
|
+
expect(
|
|
157
|
+
resolveOperatorFindingPolicy({
|
|
158
|
+
resuming: false,
|
|
159
|
+
strikeMode: true,
|
|
160
|
+
routeOverride: "native",
|
|
161
|
+
persistedDefault: "external",
|
|
162
|
+
}),
|
|
163
|
+
).toBe("native");
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("restores the policy saved with a resumed Strike session", () => {
|
|
167
|
+
expect(
|
|
168
|
+
resolveOperatorFindingPolicy({
|
|
169
|
+
resuming: true,
|
|
170
|
+
strikeMode: true,
|
|
171
|
+
savedSessionValue: "external",
|
|
172
|
+
persistedDefault: "native",
|
|
173
|
+
}),
|
|
174
|
+
).toBe("external");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("keeps legacy resumed sessions native despite a newer global preference", () => {
|
|
178
|
+
expect(
|
|
179
|
+
resolveOperatorFindingPolicy({
|
|
180
|
+
resuming: true,
|
|
181
|
+
strikeMode: true,
|
|
182
|
+
persistedDefault: "external",
|
|
183
|
+
}),
|
|
184
|
+
).toBe("native");
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("keeps standard sessions native despite external preferences or overrides", () => {
|
|
188
|
+
expect(
|
|
189
|
+
resolveOperatorFindingPolicy({
|
|
190
|
+
resuming: false,
|
|
191
|
+
strikeMode: false,
|
|
192
|
+
routeOverride: "external",
|
|
193
|
+
persistedDefault: "external",
|
|
194
|
+
}),
|
|
195
|
+
).toBe("native");
|
|
196
|
+
expect(
|
|
197
|
+
resolveOperatorFindingPolicy({
|
|
198
|
+
resuming: true,
|
|
199
|
+
strikeMode: false,
|
|
200
|
+
savedSessionValue: "external",
|
|
201
|
+
}),
|
|
202
|
+
).toBe("native");
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe("resolveActiveFindingPolicy", () => {
|
|
207
|
+
it("preserves the judge toggle in Strike and Lance", () => {
|
|
208
|
+
expect(resolveActiveFindingPolicy("lance", "external")).toBe("external");
|
|
209
|
+
expect(
|
|
210
|
+
resolveOperatorFindingPolicy({
|
|
211
|
+
resuming: false,
|
|
212
|
+
strikeMode: false,
|
|
213
|
+
lanceMode: true,
|
|
214
|
+
persistedDefault: "external",
|
|
215
|
+
}),
|
|
216
|
+
).toBe("external");
|
|
217
|
+
expect(
|
|
218
|
+
resolveOperatorFindingPolicy({
|
|
219
|
+
resuming: true,
|
|
220
|
+
strikeMode: false,
|
|
221
|
+
lanceMode: true,
|
|
222
|
+
savedSessionValue: "external",
|
|
223
|
+
}),
|
|
224
|
+
).toBe("external");
|
|
225
|
+
expect(resolveActiveFindingPolicy("fast-strike", "external")).toBe(
|
|
226
|
+
"external",
|
|
227
|
+
);
|
|
228
|
+
expect(resolveActiveFindingPolicy("default", "external")).toBe("native");
|
|
229
|
+
expect(resolveActiveFindingPolicy("plan", "external")).toBe("native");
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
// Queue navigation
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
|
|
237
|
+
describe("shouldHandleQueuedMessageKey", () => {
|
|
238
|
+
it("leaves queue navigation to the dashboard only when no dialog owns the keyboard", () => {
|
|
239
|
+
expect(shouldHandleQueuedMessageKey("running", 2, "", false)).toBe(true);
|
|
240
|
+
expect(shouldHandleQueuedMessageKey("running", 2, "", true)).toBe(false);
|
|
241
|
+
expect(
|
|
242
|
+
shouldHandleQueuedMessageKey("running", 2, " /advanced ", false),
|
|
243
|
+
).toBe(false);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
133
247
|
// ---------------------------------------------------------------------------
|
|
134
248
|
// resolveSubmit
|
|
135
249
|
// ---------------------------------------------------------------------------
|
|
@@ -195,6 +309,17 @@ describe("routeCommand", () => {
|
|
|
195
309
|
expect(routeCommand("/MODELS", noSkill)).toEqual({ type: "show-models" });
|
|
196
310
|
});
|
|
197
311
|
|
|
312
|
+
it.each([
|
|
313
|
+
"/effort",
|
|
314
|
+
"/EFFORT",
|
|
315
|
+
])("routes %s to the picker before resolving skills", (command) => {
|
|
316
|
+
const resolveSkill = vi.fn(() => "An effort skill");
|
|
317
|
+
expect(routeCommand(command, resolveSkill)).toEqual({
|
|
318
|
+
type: "show-models",
|
|
319
|
+
});
|
|
320
|
+
expect(resolveSkill).not.toHaveBeenCalled();
|
|
321
|
+
});
|
|
322
|
+
|
|
198
323
|
it("routes a skill command to run-skill with slug", () => {
|
|
199
324
|
const resolveSkill = (cmd: string) =>
|
|
200
325
|
cmd === "/sql-injection" ? "Perform SQL injection testing" : null;
|
|
@@ -623,6 +748,17 @@ describe("buildOperatorSystemPrompt", () => {
|
|
|
623
748
|
expect(prompt).toContain("account for each viable primitive");
|
|
624
749
|
});
|
|
625
750
|
|
|
751
|
+
it("keeps Strike's research loop while leaving finding review to the caller", () => {
|
|
752
|
+
const prompt = buildOperatorSystemPrompt(target, state, "fast-strike", {
|
|
753
|
+
findingPolicy: "external",
|
|
754
|
+
});
|
|
755
|
+
expect(prompt).toContain("# Strike Mode");
|
|
756
|
+
expect(prompt).toContain("requested output format");
|
|
757
|
+
expect(prompt).not.toContain("document_vulnerability");
|
|
758
|
+
expect(prompt).not.toContain("document confirmed vulnerabilities");
|
|
759
|
+
expect(prompt).not.toContain("official report is generated automatically");
|
|
760
|
+
});
|
|
761
|
+
|
|
626
762
|
it("does not include Strike Mode instructions in the standard mode", () => {
|
|
627
763
|
const prompt = buildOperatorSystemPrompt(target, state, "default");
|
|
628
764
|
expect(prompt).not.toContain("# Strike Mode");
|
|
@@ -751,3 +887,9 @@ describe("resolveInputFocused", () => {
|
|
|
751
887
|
});
|
|
752
888
|
|
|
753
889
|
// ---------------------------------------------------------------------------
|
|
890
|
+
|
|
891
|
+
it("keeps Lance independent of Strike and planning", () => {
|
|
892
|
+
expect(resolveOperatorAgentMode("manual", false, true)).toBe("lance");
|
|
893
|
+
expect(resolveOperatorAgentMode("auto", true, true)).toBe("lance");
|
|
894
|
+
expect(resolveOperatorAgentMode("plan", false, true)).toBe("lance");
|
|
895
|
+
});
|