@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
@@ -1,6 +1,29 @@
1
1
  import {
2
- OffensiveSecurityAgent
3
- } from "./cli-3w2syxpv.js";
2
+ ALL_TOOL_NAMES,
3
+ ASK_USER_QUESTIONS_TOOL_NAME,
4
+ OffensiveSecurityAgent,
5
+ SKILL_TOOL_NAMES,
6
+ buildBaseSystemPrompt,
7
+ sessions
8
+ } from "./cli-wfmdch3r.js";
9
+ import {
10
+ init_dist,
11
+ stepCountIs
12
+ } from "./cli-6p7d2k55.js";
13
+ import {
14
+ ensureValidToken,
15
+ getPensarApiUrl,
16
+ init_auth,
17
+ init_constants
18
+ } from "./cli-w5990vr6.js";
19
+ import {
20
+ exports_external1 as exports_external,
21
+ init_zod
22
+ } from "./cli-e6rgwtpb.js";
23
+ import {
24
+ config,
25
+ init_config
26
+ } from "./cli-9egg9azd.js";
4
27
  import {
5
28
  __commonJS,
6
29
  __require
@@ -1338,7 +1361,6 @@ var require_stringify = __commonJS((exports) => {
1338
1361
  nullStr: "null",
1339
1362
  simpleKeys: false,
1340
1363
  singleQuote: null,
1341
- trailingComma: false,
1342
1364
  trueStr: "true",
1343
1365
  verifyAliasOrder: true
1344
1366
  }, doc.schema.toStringOptions, options);
@@ -1847,20 +1869,13 @@ ${indent}${line}` : `
1847
1869
  if (comment)
1848
1870
  reqNewline = true;
1849
1871
  let str = stringify.stringify(item, itemCtx, () => comment = null);
1850
- reqNewline || (reqNewline = lines.length > linesAtValue || str.includes(`
1851
- `));
1852
- if (i < items.length - 1) {
1872
+ if (i < items.length - 1)
1853
1873
  str += ",";
1854
- } else if (ctx.options.trailingComma) {
1855
- if (ctx.options.lineWidth > 0) {
1856
- reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
1857
- }
1858
- if (reqNewline) {
1859
- str += ",";
1860
- }
1861
- }
1862
1874
  if (comment)
1863
1875
  str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
1876
+ if (!reqNewline && (lines.length > linesAtValue || str.includes(`
1877
+ `)))
1878
+ reqNewline = true;
1864
1879
  lines.push(str);
1865
1880
  linesAtValue = lines.length;
1866
1881
  }
