@pensar/apex 1.8.0 → 1.8.2-canary.fb75c486

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 (70) hide show
  1. package/README.md +11 -0
  2. package/build/agent-6dj1qm50.js +221 -0
  3. package/build/agent-6xr8vpgm.js +28 -0
  4. package/build/agent-x1htbpe3.js +22 -0
  5. package/build/apps-t0gmwc7z.js +446 -0
  6. package/build/{auth-dxjgy41e.js → auth-p4r1m7xq.js} +50 -13
  7. package/build/authentication-je2b0c3w.js +22 -0
  8. package/build/blackboxAgent-a4jnt0y5.js +22 -0
  9. package/build/{blackboxPentest-8ps4yvbk.js → blackboxPentest-b5741n3h.js} +19 -17
  10. package/build/{cli-y61d9433.js → cli-0tnv1vkp.js} +138 -38
  11. package/build/{cli-jg7r7y5n.js → cli-4xb21y6g.js} +30 -2
  12. package/build/{cli-k0tckznm.js → cli-6p7d2k55.js} +39701 -31695
  13. package/build/cli-87zakjb2.js +17 -0
  14. package/build/{authentication-e30mfzbe.js → cli-8frjr68r.js} +11 -18
  15. package/build/cli-8xknm7d9.js +204 -0
  16. package/build/cli-9egg9azd.js +22 -0
  17. package/build/cli-9fsre5pt.js +0 -0
  18. package/build/cli-abbka8n3.js +501 -0
  19. package/build/{cli-3y0dgy56.js → cli-c8131c4q.js} +2 -2
  20. package/build/cli-e08r86zk.js +24 -0
  21. package/build/{cli-0ghkg3w6.js → cli-e6rgwtpb.js} +19950 -18556
  22. package/build/cli-g5h24ny8.js +197 -0
  23. package/build/{cli-nr1cjfr9.js → cli-gtcd5c3f.js} +26 -7
  24. package/build/cli-k0730f59.js +52 -0
  25. package/build/{cli-tp1tqn3k.js → cli-mswm4k81.js} +1 -1
  26. package/build/{cli-m788e4f3.js → cli-q8dfq25x.js} +584 -33
  27. package/build/cli-rhry8mat.js +7213 -0
  28. package/build/{cli-g8t710ew.js → cli-ryy39d77.js} +253 -250
  29. package/build/cli-s1nckt4k.js +20 -0
  30. package/build/{cli-k4hrygff.js → cli-v9ds4jb8.js} +9 -5
  31. package/build/{cli-dqt80sw3.js → cli-w5990vr6.js} +199 -68
  32. package/build/{cli-3w2syxpv.js → cli-wfmdch3r.js} +102695 -104816
  33. package/build/cli.js +351 -280
  34. package/build/config-3bvtf3j8.js +188 -0
  35. package/build/{doctor-8tva8j99.js → doctor-2bkpddws.js} +1 -1
  36. package/build/{fixes-q5bhgxhc.js → fixes-60k3ts71.js} +23 -4
  37. package/build/{index-pfee23kv.js → index-0gp3x2r8.js} +19306 -18954
  38. package/build/index-861hkebg.js +12 -0
  39. package/build/{index-y5xpp21a.js → index-acc00eq4.js} +77 -108
  40. package/build/index-acdgrqa0.js +36 -0
  41. package/build/{index-e898mdyh.js → index-cfberehw.js} +4 -2
  42. package/build/{index-wfeb2gcc.js → index-hxn4rk8f.js} +9 -11
  43. package/build/{index-dw1xbhfn.js → index-vc29b21w.js} +161 -26
  44. package/build/index-vwt27stc.js +184 -0
  45. package/build/{issues-qbmdneej.js → issues-1bynat5q.js} +33 -9
  46. package/build/{logs-xm5vbymy.js → logs-e78vx2dy.js} +23 -4
  47. package/build/{main-3d7dfdvs.js → main-3zneyg7p.js} +93 -17
  48. package/build/{offesecAgent-re6kt2ff.js → offesecAgent-w9m0svwk.js} +14 -11
  49. package/build/parse-15kqmy2v.js +207 -0
  50. package/build/pentest-gpvqpvmd.js +31 -0
  51. package/build/{pentests-e3rj5845.js → pentests-nq7wa8yb.js} +36 -17
  52. package/build/{targetedPentest-fs0v570s.js → targetedPentest-fjxqn089.js} +15 -12
  53. package/build/threatModel-9yqx7d7x.js +29 -0
  54. package/build/{uninstall-qb2xbh2t.js → uninstall-9zbf4cwc.js} +6 -4
  55. package/build/{utils-jf52rmrb.js → utils-dh1t2r1e.js} +13 -10
  56. package/package.json +86 -88
  57. package/build/agent-4d8j2jsw.js +0 -278
  58. package/build/agent-z2s6h7n2.js +0 -19
  59. package/build/blackboxAgent-j9pczwym.js +0 -19
  60. package/build/cli-03z6pswp.js +0 -1423
  61. package/build/cli-0fy9j5dw.js +0 -61
  62. package/build/cli-asyas1xb.js +0 -110
  63. package/build/cli-dj1dgw2n.js +0 -190
  64. package/build/cli-q7r2sth7.js +0 -103
  65. package/build/cli-vkwch0bc.js +0 -1207
  66. package/build/cli-wr7g9qcr.js +0 -645
  67. package/build/index-bz6f8jry.js +0 -32
  68. package/build/pentest-mfm4hake.js +0 -29
  69. package/build/projects-qk22qcbt.js +0 -35
  70. package/build/threatModel-xfvc6cch.js +0 -67
