@cdot65/daystrom 1.1.1 → 1.2.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/README.md +1 -1
- package/dist/airs/management.d.ts.map +1 -1
- package/dist/airs/management.js +2 -7
- package/dist/airs/management.js.map +1 -1
- package/dist/airs/promptsets.d.ts +24 -0
- package/dist/airs/promptsets.d.ts.map +1 -0
- package/dist/airs/promptsets.js +35 -0
- package/dist/airs/promptsets.js.map +1 -0
- package/dist/airs/redteam.d.ts +35 -0
- package/dist/airs/redteam.d.ts.map +1 -0
- package/dist/airs/redteam.js +167 -0
- package/dist/airs/redteam.js.map +1 -0
- package/dist/airs/types.d.ts +135 -1
- package/dist/airs/types.d.ts.map +1 -1
- package/dist/airs/types.js +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +18 -0
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/redteam.d.ts +4 -0
- package/dist/cli/commands/redteam.d.ts.map +1 -0
- package/dist/cli/commands/redteam.js +203 -0
- package/dist/cli/commands/redteam.js.map +1 -0
- package/dist/cli/commands/resume.d.ts.map +1 -1
- package/dist/cli/commands/resume.js +18 -0
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/renderer.d.ts +88 -0
- package/dist/cli/renderer.d.ts.map +1 -1
- package/dist/cli/renderer.js +174 -0
- package/dist/cli/renderer.js.map +1 -1
- package/dist/core/loop.d.ts +3 -1
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +17 -0
- package/dist/core/loop.js.map +1 -1
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/schemas.d.ts +10 -10
- package/package.json +1 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { SdkRedTeamService } from '../../airs/redteam.js';
|
|
2
|
+
import { loadConfig } from '../../config/loader.js';
|
|
3
|
+
import { renderAttackList, renderCategories, renderCustomReport, renderError, renderRedteamHeader, renderScanList, renderScanProgress, renderScanStatus, renderStaticReport, renderTargetList, } from '../renderer.js';
|
|
4
|
+
/** Create an SdkRedTeamService from config. */
|
|
5
|
+
async function createService() {
|
|
6
|
+
const config = await loadConfig();
|
|
7
|
+
return new SdkRedTeamService({
|
|
8
|
+
clientId: config.mgmtClientId,
|
|
9
|
+
clientSecret: config.mgmtClientSecret,
|
|
10
|
+
tsgId: config.mgmtTsgId,
|
|
11
|
+
tokenEndpoint: config.mgmtTokenEndpoint,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/** Register the `redteam` command group. */
|
|
15
|
+
export function registerRedteamCommand(program) {
|
|
16
|
+
const redteam = program.command('redteam').description('AI Red Team scan operations');
|
|
17
|
+
// -----------------------------------------------------------------------
|
|
18
|
+
// redteam scan — execute a red team scan
|
|
19
|
+
// -----------------------------------------------------------------------
|
|
20
|
+
redteam
|
|
21
|
+
.command('scan')
|
|
22
|
+
.description('Execute a red team scan against a target')
|
|
23
|
+
.requiredOption('--target <uuid>', 'Target UUID')
|
|
24
|
+
.requiredOption('--name <name>', 'Scan name')
|
|
25
|
+
.option('--type <type>', 'Job type: STATIC, DYNAMIC, or CUSTOM', 'STATIC')
|
|
26
|
+
.option('--categories <json>', 'Category filter JSON (STATIC scans)')
|
|
27
|
+
.option('--prompt-sets <uuids>', 'Comma-separated prompt set UUIDs (CUSTOM scans)')
|
|
28
|
+
.option('--no-wait', 'Submit scan without waiting for completion')
|
|
29
|
+
.action(async (opts) => {
|
|
30
|
+
try {
|
|
31
|
+
renderRedteamHeader();
|
|
32
|
+
const service = await createService();
|
|
33
|
+
let categories;
|
|
34
|
+
if (opts.categories) {
|
|
35
|
+
categories = JSON.parse(opts.categories);
|
|
36
|
+
}
|
|
37
|
+
const customPromptSets = opts.promptSets
|
|
38
|
+
? opts.promptSets.split(',').map((s) => s.trim())
|
|
39
|
+
: undefined;
|
|
40
|
+
console.log(` Creating ${opts.type} scan "${opts.name}"...`);
|
|
41
|
+
const job = await service.createScan({
|
|
42
|
+
name: opts.name,
|
|
43
|
+
targetUuid: opts.target,
|
|
44
|
+
jobType: opts.type,
|
|
45
|
+
categories,
|
|
46
|
+
customPromptSets,
|
|
47
|
+
});
|
|
48
|
+
renderScanStatus(job);
|
|
49
|
+
if (opts.wait !== false) {
|
|
50
|
+
console.log(' Waiting for completion...\n');
|
|
51
|
+
const completed = await service.waitForCompletion(job.uuid, (progress) => renderScanProgress(progress));
|
|
52
|
+
console.log('\n');
|
|
53
|
+
renderScanStatus(completed);
|
|
54
|
+
console.log(` Job ID: ${completed.uuid}`);
|
|
55
|
+
console.log(' Run `daystrom redteam report <jobId>` to view results.\n');
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log(` Job ID: ${job.uuid}`);
|
|
59
|
+
console.log(' Run `daystrom redteam status <jobId>` to check progress.\n');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// -----------------------------------------------------------------------
|
|
68
|
+
// redteam status — check scan status
|
|
69
|
+
// -----------------------------------------------------------------------
|
|
70
|
+
redteam
|
|
71
|
+
.command('status <jobId>')
|
|
72
|
+
.description('Check scan status')
|
|
73
|
+
.action(async (jobId) => {
|
|
74
|
+
try {
|
|
75
|
+
renderRedteamHeader();
|
|
76
|
+
const service = await createService();
|
|
77
|
+
const job = await service.getScan(jobId);
|
|
78
|
+
renderScanStatus(job);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// -----------------------------------------------------------------------
|
|
86
|
+
// redteam report — view scan report
|
|
87
|
+
// -----------------------------------------------------------------------
|
|
88
|
+
redteam
|
|
89
|
+
.command('report <jobId>')
|
|
90
|
+
.description('View scan report')
|
|
91
|
+
.option('--attacks', 'Include attack list', false)
|
|
92
|
+
.option('--severity <level>', 'Filter attacks by severity')
|
|
93
|
+
.option('--limit <n>', 'Max attacks to show', '20')
|
|
94
|
+
.action(async (jobId, opts) => {
|
|
95
|
+
try {
|
|
96
|
+
renderRedteamHeader();
|
|
97
|
+
const service = await createService();
|
|
98
|
+
const job = await service.getScan(jobId);
|
|
99
|
+
renderScanStatus(job);
|
|
100
|
+
if (job.jobType === 'CUSTOM') {
|
|
101
|
+
const report = await service.getCustomReport(jobId);
|
|
102
|
+
renderCustomReport(report);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const report = await service.getStaticReport(jobId);
|
|
106
|
+
renderStaticReport(report);
|
|
107
|
+
}
|
|
108
|
+
if (opts.attacks) {
|
|
109
|
+
const attacks = await service.listAttacks(jobId, {
|
|
110
|
+
severity: opts.severity,
|
|
111
|
+
limit: Number.parseInt(opts.limit, 10),
|
|
112
|
+
});
|
|
113
|
+
renderAttackList(attacks);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// -----------------------------------------------------------------------
|
|
122
|
+
// redteam list — list recent scans
|
|
123
|
+
// -----------------------------------------------------------------------
|
|
124
|
+
redteam
|
|
125
|
+
.command('list')
|
|
126
|
+
.description('List recent scans')
|
|
127
|
+
.option('--status <status>', 'Filter by status (QUEUED, RUNNING, COMPLETED, FAILED, ABORTED)')
|
|
128
|
+
.option('--type <type>', 'Filter by job type (STATIC, DYNAMIC, CUSTOM)')
|
|
129
|
+
.option('--target <uuid>', 'Filter by target UUID')
|
|
130
|
+
.option('--limit <n>', 'Max results', '10')
|
|
131
|
+
.action(async (opts) => {
|
|
132
|
+
try {
|
|
133
|
+
renderRedteamHeader();
|
|
134
|
+
const service = await createService();
|
|
135
|
+
const scans = await service.listScans({
|
|
136
|
+
status: opts.status,
|
|
137
|
+
jobType: opts.type,
|
|
138
|
+
targetId: opts.target,
|
|
139
|
+
limit: Number.parseInt(opts.limit, 10),
|
|
140
|
+
});
|
|
141
|
+
renderScanList(scans);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// -----------------------------------------------------------------------
|
|
149
|
+
// redteam targets — list configured targets
|
|
150
|
+
// -----------------------------------------------------------------------
|
|
151
|
+
redteam
|
|
152
|
+
.command('targets')
|
|
153
|
+
.description('List configured red team targets')
|
|
154
|
+
.action(async () => {
|
|
155
|
+
try {
|
|
156
|
+
renderRedteamHeader();
|
|
157
|
+
const service = await createService();
|
|
158
|
+
const targets = await service.listTargets();
|
|
159
|
+
renderTargetList(targets);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
// -----------------------------------------------------------------------
|
|
167
|
+
// redteam categories — list attack categories
|
|
168
|
+
// -----------------------------------------------------------------------
|
|
169
|
+
redteam
|
|
170
|
+
.command('categories')
|
|
171
|
+
.description('List available attack categories')
|
|
172
|
+
.action(async () => {
|
|
173
|
+
try {
|
|
174
|
+
renderRedteamHeader();
|
|
175
|
+
const service = await createService();
|
|
176
|
+
const categories = await service.getCategories();
|
|
177
|
+
renderCategories(categories);
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// -----------------------------------------------------------------------
|
|
185
|
+
// redteam abort — abort a running scan
|
|
186
|
+
// -----------------------------------------------------------------------
|
|
187
|
+
redteam
|
|
188
|
+
.command('abort <jobId>')
|
|
189
|
+
.description('Abort a running scan')
|
|
190
|
+
.action(async (jobId) => {
|
|
191
|
+
try {
|
|
192
|
+
renderRedteamHeader();
|
|
193
|
+
const service = await createService();
|
|
194
|
+
await service.abortScan(jobId);
|
|
195
|
+
console.log(` Scan ${jobId} aborted.\n`);
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
renderError(err instanceof Error ? err.message : String(err));
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=redteam.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redteam.js","sourceRoot":"","sources":["../../../src/cli/commands/redteam.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/resume.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/resume.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBzC,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuH5D"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { SdkManagementService } from '../../airs/management.js';
|
|
3
|
+
import { SdkPromptSetService } from '../../airs/promptsets.js';
|
|
3
4
|
import { AirsScanService, DebugScanService } from '../../airs/scanner.js';
|
|
4
5
|
import { loadConfig } from '../../config/loader.js';
|
|
5
6
|
import { runLoop } from '../../core/loop.js';
|
|
@@ -14,6 +15,8 @@ export function registerResumeCommand(program) {
|
|
|
14
15
|
.description('Resume a paused or failed run')
|
|
15
16
|
.option('--max-iterations <n>', 'Additional iterations to run', '10')
|
|
16
17
|
.option('--debug-scans', 'Dump raw AIRS scan responses to JSONL for debugging', false)
|
|
18
|
+
.option('--create-prompt-set', 'Create custom prompt set from test cases after loop', false)
|
|
19
|
+
.option('--prompt-set-name <name>', 'Override auto-generated prompt set name')
|
|
17
20
|
.action(async (runId, opts) => {
|
|
18
21
|
try {
|
|
19
22
|
renderHeader();
|
|
@@ -33,6 +36,8 @@ export function registerResumeCommand(program) {
|
|
|
33
36
|
const userInput = {
|
|
34
37
|
...existingRun.userInput,
|
|
35
38
|
maxIterations: existingRun.currentIteration + additionalIterations,
|
|
39
|
+
createPromptSet: opts.createPromptSet ?? false,
|
|
40
|
+
promptSetName: opts.promptSetName,
|
|
36
41
|
};
|
|
37
42
|
const model = await createLlmProvider({
|
|
38
43
|
provider: config.llmProvider,
|
|
@@ -60,12 +65,22 @@ export function registerResumeCommand(program) {
|
|
|
60
65
|
apiEndpoint: config.mgmtEndpoint,
|
|
61
66
|
tokenEndpoint: config.mgmtTokenEndpoint,
|
|
62
67
|
});
|
|
68
|
+
// Set up prompt set service if requested
|
|
69
|
+
const promptSets = userInput.createPromptSet
|
|
70
|
+
? new SdkPromptSetService({
|
|
71
|
+
clientId: config.mgmtClientId,
|
|
72
|
+
clientSecret: config.mgmtClientSecret,
|
|
73
|
+
tsgId: config.mgmtTsgId,
|
|
74
|
+
tokenEndpoint: config.mgmtTokenEndpoint,
|
|
75
|
+
})
|
|
76
|
+
: undefined;
|
|
63
77
|
console.log(` Resuming run ${runId} from iteration ${existingRun.currentIteration}...`);
|
|
64
78
|
for await (const event of runLoop(userInput, {
|
|
65
79
|
llm,
|
|
66
80
|
management,
|
|
67
81
|
scanner,
|
|
68
82
|
propagationDelayMs: config.propagationDelayMs,
|
|
83
|
+
promptSets,
|
|
69
84
|
})) {
|
|
70
85
|
switch (event.type) {
|
|
71
86
|
case 'iteration:start':
|
|
@@ -89,6 +104,9 @@ export function registerResumeCommand(program) {
|
|
|
89
104
|
case 'iteration:complete':
|
|
90
105
|
renderIterationSummary(event.result);
|
|
91
106
|
break;
|
|
107
|
+
case 'promptset:created':
|
|
108
|
+
console.log(` ✓ Custom prompt set created: ${event.promptSetName} (${event.promptCount} prompts)`);
|
|
109
|
+
break;
|
|
92
110
|
case 'loop:complete':
|
|
93
111
|
await store.save(event.runState);
|
|
94
112
|
renderLoopComplete(event.runState);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../../src/cli/commands/resume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,sEAAsE;AACtE,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,EAAE,IAAI,CAAC;SACpE,MAAM,CAAC,eAAe,EAAE,qDAAqD,EAAE,KAAK,CAAC;SACrF,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAI,EAAE,EAAE;QACpC,IAAI,CAAC;YACH,YAAY,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE5C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,WAAW,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,WAAW,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBACvC,WAAW,CAAC,0BAA0B,CAAC,CAAC;gBACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,oBAAoB,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YAErE,qCAAqC;YACrC,MAAM,SAAS,GAAG;gBAChB,GAAG,WAAW,CAAC,SAAS;gBACxB,aAAa,EAAE,WAAW,CAAC,gBAAgB,GAAG,oBAAoB;
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../../src/cli/commands/resume.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import 'dotenv/config';
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { registerGenerateCommand } from './commands/generate.js';
|
|
5
5
|
import { registerListCommand } from './commands/list.js';
|
|
6
|
+
import { registerRedteamCommand } from './commands/redteam.js';
|
|
6
7
|
import { registerReportCommand } from './commands/report.js';
|
|
7
8
|
import { registerResumeCommand } from './commands/resume.js';
|
|
8
9
|
const program = new Command();
|
|
@@ -14,5 +15,6 @@ registerGenerateCommand(program);
|
|
|
14
15
|
registerResumeCommand(program);
|
|
15
16
|
registerReportCommand(program);
|
|
16
17
|
registerListCommand(program);
|
|
18
|
+
registerRedteamCommand(program);
|
|
17
19
|
program.parse();
|
|
18
20
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/cli/renderer.d.ts
CHANGED
|
@@ -24,6 +24,94 @@ export declare function renderIterationSummary(result: IterationResult): void;
|
|
|
24
24
|
export declare function renderMemoryLoaded(learningCount: number): void;
|
|
25
25
|
/** Render count of learnings extracted from the current run. */
|
|
26
26
|
export declare function renderMemoryExtracted(learningCount: number): void;
|
|
27
|
+
/** Render the red team banner. */
|
|
28
|
+
export declare function renderRedteamHeader(): void;
|
|
29
|
+
/** Render a scan's status summary. */
|
|
30
|
+
export declare function renderScanStatus(job: {
|
|
31
|
+
uuid: string;
|
|
32
|
+
name: string;
|
|
33
|
+
status: string;
|
|
34
|
+
jobType: string;
|
|
35
|
+
targetName?: string;
|
|
36
|
+
score?: number | null;
|
|
37
|
+
asr?: number | null;
|
|
38
|
+
completed?: number | null;
|
|
39
|
+
total?: number | null;
|
|
40
|
+
}): void;
|
|
41
|
+
/** Render a table of scans. */
|
|
42
|
+
export declare function renderScanList(jobs: Array<{
|
|
43
|
+
uuid: string;
|
|
44
|
+
name: string;
|
|
45
|
+
status: string;
|
|
46
|
+
jobType: string;
|
|
47
|
+
score?: number | null;
|
|
48
|
+
createdAt?: string | null;
|
|
49
|
+
}>): void;
|
|
50
|
+
/** Render a static scan report. */
|
|
51
|
+
export declare function renderStaticReport(report: {
|
|
52
|
+
score?: number | null;
|
|
53
|
+
asr?: number | null;
|
|
54
|
+
severityBreakdown: Array<{
|
|
55
|
+
severity: string;
|
|
56
|
+
successful: number;
|
|
57
|
+
failed: number;
|
|
58
|
+
}>;
|
|
59
|
+
reportSummary?: string | null;
|
|
60
|
+
categories: Array<{
|
|
61
|
+
id: string;
|
|
62
|
+
displayName: string;
|
|
63
|
+
asr: number;
|
|
64
|
+
successful: number;
|
|
65
|
+
failed: number;
|
|
66
|
+
total: number;
|
|
67
|
+
}>;
|
|
68
|
+
}): void;
|
|
69
|
+
/** Render a custom attack report. */
|
|
70
|
+
export declare function renderCustomReport(report: {
|
|
71
|
+
totalPrompts: number;
|
|
72
|
+
totalAttacks: number;
|
|
73
|
+
totalThreats: number;
|
|
74
|
+
score: number;
|
|
75
|
+
asr: number;
|
|
76
|
+
promptSets: Array<{
|
|
77
|
+
promptSetName: string;
|
|
78
|
+
totalPrompts: number;
|
|
79
|
+
totalThreats: number;
|
|
80
|
+
threatRate: number;
|
|
81
|
+
}>;
|
|
82
|
+
}): void;
|
|
83
|
+
/** Render attack list with severity coloring. */
|
|
84
|
+
export declare function renderAttackList(attacks: Array<{
|
|
85
|
+
name: string;
|
|
86
|
+
severity?: string;
|
|
87
|
+
category?: string;
|
|
88
|
+
successful: boolean;
|
|
89
|
+
}>): void;
|
|
90
|
+
/** Render target list. */
|
|
91
|
+
export declare function renderTargetList(targets: Array<{
|
|
92
|
+
uuid: string;
|
|
93
|
+
name: string;
|
|
94
|
+
status: string;
|
|
95
|
+
targetType?: string;
|
|
96
|
+
active: boolean;
|
|
97
|
+
}>): void;
|
|
98
|
+
/** Render attack category tree. */
|
|
99
|
+
export declare function renderCategories(categories: Array<{
|
|
100
|
+
id: string;
|
|
101
|
+
displayName: string;
|
|
102
|
+
description?: string;
|
|
103
|
+
subCategories: Array<{
|
|
104
|
+
id: string;
|
|
105
|
+
displayName: string;
|
|
106
|
+
description?: string;
|
|
107
|
+
}>;
|
|
108
|
+
}>): void;
|
|
109
|
+
/** Render polling progress inline. */
|
|
110
|
+
export declare function renderScanProgress(job: {
|
|
111
|
+
status: string;
|
|
112
|
+
completed?: number | null;
|
|
113
|
+
total?: number | null;
|
|
114
|
+
}): void;
|
|
27
115
|
/** Render accumulated test count with optional dropped info. */
|
|
28
116
|
export declare function renderTestsAccumulated(newCount: number, totalCount: number, droppedCount: number): void;
|
|
29
117
|
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/cli/renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,qCAAqC;AACrC,wBAAgB,YAAY,IAAI,IAAI,CAGnC;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAQpD;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAKzE;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAe5D;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAe7D;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAW3D;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,CAsB3D;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAUpE;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAM9D;AAED,gEAAgE;AAChE,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAEjE;AAED,gEAAgE;AAChE,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,IAAI,CAMN"}
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/cli/renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/renderer.js
CHANGED
|
@@ -112,6 +112,180 @@ export function renderMemoryLoaded(learningCount) {
|
|
|
112
112
|
export function renderMemoryExtracted(learningCount) {
|
|
113
113
|
console.log(chalk.cyan(` Memory: extracted ${learningCount} learnings from this run`));
|
|
114
114
|
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Red Team rendering
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
/** Render the red team banner. */
|
|
119
|
+
export function renderRedteamHeader() {
|
|
120
|
+
console.log(chalk.bold.red('\n Prisma AIRS — AI Red Team'));
|
|
121
|
+
console.log(chalk.dim(' Adversarial scan operations\n'));
|
|
122
|
+
}
|
|
123
|
+
/** Severity → chalk color mapping. */
|
|
124
|
+
function severityColor(severity) {
|
|
125
|
+
switch (severity.toUpperCase()) {
|
|
126
|
+
case 'CRITICAL':
|
|
127
|
+
return chalk.red;
|
|
128
|
+
case 'HIGH':
|
|
129
|
+
return chalk.magenta;
|
|
130
|
+
case 'MEDIUM':
|
|
131
|
+
return chalk.yellow;
|
|
132
|
+
case 'LOW':
|
|
133
|
+
return chalk.cyan;
|
|
134
|
+
default:
|
|
135
|
+
return chalk.dim;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Status → chalk color mapping. */
|
|
139
|
+
function statusColor(status) {
|
|
140
|
+
switch (status) {
|
|
141
|
+
case 'COMPLETED':
|
|
142
|
+
return chalk.green;
|
|
143
|
+
case 'RUNNING':
|
|
144
|
+
return chalk.blue;
|
|
145
|
+
case 'QUEUED':
|
|
146
|
+
case 'INIT':
|
|
147
|
+
return chalk.yellow;
|
|
148
|
+
case 'FAILED':
|
|
149
|
+
case 'ABORTED':
|
|
150
|
+
return chalk.red;
|
|
151
|
+
case 'PARTIALLY_COMPLETE':
|
|
152
|
+
return chalk.yellow;
|
|
153
|
+
default:
|
|
154
|
+
return chalk.white;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Render a scan's status summary. */
|
|
158
|
+
export function renderScanStatus(job) {
|
|
159
|
+
console.log(chalk.bold(' Scan Status:'));
|
|
160
|
+
console.log(` ID: ${chalk.dim(job.uuid)}`);
|
|
161
|
+
console.log(` Name: ${job.name}`);
|
|
162
|
+
console.log(` Type: ${job.jobType}`);
|
|
163
|
+
if (job.targetName)
|
|
164
|
+
console.log(` Target: ${job.targetName}`);
|
|
165
|
+
console.log(` Status: ${statusColor(job.status)(job.status)}`);
|
|
166
|
+
if (job.total != null && job.completed != null) {
|
|
167
|
+
console.log(` Progress: ${job.completed}/${job.total}`);
|
|
168
|
+
}
|
|
169
|
+
if (job.score != null)
|
|
170
|
+
console.log(` Score: ${job.score}`);
|
|
171
|
+
if (job.asr != null)
|
|
172
|
+
console.log(` ASR: ${(job.asr * 100).toFixed(1)}%`);
|
|
173
|
+
console.log();
|
|
174
|
+
}
|
|
175
|
+
/** Render a table of scans. */
|
|
176
|
+
export function renderScanList(jobs) {
|
|
177
|
+
if (jobs.length === 0) {
|
|
178
|
+
console.log(chalk.dim(' No scans found.\n'));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
console.log(chalk.bold('\n Recent Scans:\n'));
|
|
182
|
+
for (const job of jobs) {
|
|
183
|
+
console.log(` ${chalk.dim(job.uuid)}`);
|
|
184
|
+
console.log(` ${job.name} ${statusColor(job.status)(job.status)} ${job.jobType}${job.score != null ? ` score: ${job.score}` : ''}`);
|
|
185
|
+
if (job.createdAt)
|
|
186
|
+
console.log(` ${chalk.dim(job.createdAt)}`);
|
|
187
|
+
console.log();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Render a static scan report. */
|
|
191
|
+
export function renderStaticReport(report) {
|
|
192
|
+
console.log(chalk.bold('\n Static Scan Report:'));
|
|
193
|
+
if (report.score != null)
|
|
194
|
+
console.log(` Score: ${report.score}`);
|
|
195
|
+
if (report.asr != null)
|
|
196
|
+
console.log(` ASR: ${(report.asr * 100).toFixed(1)}%`);
|
|
197
|
+
if (report.severityBreakdown.length > 0) {
|
|
198
|
+
console.log(chalk.bold('\n Severity Breakdown:'));
|
|
199
|
+
for (const s of report.severityBreakdown) {
|
|
200
|
+
const color = severityColor(s.severity);
|
|
201
|
+
console.log(` ${color(s.severity.padEnd(10))} ${chalk.red(`${s.successful} bypassed`)} ${chalk.green(`${s.failed} blocked`)}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (report.categories.length > 0) {
|
|
205
|
+
console.log(chalk.bold('\n Categories:'));
|
|
206
|
+
for (const c of report.categories) {
|
|
207
|
+
const asrPct = (c.asr * 100).toFixed(1);
|
|
208
|
+
console.log(` ${c.displayName.padEnd(30)} ASR: ${asrPct}% (${c.successful}/${c.total})`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (report.reportSummary) {
|
|
212
|
+
console.log(chalk.bold('\n Summary:'));
|
|
213
|
+
console.log(` ${report.reportSummary}`);
|
|
214
|
+
}
|
|
215
|
+
console.log();
|
|
216
|
+
}
|
|
217
|
+
/** Render a custom attack report. */
|
|
218
|
+
export function renderCustomReport(report) {
|
|
219
|
+
console.log(chalk.bold('\n Custom Attack Report:'));
|
|
220
|
+
console.log(` Score: ${report.score}`);
|
|
221
|
+
console.log(` ASR: ${(report.asr * 100).toFixed(1)}%`);
|
|
222
|
+
console.log(` Attacks: ${report.totalAttacks} Threats: ${report.totalThreats}`);
|
|
223
|
+
if (report.promptSets.length > 0) {
|
|
224
|
+
console.log(chalk.bold('\n Prompt Sets:'));
|
|
225
|
+
for (const ps of report.promptSets) {
|
|
226
|
+
console.log(` ${ps.promptSetName.padEnd(40)} ${ps.totalThreats}/${ps.totalPrompts} threats (${(ps.threatRate * 100).toFixed(1)}%)`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
console.log();
|
|
230
|
+
}
|
|
231
|
+
/** Render attack list with severity coloring. */
|
|
232
|
+
export function renderAttackList(attacks) {
|
|
233
|
+
if (attacks.length === 0) {
|
|
234
|
+
console.log(chalk.dim(' No attacks found.\n'));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
console.log(chalk.bold('\n Attacks:\n'));
|
|
238
|
+
for (const a of attacks) {
|
|
239
|
+
const sev = a.severity
|
|
240
|
+
? severityColor(a.severity)(a.severity.padEnd(10))
|
|
241
|
+
: chalk.dim('N/A'.padEnd(10));
|
|
242
|
+
const result = a.successful ? chalk.red('BYPASSED') : chalk.green('BLOCKED');
|
|
243
|
+
console.log(` ${sev} ${result} ${a.name}${a.category ? chalk.dim(` [${a.category}]`) : ''}`);
|
|
244
|
+
}
|
|
245
|
+
console.log();
|
|
246
|
+
}
|
|
247
|
+
/** Render target list. */
|
|
248
|
+
export function renderTargetList(targets) {
|
|
249
|
+
if (targets.length === 0) {
|
|
250
|
+
console.log(chalk.dim(' No targets found.\n'));
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
console.log(chalk.bold('\n Targets:\n'));
|
|
254
|
+
for (const t of targets) {
|
|
255
|
+
console.log(` ${chalk.dim(t.uuid)}`);
|
|
256
|
+
console.log(` ${t.name} ${statusColor(t.active ? 'COMPLETED' : 'FAILED')(t.active ? 'active' : 'inactive')}${t.targetType ? ` type: ${t.targetType}` : ''}`);
|
|
257
|
+
}
|
|
258
|
+
console.log();
|
|
259
|
+
}
|
|
260
|
+
/** Render attack category tree. */
|
|
261
|
+
export function renderCategories(categories) {
|
|
262
|
+
if (categories.length === 0) {
|
|
263
|
+
console.log(chalk.dim(' No categories found.\n'));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
console.log(chalk.bold('\n Attack Categories:\n'));
|
|
267
|
+
for (const c of categories) {
|
|
268
|
+
console.log(` ${chalk.bold(c.displayName)}${c.description ? chalk.dim(` — ${c.description}`) : ''}`);
|
|
269
|
+
for (const sc of c.subCategories) {
|
|
270
|
+
console.log(` ${chalk.dim('•')} ${sc.displayName}${sc.description ? chalk.dim(` — ${sc.description}`) : ''}`);
|
|
271
|
+
}
|
|
272
|
+
console.log();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/** Render polling progress inline. */
|
|
276
|
+
export function renderScanProgress(job) {
|
|
277
|
+
if (job.total != null && job.completed != null && job.total > 0) {
|
|
278
|
+
const pct = Math.round((job.completed / job.total) * 100);
|
|
279
|
+
const bar = '█'.repeat(Math.round(pct / 5)) + '░'.repeat(20 - Math.round(pct / 5));
|
|
280
|
+
process.stdout.write(`\r ${statusColor(job.status)(job.status)} ${bar} ${pct}% (${job.completed}/${job.total})`);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
process.stdout.write(`\r ${statusColor(job.status)(job.status)}...`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
// Guardrail loop rendering
|
|
288
|
+
// ---------------------------------------------------------------------------
|
|
115
289
|
/** Render accumulated test count with optional dropped info. */
|
|
116
290
|
export function renderTestsAccumulated(newCount, totalCount, droppedCount) {
|
|
117
291
|
let msg = ` Tests: ${newCount} new, ${totalCount} total (accumulated)`;
|