@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,61 +0,0 @@
1
- import {
2
- exports_external1 as exports_external,
3
- init_zod
4
- } from "./cli-0ghkg3w6.js";
5
-
6
- // src/core/agents/specialized/whiteboxAttackSurface/types.ts
7
- init_zod();
8
- var RiskScoreBreakdownSchema = exports_external.object({
9
- exposure: exports_external.number().min(0).max(3).describe("Exposure Level (0-3): 3=Public no auth, 2=Standard user login, 1=Privileged/admin access, 0=Private/internal-only"),
10
- dataSensitivity: exports_external.number().min(0).max(3).describe("Data Sensitivity (0-3): 3=PII/PHI/financial/passwords/tokens, 2=Business operations/configs, 1=Low-value user data, 0=No meaningful data"),
11
- functionCriticality: exports_external.number().min(0).max(2).describe("Function Criticality (0-2): 2=Auth flows/payments/state-changing mutations, 1=Core product functionality, 0=Non-critical content"),
12
- securityIndicators: exports_external.number().min(0).max(2).describe("Security Indicators (0-2): 2=Critical vuln patterns (SQLi, command injection, hardcoded secrets), 1=Moderate concerns (missing validation, weak error handling), 0=No obvious issues")
13
- });
14
- var RiskScoreSchema = exports_external.object({
15
- score: exports_external.number().min(0).max(10).describe("Total risk score (0-10)"),
16
- explanation: exports_external.string().describe("Justification for the risk score"),
17
- breakdown: RiskScoreBreakdownSchema
18
- });
19
- var EndpointSchema = exports_external.object({
20
- method: exports_external.string().describe("HTTP method (GET, POST, PUT, DELETE, etc.) or 'PAGE' for web pages"),
21
- path: exports_external.string().describe("Route path (e.g. /api/users/:id, /dashboard)"),
22
- handler: exports_external.string().optional().describe("Handler function or component name, if identifiable"),
23
- file: exports_external.string().describe("File where this endpoint is defined"),
24
- line: exports_external.number().optional().describe("Line number in the file"),
25
- authRequired: exports_external.boolean().optional().describe("Whether this endpoint appears to require authentication"),
26
- description: exports_external.string().optional().describe("Brief description of what this endpoint does"),
27
- pentestObjectives: exports_external.array(exports_external.string()).default([]).describe("Pentest objectives for this endpoint, derived from the threat model when available " + "(e.g. 'Test for IDOR by enumerating user IDs', 'Test for SQL injection in search parameter')"),
28
- riskScore: RiskScoreSchema.optional().describe("AI-calculated risk score for prioritizing pentest efforts"),
29
- threatModel: exports_external.string().optional().describe("Endpoint-specific threat model describing attack vectors, data sensitivity, and testing priorities")
30
- });
31
- var AppSchema = exports_external.object({
32
- name: exports_external.string().describe("Application or service name"),
33
- type: exports_external.enum([
34
- "web_application",
35
- "api",
36
- "full_stack",
37
- "domain",
38
- "subdomain",
39
- "database",
40
- "cloud_resource",
41
- "storage"
42
- ]).default("web_application").describe("Type of application (web_application, api, full_stack, database, cloud_resource, storage, etc.)"),
43
- framework: exports_external.string().describe("Framework in use (e.g. Express, Next.js, Django, FastAPI, Rails)"),
44
- description: exports_external.string().describe("Brief description of what this app does"),
45
- location: exports_external.string().describe("Path to the app root relative to the repository root"),
46
- pages: exports_external.array(EndpointSchema).describe("Web pages / views defined in this app"),
47
- apiEndpoints: exports_external.array(EndpointSchema).describe("API endpoints defined in this app")
48
- });
49
- var WhiteboxAttackSurfaceResultSchema = exports_external.object({
50
- repoType: exports_external.string().describe("Repository structure type (e.g. 'monorepo', 'single-app', 'multi-package')"),
51
- packageManager: exports_external.string().describe("Package manager detected (e.g. npm, yarn, pnpm, pip, cargo, go modules)"),
52
- apps: exports_external.array(AppSchema).describe("All applications discovered in the repository"),
53
- summary: exports_external.object({
54
- totalApps: exports_external.number(),
55
- totalPages: exports_external.number(),
56
- totalApiEndpoints: exports_external.number(),
57
- totalPentestObjectives: exports_external.number()
58
- })
59
- });
60
-
61
- export { EndpointSchema, WhiteboxAttackSurfaceResultSchema };
@@ -1,110 +0,0 @@
1
- import {
2
- get,
3
- init,
4
- update
5
- } from "./cli-nr1cjfr9.js";
6
-
7
- // src/core/api/constants.ts
8
- var PENSAR_API_BASE_URL = "https://api.pensar.dev";
9
- var PENSAR_GATEWAY_BASE_URL = "https://gateway.pensar.dev";
10
- var PENSAR_CONSOLE_BASE_URL = "https://console.pensar.dev";
11
- function getPensarApiUrl() {
12
- return process.env.PENSAR_API_URL || PENSAR_API_BASE_URL;
13
- }
14
- function getPensarGatewayUrl() {
15
- return process.env.PENSAR_GATEWAY_URL || PENSAR_GATEWAY_BASE_URL;
16
- }
17
- function getPensarConsoleUrl() {
18
- return process.env.PENSAR_CONSOLE_URL || PENSAR_CONSOLE_BASE_URL;
19
- }
20
-
21
- // src/core/config/index.ts
22
- var config = {
23
- get,
24
- init,
25
- update
26
- };
27
-
28
- // src/core/auth/token.ts
29
- function decodeJwtPayload(token) {
30
- try {
31
- const parts = token.split(".");
32
- if (parts.length !== 3)
33
- return null;
34
- const payload = Buffer.from(parts[1], "base64url").toString("utf-8");
35
- return JSON.parse(payload);
36
- } catch {
37
- return null;
38
- }
39
- }
40
- function isTokenExpired(token, bufferSeconds = 60) {
41
- const payload = decodeJwtPayload(token);
42
- if (!payload || typeof payload.exp !== "number")
43
- return true;
44
- const nowSeconds = Math.floor(Date.now() / 1000);
45
- return payload.exp - nowSeconds < bufferSeconds;
46
- }
47
- var cachedClientId = null;
48
- async function fetchWorkOSClientId() {
49
- if (cachedClientId)
50
- return cachedClientId;
51
- try {
52
- const apiUrl = getPensarApiUrl();
53
- const response = await fetch(`${apiUrl}/api/cli/config`);
54
- if (!response.ok)
55
- return null;
56
- const data = await response.json();
57
- cachedClientId = data.workosClientId;
58
- return cachedClientId;
59
- } catch {
60
- return null;
61
- }
62
- }
63
- async function refreshAccessToken(clientId, refreshToken) {
64
- try {
65
- const response = await fetch("https://api.workos.com/user_management/authenticate", {
66
- method: "POST",
67
- headers: { "Content-Type": "application/json" },
68
- body: JSON.stringify({
69
- client_id: clientId,
70
- grant_type: "refresh_token",
71
- refresh_token: refreshToken
72
- })
73
- });
74
- if (!response.ok) {
75
- console.error(`[pensar] Token refresh failed: ${response.status} ${response.statusText}`);
76
- return null;
77
- }
78
- const data = await response.json();
79
- await config.update({
80
- accessToken: data.access_token,
81
- refreshToken: data.refresh_token
82
- });
83
- return data.access_token;
84
- } catch (err) {
85
- console.error("[pensar] Token refresh error:", err);
86
- return null;
87
- }
88
- }
89
- async function ensureValidToken(cfg) {
90
- if (cfg.accessToken) {
91
- if (!isTokenExpired(cfg.accessToken)) {
92
- return { token: cfg.accessToken, type: "workos" };
93
- }
94
- if (cfg.refreshToken) {
95
- const clientId = await fetchWorkOSClientId();
96
- if (clientId) {
97
- const newToken = await refreshAccessToken(clientId, cfg.refreshToken);
98
- if (newToken) {
99
- return { token: newToken, type: "workos" };
100
- }
101
- }
102
- }
103
- }
104
- if (cfg.pensarAPIKey) {
105
- return { token: cfg.pensarAPIKey, type: "legacy" };
106
- }
107
- return null;
108
- }
109
-
110
- export { getPensarApiUrl, getPensarGatewayUrl, getPensarConsoleUrl, config, isTokenExpired, fetchWorkOSClientId, refreshAccessToken, ensureValidToken };
@@ -1,190 +0,0 @@
1
- // src/core/installation/index.ts
2
- import { spawnSync } from "child_process";
3
- // package.json
4
- var package_default = {
5
- name: "@pensar/apex",
6
- version: "1.8.0",
7
- description: "AI-powered penetration testing CLI tool with terminal UI",
8
- module: "src/tui/index.tsx",
9
- main: "build/cli.js",
10
- type: "module",
11
- repository: {
12
- type: "git",
13
- url: "https://github.com/pensarai/apex.git"
14
- },
15
- bin: {
16
- pensar: "./bin/pensar.js"
17
- },
18
- files: [
19
- "build",
20
- "bin",
21
- "assets",
22
- "pensar.svg",
23
- "LICENSE"
24
- ],
25
- scripts: {
26
- 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",
27
- "generate:ascii": "bun run scripts/generate-ascii-art.ts",
28
- "generate:models": "bun run scripts/generate-models.ts",
29
- "build:binary": "bun run generate:ascii && bun build src/cli.ts --compile --outfile pensar",
30
- "build:binary:macos-arm64": "bun build src/cli.ts --compile --target=bun-darwin-arm64 --outfile dist/pensar-darwin-arm64",
31
- "build:binary:macos-x64": "bun build src/cli.ts --compile --target=bun-darwin-x64 --outfile dist/pensar-darwin-x64",
32
- "build:binary:linux-x64": "bun build src/cli.ts --compile --target=bun-linux-x64 --outfile dist/pensar-linux-x64",
33
- "build:binary:linux-arm64": "bun build src/cli.ts --compile --target=bun-linux-arm64 --outfile dist/pensar-linux-arm64",
34
- "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",
35
- dev: "bun run scripts/watch.ts",
36
- "dev:debug": "SHOW_CONSOLE=true bun run scripts/watch.ts",
37
- start: "bun run src/tui/index.tsx",
38
- pensar: "node bin/pensar.js",
39
- tsc: "tsc --noEmit",
40
- "daytona-benchmark": "bun run scripts/daytona-benchmark.ts",
41
- "local-benchmark": "bun run scripts/local-benchmark.ts",
42
- test: "vitest run",
43
- "test:watch": "vitest",
44
- lint: "eslint src/",
45
- format: "prettier --write .",
46
- "format:check": "prettier --check .",
47
- prepublishOnly: "npm run build"
48
- },
49
- keywords: [
50
- "penetration-testing",
51
- "security",
52
- "pentesting",
53
- "ai",
54
- "cli",
55
- "terminal",
56
- "tui"
57
- ],
58
- author: "Pensar",
59
- license: "MIT",
60
- engines: {
61
- node: ">=18.0.0",
62
- bun: ">=1.0.0"
63
- },
64
- optionalDependencies: {
65
- weave: "^0.12.1"
66
- },
67
- devDependencies: {
68
- "@eslint/js": "^10.0.1",
69
- "@types/bun": "^1.3.0",
70
- "@types/mailparser": "^3.4.6",
71
- "@types/mime-types": "^3.0.1",
72
- "@types/nodemailer": "^8.0.0",
73
- "@types/react": "^19.2.6",
74
- "@typescript-eslint/eslint-plugin": "^8.55.0",
75
- "@typescript-eslint/parser": "^8.55.0",
76
- dotenv: "^17.2.3",
77
- eslint: "^10.0.0",
78
- "eslint-config-prettier": "^10.1.8",
79
- "eslint-plugin-unused-imports": "^4.4.1",
80
- prettier: "^3.8.1",
81
- "typescript-eslint": "^8.55.0",
82
- vitest: "^2.1.8"
83
- },
84
- peerDependencies: {
85
- typescript: "^5.9.3"
86
- },
87
- dependencies: {
88
- "@ai-sdk/amazon-bedrock": "^4.0.69",
89
- "@ai-sdk/anthropic": "^3.0.50",
90
- "@ai-sdk/google": "^3.0.37",
91
- "@ai-sdk/openai": "3.0.46",
92
- "@ai-sdk/openai-compatible": "^2.0.35",
93
- "@daytonaio/sdk": "^0.112.1",
94
- "@googleapis/gmail": "^16.1.1",
95
- "@microsoft/microsoft-graph-client": "^3.0.7",
96
- "@modelcontextprotocol/sdk": "^1.0.0",
97
- "@openrouter/ai-sdk-provider": "^2.2.3",
98
- "@opentui/core": "^0.1.80",
99
- "@opentui/react": "^0.1.80",
100
- "@playwright/mcp": "^0.0.54",
101
- ai: "^6.0.105",
102
- glob: "^13.0.0",
103
- "google-auth-library": "^10.6.1",
104
- "highlight.js": "^11.11.1",
105
- ignore: "^7.0.5",
106
- imapflow: "^1.2.10",
107
- jsonwebtoken: "^9.0.3",
108
- mailparser: "^3.9.3",
109
- marked: "^16.4.0",
110
- "mime-types": "^3.0.2",
111
- nanoid: "^5.1.6",
112
- nodemailer: "^8.0.7",
113
- "p-limit": "^7.2.0",
114
- react: "^19.2.0",
115
- sharp: "^0.34.4",
116
- tldts: "^7.0.28",
117
- yaml: "^2.8.2",
118
- zod: "^3.25.76"
119
- },
120
- packageManager: "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
121
- };
122
-
123
- // src/core/installation/index.ts
124
- function getCurrentVersion() {
125
- return package_default.version;
126
- }
127
- function isNewerVersion(current, latest) {
128
- const parse = (v) => v.split(".").map((n) => parseInt(n, 10) || 0);
129
- const c = parse(current);
130
- const l = parse(latest);
131
- for (let i = 0;i < Math.max(c.length, l.length); i++) {
132
- const cv = c[i] ?? 0;
133
- const lv = l[i] ?? 0;
134
- if (lv > cv)
135
- return true;
136
- if (lv < cv)
137
- return false;
138
- }
139
- return false;
140
- }
141
- async function getLatestVersion() {
142
- const res = await fetch("https://registry.npmjs.org/@pensar/apex/latest");
143
- if (!res.ok)
144
- throw new Error(`Failed to fetch latest version: ${res.statusText}`);
145
- const data = await res.json();
146
- return String(data.version);
147
- }
148
- function detectInstallMethod() {
149
- const execPath = process.execPath;
150
- const argv1 = process.argv[1] ?? "";
151
- if (execPath.includes("homebrew") || execPath.includes("Cellar") || execPath.includes("linuxbrew") || argv1.includes("homebrew") || argv1.includes("Cellar")) {
152
- return "homebrew";
153
- }
154
- if (argv1.includes("node_modules") || argv1.includes(".npm") || argv1.includes("npx")) {
155
- return "npm";
156
- }
157
- const execName = execPath.split("/").pop()?.replace(/\.exe$/, "") ?? "";
158
- const isInterpreter = execName === "bun" || execName === "node" || execName === "bun-debug";
159
- if (!isInterpreter) {
160
- return "binary";
161
- }
162
- const npmCheck = spawnSync("npm", ["list", "-g", "@pensar/apex", "--depth=0"], {
163
- encoding: "utf-8",
164
- timeout: 1e4
165
- });
166
- if (npmCheck.status === 0 && npmCheck.stdout?.includes("@pensar/apex")) {
167
- return "npm";
168
- }
169
- return "binary";
170
- }
171
- async function checkForUpdate() {
172
- const currentVersion = getCurrentVersion();
173
- let latestVersion;
174
- try {
175
- latestVersion = await getLatestVersion();
176
- } catch {
177
- return {
178
- updateAvailable: false,
179
- currentVersion,
180
- latestVersion: currentVersion
181
- };
182
- }
183
- return {
184
- updateAvailable: isNewerVersion(currentVersion, latestVersion),
185
- currentVersion,
186
- latestVersion
187
- };
188
- }
189
-
190
- export { package_default, getCurrentVersion, detectInstallMethod, checkForUpdate };
@@ -1,103 +0,0 @@
1
- import {
2
- config,
3
- ensureValidToken,
4
- getPensarApiUrl
5
- } from "./cli-asyas1xb.js";
6
-
7
- // src/core/api/issues.ts
8
- async function getAuthHeaders() {
9
- const cfg = await config.get();
10
- const validToken = await ensureValidToken({
11
- accessToken: cfg.accessToken,
12
- refreshToken: cfg.refreshToken,
13
- pensarAPIKey: cfg.pensarAPIKey
14
- });
15
- if (!validToken) {
16
- throw new Error("Not authenticated. Run `pensar login` to connect to Pensar Console.");
17
- }
18
- const headers = {
19
- "Content-Type": "application/json",
20
- Authorization: `Bearer ${validToken.token}`
21
- };
22
- if (cfg.workspaceId) {
23
- headers["X-Workspace-Id"] = cfg.workspaceId;
24
- }
25
- return headers;
26
- }
27
- async function apiRequest(method, path, body) {
28
- const baseUrl = getPensarApiUrl();
29
- const headers = await getAuthHeaders();
30
- const url = `${baseUrl}${path}`;
31
- const init = { method, headers };
32
- if (body !== undefined) {
33
- init.body = JSON.stringify(body);
34
- }
35
- const response = await fetch(url, init);
36
- if (!response.ok) {
37
- const text = await response.text();
38
- let message;
39
- try {
40
- const err = JSON.parse(text);
41
- message = err.error ?? text;
42
- } catch {
43
- message = text;
44
- }
45
- throw new Error(`API error (${response.status}): ${message}`);
46
- }
47
- return await response.json();
48
- }
49
- async function listProjects() {
50
- return apiRequest("GET", "/projects");
51
- }
52
- async function listScans(projectId) {
53
- return apiRequest("GET", `/projects/${projectId}/pentests`);
54
- }
55
- async function getScan(scanId) {
56
- return apiRequest("GET", `/pentests/${scanId}`);
57
- }
58
- async function dispatchPentest(projectId, opts) {
59
- return apiRequest("POST", `/projects/${projectId}/pentests`, opts);
60
- }
61
- async function listIssues(projectId, filters) {
62
- const params = new URLSearchParams;
63
- if (filters?.scanId)
64
- params.set("scanId", filters.scanId);
65
- if (filters?.status)
66
- params.set("status", filters.status);
67
- if (filters?.severity)
68
- params.set("severity", filters.severity);
69
- if (filters?.branch)
70
- params.set("branch", filters.branch);
71
- const qs = params.toString();
72
- const path = `/projects/${projectId}/issues${qs ? `?${qs}` : ""}`;
73
- return apiRequest("GET", path);
74
- }
75
- async function getIssue(issueId) {
76
- return apiRequest("GET", `/issues/${issueId}`);
77
- }
78
- async function updateIssue(issueId, data) {
79
- return apiRequest("PATCH", `/issues/${issueId}`, data);
80
- }
81
- async function listFixes(issueId) {
82
- return apiRequest("GET", `/issues/${issueId}/fixes`);
83
- }
84
- async function getFix(fixId) {
85
- return apiRequest("GET", `/fixes/${fixId}`);
86
- }
87
- async function listAgentLogs(issueId, opts) {
88
- const params = new URLSearchParams;
89
- if (opts?.level)
90
- params.set("level", opts.level);
91
- if (opts?.role)
92
- params.set("role", opts.role);
93
- if (opts?.limit)
94
- params.set("limit", String(opts.limit));
95
- const qs = params.toString();
96
- const path = `/issues/${issueId}/logs${qs ? `?${qs}` : ""}`;
97
- return apiRequest("GET", path);
98
- }
99
- async function searchAgentLogs(issueId, query, opts) {
100
- return apiRequest("POST", `/issues/${issueId}/logs/search`, { query, ...opts });
101
- }
102
-
103
- export { listProjects, listScans, getScan, dispatchPentest, listIssues, getIssue, updateIssue, listFixes, getFix, listAgentLogs, searchAgentLogs };