package/build/cli.js CHANGED
@@ -1,136 +1,62 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ import"./cli-8xknm7d9.js";
3
4
  import {
4
5
  createThreatModelPrompt
5
6
  } from "./cli-fw5r7pfj.js";
6
- import"./cli-3y0dgy56.js";
7
+ import"./cli-c8131c4q.js";
7
8
  import {
8
9
  init_toolset
9
- } from "./cli-k0tckznm.js";
10
- import"./cli-0ghkg3w6.js";
11
- import"./cli-dqt80sw3.js";
12
- import"./cli-asyas1xb.js";
10
+ } from "./cli-s1nckt4k.js";
11
+ import {
12
+ buildAuthConfig,
13
+ init_ai,
14
+ init_models,
15
+ init_utils
16
+ } from "./cli-6p7d2k55.js";
17
+ import"./cli-w5990vr6.js";
18
+ import"./cli-e6rgwtpb.js";
19
+ import"./cli-9egg9azd.js";
13
20
  import"./cli-gpnb45ck.js";
14
- import"./cli-nr1cjfr9.js";
21
+ import"./cli-gtcd5c3f.js";
15
22
  import {
23
+ init_package,
16
24
  package_default
17
- } from "./cli-dj1dgw2n.js";
18
- import {
19
- init_models
20
- } from "./cli-03z6pswp.js";
25
+ } from "./cli-g5h24ny8.js";
21
26
  import {
22
27
  __require,
23
28
  __toESM
24
29
  } from "./cli-8rxa073f.js";
25
30
  // package.json
