cipher-security 5.0.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/bin/cipher.js +465 -0
- package/lib/api/billing.js +321 -0
- package/lib/api/compliance.js +693 -0
- package/lib/api/controls.js +1401 -0
- package/lib/api/index.js +49 -0
- package/lib/api/marketplace.js +467 -0
- package/lib/api/openai-proxy.js +383 -0
- package/lib/api/server.js +685 -0
- package/lib/autonomous/feedback-loop.js +554 -0
- package/lib/autonomous/framework.js +512 -0
- package/lib/autonomous/index.js +97 -0
- package/lib/autonomous/leaderboard.js +594 -0
- package/lib/autonomous/modes/architect.js +412 -0
- package/lib/autonomous/modes/blue.js +386 -0
- package/lib/autonomous/modes/incident.js +684 -0
- package/lib/autonomous/modes/privacy.js +369 -0
- package/lib/autonomous/modes/purple.js +294 -0
- package/lib/autonomous/modes/recon.js +250 -0
- package/lib/autonomous/parallel.js +587 -0
- package/lib/autonomous/researcher.js +583 -0
- package/lib/autonomous/runner.js +955 -0
- package/lib/autonomous/scheduler.js +615 -0
- package/lib/autonomous/task-parser.js +127 -0
- package/lib/autonomous/validators/forensic.js +266 -0
- package/lib/autonomous/validators/osint.js +216 -0
- package/lib/autonomous/validators/privacy.js +296 -0
- package/lib/autonomous/validators/purple.js +298 -0
- package/lib/autonomous/validators/sigma.js +248 -0
- package/lib/autonomous/validators/threat-model.js +363 -0
- package/lib/benchmark/agent.js +119 -0
- package/lib/benchmark/baselines.js +43 -0
- package/lib/benchmark/builder.js +143 -0
- package/lib/benchmark/config.js +35 -0
- package/lib/benchmark/coordinator.js +91 -0
- package/lib/benchmark/index.js +20 -0
- package/lib/benchmark/llm.js +58 -0
- package/lib/benchmark/models.js +137 -0
- package/lib/benchmark/reporter.js +103 -0
- package/lib/benchmark/runner.js +103 -0
- package/lib/benchmark/sandbox.js +96 -0
- package/lib/benchmark/scorer.js +32 -0
- package/lib/benchmark/solver.js +166 -0
- package/lib/benchmark/tools.js +62 -0
- package/lib/bot/bot.js +130 -0
- package/lib/commands.js +99 -0
- package/lib/complexity.js +377 -0
- package/lib/config.js +213 -0
- package/lib/gateway/client.js +309 -0
- package/lib/gateway/commands.js +830 -0
- package/lib/gateway/config-validate.js +109 -0
- package/lib/gateway/gateway.js +367 -0
- package/lib/gateway/index.js +62 -0
- package/lib/gateway/mode.js +309 -0
- package/lib/gateway/plugins.js +222 -0
- package/lib/gateway/prompt.js +214 -0
- package/lib/mcp/server.js +262 -0
- package/lib/memory/compressor.js +425 -0
- package/lib/memory/engine.js +763 -0
- package/lib/memory/evolution.js +668 -0
- package/lib/memory/index.js +58 -0
- package/lib/memory/orchestrator.js +506 -0
- package/lib/memory/retriever.js +515 -0
- package/lib/memory/synthesizer.js +333 -0
- package/lib/pipeline/async-scanner.js +510 -0
- package/lib/pipeline/binary-analysis.js +1043 -0
- package/lib/pipeline/dom-xss-scanner.js +435 -0
- package/lib/pipeline/github-actions.js +792 -0
- package/lib/pipeline/index.js +124 -0
- package/lib/pipeline/osint.js +498 -0
- package/lib/pipeline/sarif.js +373 -0
- package/lib/pipeline/scanner.js +880 -0
- package/lib/pipeline/template-manager.js +525 -0
- package/lib/pipeline/xss-scanner.js +353 -0
- package/lib/setup-wizard.js +229 -0
- package/package.json +30 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
// Copyright (c) 2026 defconxt. All rights reserved.
|
|
2
|
+
// Licensed under AGPL-3.0 — see LICENSE file for details.
|
|
3
|
+
// CIPHER is a trademark of defconxt.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ARCHITECT mode agent — Threat Modeling.
|
|
7
|
+
*
|
|
8
|
+
* Performs autonomous threat modeling using STRIDE + DREAD.
|
|
9
|
+
* Ported from autonomous/modes/architect.py.
|
|
10
|
+
*
|
|
11
|
+
* @module autonomous/modes/architect
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { ModeAgentConfig, ToolRegistry } from '../framework.js';
|
|
15
|
+
import { ThreatModelValidator } from '../validators/threat-model.js';
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Architecture analysis keywords for system decomposition
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
const _PROCESS_KEYWORDS = [
|
|
22
|
+
'service', 'server', 'api', 'gateway', 'proxy', 'worker',
|
|
23
|
+
'handler', 'controller', 'middleware', 'microservice',
|
|
24
|
+
'application', 'app', 'frontend', 'backend', 'engine',
|
|
25
|
+
'processor', 'scheduler', 'daemon', 'auth', 'authentication',
|
|
26
|
+
'authorization', 'load balancer', 'reverse proxy',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const _DATA_STORE_KEYWORDS = [
|
|
30
|
+
'database', 'db', 'postgresql', 'postgres', 'mysql', 'mariadb',
|
|
31
|
+
'mongodb', 'redis', 'memcached', 'cache', 'elasticsearch',
|
|
32
|
+
'sqlite', 'dynamodb', 'cassandra', 's3', 'blob storage',
|
|
33
|
+
'file system', 'data warehouse', 'data lake', 'queue',
|
|
34
|
+
'message broker', 'kafka', 'rabbitmq', 'sqs',
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const _EXTERNAL_ENTITY_KEYWORDS = [
|
|
38
|
+
'external api', 'third-party', 'third party', '3rd party',
|
|
39
|
+
'stripe', 'twilio', 'sendgrid', 'aws', 'azure', 'gcp',
|
|
40
|
+
'oauth', 'sso', 'ldap', 'saml', 'webhook', 'cdn',
|
|
41
|
+
'payment', 'email service', 'sms', 'push notification',
|
|
42
|
+
'analytics', 'monitoring service', 'logging service',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Tool handlers
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Decompose a system description into architectural components.
|
|
51
|
+
* @param {*} context
|
|
52
|
+
* @param {Object} toolInput
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
export function _architectAnalyzeArchitecture(context, toolInput) {
|
|
56
|
+
const description = toolInput.system_description || '';
|
|
57
|
+
if (!description || !description.trim()) {
|
|
58
|
+
return "ERROR: 'system_description' parameter is required and must not be empty.";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const descLower = description.toLowerCase();
|
|
62
|
+
|
|
63
|
+
// Identify processes/services
|
|
64
|
+
const components = [];
|
|
65
|
+
for (const keyword of _PROCESS_KEYWORDS) {
|
|
66
|
+
if (descLower.includes(keyword)) {
|
|
67
|
+
const idx = descLower.indexOf(keyword);
|
|
68
|
+
const start = Math.max(0, idx - 40);
|
|
69
|
+
const end = Math.min(description.length, idx + keyword.length + 40);
|
|
70
|
+
const snippet = description.slice(start, end).trim();
|
|
71
|
+
components.push({
|
|
72
|
+
name: keyword.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
|
|
73
|
+
type: 'process',
|
|
74
|
+
source: snippet,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Identify data stores
|
|
80
|
+
const dataStores = [];
|
|
81
|
+
for (const keyword of _DATA_STORE_KEYWORDS) {
|
|
82
|
+
if (descLower.includes(keyword)) {
|
|
83
|
+
dataStores.push({
|
|
84
|
+
name: keyword.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
|
|
85
|
+
type: 'data_store',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Identify external entities
|
|
91
|
+
const externalEntities = [];
|
|
92
|
+
for (const keyword of _EXTERNAL_ENTITY_KEYWORDS) {
|
|
93
|
+
if (descLower.includes(keyword)) {
|
|
94
|
+
externalEntities.push({
|
|
95
|
+
name: keyword.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
|
|
96
|
+
type: 'external_entity',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Infer data flows between consecutive identified components
|
|
102
|
+
const allNames = [
|
|
103
|
+
...components.map(c => c.name),
|
|
104
|
+
...dataStores.map(d => d.name),
|
|
105
|
+
...externalEntities.map(e => e.name),
|
|
106
|
+
];
|
|
107
|
+
const dataFlows = [];
|
|
108
|
+
for (let i = 0; i < allNames.length - 1; i++) {
|
|
109
|
+
dataFlows.push({
|
|
110
|
+
from: allNames[i],
|
|
111
|
+
to: allNames[i + 1],
|
|
112
|
+
description: `Data flow from ${allNames[i]} to ${allNames[i + 1]}`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return JSON.stringify({
|
|
117
|
+
components,
|
|
118
|
+
data_stores: dataStores,
|
|
119
|
+
external_entities: externalEntities,
|
|
120
|
+
data_flows: dataFlows,
|
|
121
|
+
total_identified: components.length + dataStores.length + externalEntities.length,
|
|
122
|
+
}, null, 2);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Validate and score threats using DREAD risk methodology.
|
|
127
|
+
* @param {*} context
|
|
128
|
+
* @param {Object} toolInput
|
|
129
|
+
* @returns {string}
|
|
130
|
+
*/
|
|
131
|
+
export function _architectScoreThreats(context, toolInput) {
|
|
132
|
+
const threats = toolInput.threats || [];
|
|
133
|
+
if (!threats.length) {
|
|
134
|
+
return "ERROR: 'threats' parameter is required and must not be empty.";
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const dreadDimensions = [
|
|
138
|
+
'Damage', 'Reproducibility', 'Exploitability',
|
|
139
|
+
'Affected Users', 'Discoverability',
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
const scoredThreats = [];
|
|
143
|
+
let highestRisk = 'Low';
|
|
144
|
+
const riskPriority = { Critical: 4, High: 3, Medium: 2, Low: 1 };
|
|
145
|
+
|
|
146
|
+
for (let i = 0; i < threats.length; i++) {
|
|
147
|
+
const threat = threats[i];
|
|
148
|
+
if (typeof threat !== 'object' || threat === null) {
|
|
149
|
+
return `ERROR: threats[${i}] must be a dict (got ${typeof threat}).`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const dread = threat.dread || {};
|
|
153
|
+
if (typeof dread !== 'object' || dread === null) {
|
|
154
|
+
return `ERROR: threats[${i}].dread must be a dict (got ${typeof dread}).`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Validate each DREAD dimension
|
|
158
|
+
let total = 0;
|
|
159
|
+
for (const dim of dreadDimensions) {
|
|
160
|
+
const val = dread[dim];
|
|
161
|
+
if (val === undefined || val === null) {
|
|
162
|
+
return `ERROR: threats[${i}].dread missing dimension: ${dim}`;
|
|
163
|
+
}
|
|
164
|
+
if (typeof val !== 'number') {
|
|
165
|
+
return `ERROR: threats[${i}].dread.${dim} must be an integer (got ${typeof val})`;
|
|
166
|
+
}
|
|
167
|
+
const valInt = Math.floor(val);
|
|
168
|
+
if (valInt < 1 || valInt > 10) {
|
|
169
|
+
return `ERROR: threats[${i}].dread.${dim} must be 1-10 (got ${valInt})`;
|
|
170
|
+
}
|
|
171
|
+
total += valInt;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const average = total / dreadDimensions.length;
|
|
175
|
+
|
|
176
|
+
// Assign risk level
|
|
177
|
+
let riskLevel;
|
|
178
|
+
if (average >= 8) riskLevel = 'Critical';
|
|
179
|
+
else if (average >= 6) riskLevel = 'High';
|
|
180
|
+
else if (average >= 4) riskLevel = 'Medium';
|
|
181
|
+
else riskLevel = 'Low';
|
|
182
|
+
|
|
183
|
+
if ((riskPriority[riskLevel] || 0) > (riskPriority[highestRisk] || 0)) {
|
|
184
|
+
highestRisk = riskLevel;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
scoredThreats.push({
|
|
188
|
+
component: threat.component || 'unknown',
|
|
189
|
+
threat_type: threat.threat_type || 'unknown',
|
|
190
|
+
description: threat.description || '',
|
|
191
|
+
dread,
|
|
192
|
+
average_score: Math.round(average * 100) / 100,
|
|
193
|
+
risk_level: riskLevel,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return JSON.stringify({
|
|
198
|
+
scored_threats: scoredThreats,
|
|
199
|
+
total_threats: scoredThreats.length,
|
|
200
|
+
highest_risk_level: highestRisk,
|
|
201
|
+
}, null, 2);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Store a structured JSON threat model report in context.
|
|
206
|
+
* @param {*} context
|
|
207
|
+
* @param {Object} toolInput
|
|
208
|
+
* @returns {string}
|
|
209
|
+
*/
|
|
210
|
+
export function _architectWriteThreatModel(context, toolInput) {
|
|
211
|
+
const report = toolInput.report || '';
|
|
212
|
+
|
|
213
|
+
if (typeof context !== 'object' || context === null) {
|
|
214
|
+
return 'ERROR: Context must be a dict.';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let reportData;
|
|
218
|
+
if (typeof report === 'string') {
|
|
219
|
+
try {
|
|
220
|
+
reportData = JSON.parse(report);
|
|
221
|
+
} catch {
|
|
222
|
+
reportData = report;
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
reportData = report;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
context.report = reportData;
|
|
229
|
+
const filename = toolInput.filename || 'threat_model.json';
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
`Threat model report stored as ${filename}. ` +
|
|
233
|
+
`Report is available in context['report'].`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
// Tool schemas (Anthropic format)
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
|
|
241
|
+
const _ARCHITECT_ANALYZE_ARCHITECTURE_SCHEMA = {
|
|
242
|
+
name: 'analyze_architecture',
|
|
243
|
+
description:
|
|
244
|
+
'Decompose a system description into architectural components: ' +
|
|
245
|
+
'processes/services, data stores, external entities, and data flows.',
|
|
246
|
+
input_schema: {
|
|
247
|
+
type: 'object',
|
|
248
|
+
properties: {
|
|
249
|
+
system_description: {
|
|
250
|
+
type: 'string',
|
|
251
|
+
description: 'Natural language description of the system architecture',
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
required: ['system_description'],
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const _ARCHITECT_SCORE_THREATS_SCHEMA = {
|
|
259
|
+
name: 'score_threats',
|
|
260
|
+
description:
|
|
261
|
+
'Validate and score threats using DREAD risk methodology. Each threat ' +
|
|
262
|
+
'needs DREAD dimension scores (1-10). Returns scored threats with risk levels.',
|
|
263
|
+
input_schema: {
|
|
264
|
+
type: 'object',
|
|
265
|
+
properties: {
|
|
266
|
+
threats: {
|
|
267
|
+
type: 'array',
|
|
268
|
+
description: 'List of threat objects with component, threat_type, description, dread scores',
|
|
269
|
+
items: {
|
|
270
|
+
type: 'object',
|
|
271
|
+
properties: {
|
|
272
|
+
component: { type: 'string', description: 'Component being threatened' },
|
|
273
|
+
threat_type: {
|
|
274
|
+
type: 'string',
|
|
275
|
+
description: 'STRIDE category: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, or Elevation of Privilege',
|
|
276
|
+
},
|
|
277
|
+
description: { type: 'string', description: 'Description of the threat' },
|
|
278
|
+
dread: {
|
|
279
|
+
type: 'object',
|
|
280
|
+
description: 'DREAD scores: Damage, Reproducibility, Exploitability, Affected Users, Discoverability (each 1-10)',
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
required: ['component', 'threat_type', 'description', 'dread'],
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
required: ['threats'],
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const _ARCHITECT_WRITE_THREAT_MODEL_SCHEMA = {
|
|
292
|
+
name: 'write_threat_model',
|
|
293
|
+
description:
|
|
294
|
+
'Submit the completed threat model report as JSON with required sections: ' +
|
|
295
|
+
'system_description, components, trust_boundaries, stride_analysis, ' +
|
|
296
|
+
'dread_scores, mitigations, dfd_mermaid.',
|
|
297
|
+
input_schema: {
|
|
298
|
+
type: 'object',
|
|
299
|
+
properties: {
|
|
300
|
+
report: {
|
|
301
|
+
type: 'string',
|
|
302
|
+
description: 'Full JSON threat model report as a string.',
|
|
303
|
+
},
|
|
304
|
+
filename: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
description: 'Filename for the report (e.g. threat_model.json)',
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
required: ['report'],
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
// System prompt template
|
|
315
|
+
// ---------------------------------------------------------------------------
|
|
316
|
+
|
|
317
|
+
const _ARCHITECT_SYSTEM_PROMPT = `\
|
|
318
|
+
You are an expert security architect performing threat modeling using the \
|
|
319
|
+
STRIDE methodology with DREAD risk scoring. Analyze the system description \
|
|
320
|
+
and produce a comprehensive structured threat model.
|
|
321
|
+
|
|
322
|
+
## System Description
|
|
323
|
+
{system_description}
|
|
324
|
+
|
|
325
|
+
## Instructions
|
|
326
|
+
1. Use \`analyze_architecture\` to decompose the system into components.
|
|
327
|
+
2. Perform STRIDE analysis on each component and data flow.
|
|
328
|
+
3. Use \`score_threats\` to compute DREAD risk scores for each threat.
|
|
329
|
+
4. Generate a Mermaid DFD showing components, trust boundaries, and data flows.
|
|
330
|
+
5. Use \`write_threat_model\` to submit the final report.
|
|
331
|
+
|
|
332
|
+
## Rules
|
|
333
|
+
- Analyze EVERY component for ALL 6 STRIDE categories
|
|
334
|
+
- Score EVERY threat with ALL 5 DREAD dimensions (integers 1-10)
|
|
335
|
+
- Include trust boundaries between all architectural tiers
|
|
336
|
+
- Generate valid Mermaid DFD syntax (starts with 'graph' or 'flowchart')
|
|
337
|
+
- Provide specific, actionable mitigations
|
|
338
|
+
`;
|
|
339
|
+
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
// Output parser (fallback for text-based output)
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Extract JSON threat model from LLM text output.
|
|
346
|
+
* @param {string} text
|
|
347
|
+
* @returns {Object}
|
|
348
|
+
*/
|
|
349
|
+
export function _architectOutputParser(text) {
|
|
350
|
+
if (!text || !text.trim()) {
|
|
351
|
+
return { raw_text: text, parse_error: 'empty output' };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
let matches = [...text.matchAll(/```json\s*\n(.*?)```/gs)].map(m => m[1]);
|
|
355
|
+
if (matches.length > 0) {
|
|
356
|
+
const jsonText = matches.join('\n');
|
|
357
|
+
try { return JSON.parse(jsonText); } catch (e) {
|
|
358
|
+
return { raw_text: text, parse_error: e.message };
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
matches = [...text.matchAll(/```\s*\n(.*?)```/gs)].map(m => m[1]);
|
|
363
|
+
if (matches.length > 0) {
|
|
364
|
+
const jsonText = matches.join('\n');
|
|
365
|
+
try { return JSON.parse(jsonText); } catch (e) {
|
|
366
|
+
return { raw_text: text, parse_error: e.message };
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
try { return JSON.parse(text); } catch (e) {
|
|
371
|
+
return { raw_text: text, parse_error: e.message };
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ---------------------------------------------------------------------------
|
|
376
|
+
// Factory function
|
|
377
|
+
// ---------------------------------------------------------------------------
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Build an ARCHITECT-mode ModeAgentConfig for threat modeling.
|
|
381
|
+
* @returns {ModeAgentConfig}
|
|
382
|
+
*/
|
|
383
|
+
function _makeArchitectConfig() {
|
|
384
|
+
const reg = new ToolRegistry();
|
|
385
|
+
reg.register('analyze_architecture', _ARCHITECT_ANALYZE_ARCHITECTURE_SCHEMA, _architectAnalyzeArchitecture);
|
|
386
|
+
reg.register('score_threats', _ARCHITECT_SCORE_THREATS_SCHEMA, _architectScoreThreats);
|
|
387
|
+
reg.register('write_threat_model', _ARCHITECT_WRITE_THREAT_MODEL_SCHEMA, _architectWriteThreatModel);
|
|
388
|
+
|
|
389
|
+
return new ModeAgentConfig({
|
|
390
|
+
mode: 'ARCHITECT',
|
|
391
|
+
toolRegistry: reg,
|
|
392
|
+
systemPromptTemplate: _ARCHITECT_SYSTEM_PROMPT,
|
|
393
|
+
validator: new ThreatModelValidator(),
|
|
394
|
+
maxTurns: 15,
|
|
395
|
+
requiresSandbox: false,
|
|
396
|
+
completionCheck: null,
|
|
397
|
+
outputParser: _architectOutputParser,
|
|
398
|
+
outputFormat: 'json',
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// ---------------------------------------------------------------------------
|
|
403
|
+
// Registration function — called by runner.initModes()
|
|
404
|
+
// ---------------------------------------------------------------------------
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Register ARCHITECT mode with the given registerMode function.
|
|
408
|
+
* @param {Function} registerMode
|
|
409
|
+
*/
|
|
410
|
+
export function register(registerMode) {
|
|
411
|
+
registerMode('ARCHITECT', _makeArchitectConfig);
|
|
412
|
+
}
|