@pensar/apex 2.6.1 → 2.7.0-canary.21cb83dc

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.
Files changed (226) hide show
  1. package/build/{agent-yby11zaq.js → agent-68t2wzmc.js} +6 -6
  2. package/build/agent-jhekpern.js +13 -0
  3. package/build/{agent-ayreaj6z.js → agent-qvreg8a4.js} +5 -5
  4. package/build/{agent-runs-g37vkrjr.js → agent-runs-30dvbvmm.js} +18 -18
  5. package/build/agent-vybw255f.js +13 -0
  6. package/build/{apps-xn6km9yn.js → apps-na0y0992.js} +13 -13
  7. package/build/{auth-d105wc64.js → auth-dz2c5thx.js} +13 -13
  8. package/build/{blackboxAgent-s56sgx9b.js → blackboxAgent-2mwvaajb.js} +6 -6
  9. package/build/{blackboxPentest-ps78v3w7.js → blackboxPentest-s2mfze9p.js} +17 -12
  10. package/build/{cli-kb21qhvm.js → cli-1pmfnz1a.js} +4 -3
  11. package/build/{cli-ae8jqxqr.js → cli-563yntrb.js} +2 -2
  12. package/build/{cli-7eea4e2y.js → cli-5ab346kd.js} +6 -6
  13. package/build/{cli-1ve18npr.js → cli-72y76bpg.js} +3 -2
  14. package/build/{cli-fy6vh2a7.js → cli-98wmmphf.js} +1 -1
  15. package/build/{cli-c05y640n.js → cli-9jscnhtg.js} +1 -1
  16. package/build/{cli-3sp6nd8d.js → cli-9kk9tm58.js} +2 -2
  17. package/build/{cli-d37a42dc.js → cli-9pz9wjt2.js} +101 -18
  18. package/build/{cli-dpsw2fe6.js → cli-a6x4jm5a.js} +476 -193
  19. package/build/{cli-az3xq70v.js → cli-cfrdr25z.js} +1 -1
  20. package/build/{cli-ngq9dr8n.js → cli-fdrrbb9p.js} +3 -3
  21. package/build/{cli-k2nwxta0.js → cli-t09zj814.js} +2 -2
  22. package/build/{cli-qgz1q9g5.js → cli-t4q4t4dx.js} +223 -76
  23. package/build/{cli-xtc2t6me.js → cli-vdd1s3x9.js} +103 -39
  24. package/build/{cli-gx71jcke.js → cli-vn4cwac3.js} +1 -1
  25. package/build/{cli-65g6rcat.js → cli-w9nw2a4z.js} +1 -1
  26. package/build/{cli-n2en7j5b.js → cli-z7ysyrr4.js} +1 -1
  27. package/build/{cli-709rvekb.js → cli-zbbtr4sb.js} +4 -2
  28. package/build/cli.js +70 -40
  29. package/build/{config-zpqkd5cz.js → config-nkzm9arw.js} +1 -1
  30. package/build/{fastStrike-mcjdvwez.js → fastStrike-16jw1s61.js} +67 -15
  31. package/build/{fixes-kytx5dmj.js → fixes-6wxk22v5.js} +13 -13
  32. package/build/{index-4vqdgb42.js → index-36p56pcf.js} +1473 -1217
  33. package/build/{index-je6hcsqr.js → index-6nejymsc.js} +1 -1
  34. package/build/{index-fv64eb32.js → index-asm4y7e4.js} +2 -2
  35. package/build/{index-n65z6v7b.js → index-bfmn52za.js} +6 -6
  36. package/build/{index-qv4cc65p.js → index-bt4r13q7.js} +13 -13
  37. package/build/{index-dr3tg1w3.js → index-gfq1rp1q.js} +1 -1
  38. package/build/{index-wqetp6gq.js → index-j9pxgrzd.js} +12 -7
  39. package/build/{index-r9yjkfrv.js → index-n9kapn1x.js} +4 -4
  40. package/build/{index-ns4m4s01.js → index-tr6evhyg.js} +4 -4
  41. package/build/{issues-eb3q9d3a.js → issues-7rmf4ker.js} +13 -13
  42. package/build/{knowledge-fqsvtx0f.js → knowledge-s2sxh8nb.js} +13 -13
  43. package/build/lib/{chunk-1azdancq.js → chunk-0dnx79b1.js} +1 -1
  44. package/build/lib/{chunk-4hwzqthr.js → chunk-161ak2am.js} +3 -2
  45. package/build/lib/{chunk-z137x08b.js → chunk-1rqbhx4b.js} +7 -5
  46. package/build/lib/{chunk-1yct6cra.js → chunk-3hjvdf67.js} +1 -1
  47. package/build/lib/{chunk-r2dkp4tb.js → chunk-5j8pp0xf.js} +1 -1
  48. package/build/lib/{chunk-3c00n0cy.js → chunk-77se1d35.js} +8 -3
  49. package/build/lib/{chunk-yrnrbjes.js → chunk-7tft4b8b.js} +4 -2
  50. package/build/lib/{chunk-w66ce82a.js → chunk-8njjwwcw.js} +4 -2
  51. package/build/lib/{chunk-v3dk9j7k.js → chunk-aq9eyxas.js} +80 -21
  52. package/build/lib/{chunk-9tt2021m.js → chunk-d05cvnv8.js} +9 -9
  53. package/build/lib/{chunk-e8yy2k73.js → chunk-f3sq4896.js} +28 -2
  54. package/build/lib/{chunk-1fy8azee.js → chunk-fasqtjq1.js} +1 -1
  55. package/build/lib/{chunk-1jvwqnem.js → chunk-gm3b9j4y.js} +104 -40
  56. package/build/lib/{chunk-r4j8ybn9.js → chunk-hys7nemr.js} +87 -36
  57. package/build/lib/{chunk-7pwa92rn.js → chunk-j9668h16.js} +1 -1
  58. package/build/lib/{chunk-ba41jh41.js → chunk-kcw4cpr3.js} +418 -133
  59. package/build/lib/{chunk-z96pbjhd.js → chunk-m4swxy5r.js} +13 -6
  60. package/build/lib/{chunk-xhdpgpkm.js → chunk-mbsde9d0.js} +2 -2
  61. package/build/lib/{chunk-9yksqgzr.js → chunk-mpvjfvz0.js} +20 -13
  62. package/build/lib/{chunk-2qsq76xq.js → chunk-qkz5sm0d.js} +128 -34
  63. package/build/lib/{chunk-nhfax4gb.js → chunk-rfyjqybp.js} +1 -1
  64. package/build/lib/{chunk-mg03jdmt.js → chunk-vsnwzne5.js} +1 -1
  65. package/build/lib/{chunk-acgbyf5h.js → chunk-ydxhkgjw.js} +3 -2
  66. package/build/lib/{chunk-bb0ekhkw.js → chunk-z8kej0sp.js} +69 -18
  67. package/build/lib/core/agents/agentRuntime.d.ts +2 -1
  68. package/build/lib/core/agents/defineAgent.d.ts +3 -2
  69. package/build/lib/core/agents/offSecAgent/index.d.ts +3 -1
  70. package/build/lib/core/agents/offSecAgent/index.js +10 -8
  71. package/build/lib/core/agents/offSecAgent/prompt.d.ts +3 -1
  72. package/build/lib/core/agents/offSecAgent/subagentSpawner.d.ts +2 -1
  73. package/build/lib/core/agents/offSecAgent/subagentSpawner.js +5 -5
  74. package/build/lib/core/agents/offSecAgent/tools/index.js +4 -4
  75. package/build/lib/core/agents/offSecAgent/tools/listMemories.d.ts +11 -1
  76. package/build/lib/core/agents/offSecAgent/tools/reportError.d.ts +2 -1
  77. package/build/lib/core/agents/offSecAgent/tools/runPentestWorkflow.d.ts +20 -1
  78. package/build/lib/core/agents/offSecAgent/tools/spawnPentestAgent.d.ts +4 -7
  79. package/build/lib/core/agents/offSecAgent/tools/spawnPentestSwarm.d.ts +7 -1
  80. package/build/lib/core/agents/offSecAgent/tools/types.d.ts +2 -1
  81. package/build/lib/core/agents/offSecAgent/types.d.ts +7 -1
  82. package/build/lib/core/agents/specialized/attackSurface/blackboxAgent.js +9 -9
  83. package/build/lib/core/agents/specialized/attackSurface/schemas.js +9 -9
  84. package/build/lib/core/agents/specialized/authenticationAgent/index.js +10 -10
  85. package/build/lib/core/agents/specialized/codeAgent/agent.js +9 -9
  86. package/build/lib/core/agents/specialized/codeAgent/prompts.d.ts +1 -0
  87. package/build/lib/core/agents/specialized/findingJudge/agent.js +8 -8
  88. package/build/lib/core/agents/specialized/findingJudge/index.js +3 -3
  89. package/build/lib/core/agents/specialized/patching/index.js +10 -10
  90. package/build/lib/core/agents/specialized/pentest/agent.d.ts +18 -4
  91. package/build/lib/core/agents/specialized/pentest/agent.js +11 -9
  92. package/build/lib/core/agents/specialized/whiteboxAttackSurface/index.js +9 -9
  93. package/build/lib/core/ai/ai.d.ts +23 -6
  94. package/build/lib/core/ai/ai.js +2 -2
  95. package/build/lib/core/ai/index.js +2 -2
  96. package/build/lib/core/ai/models/claude-capabilities.d.ts +3 -2
  97. package/build/lib/core/ai/models/concentrate.d.ts +1 -0
  98. package/build/lib/core/ai/models/index.d.ts +1 -1
  99. package/build/lib/core/ai/providers/concentrate.d.ts +1 -0
  100. package/build/lib/core/ai/utils.d.ts +2 -0
  101. package/build/lib/core/ai/utils.js +4 -2
  102. package/build/lib/core/api/index.d.ts +3 -0
  103. package/build/lib/core/api/index.js +22 -19
  104. package/build/lib/core/api/targetedPentest.d.ts +1 -0
  105. package/build/lib/core/api/targetedPentest.js +10 -10
  106. package/build/lib/core/config/config.d.ts +3 -0
  107. package/build/lib/core/config/index.js +1 -1
  108. package/build/lib/core/findings/registry.js +3 -3
  109. package/build/lib/core/session/index.d.ts +12 -0
  110. package/build/lib/core/session/index.js +2 -2
  111. package/build/lib/core/session/persistence.d.ts +7 -0
  112. package/build/lib/core/session/persistence.js +7 -3
  113. package/build/lib/core/workflows/fastStrike.d.ts +3 -1
  114. package/build/lib/core/workflows/pentest.d.ts +8 -1
  115. package/build/lib/core/workflows/pentest.js +15 -15
  116. package/build/lib/core/workflows/seams.js +4 -4
  117. package/build/lib/core/workflows/whiteboxAttackSurface.js +11 -11
  118. package/build/lib/index.js +22 -22
  119. package/build/{logs-x62b7hk1.js → logs-70fyr848.js} +13 -13
  120. package/build/{native-rollout-evidence-c9yhfqcs.js → native-rollout-evidence-ntensvzb.js} +3 -3
  121. package/build/{offesecAgent-5whnpeta.js → offesecAgent-kk62tf60.js} +4 -4
  122. package/build/pentest-4jgznn7h.js +22 -0
  123. package/build/{pentests-e0f32aqx.js → pentests-3e41hj08.js} +13 -13
  124. package/build/recordedRunClient-w34kcch1.js +11 -0
  125. package/build/{targetedPentest-rcbs4nvp.js → targetedPentest-t9snxcj2.js} +18 -11
  126. package/build/{targets-xj9g3q0z.js → targets-1pyf21c7.js} +13 -13
  127. package/build/threatModel-48y5qjze.js +21 -0
  128. package/build/{uninstall-7s784q4a.js → uninstall-fbydd9t6.js} +1 -1
  129. package/build/{upload-4gvhwmvr.js → upload-sbhwe2fq.js} +4 -4
  130. package/build/{utils-cjrz64pc.js → utils-23903gcj.js} +3 -3
  131. package/package.json +1 -1
  132. package/src/cli.ts +48 -14
  133. package/src/core/agents/agentRuntime.test.ts +38 -0
  134. package/src/core/agents/agentRuntime.ts +5 -2
  135. package/src/core/agents/defineAgent.ts +3 -1
  136. package/src/core/agents/offSecAgent/index.ts +3 -0
  137. package/src/core/agents/offSecAgent/offensiveSecurityAgent.test.ts +92 -5
  138. package/src/core/agents/offSecAgent/offensiveSecurityAgent.ts +70 -31
  139. package/src/core/agents/offSecAgent/prompt.test.ts +46 -0
  140. package/src/core/agents/offSecAgent/prompt.ts +52 -8
  141. package/src/core/agents/offSecAgent/selectiveConstruction.publicPath.test.ts +38 -0
  142. package/src/core/agents/offSecAgent/selectiveConstruction.test.ts +64 -0
  143. package/src/core/agents/offSecAgent/subagentSpawner.ts +12 -1
  144. package/src/core/agents/offSecAgent/tools/delegateAuth.ts +1 -0
  145. package/src/core/agents/offSecAgent/tools/listMemories.test.ts +230 -0
  146. package/src/core/agents/offSecAgent/tools/listMemories.ts +73 -6
  147. package/src/core/agents/offSecAgent/tools/reportError.test.ts +6 -0
  148. package/src/core/agents/offSecAgent/tools/reportError.ts +10 -2
  149. package/src/core/agents/offSecAgent/tools/runAttackSurface.ts +2 -0
  150. package/src/core/agents/offSecAgent/tools/runPentestWorkflow.test.ts +57 -0
  151. package/src/core/agents/offSecAgent/tools/runPentestWorkflow.ts +19 -1
  152. package/src/core/agents/offSecAgent/tools/runWhiteboxScan.ts +5 -2
  153. package/src/core/agents/offSecAgent/tools/spawnCodingAgent.ts +1 -0
  154. package/src/core/agents/offSecAgent/tools/spawnPentestAgent.test.ts +72 -2
  155. package/src/core/agents/offSecAgent/tools/spawnPentestAgent.ts +32 -11
  156. package/src/core/agents/offSecAgent/tools/spawnPentestSwarm.ts +25 -5
  157. package/src/core/agents/offSecAgent/tools/threatModelGenerator.ts +1 -0
  158. package/src/core/agents/offSecAgent/tools/types.ts +6 -1
  159. package/src/core/agents/offSecAgent/tools/updateTask.ts +5 -1
  160. package/src/core/agents/offSecAgent/tools/whiteboxCandidates.ts +11 -4
  161. package/src/core/agents/offSecAgent/types.ts +9 -0
  162. package/src/core/agents/specialized/codeAgent/agent.test.ts +7 -0
  163. package/src/core/agents/specialized/codeAgent/agent.ts +9 -2
  164. package/src/core/agents/specialized/codeAgent/prompts.ts +6 -0
  165. package/src/core/agents/specialized/pentest/agent.test.ts +116 -0
  166. package/src/core/agents/specialized/pentest/agent.ts +178 -49
  167. package/src/core/agents/specialized/pentest/results.test.ts +59 -4
  168. package/src/core/agents/specialized/whiteboxAttackSurface/endpointDocumentationAgent.ts +1 -0
  169. package/src/core/ai/ai.operator-context.bench.test.ts +1408 -0
  170. package/src/core/ai/ai.recorded-context.test.ts +74 -0
  171. package/src/core/ai/ai.test.ts +54 -0
  172. package/src/core/ai/ai.ts +312 -82
  173. package/src/core/ai/compactionTelemetry.test.ts +2 -2
  174. package/src/core/ai/models/anthropic.ts +6 -0
  175. package/src/core/ai/models/bedrock.ts +18 -0
  176. package/src/core/ai/models/claude-capabilities.ts +29 -8
  177. package/src/core/ai/models/concentrate.ts +52 -0
  178. package/src/core/ai/models/index.ts +25 -4
  179. package/src/core/ai/models/models.test.ts +154 -0
  180. package/src/core/ai/models/openrouter.ts +43 -1
  181. package/src/core/ai/providers/anthropic-models.test.ts +60 -1
  182. package/src/core/ai/providers/bedrock-models.test.ts +81 -0
  183. package/src/core/ai/providers/concentrate.test.ts +31 -0
  184. package/src/core/ai/providers/concentrate.ts +11 -0
  185. package/src/core/ai/providers/gateway-models.test.ts +16 -6
  186. package/src/core/ai/utils.native-rollout-evidence.test.ts +1 -0
  187. package/src/core/ai/utils.ts +189 -143
  188. package/src/core/api/blackboxPentest.ts +9 -1
  189. package/src/core/api/index.ts +9 -0
  190. package/src/core/api/targetedPentest.ts +19 -5
  191. package/src/core/config/config.test.ts +35 -0
  192. package/src/core/config/config.ts +5 -0
  193. package/src/core/observability/telemetry.test.ts +2 -3
  194. package/src/core/session/index.ts +5 -0
  195. package/src/core/session/persistence.test.ts +62 -0
  196. package/src/core/session/persistence.ts +56 -0
  197. package/src/core/workflows/fastStrike.seams.test.ts +149 -0
  198. package/src/core/workflows/fastStrike.test.ts +18 -1
  199. package/src/core/workflows/fastStrike.ts +103 -11
  200. package/src/core/workflows/pentest.test.ts +104 -0
  201. package/src/core/workflows/pentest.ts +110 -7
  202. package/src/core/workflows/seams.test.ts +13 -0
  203. package/src/core/workflows/seams.ts +5 -1
  204. package/src/core/workflows/whiteboxAttackSurface.ts +1 -0
  205. package/src/tui/components/chat/loading-indicator.tsx +20 -4
  206. package/src/tui/components/chat/message-list.tsx +1 -0
  207. package/src/tui/components/commands/__tests__/advanced-settings-lifecycle.tsx +176 -0
  208. package/src/tui/components/commands/advanced-settings.test.ts +28 -0
  209. package/src/tui/components/commands/advanced-settings.tsx +237 -19
  210. package/src/tui/components/operator-dashboard/index.tsx +46 -9
  211. package/src/tui/components/operator-dashboard/logic.test.ts +106 -0
  212. package/src/tui/components/operator-dashboard/logic.ts +42 -2
  213. package/src/tui/components/operator-dashboard/run-events.test.ts +3 -1
  214. package/src/tui/components/shared/__tests__/tool-renderer-lifecycle.tsx +18 -0
  215. package/src/tui/components/shared/action-label.test.ts +9 -0
  216. package/src/tui/components/shared/compacting-icon.tsx +18 -0
  217. package/src/tui/components/shared/index.ts +1 -0
  218. package/src/tui/components/shared/tool-registry.ts +1 -0
  219. package/src/tui/components/shared/tool-renderer.tsx +21 -7
  220. package/src/tui/context/route.tsx +1 -0
  221. package/src/tui/keybindings/registry.ts +2 -0
  222. package/build/agent-6w7egcf1.js +0 -13
  223. package/build/agent-9zx75feh.js +0 -13
  224. package/build/pentest-e61hc38s.js +0 -22
  225. package/build/recordedRunClient-dp032c32.js +0 -11
  226. package/build/threatModel-jkxfa40s.js +0 -21
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  type AgentMode,
3
3
  buildBaseSystemPrompt,