26
31
  var package_default2 = {
27
- name: "@pensar/apex",
28
- version: "1.8.0",
29
- description: "AI-powered penetration testing CLI tool with terminal UI",
30
- module: "src/tui/index.tsx",
31
- main: "build/cli.js",
32
- type: "module",
33
- repository: {
34
- type: "git",
35
- url: "https://github.com/pensarai/apex.git"
36
- },
32
+ author: "Pensar",
37
33
  bin: {
38
34
  pensar: "./bin/pensar.js"
39
35
  },
40
- files: [
41
- "build",
42
- "bin",
43
- "assets",
44
- "pensar.svg",
45
- "LICENSE"
46
- ],
47
- scripts: {
48
- build: "bun build src/cli.ts --outdir build --target node --format esm --splitting --external @opentui/core --external @opentui/react --external @opentui/react/* --external react --external react/jsx-runtime --external react/jsx-dev-runtime --external react-reconciler --external weave",
49
- "generate:ascii": "bun run scripts/generate-ascii-art.ts",
50
- "generate:models": "bun run scripts/generate-models.ts",
51
- "build:binary": "bun run generate:ascii && bun build src/cli.ts --compile --outfile pensar",
52
- "build:binary:macos-arm64": "bun build src/cli.ts --compile --target=bun-darwin-arm64 --outfile dist/pensar-darwin-arm64",
53
- "build:binary:macos-x64": "bun build src/cli.ts --compile --target=bun-darwin-x64 --outfile dist/pensar-darwin-x64",
54
- "build:binary:linux-x64": "bun build src/cli.ts --compile --target=bun-linux-x64 --outfile dist/pensar-linux-x64",
55
- "build:binary:linux-arm64": "bun build src/cli.ts --compile --target=bun-linux-arm64 --outfile dist/pensar-linux-arm64",
56
- "build:binaries": "bun run generate:ascii && mkdir -p dist && bun run build:binary:macos-arm64 && bun run build:binary:macos-x64 && bun run build:binary:linux-x64 && bun run build:binary:linux-arm64",
57
- dev: "bun run scripts/watch.ts",
58
- "dev:debug": "SHOW_CONSOLE=true bun run scripts/watch.ts",
59
- start: "bun run src/tui/index.tsx",
60
- pensar: "node bin/pensar.js",
61
- tsc: "tsc --noEmit",
62
- "daytona-benchmark": "bun run scripts/daytona-benchmark.ts",
63
- "local-benchmark": "bun run scripts/local-benchmark.ts",
64
- test: "vitest run",
65
- "test:watch": "vitest",
66
- lint: "eslint src/",
67
- format: "prettier --write .",
68
- "format:check": "prettier --check .",
69
- prepublishOnly: "npm run build"
70
- },
71
- keywords: [
72
- "penetration-testing",
73
- "security",
74
- "pentesting",
75
- "ai",
76
- "cli",
77
- "terminal",
78
- "tui"
79
- ],
80
- author: "Pensar",
81
- license: "MIT",
82
- engines: {
83
- node: ">=18.0.0",
84
- bun: ">=1.0.0"
85
- },
86
- optionalDependencies: {
87
- weave: "^0.12.1"
88
- },
89
- devDependencies: {
90
- "@eslint/js": "^10.0.1",
91
- "@types/bun": "^1.3.0",
92
- "@types/mailparser": "^3.4.6",
93
- "@types/mime-types": "^3.0.1",
94
- "@types/nodemailer": "^8.0.0",
95
- "@types/react": "^19.2.6",
96
- "@typescript-eslint/eslint-plugin": "^8.55.0",
97
- "@typescript-eslint/parser": "^8.55.0",
98
- dotenv: "^17.2.3",
99
- eslint: "^10.0.0",
100
- "eslint-config-prettier": "^10.1.8",
101
- "eslint-plugin-unused-imports": "^4.4.1",
102
- prettier: "^3.8.1",
103
- "typescript-eslint": "^8.55.0",
104
- vitest: "^2.1.8"
105
- },
106
- peerDependencies: {
107
- typescript: "^5.9.3"
108
- },
109
36
  dependencies: {
110
- "@ai-sdk/amazon-bedrock": "^4.0.69",
111
- "@ai-sdk/anthropic": "^3.0.50",
37
+ "@ai-sdk/amazon-bedrock": "^4.0.113",
38
+ "@ai-sdk/anthropic": "^3.0.81",
112
39
  "@ai-sdk/google": "^3.0.37",
113
40
  "@ai-sdk/openai": "3.0.46",
114
41
  "@ai-sdk/openai-compatible": "^2.0.35",
42
+ "@ai-sdk/provider": "^3.0.8",
115
43
  "@daytonaio/sdk": "^0.112.1",
116
44
  "@googleapis/gmail": "^16.1.1",
117
45
  "@microsoft/microsoft-graph-client": "^3.0.7",
118
46
  "@modelcontextprotocol/sdk": "^1.0.0",
119
47
  "@openrouter/ai-sdk-provider": "^2.2.3",
120
- "@opentui/core": "^0.1.80",
121
- "@opentui/react": "^0.1.80",
48
+ "@opentelemetry/api": "^1.9.0",
49
+ "@opentui/core": "^0.1.107",
50
+ "@opentui/react": "^0.1.107",
51
+ "@pensar/surface": "0.2.1",
122
52
  "@playwright/mcp": "^0.0.54",
123
53
  ai: "^6.0.105",
124
54
  glob: "^13.0.0",
125
- "google-auth-library": "^10.6.1",
126
55
  "highlight.js": "^11.11.1",
127
- ignore: "^7.0.5",
128
56
  imapflow: "^1.2.10",
129
- jsonwebtoken: "^9.0.3",
130
57
  mailparser: "^3.9.3",
131
58
  marked: "^16.4.0",
132
59
  "mime-types": "^3.0.2",
133
- nanoid: "^5.1.6",
134
60
  nodemailer: "^8.0.7",
135
61
  "p-limit": "^7.2.0",
136
62
  react: "^19.2.0",
@@ -139,10 +65,232 @@ var package_default2 = {
139
65
  yaml: "^2.8.2",
140
66
  zod: "^3.25.76"
141
67
  },
142
- packageManager: "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
68
+ description: "AI-powered penetration testing CLI tool with terminal UI",
69
+ devDependencies: {
70
+ "@biomejs/biome": "2.4.14",
71
+ "@types/bun": "^1.3.0",
72
+ "@types/mailparser": "^3.4.6",
73
+ "@types/mime-types": "^3.0.1",
74
+ "@types/nodemailer": "^8.0.0",
75
+ "@types/react": "^19.2.6",
76
+ dotenv: "^17.2.3",
77
+ knip: "^6.12.0",
78
+ prettier: "^3.8.1",
79
+ vitest: "^2.1.8"
80
+ },
81
+ engines: {
82
+ bun: ">=1.0.0",
83
+ node: ">=18.0.0"
84
+ },
85
+ files: [
86
+ "build",
87
+ "bin",
88
+ "assets",
89
+ "pensar.svg",
90
+ "LICENSE"
91
+ ],
92
+ keywords: [
93
+ "penetration-testing",
94
+ "security",
95
+ "pentesting",
96
+ "ai",
97
+ "cli",
98
+ "terminal",
99
+ "tui"
100
+ ],
101
+ license: "MIT",
102
+ main: "build/cli.js",
103
+ module: "src/tui/index.tsx",
104
+ name: "@pensar/apex",
105
+ optionalDependencies: {
106
+ weave: "^0.12.1"
107
+ },
108
+ packageManager: "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
109
+ peerDependencies: {
110
+ typescript: "^5.9.3"
111
+ },
112
+ repository: {
113
+ type: "git",
114
+ url: "https://github.com/pensarai/apex.git"
115
+ },
116
+ scripts: {
117
+ build: "bun build src/cli.ts --outdir build --target node --format esm --splitting --external @opentui/core --external @opentui/react --external @opentui/react/* --external react --external react/jsx-runtime --external react/jsx-dev-runtime --external react-reconciler --external weave",
118
+ "build:binaries": "bun run generate:ascii && mkdir -p dist && bun run build:binary:macos-arm64 && bun run build:binary:macos-x64 && bun run build:binary:linux-x64 && bun run build:binary:linux-arm64",
119
+ "build:binary": "bun run generate:ascii && bun build src/cli.ts --compile --outfile pensar",
120
+ "build:binary:linux-arm64": "bun build src/cli.ts --compile --target=bun-linux-arm64 --outfile dist/pensar-linux-arm64",
121
+ "build:binary:linux-x64": "bun build src/cli.ts --compile --target=bun-linux-x64 --outfile dist/pensar-linux-x64",
122
+ "build:binary:macos-arm64": "bun build src/cli.ts --compile --target=bun-darwin-arm64 --outfile dist/pensar-darwin-arm64",
123
+ "build:binary:macos-x64": "bun build src/cli.ts --compile --target=bun-darwin-x64 --outfile dist/pensar-darwin-x64",
124
+ check: "biome check --write",
125
+ "check:ci": "biome check",
126
+ "daytona-benchmark": "bun run scripts/daytona-benchmark.ts",
127
+ dev: "bun run scripts/watch.ts",
128
+ "dev:debug": "SHOW_CONSOLE=true bun run scripts/watch.ts",
129
+ format: 'biome check --write && prettier --write "**/*.{md,yml,yaml}"',
130
+ "format:check": 'biome check && prettier --check "**/*.{md,yml,yaml}"',
131
+ "generate:ascii": "bun run scripts/generate-ascii-art.ts",
132
+ "generate:models": "bun run scripts/generate-models.ts",
133
+ knip: "knip",
134
+ lint: "biome lint src/",
135
+ "lint:fix": "biome lint --write src/",
136
+ "local-benchmark": "bun run scripts/local-benchmark.ts",
137
+ pensar: "node bin/pensar.js",
138
+ prepublishOnly: "npm run build",
139
+ start: "bun run src/tui/index.tsx",
140
+ test: "vitest run",
141
+ "test:watch": "vitest",
142
+ tsc: "tsc --noEmit"
143
+ },
144
+ type: "module",
145
+ version: "1.8.2-canary.fb75c486"
143
146
  };
144
147
 
148
+ // src/core/ai/index.ts
149
+ init_ai();
150
+ init_models();
151
+ init_utils();
152
+
153
+ // src/core/cli/pentestMode.ts
154
+ var SUPPORTED_PENTEST_MODES = ["exfil"];
155
+ function resolvePentestMode(mode) {
156
+ if (!mode) {
157
+ return { exfilMode: false };
158
+ }
159
+ if (mode === "exfil") {
160
+ return { exfilMode: true };
161
+ }
162
+ return {
163
+ exfilMode: false,
164
+ warning: `Warning: Unsupported --mode value "${mode}". Supported values: ${SUPPORTED_PENTEST_MODES.join(", ")}. Continuing in default mode.`
165
+ };
166
+ }
167
+
168
+ // src/core/eventBus.ts
169
+ import { EventEmitter } from "events";
170
+ var CHILD_BUS_FORWARD_POLICY = {
171
+ "text-delta": "forward",
172
+ "tool-call-start": "forward",
173
+ "tool-call-delta": "forward",
174
+ "tool-call-complete": "forward",
175
+ "tool-result": "forward",
176
+ "subagent-spawn": "forward",
177
+ "subagent-complete": "forward",
178
+ "step-finish": "forward",
179
+ "command-output": "forward",
180
+ error: "forward",
181
+ "trace-record": "forward",
182
+ "workflow-phase-start": "parent-only",
183
+ "workflow-phase-complete": "parent-only",
184
+ "app-analysis-progress": "parent-only"
185
+ };
186
+ var CHILD_BUS_FORWARDED_EVENTS = Object.keys(CHILD_BUS_FORWARD_POLICY).filter((key) => CHILD_BUS_FORWARD_POLICY[key] === "forward");
187
+
188
+ class AgentEventBus {
189
+ emitter = new EventEmitter;
190
+ constructor() {
191
+ this.emitter.setMaxListeners(50);
192
+ }
193
+ on(event, handler) {
194
+ this.emitter.on(event, handler);
195
+ return this;
196
+ }
197
+ once(event, handler) {
198
+ this.emitter.once(event, handler);
199
+ return this;
200
+ }
201
+ off(event, handler) {
202
+ this.emitter.off(event, handler);
203
+ return this;
204
+ }
205
+ emit(event, payload) {
206
+ return this.emitter.emit(event, payload);
207
+ }
208
+ removeAllListeners(event) {
209
+ if (event) {
210
+ this.emitter.removeAllListeners(event);
211
+ } else {
212
+ this.emitter.removeAllListeners();
213
+ }
214
+ return this;
215
+ }
216
+ static attachChild(child, parent, subagentId) {
217
+ if (!parent)
218
+ return;
219
+ for (const key of CHILD_BUS_FORWARDED_EVENTS) {
220
+ const forwardKey = key;
221
+ child.on(forwardKey, (payload) => {
222
+ const p = payload;
223
+ const isLifecycle = forwardKey === "subagent-spawn" || forwardKey === "subagent-complete";
224
+ if (isLifecycle) {
225
+ if (p.parentSubagentId) {
226
+ parent.emit(forwardKey, payload);
227
+ } else {
228
+ parent.emit(forwardKey, {
229
+ ...p,
230
+ parentSubagentId: subagentId
231
+ });
232
+ }
233
+ return;
234
+ }
235
+ if (!p.subagentId) {
236
+ parent.emit(forwardKey, { ...p, subagentId });
237
+ } else {
238
+ parent.emit(forwardKey, payload);
239
+ }
240
+ });
241
+ }
242
+ }
243
+ emitStreamPart(chunk, subagentId) {
244
+ switch (chunk.type) {
245
+ case "text-delta":
246
+ this.emit("text-delta", { text: chunk.text, subagentId });
247
+ break;
248
+ case "tool-input-start":
249
+ this.emit("tool-call-start", {
250
+ toolCallId: chunk.id,
251
+ toolName: chunk.toolName,
252
+ subagentId
253
+ });
254
+ break;
255
+ case "tool-input-delta":
256
+ this.emit("tool-call-delta", {
257
+ toolCallId: chunk.id,
258
+ argsTextDelta: chunk.delta,
259
+ subagentId
260
+ });
261
+ break;
262
+ case "tool-call": {
263
+ const tc = chunk;
264
+ this.emit("tool-call-complete", {
265
+ toolCallId: tc.toolCallId,
266
+ toolName: tc.toolName,
267
+ args: tc.args ?? tc.input,
268
+ subagentId
269
+ });
270
+ break;
271
+ }
272
+ case "tool-result": {
273
+ const tr = chunk;
274
+ this.emit("tool-result", {
275
+ toolCallId: tr.toolCallId,
276
+ toolName: tr.toolName,
277
+ result: tr.result ?? tr.output,
278
+ subagentId
279
+ });
280
+ break;
281
+ }
282
+ case "error":
283
+ this.emit("error", {
284
+ error: chunk.error,
285
+ subagentId
286
+ });
287
+ break;
288
+ }
289
+ }
290
+ }
291
+
145
292
  // src/core/installation/index.ts
293
+ init_package();
146
294
  import { spawnSync } from "child_process";
147
295
  function getCurrentVersion() {
148
296
  return package_default.version;
@@ -273,152 +421,10 @@ You can upgrade manually by running:
273
421
  };
274
422
  }
