opencode-api-security-testing 5.4.11 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/api-cyber-supervisor.md +31 -5
- package/package.json +1 -1
- package/src/index.ts +264 -4
|
@@ -33,20 +33,46 @@ color: "#FF5733"
|
|
|
33
33
|
|------|------|------|
|
|
34
34
|
| api_security_scan | 完整扫描 | 全面测试 |
|
|
35
35
|
| api_fuzz_test | 模糊测试 | 发现未知端点 |
|
|
36
|
-
| browser_collect | 浏览器采集 | SPA 应用 |
|
|
36
|
+
| browser_collect | 浏览器采集 | SPA 应用 (**侦察首选**) |
|
|
37
37
|
| js_parse | JS 分析 | 提取 API 模式 |
|
|
38
38
|
| vuln_verify | 漏洞验证 | 确认发现 |
|
|
39
39
|
| graphql_test | GraphQL 测试 | GraphQL 端点 |
|
|
40
40
|
| cloud_storage_test | 云存储测试 | OSS/S3 |
|
|
41
41
|
| idor_test | IDOR 测试 | 越权漏洞 |
|
|
42
42
|
| sqli_test | SQLi 测试 | 注入漏洞 |
|
|
43
|
+
| pentest_planner | 测试规划 | 生成 Todo 清单 |
|
|
44
|
+
|
|
45
|
+
## 任务管理 (关键)
|
|
46
|
+
|
|
47
|
+
**默认行为**: 在开始任何多步测试之前,先使用 `todowrite` 创建 Todo 清单。
|
|
48
|
+
|
|
49
|
+
### 工作流 (不可违背)
|
|
50
|
+
|
|
51
|
+
1. **收到请求后立即**: 使用 `pentest_planner` 或手动用 `todowrite` 规划步骤
|
|
52
|
+
2. **开始每个步骤前**: 标记为 `in_progress` (同时只有一个)
|
|
53
|
+
3. **完成每个步骤后**: 立即标记为 `completed` (绝不批量)
|
|
54
|
+
4. **如果发现新目标**: 先更新 Todo 再继续
|
|
55
|
+
|
|
56
|
+
### 为什么不可违背
|
|
57
|
+
|
|
58
|
+
- **用户可见性**: 用户在右侧面板实时看到进度
|
|
59
|
+
- **防止漂移**: Todo 锚定你到实际请求
|
|
60
|
+
- **自动续写**: 系统在空闲时自动注入未完成任务
|
|
43
61
|
|
|
44
62
|
## 测试流程
|
|
45
63
|
|
|
46
|
-
### Phase 1: 侦察
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
### Phase 1: 侦察 (**必须使用无头浏览器**)
|
|
65
|
+
|
|
66
|
+
**第一步永远是 browser_collect**,不是 curl/fetch!
|
|
67
|
+
|
|
68
|
+
1. **browser_collect(url, mode="dynamic")** - 使用 Playwright 无头浏览器采集动态端点
|
|
69
|
+
2. js_parse 分析 JS 文件 - 提取 API 路由模式
|
|
70
|
+
3. 基于采集结果发现更多隐藏端点
|
|
71
|
+
|
|
72
|
+
> ⚠️ 为什么侦察阶段必须用 browser_collect?
|
|
73
|
+
> - SPA 应用需要执行 JS 才能获取动态路由
|
|
74
|
+
> - curl/fetch 只能获取静态 HTML,会遗漏大量 API 端点
|
|
75
|
+
> - Playwright 可以模拟真实浏览器行为,触发 XHR/Fetch 请求
|
|
50
76
|
|
|
51
77
|
### Phase 2: 分析
|
|
52
78
|
1. 识别技术栈
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -432,7 +432,7 @@ class ContextCollector {
|
|
|
432
432
|
|
|
433
433
|
return entries.sort((a, b) => {
|
|
434
434
|
const priorityDiff = PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority];
|
|
435
|
-
if (priorityDiff !==
|
|
435
|
+
if (priorityDiff !== 0) return priorityDiff;
|
|
436
436
|
return a.registrationOrder - b.registrationOrder;
|
|
437
437
|
});
|
|
438
438
|
}
|
|
@@ -479,6 +479,127 @@ function clearSessionState(sessionID: string | undefined): void {
|
|
|
479
479
|
}
|
|
480
480
|
}
|
|
481
481
|
|
|
482
|
+
// ============================================================================
|
|
483
|
+
// P9 内部触发器 + Todo 持续注入系统 (参考 oh-my-opencode)
|
|
484
|
+
// ============================================================================
|
|
485
|
+
|
|
486
|
+
const P9_INTERNAL_INITIATOR = "<!-- P9_INTERNAL_INITIATOR -->";
|
|
487
|
+
|
|
488
|
+
// 创建内部 agent 文本 part (不会被 UI 显示)
|
|
489
|
+
function createP9InternalTextPart(text: string) {
|
|
490
|
+
return {
|
|
491
|
+
type: "text" as const,
|
|
492
|
+
text: `${text}\n${P9_INTERNAL_INITIATOR}`,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Todo 持续注入提示
|
|
497
|
+
const P9_CONTINUATION_PROMPT = `[SYSTEM DIRECTIVE: P9 - TODO CONTINUATION]
|
|
498
|
+
|
|
499
|
+
渗透测试任务未完成。继续执行下一个待处理任务。
|
|
500
|
+
|
|
501
|
+
- 直接执行,不要询问用户
|
|
502
|
+
- 完成每个任务后立即标记为 completed
|
|
503
|
+
- 不要停止直到所有任务完成
|
|
504
|
+
- 如果所有测试已完成,生成最终报告`;
|
|
505
|
+
|
|
506
|
+
// 覆盖 todowrite 工具描述 (渗透测试专用)
|
|
507
|
+
const P9_TODOWRITE_DESCRIPTION = `使用此工具创建和管理渗透测试任务清单。
|
|
508
|
+
|
|
509
|
+
## 任务格式 (必须)
|
|
510
|
+
|
|
511
|
+
每个任务标题必须编码: [阶段] [动作] [目标] - 预期 [结果]
|
|
512
|
+
|
|
513
|
+
好的:
|
|
514
|
+
- "[侦察] browser_collect 采集 https://target - 提取 JS 端点"
|
|
515
|
+
- "[认证] sqli_test 测试 /api/login - 检测注入"
|
|
516
|
+
- "[验证] vuln_verify 确认 SQL 注入 - 获取 PoC"
|
|
517
|
+
|
|
518
|
+
坏的:
|
|
519
|
+
- "测试登录" (哪个接口? 怎么测? 预期什么?)
|
|
520
|
+
- "扫描目标" (太笼统)
|
|
521
|
+
|
|
522
|
+
## 测试阶段
|
|
523
|
+
|
|
524
|
+
1. **侦察**: browser_collect → js_parse → 端点发现
|
|
525
|
+
2. **认证**: 登录接口测试 → 认证绕过 → 暴力破解
|
|
526
|
+
3. **漏洞**: SQLi → IDOR → XSS → 信息泄露
|
|
527
|
+
4. **报告**: 生成结构化 Markdown 报告
|
|
528
|
+
|
|
529
|
+
## 管理规则
|
|
530
|
+
- 一次只标记一个 in_progress
|
|
531
|
+
- 完成后立即标记 completed
|
|
532
|
+
- 你的 TODO 会被 HOOK([SYSTEM REMINDER - TODO CONTINUATION]) 自动追踪`;
|
|
533
|
+
|
|
534
|
+
// Todo 持续状态追踪
|
|
535
|
+
const todoContinuationState = new Map<string, {
|
|
536
|
+
lastInjectedAt: number;
|
|
537
|
+
incompleteCount: number;
|
|
538
|
+
stagnationCount: number;
|
|
539
|
+
}>();
|
|
540
|
+
|
|
541
|
+
const CONTINUATION_COOLDOWN_MS = 5000;
|
|
542
|
+
const MAX_STAGNATION_COUNT = 3;
|
|
543
|
+
|
|
544
|
+
function getIncompleteCount(todos: Array<{ status: string }>): number {
|
|
545
|
+
return todos.filter(t =>
|
|
546
|
+
t.status !== "completed" &&
|
|
547
|
+
t.status !== "cancelled" &&
|
|
548
|
+
t.status !== "blocked"
|
|
549
|
+
).length;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// 系统提示 - 渗透测试 Todo 管理 (注入到 system prompt, 参考 oh-my-opencode Sisyphus)
|
|
553
|
+
const PENTEST_TODO_SYSTEM_PROMPT = `<Pentest_Task_Management>
|
|
554
|
+
## 渗透测试 Todo 管理 (关键)
|
|
555
|
+
|
|
556
|
+
**默认行为**: 在开始任何渗透测试之前,必须先使用 todowrite 创建 Todo 清单。这是你的首要协调机制。
|
|
557
|
+
|
|
558
|
+
### 何时创建 Todo (必须)
|
|
559
|
+
|
|
560
|
+
- 多步骤测试 (2+ 步骤) → 始终先创建 Todo
|
|
561
|
+
- 用户提出安全测试请求 → 始终
|
|
562
|
+
- 使用 pentest_planner 工具后 → 立即将输出转为 todowrite 调用
|
|
563
|
+
- 复杂单一任务 → 创建 Todo 拆解
|
|
564
|
+
|
|
565
|
+
### 工作流 (不可协商)
|
|
566
|
+
|
|
567
|
+
1. **收到请求后立即**: 使用 todowrite 规划原子步骤
|
|
568
|
+
2. **开始每步前**: 标记 in_progress (同时只有一个)
|
|
569
|
+
3. **完成每步后**: 立即标记 completed (绝不批量)
|
|
570
|
+
4. **范围变化时**: 先更新 Todo 再继续
|
|
571
|
+
|
|
572
|
+
### 侦察阶段 (必须先使用 Playwright 无头浏览器)
|
|
573
|
+
|
|
574
|
+
**侦察阶段必须第一步就使用 browser_collect 工具 (基于 Playwright)!**
|
|
575
|
+
不要用 curl/fetch 做侦察,必须直接上无头浏览器。
|
|
576
|
+
|
|
577
|
+
侦察顺序:
|
|
578
|
+
1. browser_collect(url, mode="dynamic") - 用 Playwright 采集 SPA 动态内容
|
|
579
|
+
2. js_parse(file_path) - 分析 JS 文件中的 API 模式
|
|
580
|
+
3. 根据发现使用专业工具深入
|
|
581
|
+
|
|
582
|
+
### 为什么这是不可协商的
|
|
583
|
+
|
|
584
|
+
- **用户可见性**: 用户在右侧面板实时看到进度
|
|
585
|
+
- **防止漂移**: Todo 锚定你到实际请求
|
|
586
|
+
- **自动继续**: 系统会自动追踪并注入未完成的 Todo,驱动你继续执行
|
|
587
|
+
- **问责制**: 每个 Todo = 明确承诺
|
|
588
|
+
|
|
589
|
+
### 反模式 (禁止)
|
|
590
|
+
|
|
591
|
+
- 多步测试跳过 Todo - 用户无可见性,步骤被遗忘
|
|
592
|
+
- 批量完成多个 Todo - 失去实时追踪意义
|
|
593
|
+
- 不标记 in_progress 就开始 - 无法知道你在做什么
|
|
594
|
+
- 完成但不标记 completed - 任务对用户显示为未完成
|
|
595
|
+
|
|
596
|
+
**未在非琐碎任务上使用 Todo = 不完整的工作。**
|
|
597
|
+
|
|
598
|
+
你的 Todo 创建会被 HOOK([SYSTEM REMINDER - TODO CONTINUATION]) 自动追踪。
|
|
599
|
+
</Pentest_Task_Management>`;
|
|
600
|
+
|
|
601
|
+
const TODO_HOOK_NOTE = `\n[P9 HOOK NOTE] 你的 Todo 创建会被 HOOK([SYSTEM REMINDER - TODO CONTINUATION]) 自动追踪。当会话空闲且有未完成任务时,系统会自动注入续写提示。`;
|
|
602
|
+
|
|
482
603
|
function getConfigPath(ctx: { directory: string }): string {
|
|
483
604
|
return join(ctx.directory, SKILL_DIR, "assets", CONFIG_FILE);
|
|
484
605
|
}
|
|
@@ -1933,9 +2054,9 @@ ${f.remediation}
|
|
|
1933
2054
|
// 自主任务编排 + 测试规划
|
|
1934
2055
|
// ========================================
|
|
1935
2056
|
|
|
1936
|
-
// 渗透测试规划器 - 先规划后执行
|
|
2057
|
+
// 渗透测试规划器 - 先规划后执行 (使用 OpenCode 内置 todowrite)
|
|
1937
2058
|
pentest_planner: tool({
|
|
1938
|
-
description: "
|
|
2059
|
+
description: "渗透测试规划器。侦察目标后输出 todowrite 指令,让你使用 OpenCode 内置 Todo 面板追踪测试进度。参数: target(目标URL), scope(测试范围), depth(测试深度)",
|
|
1939
2060
|
args: {
|
|
1940
2061
|
target: tool.schema.string(),
|
|
1941
2062
|
scope: tool.schema.enum(["full", "auth_only", "api_only", "infra_only", "quick"]).optional(),
|
|
@@ -1994,7 +2115,36 @@ ${f.remediation}
|
|
|
1994
2115
|
// Phase 2: 根据侦察结果生成测试计划
|
|
1995
2116
|
const plan = generateTestPlan(target, scope, depth, reconResults, requirements);
|
|
1996
2117
|
|
|
1997
|
-
|
|
2118
|
+
// Phase 3: 输出 todowrite 指令而非 JSON
|
|
2119
|
+
// 这样 LLM 会调用 OpenCode 内置的 todowrite 工具,显示在右侧面板
|
|
2120
|
+
const todoItems = plan.plan.map(t => {
|
|
2121
|
+
const status = t.priority === "P0" ? "pending" : "pending";
|
|
2122
|
+
return ` { content: "${t.phase}: ${t.task} - 预期${t.reason.includes("泄露") ? "发现/排除信息泄露" : t.reason.includes("注入") ? "确认/排除注入漏洞" : "完成测试"}, 使用 ${t.tool}", status: "${status}", priority: "${t.priority === "P0" ? "high" : t.priority === "P1" ? "medium" : "low"}" }`;
|
|
2123
|
+
}).join(",\n");
|
|
2124
|
+
|
|
2125
|
+
return `## 侦察完成 - 目标分析结果
|
|
2126
|
+
|
|
2127
|
+
**目标**: ${target}
|
|
2128
|
+
**技术栈**: ${reconResults.framework || "Unknown"} | SPA: ${reconResults.is_spa ? "是" : "否"} | JS文件: ${reconResults.js_files_count || 0} | API路径: ${reconResults.api_paths_found || 0}
|
|
2129
|
+
**首页状态**: ${reconResults.home_status || "N/A"}
|
|
2130
|
+
|
|
2131
|
+
### 安全端点探测
|
|
2132
|
+
${JSON.stringify(reconResults.security_checks || [], null, 2)}
|
|
2133
|
+
|
|
2134
|
+
### 测试计划已生成 (${plan.summary.total_tasks} 项任务)
|
|
2135
|
+
|
|
2136
|
+
**⚠️ 请立即使用 \`todowrite\` 工具创建以下 Todo 清单 (会显示在右侧面板):**
|
|
2137
|
+
|
|
2138
|
+
\`\`\`
|
|
2139
|
+
todowrite({
|
|
2140
|
+
todos: [
|
|
2141
|
+
${todoItems}
|
|
2142
|
+
]
|
|
2143
|
+
})
|
|
2144
|
+
\`\`\`
|
|
2145
|
+
|
|
2146
|
+
创建 Todo 后,系统会自动追踪进度并在你完成每个任务后自动继续下一个。
|
|
2147
|
+
从第一个 P0 任务开始执行!`;
|
|
1998
2148
|
},
|
|
1999
2149
|
}),
|
|
2000
2150
|
|
|
@@ -2453,6 +2603,37 @@ ${LEVEL_PROMPTS[level]}
|
|
|
2453
2603
|
return output;
|
|
2454
2604
|
},
|
|
2455
2605
|
|
|
2606
|
+
// Todo 工具描述覆盖 - 参考 oh-my-opencode 的 todo-description-override hook
|
|
2607
|
+
"tool.definition": async (input, output) => {
|
|
2608
|
+
if (input.toolID === "todowrite") {
|
|
2609
|
+
output.description = `使用此工具创建和管理渗透测试任务清单,实时显示在 OpenCode 右侧面板。
|
|
2610
|
+
|
|
2611
|
+
## Todo 格式 (强制)
|
|
2612
|
+
|
|
2613
|
+
每个 todo 标题必须包含四个要素: WHERE, WHY, HOW, 预期结果。
|
|
2614
|
+
|
|
2615
|
+
格式: "[目标/端点] [操作] - 预期 [结果]"
|
|
2616
|
+
|
|
2617
|
+
好的示例:
|
|
2618
|
+
- "https://target/api/login: 使用 sqli_test 测试 SQL 注入 - 预期发现/排除注入漏洞"
|
|
2619
|
+
- "JS 文件分析: 使用 js_parse 提取所有 API 端点 - 预期获得完整端点列表"
|
|
2620
|
+
- "认证绕过测试: 使用 auth_bypass_test 测试 /api/user - 预期确认/排除绕过可能"
|
|
2621
|
+
|
|
2622
|
+
坏的示例:
|
|
2623
|
+
- "测试 SQL 注入" (哪个端点? 什么工具? 什么结果?)
|
|
2624
|
+
- "安全测试" (太笼统)
|
|
2625
|
+
|
|
2626
|
+
## 粒度规则
|
|
2627
|
+
|
|
2628
|
+
每个 todo 必须是单个原子操作,可以在 1-3 次工具调用内完成。如果需要更多步骤,拆分它。
|
|
2629
|
+
|
|
2630
|
+
## 任务管理
|
|
2631
|
+
- 一次只标记一个 in_progress。完成后再开始下一个。
|
|
2632
|
+
- 每完成一项立即标记 completed。
|
|
2633
|
+
- 单步简单任务跳过此工具。`;
|
|
2634
|
+
}
|
|
2635
|
+
},
|
|
2636
|
+
|
|
2456
2637
|
// 会话事件处理
|
|
2457
2638
|
event: async (input) => {
|
|
2458
2639
|
const { event } = input
|
|
@@ -2469,6 +2650,77 @@ ${LEVEL_PROMPTS[level]}
|
|
|
2469
2650
|
}
|
|
2470
2651
|
}
|
|
2471
2652
|
|
|
2653
|
+
// 会话空闲 - 触发 Todo 持续注入 (参考 oh-my-opencode 的 todo-continuation-enforcer)
|
|
2654
|
+
if (event.type === "session.idle") {
|
|
2655
|
+
const props = event.properties as Record<string, unknown> | undefined;
|
|
2656
|
+
const sessionID = (props?.info as { id?: string })?.id;
|
|
2657
|
+
|
|
2658
|
+
if (sessionID) {
|
|
2659
|
+
try {
|
|
2660
|
+
// 获取当前 todo 列表
|
|
2661
|
+
const response = await ctx.client.session.todo({ path: { id: sessionID } });
|
|
2662
|
+
const todos = (response as any)?.data || response || [];
|
|
2663
|
+
const incompleteCount = getIncompleteCount(Array.isArray(todos) ? todos : []);
|
|
2664
|
+
|
|
2665
|
+
if (incompleteCount === 0) {
|
|
2666
|
+
return; // 没有未完成的 todo,不需要持续注入
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
// 检查冷却时间和停滞状态
|
|
2670
|
+
const state = todoContinuationState.get(sessionID);
|
|
2671
|
+
const now = Date.now();
|
|
2672
|
+
|
|
2673
|
+
if (state) {
|
|
2674
|
+
// 冷却期内跳过
|
|
2675
|
+
if (now - state.lastInjectedAt < CONTINUATION_COOLDOWN_MS) {
|
|
2676
|
+
return;
|
|
2677
|
+
}
|
|
2678
|
+
// 停滞检测 (连续未进展)
|
|
2679
|
+
if (state.stagnationCount >= MAX_STAGNATION_COUNT) {
|
|
2680
|
+
console.log(`[api-security-testing] Todo continuation stagnated for session ${sessionID}`);
|
|
2681
|
+
return;
|
|
2682
|
+
}
|
|
2683
|
+
// 更新停滞计数
|
|
2684
|
+
if (state.incompleteCount === incompleteCount) {
|
|
2685
|
+
state.stagnationCount++;
|
|
2686
|
+
} else {
|
|
2687
|
+
state.stagnationCount = 0; // 有进展,重置
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
|
|
2691
|
+
// 构建持续注入 prompt
|
|
2692
|
+
const incompleteTodos = Array.isArray(todos)
|
|
2693
|
+
? todos.filter((t: any) => t.status !== "completed" && t.status !== "cancelled")
|
|
2694
|
+
: [];
|
|
2695
|
+
const todoList = incompleteTodos
|
|
2696
|
+
.map((t: any) => `- [${t.status || "pending"}] ${t.content || t.text || "Unknown task"}`)
|
|
2697
|
+
.join("\n");
|
|
2698
|
+
|
|
2699
|
+
const continuationPrompt = `${CONTINUATION_PROMPT}\n\n[状态: ${Array.isArray(todos) ? todos.length - incompleteCount : "?"}/${Array.isArray(todos) ? todos.length : "?"} 已完成, ${incompleteCount} 剩余]\n\n剩余任务:\n${todoList}`;
|
|
2700
|
+
|
|
2701
|
+
// 注入持续 prompt (参考 oh-my-opencode 的 injectContinuation)
|
|
2702
|
+
await ctx.client.session.promptAsync({
|
|
2703
|
+
path: { id: sessionID },
|
|
2704
|
+
body: {
|
|
2705
|
+
parts: [createP9InternalTextPart(continuationPrompt)],
|
|
2706
|
+
},
|
|
2707
|
+
query: { directory: ctx.directory },
|
|
2708
|
+
} as any);
|
|
2709
|
+
|
|
2710
|
+
// 更新状态
|
|
2711
|
+
todoContinuationState.set(sessionID, {
|
|
2712
|
+
lastInjectedAt: now,
|
|
2713
|
+
incompleteCount,
|
|
2714
|
+
stagnationCount: state?.stagnationCount || 0,
|
|
2715
|
+
});
|
|
2716
|
+
|
|
2717
|
+
console.log(`[api-security-testing] Injected todo continuation for session ${sessionID}, ${incompleteCount} tasks remaining`);
|
|
2718
|
+
} catch (err) {
|
|
2719
|
+
console.error(`[api-security-testing] Todo continuation injection failed:`, err);
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2472
2724
|
// 会话删除或压缩 - 清理状态
|
|
2473
2725
|
if (event.type === "session.deleted" || event.type === "session.compacted") {
|
|
2474
2726
|
const props = event.properties as Record<string, unknown> | undefined;
|
|
@@ -2484,6 +2736,7 @@ ${LEVEL_PROMPTS[level]}
|
|
|
2484
2736
|
clearSessionState(sessionID);
|
|
2485
2737
|
resetFailureCount(sessionID);
|
|
2486
2738
|
resetModelFailures(sessionID);
|
|
2739
|
+
todoContinuationState.delete(sessionID);
|
|
2487
2740
|
}
|
|
2488
2741
|
}
|
|
2489
2742
|
},
|
|
@@ -2554,6 +2807,13 @@ ${LEVEL_PROMPTS[level]}
|
|
|
2554
2807
|
|
|
2555
2808
|
console.log(`[api-security-testing] Injected context via synthetic part, session=${sessionID}, length=${pending.merged.length}`);
|
|
2556
2809
|
},
|
|
2810
|
+
|
|
2811
|
+
// 系统 Prompt 注入 - Todo 管理指令 (参考 oh-my-opencode Sisyphus agent)
|
|
2812
|
+
"experimental.chat.system.transform": async (_input, output) => {
|
|
2813
|
+
output.system.push(PENTEST_TODO_SYSTEM_PROMPT);
|
|
2814
|
+
output.system.push(TODO_HOOK_NOTE);
|
|
2815
|
+
console.log(`[api-security-testing] Injected pentest todo management into system prompt`);
|
|
2816
|
+
},
|
|
2557
2817
|
};
|
|
2558
2818
|
};
|
|
2559
2819
|
|