4
+ type FindingPolicy,
4
5
  } from "../../../core/agents/offSecAgent";
5
6
  import type {
6
7
  OperatorMode,
@@ -39,6 +40,17 @@ export function filterOperatorAutocomplete(
39
40
 
40
41
  export type DashboardStatus = "idle" | "running" | "waiting" | "done";
41
42
 
43
+ export function shouldHandleQueuedMessageKey(
44
+ status: DashboardStatus,
45
+ queuedCount: number,
46
+ inputValue: string,
47
+ dialogOpen: boolean,
48
+ ): boolean {
49
+ return (
50
+ !dialogOpen && status === "running" && queuedCount > 0 && !inputValue.trim()
51
+ );
52
+ }
53
+
42
54
  export function resolveOperatorAgentMode(
43
55
  operatorMode: OperatorMode,
44
56
  strikeMode: boolean,
@@ -64,6 +76,33 @@ export function resolveOperatorStrikeMode({
64
76
  return routeOverride ?? persistedDefault ?? false;
65
77
  }
66
78
 
79
+ interface FindingPolicyResolutionInput {
80
+ resuming: boolean;
81
+ strikeMode: boolean;
82
+ savedSessionValue?: FindingPolicy;
83
+ routeOverride?: FindingPolicy;
84
+ persistedDefault?: FindingPolicy;
85
+ }
86
+
87
+ export function resolveOperatorFindingPolicy({
88
+ resuming,
89
+ strikeMode,
90
+ savedSessionValue,
91
+ routeOverride,
92
+ persistedDefault,
93
+ }: FindingPolicyResolutionInput): FindingPolicy {
94
+ if (!strikeMode) return "native";
95
+ if (resuming) return savedSessionValue ?? "native";
96
+ return routeOverride ?? persistedDefault ?? "native";
97
+ }
98
+
99
+ export function resolveActiveFindingPolicy(
100
+ agentMode: AgentMode,
101
+ findingPolicy: FindingPolicy,
102
+ ): FindingPolicy {
103
+ return agentMode === "fast-strike" ? findingPolicy : "native";
104
+ }
105
+
67
106
  export interface SubmitResult {
68
107
  action: "run" | "blocked" | "empty";
69
108
  prompt?: string;
@@ -286,6 +325,7 @@ export function buildOperatorSystemPrompt(
286
325
  existingPlanContent?: string | null;
287
326
  approvedPlanContent?: string | null;
288
327
  taskDriven?: boolean;
328
+ findingPolicy?: FindingPolicy;
289
329
  },
290
330
  ): string {
291
331
  const { skillsCatalog, activeSkillInstructions } = opts ?? {};
@@ -313,7 +353,7 @@ For each directive, run a tight loop:
313
353
  2. HYPOTHESIZE — choose the single most likely vulnerability or next pivot.
314
354
  3. ACT — use direct tools for quick probes, but treat the shell as a working environment rather than merely a way to issue one-off commands. When the work becomes stateful, repetitive, concurrent, protocol-heavy, or multi-stage, externalize it into an editable script in the session scratchpad directory identified in the Session Workspace or Working Directory section. Never create a scratchpad/ directory inside the target repository. Run the script, inspect the results, modify it, and rerun it as the attack develops.
315
355
  4. PRUNE — drop disproven leads instead of repeating them.
316
- 5. EXPLOIT — preserve viable primitives and build on them. Prefer extending a working script into an end-to-end exploit over rebuilding the chain with repeated one-off tool calls or stopping at the next network or protocol boundary. Prove impact and document confirmed vulnerabilities.
356
+ 5. EXPLOIT — preserve viable primitives and build on them. Prefer extending a working script into an end-to-end exploit over rebuilding the chain with repeated one-off tool calls or stopping at the next network or protocol boundary. ${opts?.findingPolicy === "external" ? "Pursue the assigned objective and submit concise findings in the requested output format." : "Prove impact and document confirmed vulnerabilities."}
317
357
 
318
358
  Spend your reasoning on choosing techniques and interpreting evidence; use scripts for deterministic mechanics, iteration, and chain execution. Before stopping with the objective unmet, account for each viable primitive and pursue any concrete path that could still close it. Stop and summarize when the objective is met, credible leads are genuinely exhausted, or human input is needed. Stay in scope and never trade verification for speed.`;
319
359
  }
@@ -334,7 +374,7 @@ ${opts.approvedPlanContent}
334
374
  // Runtime execution facts and bundled assets are appended by the agent
335
375
  // harness after this persona (OffensiveSecurityAgent assembles the final
336
376
  // system prompt) — embedding them here would duplicate the blocks.
337
- let prompt = `${buildBaseSystemPrompt({ sandboxMode: opts?.sandboxMode })}
377
+ let prompt = `${buildBaseSystemPrompt({ sandboxMode: opts?.sandboxMode, findingPolicy: opts?.findingPolicy })}
338
378
 
339
379
  # Operator Mode
340
380
 
@@ -567,7 +567,9 @@ describe("createDisplayEventHandlers", () => {
567
567
  (callback, delay = 0, ...args) =>
568
568
  schedule(() => {
569
569
  timerCallbacks++;
570
- callback(...args);
570
+ if (typeof callback === "function") {
571
+ Reflect.apply(callback, undefined, args);
572
+ }
571
573
  }, delay),
572
574
  );
573
575
  }
@@ -64,6 +64,24 @@ try {
64
64
  ),
65
65
  );
66
66
  }
67
+
68
+ const compacting = applyToolCall([], "compact-1", "summarize_conversation", {
69
+ reason: "Compacting context to continue",
70
+ messageCount: 20,
71
+ });
72
+ const pendingFrame = await frame(compacting);
73
+ assert.ok(pendingFrame.includes("⠁ Compacting"));
74
+ assert.ok(!pendingFrame.includes("summarize_conversation"));
75
+
76
+ const completedFrame = await frame(
77
+ applyToolResult(
78
+ compacting,
79
+ "compact-1",
80
+ "Conversation summarized successfully. Resuming with condensed context...",
81
+ ),
82
+ );
83
+ assert.ok(completedFrame.includes("Context compacted"));
84
+ assert.ok(!completedFrame.includes("summarized"));
67
85
  } finally {
68
86
  await act(() => setup.renderer.destroy());
69
87
  }
@@ -127,6 +127,15 @@ describe("deriveActionLabel", () => {
127
127
  expect(deriveActionLabel("scratchpad", undefined)).toBe("note");
128
128
  });
129
129
 
130
+ it("labels context compaction without exposing the synthetic tool name", () => {
131
+ expect(
132
+ deriveActionLabel("summarize_conversation", {
133
+ reason: "Compacting context to continue",
134
+ messageCount: 20,
135
+ }),
136
+ ).toBe("Compacting");
137
+ });
138
+
130
139
  it("handles empty args gracefully (returns the tool name itself)", () => {
131
140
  expect(deriveActionLabel("custom_tool", {})).toBe("custom_tool");
132
141
  });
@@ -0,0 +1,18 @@
1
+ import type { RGBA } from "@opentui/core";
2
+ import { useEffect, useState } from "react";
3
+
4
+ // From throbber-widgets FALLING_SAND (MIT); local to avoid its react-dom peer.
5
+ const FRAMES = [..."⠁⠂⠄⡀⡈⡐⡠⣀⣁⣂⣄⣌⣔⣤⣥⣦⣮⣶⣷⣿⡿⠿⢟⠟⡛⠛⠫⢋⠋⠍⡉⠉⠑⠡⢁"];
6
+
7
+ export function CompactingIcon({ fg }: { fg: RGBA }) {
8
+ const [frame, setFrame] = useState(0);
9
+
10
+ useEffect(() => {
11
+ const interval = setInterval(() => {
12
+ setFrame((current) => (current + 1) % FRAMES.length);
13
+ }, 80);
14
+ return () => clearInterval(interval);
15
+ }, []);
16
+
17
+ return <text fg={fg}>{FRAMES[frame]}</text>;
18
+ }
@@ -7,6 +7,7 @@
7
7
  // Action labels
8
8
  export { deriveActionLabel, deriveApprovedActionLabel } from "./action-label";
9
9
  export { AsciiSpinner } from "./ascii-spinner";
10
+ export { CompactingIcon } from "./compacting-icon";
10
11
  // Components
11
12
  export {
12
13
  type ControlItem,
@@ -150,6 +150,7 @@ const TOOL_SUMMARY_MAP: Record<string, ToolSummaryFn> = {
150
150
 
151
151
  // Utility tools
152
152
  scratchpad: () => "note",
153
+ summarize_conversation: () => "Compacting",
153
154
  };
154
155
 
155
156
  /**
@@ -10,6 +10,7 @@ import { useObfuscation } from "../../context/obfuscation";
10
10
  import { useTheme } from "../../theme";
11
11
  import type { DisplayMessage } from "../agent-display";
12
12
  import { ShiningText } from "../loaders";
13
+ import { CompactingIcon } from "./compacting-icon";
13
14
  import { PentestWorkflowDisplay } from "./pentest-workflow-display";
14
15
  import { getResultSummary, type ResultSummary } from "./result-registry";
15
16
  import { getToolDisplayLabel } from "./tool-registry";
@@ -74,10 +75,14 @@ export const ToolRenderer = memo(function ToolRenderer({
74
75
  const isError = message.status === "error";
75
76
  const { toolName, result, logs } = message;
76
77
  const args = message.args ?? {};
78
+ const isCompacting = toolName === "summarize_conversation";
77
79
 
78
- const summary = getToolDisplayLabel(toolName, args, {
79
- preferDescription: isPending,
80
- });
80
+ const summary =
81
+ isCompacting && isCompleted
82
+ ? "Context compacted"
83
+ : getToolDisplayLabel(toolName, args, {
84
+ preferDescription: isPending,
85
+ });
81
86
 
82
87
  // For execute_command, extract both description and command so we can show
83
88
  // both. Strings flow into `<text>` children, so the centralised
@@ -101,9 +106,11 @@ export const ToolRenderer = memo(function ToolRenderer({
101
106
 
102
107
  // Get result summary for completed tools
103
108
  const resultDisplay: ResultSummary | null =
104
- isCompleted || isError
105
- ? getResultSummary(result, toolName, args, colors)
106
- : null;
109
+ isCompleted && isCompacting
110
+ ? null
111
+ : isCompleted || isError
112
+ ? getResultSummary(result, toolName, args, colors)
113
+ : null;
107
114
 
108
115
  // Determine border color based on status
109
116
  const borderColor = isError
@@ -121,7 +128,14 @@ export const ToolRenderer = memo(function ToolRenderer({
121
128
  {/* Tool header line */}
122
129
  <box flexDirection="row" gap={1}>
123
130
  {isPending ? (
124
- <ShiningText text={summary} fg={colors.warning} />
131
+ isCompacting ? (
132
+ <>
133
+ <CompactingIcon fg={colors.primary} />
134
+ <text fg={colors.info}>{summary}</text>
135
+ </>
136
+ ) : (
137
+ <ShiningText text={summary} fg={colors.warning} />
138
+ )
125
139
  ) : (
126
140
  <>
127
141
  <text fg={isError ? colors.error : colors.success}>
@@ -70,6 +70,7 @@ export type Route =
70
70
  operatorMode?: import("../../core/operator").OperatorMode;
71
71
  /** Overrides the persisted Strike Mode preference for this new session. */
72
72
  strikeMode?: boolean;
73
+ findingPolicy?: import("../../core/agents/offSecAgent").FindingPolicy;
73
74
  sandbox?: boolean;
74
75
  taskDriven?: boolean;
75
76
  /** Headers from wizard/CLI; replace the snapshotted global defaults. */
@@ -120,6 +120,7 @@ export function createKeybindings(
120
120
  combo: "tab",
121
121
  description: "Next focusable item",
122
122
  fn: async () => {
123
+ if (stack.length > 0 || externalDialogOpen) return;
123
124
  setFocusIndex((prev) => (prev + 1) % navigableItems.length);
124
125
  },
125
126
  },
@@ -127,6 +128,7 @@ export function createKeybindings(
127
128
  combo: "shift+tab",
128
129
  description: "Previous focusable item",
129
130
  fn: async () => {
131
+ if (stack.length > 0 || externalDialogOpen) return;
130
132
  setFocusIndex(
131
133
  (prev) => (prev - 1 + navigableItems.length) % navigableItems.length,
132
134
  );
@@ -1,13 +0,0 @@
1
- import {
2
- runAuthenticationAgent2
3
- } from "./cli-3sp6nd8d.js";
4
- import"./cli-1ve18npr.js";
5
- import"./cli-qba2x69h.js";
6
- import"./cli-qgz1q9g5.js";
7
- import"./cli-dpsw2fe6.js";
8
- import"./cli-c05y640n.js";
9
- import"./cli-c2k4xxaw.js";
10
- import"./cli-fy6vh2a7.js";
11
- export {
12
- runAuthenticationAgent2 as runAuthenticationAgent
13
- };
@@ -1,13 +0,0 @@
1
- import {
2
- CodeAgent2
3
- } from "./cli-kb21qhvm.js";
4
- import"./cli-1ve18npr.js";
5
- import"./cli-qba2x69h.js";
6
- import"./cli-qgz1q9g5.js";
7
- import"./cli-dpsw2fe6.js";
8
- import"./cli-c05y640n.js";
9
- import"./cli-c2k4xxaw.js";
10
- import"./cli-fy6vh2a7.js";
11
- export {
12
- CodeAgent2 as CodeAgent
13
- };
@@ -1,22 +0,0 @@
1
- import {
2
- DEFAULT_CONCURRENCY2,
3
- runPentestSwarm2,
4
- runPentestWorkflow2
5
- } from "./cli-d37a42dc.js";
6
- import"./cli-n2en7j5b.js";
7
- import"./cli-ngq9dr8n.js";
8
- import"./cli-k2nwxta0.js";
9
- import"./cli-xtc2t6me.js";
10
- import"./cli-kb21qhvm.js";
11
- import"./cli-1ve18npr.js";
12
- import"./cli-qba2x69h.js";
13
- import"./cli-qgz1q9g5.js";
14
- import"./cli-dpsw2fe6.js";
15
- import"./cli-c05y640n.js";
16
- import"./cli-c2k4xxaw.js";
17
- import"./cli-fy6vh2a7.js";
18
- export {
19
- DEFAULT_CONCURRENCY2 as DEFAULT_CONCURRENCY,
20
- runPentestSwarm2 as runPentestSwarm,
21
- runPentestWorkflow2 as runPentestWorkflow
22
- };
@@ -1,11 +0,0 @@
1
- import {
2
- openRecordedRunClient2
3
- } from "./cli-ae8jqxqr.js";
4
- import"./cli-gx71jcke.js";
5
- import"./cli-dpsw2fe6.js";
6
- import"./cli-c05y640n.js";
7
- import"./cli-c2k4xxaw.js";
8
- import"./cli-fy6vh2a7.js";
9
- export {
10
- openRecordedRunClient2 as openRecordedRunClient
11
- };
@@ -1,21 +0,0 @@
1
- import"./cli-qgz1q9g5.js";
2
- import"./cli-fy6vh2a7.js";
3
- import"./cli-c05y640n.js";
4
- import {
5
- runThreatModelWorkflow2
6
- } from "./cli-7eea4e2y.js";
7
- import"./cli-k2nwxta0.js";
8
- import"./cli-kb21qhvm.js";
9
- import"./cli-ngq9dr8n.js";
10
- import"./cli-d37a42dc.js";
11
- import"./cli-3sp6nd8d.js";
12
- import"./cli-xtc2t6me.js";
13
- import"./cli-n2en7j5b.js";
14
- import"./cli-xcy2vxj2.js";
15
- import"./cli-1ve18npr.js";
16
- import"./cli-qba2x69h.js";
17
- import"./cli-dpsw2fe6.js";
18
- import"./cli-c2k4xxaw.js";
19
- export {
20
- runThreatModelWorkflow2 as runThreatModelWorkflow
21
- };