275
423
 
276
- // src/core/ai/utils.ts
277
- init_models();
278
- var STREAMING_FETCH_TIMEOUT_MS = 15 * 60 * 1000;
279
- function buildAuthConfig(cfg) {
280
- return {
281
- anthropicAPIKey: cfg.anthropicAPIKey ?? undefined,
282
- openAiAPIKey: cfg.openAiAPIKey ?? undefined,
283
- googleAPIKey: cfg.googleAPIKey ?? undefined,
284
- openRouterAPIKey: cfg.openRouterAPIKey ?? undefined,
285
- inceptionAPIKey: cfg.inceptionAPIKey ?? undefined,
286
- pensarAPIKey: cfg.pensarAPIKey ?? undefined,
287
- accessToken: cfg.accessToken ?? undefined,
288
- refreshToken: cfg.refreshToken ?? undefined,
289
- workspaceId: cfg.workspaceId ?? undefined,
290
- gatewaySigningKey: cfg.gatewaySigningKey ?? undefined,
291
- gatewayUrl: cfg.gatewayUrl ?? undefined,
292
- bedrock: cfg.bedrockAPIKey ? { apiKey: cfg.bedrockAPIKey } : undefined,
293
- local: cfg.localModelUrl ? { baseURL: cfg.localModelUrl } : undefined
294
- };
295
- }
296
-
297
- // src/core/cli/pentestMode.ts
298
- var SUPPORTED_PENTEST_MODES = ["exfil"];
299
- function resolvePentestMode(mode) {
300
- if (!mode) {
301
- return { exfilMode: false };
302
- }
303
- if (mode === "exfil") {
304
- return { exfilMode: true };
305
- }
306
- return {
307
- exfilMode: false,
308
- warning: `Warning: Unsupported --mode value "${mode}". Supported values: ${SUPPORTED_PENTEST_MODES.join(", ")}. Continuing in default mode.`
309
- };
310
- }
311
-
312
- // src/core/eventBus.ts
313
- import { EventEmitter } from "events";
314
- var CHILD_BUS_FORWARDED_EVENTS = [
315
- "text-delta",
316
- "tool-call-start",
317
- "tool-call-delta",
318
- "tool-call-complete",
319
- "tool-result",
320
- "subagent-spawn",
321
- "subagent-complete",
322
- "command-output",
323
- "error",
324
- "step-finish"
325
- ];
326
-
327
- class AgentEventBus {
328
- emitter = new EventEmitter;
329
- constructor() {
330
- this.emitter.setMaxListeners(50);
331
- }
332
- on(event, handler) {
333
- this.emitter.on(event, handler);
334
- return this;
335
- }
336
- once(event, handler) {
337
- this.emitter.once(event, handler);
338
- return this;
339
- }
340
- off(event, handler) {
341
- this.emitter.off(event, handler);
342
- return this;
343
- }
344
- emit(event, payload) {
345
- return this.emitter.emit(event, payload);
346
- }
347
- removeAllListeners(event) {
348
- if (event) {
349
- this.emitter.removeAllListeners(event);
350
- } else {
351
- this.emitter.removeAllListeners();
352
- }
353
- return this;
354
- }
355
- static attachChild(child, parent, subagentId) {
356
- for (const key of CHILD_BUS_FORWARDED_EVENTS) {
357
- child.on(key, (payload) => {
358
- if (!parent)
359
- return;
360
- const p = payload;
361
- if (!p.subagentId) {
362
- parent.emit(key, { ...p, subagentId });
363
- } else {
364
- parent.emit(key, payload);
365
- }
366
- });
367
- }
368
- }
369
- emitStreamPart(chunk, subagentId) {
370
- switch (chunk.type) {
371
- case "text-delta":
372
- this.emit("text-delta", { text: chunk.text, subagentId });
373
- break;
374
- case "tool-input-start":
375
- this.emit("tool-call-start", {
376
- toolCallId: chunk.id,
377
- toolName: chunk.toolName,
378
- subagentId
379
- });
380
- break;
381
- case "tool-input-delta":
382
- this.emit("tool-call-delta", {
383
- toolCallId: chunk.id,
384
- argsTextDelta: chunk.delta,
385
- subagentId
386
- });
387
- break;
388
- case "tool-call": {
389
- const tc = chunk;
390
- this.emit("tool-call-complete", {
391
- toolCallId: tc.toolCallId,
392
- toolName: tc.toolName,
393
- args: tc.args ?? tc.input,
394
- subagentId
395
- });
396
- break;
397
- }
398
- case "tool-result": {
399
- const tr = chunk;
400
- this.emit("tool-result", {
401
- toolCallId: tr.toolCallId,
402
- toolName: tr.toolName,
403
- result: tr.result ?? tr.output,
404
- subagentId
405
- });
406
- break;
407
- }
408
- case "error":
409
- this.emit("error", {
410
- error: chunk.error,
411
- subagentId
412
- });
413
- break;
414
- }
415
- }
416
- }
417
-
418
424
  // src/tui/utils/command-flags.ts