@@ -4655,22 +4670,17 @@ var require_compose_node = __commonJS((exports) => {
4655
4670
  case "block-map":
4656
4671
  case "block-seq":
4657
4672
  case "flow-collection":
4658
- try {
4659
- node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4660
- if (anchor)
4661
- node.anchor = anchor.source.substring(1);
4662
- } catch (error) {
4663
- const message = error instanceof Error ? error.message : String(error);
4664
- onError(token, "RESOURCE_EXHAUSTION", message);
4665
- }
4673
+ node = composeCollection.composeCollection(CN, ctx, token, props, onError);
4674
+ if (anchor)
4675
+ node.anchor = anchor.source.substring(1);
4666
4676
  break;
4667
4677
  default: {
4668
4678
  const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`;
4669
4679
  onError(token, "UNEXPECTED_TOKEN", message);
4680
+ node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
4670
4681
  isSrcToken = false;
4671
4682
  }
4672
4683
  }
4673
- node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));
4674
4684
  if (anchor && node.anchor === "")
4675
4685
  onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
4676
4686
  if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
@@ -6920,6 +6930,329 @@ var require_public_api = __commonJS((exports) => {
6920
6930
  exports.parseDocument = parseDocument;
6921
6931
  exports.stringify = stringify;
6922
6932
  });
6933
+
6934
+ // src/core/api/apiClient.ts
6935
+ init_auth();
6936
+ init_config();
6937
+ init_constants();
6938
+ async function getAuthHeaders() {
6939
+ const cfg = await config.get();
6940
+ const validToken = await ensureValidToken({
6941
+ accessToken: cfg.accessToken,
6942
+ refreshToken: cfg.refreshToken,
6943
+ pensarAPIKey: cfg.pensarAPIKey
6944
+ });
6945
+ if (!validToken) {
6946
+ throw new Error("Not authenticated. Run `pensar login` to connect to Pensar Console.");
6947
+ }
6948
+ const headers = {
6949
+ "Content-Type": "application/json",
6950
+ Authorization: `Bearer ${validToken.token}`
6951
+ };
6952
+ if (cfg.workspaceId) {
6953
+ headers["X-Workspace-Id"] = cfg.workspaceId;
6954
+ }
6955
+ return headers;
6956
+ }
6957
+ async function apiRequest(method, path, body) {
6958
+ const baseUrl = getPensarApiUrl();
6959
+ const headers = await getAuthHeaders();
6960
+ const url = `${baseUrl}${path}`;
6961
+ const init = { method, headers };
6962
+ if (body !== undefined) {
6963
+ init.body = JSON.stringify(body);
6964
+ }
6965
+ const response = await fetch(url, init);
6966
+ if (!response.ok) {
6967
+ const text2 = await response.text();
6968
+ let message;
6969
+ try {
6970
+ const err = JSON.parse(text2);
6971
+ message = err.error ?? text2;
6972
+ } catch {
6973
+ message = text2;
6974
+ }
6975
+ throw new Error(`API error (${response.status}): ${message}`);
6976
+ }
6977
+ const text = await response.text();
6978
+ if (!text)
6979
+ return;
6980
+ return JSON.parse(text);
6981
+ }
6982
+
6983
+ // src/core/api/apps.ts
6984
+ async function listApps(opts) {
6985
+ const params = new URLSearchParams;
6986
+ if (opts?.limit !== undefined)
6987
+ params.set("limit", String(opts.limit));
6988
+ if (opts?.offset !== undefined)
6989
+ params.set("offset", String(opts.offset));
6990
+ const qs = params.toString();
6991
+ return apiRequest("GET", `/apps${qs ? `?${qs}` : ""}`);
6992
+ }
6993
+ async function getApp(appId) {
6994
+ return apiRequest("GET", `/apps/${appId}`);
6995
+ }
6996
+ async function createApp(data) {
6997
+ return apiRequest("POST", "/apps", data);
6998
+ }
6999
+ async function updateApp(appId, data) {
7000
+ return apiRequest("PATCH", `/apps/${appId}`, data);
7001
+ }
7002
+ async function deleteApp(appId) {
7003
+ return apiRequest("DELETE", `/apps/${appId}`);
7004
+ }
7005
+ async function listEndpoints(appId, filters) {
7006
+ const params = new URLSearchParams;
7007
+ if (filters?.type)
7008
+ params.set("type", filters.type);
7009
+ if (filters?.minRiskScore !== undefined) {
7010
+ params.set("minRiskScore", String(filters.minRiskScore));
7011
+ }
7012
+ if (filters?.limit !== undefined)
7013
+ params.set("limit", String(filters.limit));
7014
+ if (filters?.offset !== undefined) {
7015
+ params.set("offset", String(filters.offset));
7016
+ }
7017
+ const qs = params.toString();
7018
+ const path = `/apps/${appId}/endpoints${qs ? `?${qs}` : ""}`;
7019
+ return apiRequest("GET", path);
7020
+ }
7021
+ async function getEndpoint(endpointId) {
7022
+ return apiRequest("GET", `/endpoints/${endpointId}`);
7023
+ }
7024
+ async function createEndpoint(appId, data) {
7025
+ return apiRequest("POST", `/apps/${appId}/endpoints`, data);
7026
+ }
7027
+ async function updateEndpoint(endpointId, data) {
7028
+ return apiRequest("PATCH", `/endpoints/${endpointId}`, data);
7029
+ }
7030
+ async function deleteEndpoint(endpointId) {
7031
+ return apiRequest("DELETE", `/endpoints/${endpointId}`);
7032
+ }
7033
+ async function searchApps(query, opts) {
7034
+ const params = new URLSearchParams({ q: query });
7035
+ if (opts?.type)
7036
+ params.set("type", opts.type);
7037
+ if (opts?.limit !== undefined)
7038
+ params.set("limit", String(opts.limit));
7039
+ if (opts?.offset !== undefined)
7040
+ params.set("offset", String(opts.offset));
7041
+ return apiRequest("GET", `/search/apps?${params.toString()}`);
7042
+ }
7043
+ async function searchEndpoints(query, opts) {
7044
+ const params = new URLSearchParams({ q: query });
7045
+ if (opts?.applicationId)
7046
+ params.set("applicationId", opts.applicationId);
7047
+ if (opts?.type)
7048
+ params.set("type", opts.type);
7049
+ if (opts?.minRiskScore !== undefined) {
7050
+ params.set("minRiskScore", String(opts.minRiskScore));
7051
+ }
7052
+ if (opts?.authRequired !== undefined) {
7053
+ params.set("authRequired", opts.authRequired ? "true" : "false");
7054
+ }
7055
+ if (opts?.limit !== undefined)
7056
+ params.set("limit", String(opts.limit));
7057
+ if (opts?.offset !== undefined)
7058
+ params.set("offset", String(opts.offset));
7059
+ return apiRequest("GET", `/search/endpoints?${params.toString()}`);
7060
+ }
7061
+
7062
+ // src/core/api/issues.ts
7063
+ async function listScans() {
7064
+ return apiRequest("GET", "/pentests");
7065
+ }
7066
+ async function getScan(scanId) {
7067
+ return apiRequest("GET", `/pentests/${scanId}`);
7068
+ }
7069
+ async function dispatchPentest(opts) {
7070
+ return apiRequest("POST", "/pentests", opts);
7071
+ }
7072
+ async function listIssues(filters) {
7073
+ const params = new URLSearchParams;
7074
+ if (filters?.scanId)
7075
+ params.set("scanId", filters.scanId);
7076
+ if (filters?.status)
7077
+ params.set("status", filters.status);
7078
+ if (filters?.severity)
7079
+ params.set("severity", filters.severity);
7080
+ if (filters?.branch)
7081
+ params.set("branch", filters.branch);
7082
+ const qs = params.toString();
7083
+ const path = `/issues${qs ? `?${qs}` : ""}`;
7084
+ return apiRequest("GET", path);
7085
+ }
7086
+ async function getIssue(issueId) {
7087
+ return apiRequest("GET", `/issues/${issueId}`);
7088
+ }
7089
+ async function updateIssue(issueId, data) {
7090
+ return apiRequest("PATCH", `/issues/${issueId}`, data);
7091
+ }
7092
+ async function listFixes(issueId) {
7093
+ return apiRequest("GET", `/issues/${issueId}/fixes`);
7094
+ }
7095
+ async function getFix(fixId) {
7096
+ return apiRequest("GET", `/fixes/${fixId}`);
7097
+ }
7098
+ async function listAgentLogs(issueId, opts) {
7099
+ const params = new URLSearchParams;
7100
+ if (opts?.level)
7101
+ params.set("level", opts.level);
7102
+ if (opts?.role)
7103
+ params.set("role", opts.role);
7104
+ if (opts?.limit)
7105
+ params.set("limit", String(opts.limit));
7106
+ const qs = params.toString();
7107
+ const path = `/issues/${issueId}/logs${qs ? `?${qs}` : ""}`;
7108
+ return apiRequest("GET", path);
7109
+ }
7110
+ async function searchAgentLogs(issueId, query, opts) {
7111
+ return apiRequest("POST", `/issues/${issueId}/logs/search`, { query, ...opts });
7112
+ }
7113
+
7114
+ // src/core/api/index.ts
7115
+ init_constants();
7116
+
7117
+ // src/core/agents/specialized/environment/prompts.ts
7118
+ var PREAMBLE = `You are an expert DevOps agent responsible for setting up and validating development environments. Your goal is to ensure the application can run fully with all required services operational and healthy.`;
7119
+ var DOCKER_COMPOSE_STEP = `1. **Docker Compose Assessment**
7120
+ - First, check if a docker-compose.yml or docker-compose.yaml file exists in the repository
7121
+ - If present, thoroughly review its configuration:
7122
+ * Verify all services are properly defined
7123
+ * Check for proper networking configuration
7124
+ * Validate volume mounts and environment variables
7125
+ * Ensure health checks are configured where appropriate
7126
+ - If not present, analyze the application to determine if Docker Compose is required:
7127
+ * Check for databases (PostgreSQL, MySQL, MongoDB, Redis, etc.)
7128
+ * Look for message queues (RabbitMQ, Kafka, etc.)
7129
+ * Identify cache layers or other external dependencies
7130
+ * Review application configuration files for service dependencies`;
7131
+ var DOCKER_COMPOSE_CREATION_STEP = `2. **Docker Compose Creation (if required but missing)**
7132
+ - Analyze package.json, requirements.txt, go.mod, or other dependency files
7133
+ - Identify database and service requirements from:
7134
+ * Environment variable examples (.env.example, .env.sample)
7135
+ * Configuration files
7136
+ * Database connection strings in code
7137
+ * Documentation (README.md, docs/)
7138
+ - Create a comprehensive docker-compose.yml that includes:
7139
+ * All required services (databases, caches, message queues, etc.)
7140
+ * Proper service networking
7141
+ * Volume mounts for data persistence
7142
+ * Health checks for each service
7143
+ * Appropriate environment variables
7144
+ * Dependency ordering (depends_on with conditions)`;
7145
+ var STARTUP_STEP = `3. **Environment Startup & Validation**
7146
+ - Use docker-compose to bring up all services
7147
+ - Monitor startup logs for errors
7148
+ - Wait for all health checks to pass
7149
+ - Verify service accessibility:
7150
+ * Check database connectivity
7151
+ * Verify ports are properly exposed and accessible
7152
+ * Test inter-service communication
7153
+ - If the application itself needs to run, start it and ensure it connects to all services`;
7154
+ var TROUBLESHOOTING_STEP = `4. **Iteration & Troubleshooting**
7155
+ - If any service fails to start or becomes unhealthy:
7156
+ * Analyze logs to identify the root cause
7157
+ * Fix configuration issues (ports, environment variables, volumes, etc.)
7158
+ * Update the docker-compose.yml as needed
7159
+ * Recreate and restart affected services
7160
+ - Continue iterating until:
7161
+ * All services are running and healthy
7162
+ * The application can successfully connect to all dependencies
7163
+ * No error logs indicate configuration issues`;
7164
+ var AUTH_STEP = `5. **Authentication Testing & Documentation**
7165
+ - After the application is running, thoroughly investigate authentication:
7166
+ * Check the codebase for authentication mechanisms (JWT, sessions, OAuth, etc.)
7167
+ * Identify registration/signup endpoints and methods
7168
+ * Identify login/authentication endpoints
7169
+ * Look for initial admin user creation or seed data scripts
7170
+ * Review documentation (README.md, API docs) for auth instructions
7171
+ - Test the authentication flow:
7172
+ * Attempt to register a new user (via API, CLI, or web interface)
7173
+ * Try to login with the registered credentials
7174
+ * Verify that authentication tokens/sessions are properly issued
7175
+ * Test accessing a protected endpoint to confirm auth is working
7176
+ - Document your findings:
7177
+ * Step-by-step instructions for registering a new user
7178
+ * Step-by-step instructions for authenticating/logging in
7179
+ * Any default credentials that exist
7180
+ * API endpoints for registration and login (including HTTP methods and payload format)
7181
+ * Authentication method used (bearer tokens, cookies, etc.)
7182
+ * Example curl commands or code snippets for registration and login
7183
+ * Any prerequisites or special configuration needed for auth to work`;
7184
+ var COMPLETION_STEP = `6. **Completion**
7185
+ - Once the environment is fully operational and authentication has been tested:
7186
+ * Verify all services are accessible
7187
+ * Note the URL where the application is running (if applicable)
7188
+ * Use the response tool with:
7189
+ - status: "ready" if successful
7190
+ - status: "failed" if unable to establish a working environment after extensive attempts
7191
+ - url: the URL where the application is accessible (or empty string if not applicable)
7192
+ - authenticationDetails: comprehensive details on how to register and authenticate, including tested examples`;
7193
+ var TOOL_USAGE = `## Available Tools
7194
+
7195
+ - **execute_command**: Run shell commands (docker-compose, curl, database clients, etc.)
7196
+ - **list_files**: List files in directories to explore the repository structure
7197
+ - **read_file**: Read file contents to understand configurations and dependencies
7198
+ - **grep**: Search for patterns across the codebase
7199
+ - **create_file**: Create new files (like docker-compose.yml)
7200
+ - **update_file**: Update existing files to fix configurations
7201
+ - **response**: Call this when the environment is ready or has failed after extensive attempts`;
7202
+ var BEST_PRACTICES = `## Best Practices
7203
+
7204
+ - Always check for existing configuration before creating new files
7205
+ - Use health checks to properly wait for services to be ready
7206
+ - Check logs thoroughly when services fail
7207
+ - For databases, ensure proper initialization scripts are run
7208
+ - Consider startup order - databases should be healthy before apps connect
7209
+ - Test connectivity explicitly (ping, curl, database client connections)
7210
+ - Be thorough but efficient - don't repeat failed attempts without changes`;
7211
+ var IMPORTANT_NOTES = `## Important Notes
7212
+
7213
+ - You have up to 1000 steps to complete this task
7214
+ - Always provide clear reasoning for your decisions
7215
+ - Document any assumptions you make about the application's requirements
7216
+ - If you cannot determine requirements from the codebase, make reasonable defaults
7217
+ - Prioritize getting a working environment over perfect configuration
7218
+
7219
+ STOP when you have called the response tool with status "ready" or "failed"`;
7220
+ function buildEnvironmentSystemPrompt() {
7221
+ return [
7222
+ PREAMBLE,
7223
+ "",
7224
+ "## Core Responsibilities",
7225
+ "",
7226
+ DOCKER_COMPOSE_STEP,
7227
+ "",
7228
+ DOCKER_COMPOSE_CREATION_STEP,
7229
+ "",
7230
+ STARTUP_STEP,
7231
+ "",
7232
+ TROUBLESHOOTING_STEP,
7233
+ "",
7234
+ AUTH_STEP,
7235
+ "",
7236
+ COMPLETION_STEP,
7237
+ "",
7238
+ TOOL_USAGE,
7239
+ "",
7240
+ BEST_PRACTICES,
7241
+ "",
7242
+ IMPORTANT_NOTES
7243
+ ].join(`
7244
+ `);
7245
+ }
7246
+ var ENVIRONMENT_SYSTEM_PROMPT = buildEnvironmentSystemPrompt();
7247
+
7248
+ // src/core/agents/specialized/environment/types.ts
7249
+ init_zod();
7250
+ var EnvironmentResultSchema = exports_external.object({
7251
+ url: exports_external.string().describe("The URL where the application is accessible"),
7252
+ status: exports_external.enum(["ready", "failed"]).describe("The status of the development environment"),
7253
+ stepsTaken: exports_external.string().describe("The steps taken to start the development environment"),
7254
+ authenticationDetails: exports_external.string().describe("Details on how to register a user and authenticate within the development environment")
7255
+ });
6923
7256
  // src/core/api/offesecAgent.ts
6924
7257
  async function runOffensiveSecurityAgent(input) {
6925
7258
  const agent = input.session ? new OffensiveSecurityAgent(input) : await OffensiveSecurityAgent.create(input);
@@ -6927,6 +7260,190 @@ async function runOffensiveSecurityAgent(input) {
6927
7260
  await agent.consume();
6928
7261
  return { streamResult: agent.streamResult, session: agent.session };
6929
7262
  }
7263
+ // src/core/agents/specialized/patching/prompts.ts
7264
+ var PREAMBLE2 = `You are an expert security vulnerability patching agent. Your goal is to analyze security vulnerabilities, provide high-quality fixes, and verify the fixes don't break existing functionality.`;
7265
+ var ORIENT_STEP = `1. **Orient Yourself**:
7266
+ - Review the AGENTS.md / project documentation provided in your prompt for build, lint, and test commands
7267
+ - Use list_files to explore the repository structure
7268
+ - Read package.json, Makefile, or equivalent to understand the project's toolchain
7269
+ - Identify the lint command, test command, type-check command, and any other verification scripts`;
7270
+ var UNDERSTAND_STEP = `2. **Understand the Vulnerability**:
7271
+ - Carefully read the vulnerability description, CWE mappings, and any dataflow analysis provided
7272
+ - Understand the root cause: What makes this code vulnerable?
7273
+ - Identify the attack vector: How would an attacker exploit this?
7274
+ - Consider the context: What is the application trying to do?`;
7275
+ var REVIEW_STEP = `3. **Review the Code**:
7276
+ - Use read_file to read the vulnerable file(s) mentioned in the issue
7277
+ - Use grep to search for related code patterns, similar vulnerabilities, or existing security controls
7278
+ - Review related files: imports, dependencies, configuration files
7279
+ - Understand the data flow: Where does user input come from? Where does it go?`;
7280
+ var PLAN_STEP = `4. **Plan Your Fix**:
7281
+ - Identify the exact code that needs to change
7282
+ - Determine the appropriate security control (input validation, parameterized queries, access control, etc.)
7283
+ - Consider side effects: Will this break existing functionality?
7284
+ - Think about edge cases: What other inputs or scenarios need to be handled?
7285
+ - Look for framework-specific or language-specific best practices
7286
+ - State your complete plan clearly before making changes`;
7287
+ var APPLY_STEP = `5. **Apply the Patch**:
7288
+ - Use update_file to modify existing files with your security fixes
7289
+ - Use create_file if you need to add new security utilities or middleware
7290
+ - Make minimal, targeted changes — don't refactor unrelated code
7291
+ - Follow the existing code style and conventions
7292
+ - Ensure your changes integrate cleanly with the existing codebase`;
7293
+ var RESTART_STEP = `6. **Restart Dev Environment** (if applicable):
7294
+ - Use execute_command to restart any dev servers or services so your changes are loaded
7295
+ - Wait for the services to become healthy`;
7296
+ var VERIFY_STEP = `7. **Verify the Patch**:
7297
+ - Use execute_command to run the project's lint command (e.g. \`npm run lint\`, \`ruff check\`, \`cargo clippy\`)
7298
+ - Use execute_command to run the project's type-check command if applicable (e.g. \`npx tsc --noEmit\`, \`mypy\`)
7299
+ - Use execute_command to run the project's test suite (e.g. \`npm test\`, \`pytest\`, \`cargo test\`)
7300
+ - If a Proof of Concept (POC) is provided, run it to verify the vulnerability is fixed — the POC should FAIL (non-zero exit code) after a successful patch
7301
+ - If any check fails, read the error output carefully, fix the issues, and re-run until all checks pass
7302
+ - If the project has no clear lint/test commands, at minimum verify the changed files parse correctly (e.g. \`node -c file.js\`, \`python -m py_compile file.py\`)`;
7303
+ var FINALIZE_STEP = `8. **Finalize**:
7304
+ - Use the response tool to complete the patching process
7305
+ - Provide a clear, detailed summary of:
7306
+ * Each file you changed and why
7307
+ * The security principles applied
7308
+ * How your fix addresses the vulnerability
7309
+ * Verification results (lint, type-check, test outcomes, POC result if applicable)
7310
+ * Any assumptions or limitations of the fix
7311
+ - Write a professional PR title and description that explains the security fix`;
7312
+ var SECURITY_BEST_PRACTICES = `# Security Best Practices by Vulnerability Type
7313
+
7314
+ **SQL Injection / NoSQL Injection**:
7315
+ - Use parameterized queries or prepared statements ALWAYS
7316
+ - Use ORM query builders with parameterization
7317
+ - Never concatenate user input into queries
7318
+ - Validate and sanitize input as a defense-in-depth measure
7319
+
7320
+ **Cross-Site Scripting (XSS)**:
7321
+ - Use framework-provided output encoding (React JSX, template engines with auto-escaping)
7322
+ - Apply context-appropriate encoding (HTML, JavaScript, URL, CSS)
7323
+ - Use Content Security Policy headers
7324
+ - Sanitize rich text input with allowlist-based libraries
7325
+
7326
+ **Path Traversal / Directory Traversal**:
7327
+ - Validate file paths against an allowlist
7328
+ - Use path normalization and canonicalization
7329
+ - Check that resolved paths stay within intended directories
7330
+ - Never trust user input for file paths
7331
+
7332
+ **Authentication / Authorization Issues**:
7333
+ - Verify user identity before sensitive operations
7334
+ - Check permissions at the application layer, not just UI
7335
+ - Use framework authentication middleware
7336
+ - Implement proper session management
7337
+ - Follow principle of least privilege
7338
+
7339
+ **Command Injection**:
7340
+ - Avoid executing shell commands with user input
7341
+ - Use language-specific APIs instead of shell commands
7342
+ - If shell execution is necessary, use safe APIs with argument arrays
7343
+ - Validate input against strict allowlists
7344
+
7345
+ **Insecure Deserialization**:
7346
+ - Avoid deserializing untrusted data
7347
+ - Use safe data formats (JSON instead of pickle/Java serialization)
7348
+ - Implement integrity checks (HMAC signatures)
7349
+ - Validate deserialized objects strictly
7350
+
7351
+ **Server-Side Request Forgery (SSRF)**:
7352
+ - Validate and sanitize URLs
7353
+ - Use allowlists for allowed domains/IPs
7354
+ - Disable URL redirects or validate redirect targets
7355
+ - Block access to internal/private IP ranges
7356
+
7357
+ **Cryptographic Issues**:
7358
+ - Use strong, modern algorithms (AES-256, RSA-2048+, SHA-256+)
7359
+ - Never implement custom cryptography
7360
+ - Use cryptographically secure random number generators
7361
+ - Properly handle keys (don't hardcode, use key management)
7362
+
7363
+ **Sensitive Data Exposure**:
7364
+ - Don't log sensitive data (passwords, tokens, PII)
7365
+ - Use proper error handling that doesn't leak implementation details
7366
+ - Encrypt sensitive data at rest and in transit
7367
+ - Remove sensitive data from client-side code`;
7368
+ var TOOL_USAGE2 = `# Tool Usage
7369
+
7370
+ - **list_files**: Explore directory structure and find relevant files
7371
+ - **read_file**: Read file contents to understand code
7372
+ - **grep**: Search for patterns across the codebase
7373
+ - **update_file**: Modify existing files with security fixes
7374
+ - **create_file**: Create new files if needed (utilities, middleware, etc.)
7375
+ - **execute_command**: Run shell commands — use for linting, type-checking, running tests, restarting services, running POCs, installing dependencies, and verifying your changes
7376
+ - **response**: Complete the process with the structured patch result`;
7377
+ var REQUIREMENTS = `# Critical Requirements
7378
+
7379
+ 1. **Be Thorough**: Your analysis must be comprehensive — read related code, not just the vulnerable file
7380
+ 2. **Be Conservative**: When in doubt, prefer defense-in-depth approaches
7381
+ 3. **Be Specific**: Provide exact code changes, not vague suggestions
7382
+ 4. **Be Contextual**: Respect the existing codebase, frameworks, and patterns
7383
+ 5. **Verify Your Work**: Always run lint, type-check, and tests after applying the patch. Fix any failures before finalizing.
7384
+ 6. **Test the Fix**: If a POC is provided, run it after patching. The POC should FAIL (non-zero exit code) once the vulnerability is fixed.
7385
+ 7. **Be Persistent**: It may take multiple iterations to get the fix right — iterate until the POC fails and tests pass.
7386
+ 8. **Be Complete**: Address the root cause, not just symptoms
7387
+
7388
+ # Important Notes
7389
+
7390
+ - You are creating production code that will be deployed
7391
+ - Your fixes must not break existing functionality — verify this by running the project's tests
7392
+ - If a POC is provided, the POC should FAIL after patching (meaning the exploit no longer works)
7393
+ - Consider backward compatibility and edge cases
7394
+ - Follow language and framework conventions
7395
+ - When multiple approaches exist, choose the most secure and idiomatic
7396
+ - If a fix requires configuration changes or environment variables, note this clearly
7397
+ - If AGENTS.md or project docs specify particular lint/test/build commands, use those exact commands`;
7398
+ function buildSystemPrompt() {
7399
+ return [
7400
+ PREAMBLE2,
7401
+ "",
7402
+ "# Process",
7403
+ "",
7404
+ "You MUST follow this prescriptive process:",
7405
+ "",
7406
+ ORIENT_STEP,
7407
+ "",
7408
+ UNDERSTAND_STEP,
7409
+ "",
7410
+ REVIEW_STEP,
7411
+ "",
7412
+ PLAN_STEP,
7413
+ "",
7414
+ APPLY_STEP,
7415
+ "",
7416
+ RESTART_STEP,
7417
+ "",
7418
+ VERIFY_STEP,
7419
+ "",
7420
+ FINALIZE_STEP,
7421
+ "",
7422
+ SECURITY_BEST_PRACTICES,
7423
+ "",
7424
+ TOOL_USAGE2,
7425
+ "",
7426
+ REQUIREMENTS
7427
+ ].join(`
7428
+ `);
7429
+ }
7430
+ var PATCHING_SYSTEM_PROMPT = buildSystemPrompt();
7431
+
7432
+ // src/core/agents/specialized/patching/types.ts
7433
+ init_zod();
7434
+ var PatchResultSchema = exports_external.object({
7435
+ filesChanged: exports_external.array(exports_external.object({
7436
+ filePath: exports_external.string().describe("Path to the file that was changed"),
7437
+ changesDescription: exports_external.string().describe("Detailed description of the changes made to the file")
7438
+ })),
7439
+ prTitle: exports_external.string().describe("Title for the pull request"),
7440
+ prDescription: exports_external.string().describe("Description for the pull request")
7441
+ });
7442
+ // src/core/workflows/threatModel.ts
7443
+ init_dist();
7444
+
7445
+ // src/core/skills/registry.ts
7446
+ import fs2 from "fs/promises";
6930
7447
 
6931
7448
  // src/core/skills/builtins/pentest.ts
6932
7449
  function buildPentestPrompt(opts) {
@@ -7380,12 +7897,8 @@ IMPORTANT: When writing the output, use the \`create_file\` tool with the EXACT
7380
7897
  `
7381
7898
  };
7382
7899
 
7383
- // src/core/skills/registry.ts
7384
- import fs2 from "fs/promises";
7385
-
7386
- // src/core/skills/scanner.ts
7387
- import path2 from "path";
7388
- import fs from "fs/promises";
7900
+ // src/core/skills/builtins/index.ts
7901
+ var BUILTIN_SKILLS = [pentestSkill, threatModelSkill];
7389
7902
 
7390
7903
  // node_modules/yaml/dist/index.js
7391
7904
  var composer = require_composer();
@@ -7501,6 +8014,10 @@ function parseSkillMd(raw) {
7501
8014
  return { manifest, instructions: parts.body };
7502
8015
  }
7503
8016
 
8017
+ // src/core/skills/scanner.ts
8018
+ import fs from "fs/promises";
8019
+ import path2 from "path";
8020
+
7504
8021
  // src/core/skills/utils.ts
7505
8022
  import os from "os";
7506
8023
  import path from "path";
@@ -7575,9 +8092,6 @@ async function discoverScripts(skillDir) {
7575
8092
  return scripts;
7576
8093
  }
7577
8094
 
7578
- // src/core/skills/builtins/index.ts
7579
- var BUILTIN_SKILLS = [pentestSkill, threatModelSkill];
7580
-
7581
8095
  // src/core/skills/registry.ts
7582
8096
  class SkillsRegistry {
7583
8097
  skills = new Map;
@@ -7647,4 +8161,41 @@ function createSkillsRegistry() {
7647
8161
  return new SkillsRegistry;
7648
8162
  }
7649
8163
 
7650
- export { runOffensiveSecurityAgent, buildPentestPrompt, buildThreatModelPrompt, createSkillsRegistry };
8164
+ // src/core/workflows/threatModel.ts
8165
+ var HEADLESS_TOOL_NAMES = ALL_TOOL_NAMES.filter((name) => name !== ASK_USER_QUESTIONS_TOOL_NAME);
8166
+ async function runThreatModelWorkflow(input) {
8167
+ const model = input.model ?? "claude-sonnet-4-5";
8168
+ const registry = createSkillsRegistry();
8169
+ await registry.load({ projectRoot: input.codebasePath });
8170
+ const { content } = await registry.readSkillContent("threat-model");
8171
+ const prompt = buildThreatModelPrompt({
8172
+ outputPath: input.outputPath,
8173
+ codebasePath: input.codebasePath,
8174
+ skillContent: content
8175
+ });
8176
+ const session = input.session ?? await sessions.create({
8177
+ name: "Threat Model",
8178
+ targets: [input.codebasePath],
8179
+ config: { mode: "operator", agentCwd: input.codebasePath }
8180
+ });
8181
+ const system = `${buildBaseSystemPrompt({ sandboxMode: false })}
8182
+
8183
+ # Threat Model Mode
8184
+
8185
+ You are generating an application-centric threat model from source code analysis.
8186
+ Working directory: ${input.codebasePath}`;
8187
+ await runOffensiveSecurityAgent({
8188
+ system,
8189
+ prompt,
8190
+ model,
8191
+ session,
8192
+ activeTools: [...HEADLESS_TOOL_NAMES, ...SKILL_TOOL_NAMES],
8193
+ authConfig: input.authConfig,
8194
+ abortSignal: input.abortSignal,
8195
+ skillsRegistry: registry,
8196
+ eventBus: input.eventBus,
8197
+ stopWhen: stepCountIs(1e4)
8198
+ });
8199
+ return { session, outputPath: input.outputPath };
8200
+ }
8201
+ export { listApps, getApp, createApp, updateApp, deleteApp, listEndpoints, getEndpoint, createEndpoint, updateEndpoint, deleteEndpoint, searchApps, searchEndpoints, listScans, getScan, dispatchPentest, listIssues, getIssue, updateIssue, listFixes, getFix, listAgentLogs, searchAgentLogs, runOffensiveSecurityAgent, buildPentestPrompt, buildThreatModelPrompt, createSkillsRegistry, runThreatModelWorkflow };