419
- init_toolset();
420
425
  import { readFileSync } from "fs";
421
- import { resolve, isAbsolute } from "path";
426
+ import { isAbsolute, resolve } from "path";
427
+ init_toolset();
422
428
  function combinePromptParts(threatModel, prompt) {
423
429
  const parts = [];
424
430
  if (threatModel)
@@ -496,12 +502,52 @@ async function createInstrumentedBus(session) {
496
502
  });
497
503
  return { bus, cleanup: async () => wandbCleanup?.() };
498
504
  }
505
+ async function resolveCliHeaders() {
506
+ const headerArgs = getAllArgs("--header");
507
+ const headersFromArg = getArg("--headers-from");
508
+ const noGlobal = hasFlag("--no-global-headers");
509
+ if (headerArgs.length === 0 && !headersFromArg && !noGlobal) {
510
+ return;
511
+ }
512
+ const { parseHeaderLine: parseHeaderLine2, parseHeadersFromFile, formatParseError: formatParseError2 } = await import("./parse-15kqmy2v.js");
513
+ const merged = {};
514
+ if (!noGlobal) {
515
+ const { config: appConfig } = await import("./index-cfberehw.js");
516
+ const cfg = await appConfig.get();
517
+ if (cfg.defaultHeaders) {
518
+ Object.assign(merged, cfg.defaultHeaders);
519
+ }
520
+ }
521
+ if (headersFromArg) {
522
+ const parsed = await parseHeadersFromFile(headersFromArg);
523
+ if (!parsed.ok) {
524
+ for (const err of parsed.error) {
525
+ console.error(`--headers-from error:
526
+ ${formatParseError2(err)}`);
527
+ }
528
+ process.exit(1);
529
+ }
530
+ for (const entry of parsed.value) {
531
+ merged[entry.name] = entry.value;
532
+ }
533
+ }
534
+ for (const arg of headerArgs) {
535
+ const parsed = parseHeaderLine2(arg);
536
+ if (!parsed.ok) {
537
+ console.error(`--header "${arg}" rejected:
538
+ ${formatParseError2(parsed.error)}`);
539
+ process.exit(1);
540
+ }
541
+ merged[parsed.value.name] = parsed.value.value;
542
+ }
543
+ return merged;
544
+ }
499
545
  async function resolveCliModel() {
500
546
  const explicit = getArg("--model");
501
547
  if (explicit)
502
548
  return explicit;
503
- const { config: appConfig } = await import("./index-e898mdyh.js");
504
- const { getDefaultModelForConfig } = await import("./utils-jf52rmrb.js");
549
+ const { config: appConfig } = await import("./index-cfberehw.js");
550
+ const { getDefaultModelForConfig } = await import("./utils-dh1t2r1e.js");
505
551
  const pensarConfig = await appConfig.get();
506
552
  const defaultModel = getDefaultModelForConfig(pensarConfig);
507
553
  if (!defaultModel) {
@@ -527,11 +573,12 @@ Usage:
527
573
  pensar threat-model [options] Generate application-centric threat model
528
574
  pensar login Connect to Pensar Console
529
575
  pensar uninstall Uninstall Pensar (keeps sessions, memories, skills)
530
- pensar projects List workspace projects
576
+ pensar apps Manage the attack surface (apps & endpoints)
531
577
  pensar pentests List and manage pentests
532
578
  pensar issues List and manage security issues
533
579
  pensar fixes View security fixes
534
580
  pensar logs View agent execution logs
581
+ pensar config headers Manage global default HTTP headers
535
582
  pensar upgrade Update pensar to the latest version
536
583
  pensar doctor Check dependencies and install missing tools
537
584
  pensar help Show this help message
@@ -542,6 +589,9 @@ operator options (-p):
542
589
  -s, --system <text|@file> Override the default system prompt
543
590
  --target <url> Target URL / domain / IP
544
591
  --model <model> AI model (default: auto-selected from configured provider)
592
+ --header "Name: Value" Custom HTTP header (repeatable)
593
+ --headers-from <file> Load headers from a JSON object or Name:Value file
594
+ --no-global-headers Skip the global defaultHeaders snapshot
545
595
 
546
596
  pentest options:
547
597
  --target <url> (required) Target URL / domain / IP
@@ -552,11 +602,17 @@ pentest options:
552
602
  --task-driven Enable task-driven architecture (experimental)
553
603
  --prompt <text|@file> Guidance for the pentest agent (inline text or @filepath)
554
604
  --threat-model <text|@file> Threat model to guide the pentest (inline or @filepath)
605
+ --header "Name: Value" Custom HTTP header (repeatable)
606
+ --headers-from <file> Load headers from a JSON object or Name:Value file
607
+ --no-global-headers Skip the global defaultHeaders snapshot
555
608
 
556
609
  targeted-pentest options:
557
610
  --target <url> (required) Target URL / domain / IP
558
611
  --objective <text> (required, repeatable) Testing objective
559
612
  --model <model> AI model (default: auto-selected from configured provider)
613
+ --header "Name: Value" Custom HTTP header (repeatable)
614
+ --headers-from <file> Load headers from a JSON object or Name:Value file
615
+ --no-global-headers Skip the global defaultHeaders snapshot
560
616
 
561
617
  threat-model options:
562
618
  --output, -o <path> Output file path (default: ./threat-model.md)
@@ -571,11 +627,11 @@ Global options:
571
627
  `);
572
628
  }
573
629
  async function runPentest() {
574
- const { config: config2 } = await import("./main-3d7dfdvs.js").then((m)=>__toESM(m.default,1));
575
- config2();
576
- const { runPentestAgent } = await import("./blackboxPentest-8ps4yvbk.js");
577
- const { sessions } = await import("./index-y5xpp21a.js");
578
- const { config: appConfig } = await import("./index-e898mdyh.js");
630
+ const { config } = await import("./main-3zneyg7p.js").then((m)=>__toESM(m.default,1));
631
+ config();
632
+ const { runPentestAgent } = await import("./blackboxPentest-b5741n3h.js");
633
+ const { sessions } = await import("./index-acc00eq4.js");
634
+ const { config: appConfig } = await import("./index-cfberehw.js");
579
635
  const target = getArgRequired("--target");
580
636
  const cwd = getArg("--cwd");
581
637
  const mode = getArg("--mode");
@@ -588,6 +644,7 @@ async function runPentest() {
588
644
  const prompt = combinePromptParts(resolvedTm, resolvedPrompt);
589
645
  const pensarConfig = await appConfig.get();
590
646
  const model = await resolveCliModel();
647
+ const headers = await resolveCliHeaders();
591
648
  const { exfilMode, warning: modeWarning } = resolvePentestMode(mode);
592
649
  if (modeWarning) {
593
650
  console.warn(modeWarning);
@@ -601,7 +658,8 @@ Cwd: ${cwd} (whitebox)` : ""}${exfilMode ? `
601
658
  Mode: exfil` : ""}
602
659
  Model: ${model}${enableThinking ? `
603
660
  Thinking: enabled` : ""}${taskDriven ? `
604
- Task-driven: enabled` : ""}
661
+ Task-driven: enabled` : ""}${headers ? `
662
+ Headers: ${Object.keys(headers).length} configured` : ""}
605
663
  `);
606
664
  const session = await sessions.create({
607
665
  name: cwd ? "Whitebox Pentest" : "Blackbox Pentest",
@@ -610,9 +668,11 @@ Task-driven: enabled` : ""}
610
668
  ...cwd ? { cwd } : {},
611
669
  ...exfilMode ? { exfilMode: true } : {},
612
670
  ...prompt ? { prompt } : {},
613
- ...taskDriven ? { taskDriven: true } : {}
671
+ ...taskDriven ? { taskDriven: true } : {},
672
+ ...headers !== undefined ? { headers } : {}
614
673
  }
615
674
  });
675
+ console.log(`PENSAR_SESSION_PATH:${session.rootPath}`);
616
676
  const { bus: pentestBus, cleanup: wandbCleanup } = await createInstrumentedBus(session);
617
677
  try {
618
678
  const { findings, findingsPath, pocsPath, reportPath } = await runPentestAgent({
@@ -621,6 +681,7 @@ Task-driven: enabled` : ""}
621
681
  session,
622
682
  model,
623
683
  enableThinking,
684
+ surfaceIntegrationEnabled: pensarConfig.surfaceIntegrationEnabled,
624
685
  authConfig: buildAuthConfig(pensarConfig),
625
686
  eventBus: pentestBus
626
687
  });
@@ -635,13 +696,14 @@ Report: ${reportPath}` : ""}`);
635
696
  } finally {
636
697
  await wandbCleanup();
637
698
  }
699
+ process.exit(0);
638
700
  }
639
701
  async function runTargetedPentest() {
640
- const { config: config2 } = await import("./main-3d7dfdvs.js").then((m)=>__toESM(m.default,1));
641
- config2();
642
- const { runTargetedPentestAgent } = await import("./targetedPentest-fs0v570s.js");
643
- const { sessions } = await import("./index-y5xpp21a.js");
644
- const { config: appConfig } = await import("./index-e898mdyh.js");
702
+ const { config } = await import("./main-3zneyg7p.js").then((m)=>__toESM(m.default,1));
703
+ config();
704
+ const { runTargetedPentestAgent } = await import("./targetedPentest-fjxqn089.js");
705
+ const { sessions } = await import("./index-acc00eq4.js");
706
+ const { config: appConfig } = await import("./index-cfberehw.js");
645
707
  const target = getArgRequired("--target");
646
708
  const objectives = getAllArgs("--objective");
647
709
  const pensarConfig = await appConfig.get();
@@ -661,10 +723,13 @@ Model: ${model}
661
723
  Objectives:
662
724
  ${objectivesList}
663
725
  `);
726
+ const headers = await resolveCliHeaders();
664
727
  const session = await sessions.create({
665
728
  name: "Targeted Pentest",
666
- targets: [target]
729
+ targets: [target],
730
+ ...headers !== undefined ? { config: { headers } } : {}
667
731
  });
732
+ console.log(`PENSAR_SESSION_PATH:${session.rootPath}`);
668
733
  const { bus: targetedBus, cleanup: wandbCleanup } = await createInstrumentedBus(session);
669
734
  try {
670
735
  const { findings, findingsPath, pocsPath } = await runTargetedPentestAgent({
@@ -685,12 +750,13 @@ POCs: ${pocsPath}`);
685
750
  } finally {
686
751
  await wandbCleanup();
687
752
  }
753
+ process.exit(0);
688
754
  }
689
755
  async function runThreatModel() {
690
- const { config: config2 } = await import("./main-3d7dfdvs.js").then((m)=>__toESM(m.default,1));
691
- config2();
692
- const { runThreatModelWorkflow } = await import("./threatModel-xfvc6cch.js");
693
- const { config: appConfig } = await import("./index-e898mdyh.js");
756
+ const { config } = await import("./main-3zneyg7p.js").then((m)=>__toESM(m.default,1));
757
+ config();
758
+ const { runThreatModelWorkflow } = await import("./threatModel-9yqx7d7x.js");
759
+ const { config: appConfig } = await import("./index-cfberehw.js");
694
760
  const path = await import("path");
695
761
  const pensarConfig = await appConfig.get();
696
762
  const model = await resolveCliModel();
@@ -724,16 +790,16 @@ ${sep}
724
790
  Threat model written to: ${resolvedPath}`);
725
791
  }
726
792
  async function runOperator() {
727
- const { config: config2 } = await import("./main-3d7dfdvs.js").then((m)=>__toESM(m.default,1));
728
- config2();
729
- const { runOffensiveSecurityAgent } = await import("./offesecAgent-re6kt2ff.js");
730
- const { sessions, normalizeMessages, getResumeMessages } = await import("./index-y5xpp21a.js");
731
- const { ALL_TOOL_NAMES, SKILL_TOOL_NAMES } = await import("./index-bz6f8jry.js");
732
- const { config: appConfig } = await import("./index-e898mdyh.js");
793
+ const { config } = await import("./main-3zneyg7p.js").then((m)=>__toESM(m.default,1));
794
+ config();
795
+ const { runOffensiveSecurityAgent } = await import("./offesecAgent-w9m0svwk.js");
796
+ const { sessions, normalizeMessages, getResumeMessages } = await import("./index-acc00eq4.js");
797
+ const { ALL_TOOL_NAMES, SKILL_TOOL_NAMES } = await import("./index-vwt27stc.js");
798
+ const { config: appConfig } = await import("./index-cfberehw.js");
733
799
  const { createInterface } = await import("readline");
734
800
  const { readFileSync: readFileSync2, existsSync } = await import("fs");
735
801
  const path = await import("path");
736
- const { stepCountIs } = await import("./index-dw1xbhfn.js");
802
+ const { stepCountIs } = await import("./index-vc29b21w.js");
737
803
  const promptRaw = getArg("-p") ?? getArg("--prompt");
738
804
  if (!promptRaw) {
739
805
  console.error("Error: -p <prompt> is required");
@@ -753,6 +819,7 @@ Model: ${model}${target ? `
753
819
  Target: ${target}` : ""}
754
820
  ${sep}
755
821
  `);
822
+ const headers = await resolveCliHeaders();
756
823
  const session = await sessions.create({
757
824
  name: "Operator Session",
758
825
  targets: target ? [target] : [],
@@ -763,7 +830,8 @@ ${sep}
763
830
  initialMode: "auto",
764
831
  requireApproval: false,
765
832
  enableSuggestions: false
766
- }
833
+ },
834
+ ...headers !== undefined ? { headers } : {}
767
835
  }
768
836
  });
769
837
  const { bus, cleanup: wandbCleanup } = await createInstrumentedBus(session);
@@ -841,29 +909,32 @@ if (hasFlag("-p") || command === "--prompt") {
841
909
  await runTargetedPentest();
842
910
  } else if (command === "login" || command === "auth") {
843
911
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
844
- await import("./auth-dxjgy41e.js");
912
+ await import("./auth-p4r1m7xq.js");
845
913
  } else if (command === "uninstall") {
846
914
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
847
- await import("./uninstall-qb2xbh2t.js");
848
- } else if (command === "projects") {
915
+ await import("./uninstall-9zbf4cwc.js");
916
+ } else if (command === "apps") {
849
917
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
850
- await import("./projects-qk22qcbt.js");
918
+ await import("./apps-t0gmwc7z.js");
851
919
  } else if (command === "pentests") {
852
920
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
853
- await import("./pentests-e3rj5845.js");
921
+ await import("./pentests-nq7wa8yb.js");
854
922
  } else if (command === "issues") {
855
923
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
856
- await import("./issues-qbmdneej.js");
924
+ await import("./issues-1bynat5q.js");
857
925
  } else if (command === "fixes") {
858
926
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
859
- await import("./fixes-q5bhgxhc.js");
927
+ await import("./fixes-60k3ts71.js");
860
928
  } else if (command === "logs") {
861
929
  process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
862
- await import("./logs-xm5vbymy.js");
930
+ await import("./logs-e78vx2dy.js");
931
+ } else if (command === "config") {
932
+ process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
933
+ await import("./config-3bvtf3j8.js");
863
934
  } else if (command === "threat-model") {
864
935
  await runThreatModel();
865
936
  } else if (command === "doctor") {
866
- const { runDoctor } = await import("./doctor-8tva8j99.js");
937
+ const { runDoctor } = await import("./doctor-2bkpddws.js");
867
938
  await runDoctor();
868
939
  } else if (args.length === 0) {
869
940
  if (process.env.PENSAR_NO_TUI === "1") {
@@ -871,7 +942,7 @@ if (hasFlag("-p") || command === "--prompt") {
871
942
  console.error("All other commands work with Node \u2014 run 'pensar --help'.");
872
943
  process.exit(1);
873
944
  }
874
- await import("./index-pfee23kv.js");
945
+ await import("./index-0gp3x2r8.js");
875
946
  } else {
876
947
  console.error(`Error: Unknown command '${command}'`);
877
948
  console.error();