@phenixstar/talon 1.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.
Files changed (112) hide show
  1. package/.env.example +72 -0
  2. package/Dockerfile +161 -0
  3. package/Dockerfile.router +16 -0
  4. package/LICENSE +661 -0
  5. package/README.md +709 -0
  6. package/bin/talon.js +96 -0
  7. package/bin/talon.mjs +96 -0
  8. package/configs/config-schema.json +160 -0
  9. package/configs/example-config.yaml +50 -0
  10. package/configs/mcp-allowlist.json +47 -0
  11. package/configs/model-routing.yaml +39 -0
  12. package/configs/router-config.json +73 -0
  13. package/configs/talon-seccomp.json +89 -0
  14. package/dist/cli/dependency-checker.d.ts +25 -0
  15. package/dist/cli/dependency-checker.d.ts.map +1 -0
  16. package/dist/cli/dependency-checker.js +165 -0
  17. package/dist/cli/dependency-checker.js.map +1 -0
  18. package/dist/cli/doctor.d.ts +2 -0
  19. package/dist/cli/doctor.d.ts.map +1 -0
  20. package/dist/cli/doctor.js +127 -0
  21. package/dist/cli/doctor.js.map +1 -0
  22. package/dist/cli/env-configurator.d.ts +27 -0
  23. package/dist/cli/env-configurator.d.ts.map +1 -0
  24. package/dist/cli/env-configurator.js +115 -0
  25. package/dist/cli/env-configurator.js.map +1 -0
  26. package/dist/cli/setup-renderer.d.ts +23 -0
  27. package/dist/cli/setup-renderer.d.ts.map +1 -0
  28. package/dist/cli/setup-renderer.js +71 -0
  29. package/dist/cli/setup-renderer.js.map +1 -0
  30. package/dist/cli/setup.d.ts +2 -0
  31. package/dist/cli/setup.d.ts.map +1 -0
  32. package/dist/cli/setup.js +302 -0
  33. package/dist/cli/setup.js.map +1 -0
  34. package/dist/types/activity-logger.d.ts +10 -0
  35. package/dist/types/activity-logger.d.ts.map +1 -0
  36. package/dist/types/activity-logger.js +7 -0
  37. package/dist/types/activity-logger.js.map +1 -0
  38. package/dist/types/agents.d.ts +39 -0
  39. package/dist/types/agents.d.ts.map +1 -0
  40. package/dist/types/agents.js +28 -0
  41. package/dist/types/agents.js.map +1 -0
  42. package/dist/types/audit.d.ts +28 -0
  43. package/dist/types/audit.d.ts.map +1 -0
  44. package/dist/types/audit.js +7 -0
  45. package/dist/types/audit.js.map +1 -0
  46. package/dist/types/backtesting.d.ts +45 -0
  47. package/dist/types/backtesting.d.ts.map +1 -0
  48. package/dist/types/backtesting.js +3 -0
  49. package/dist/types/backtesting.js.map +1 -0
  50. package/dist/types/config.d.ts +48 -0
  51. package/dist/types/config.d.ts.map +1 -0
  52. package/dist/types/config.js +7 -0
  53. package/dist/types/config.js.map +1 -0
  54. package/dist/types/errors.d.ts +55 -0
  55. package/dist/types/errors.d.ts.map +1 -0
  56. package/dist/types/errors.js +41 -0
  57. package/dist/types/errors.js.map +1 -0
  58. package/dist/types/evolution.d.ts +36 -0
  59. package/dist/types/evolution.d.ts.map +1 -0
  60. package/dist/types/evolution.js +14 -0
  61. package/dist/types/evolution.js.map +1 -0
  62. package/dist/types/index.d.ts +11 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +16 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/types/metrics.d.ts +13 -0
  67. package/dist/types/metrics.d.ts.map +1 -0
  68. package/dist/types/metrics.js +7 -0
  69. package/dist/types/metrics.js.map +1 -0
  70. package/dist/types/resilience.d.ts +30 -0
  71. package/dist/types/resilience.d.ts.map +1 -0
  72. package/dist/types/resilience.js +7 -0
  73. package/dist/types/resilience.js.map +1 -0
  74. package/dist/types/result.d.ts +42 -0
  75. package/dist/types/result.d.ts.map +1 -0
  76. package/dist/types/result.js +30 -0
  77. package/dist/types/result.js.map +1 -0
  78. package/docker-compose.yml +91 -0
  79. package/package.json +75 -0
  80. package/prompts/exploit-auth.txt +423 -0
  81. package/prompts/exploit-authz.txt +425 -0
  82. package/prompts/exploit-injection.txt +452 -0
  83. package/prompts/exploit-ssrf.txt +502 -0
  84. package/prompts/exploit-xss.txt +442 -0
  85. package/prompts/pipeline-testing/exploit-auth.txt +31 -0
  86. package/prompts/pipeline-testing/exploit-authz.txt +31 -0
  87. package/prompts/pipeline-testing/exploit-injection.txt +31 -0
  88. package/prompts/pipeline-testing/exploit-ssrf.txt +31 -0
  89. package/prompts/pipeline-testing/exploit-xss.txt +31 -0
  90. package/prompts/pipeline-testing/pre-recon-code.txt +1 -0
  91. package/prompts/pipeline-testing/recon.txt +1 -0
  92. package/prompts/pipeline-testing/report-executive.txt +1 -0
  93. package/prompts/pipeline-testing/vuln-auth.txt +13 -0
  94. package/prompts/pipeline-testing/vuln-authz.txt +13 -0
  95. package/prompts/pipeline-testing/vuln-injection.txt +13 -0
  96. package/prompts/pipeline-testing/vuln-ssrf.txt +13 -0
  97. package/prompts/pipeline-testing/vuln-xss.txt +13 -0
  98. package/prompts/pre-recon-code.txt +403 -0
  99. package/prompts/recon.txt +382 -0
  100. package/prompts/report-executive.txt +126 -0
  101. package/prompts/shared/_exploit-scope.txt +14 -0
  102. package/prompts/shared/_rules.txt +2 -0
  103. package/prompts/shared/_target.txt +1 -0
  104. package/prompts/shared/_vuln-scope.txt +1 -0
  105. package/prompts/shared/login-instructions.txt +82 -0
  106. package/prompts/vuln-auth.txt +268 -0
  107. package/prompts/vuln-authz.txt +373 -0
  108. package/prompts/vuln-injection.txt +380 -0
  109. package/prompts/vuln-ssrf.txt +315 -0
  110. package/prompts/vuln-xss.txt +304 -0
  111. package/talon +459 -0
  112. package/talon.ps1 +348 -0
package/talon.ps1 ADDED
@@ -0,0 +1,348 @@
1
+ #Requires -Version 5.1
2
+ <#
3
+ .SYNOPSIS
4
+ Talon CLI - AI Penetration Testing Framework (PowerShell wrapper)
5
+ .DESCRIPTION
6
+ PowerShell-native wrapper for Talon. Translates CLI commands to Docker Compose operations.
7
+ Equivalent to the bash ./talon script for Windows users without WSL/Git Bash.
8
+ .EXAMPLE
9
+ .\talon.ps1 start -URL http://localhost:3000 -REPO juice-shop
10
+ .\talon.ps1 workspaces
11
+ .\talon.ps1 logs -ID example_talon-123
12
+ .\talon.ps1 stop -CLEAN
13
+ #>
14
+
15
+ [CmdletBinding()]
16
+ param(
17
+ [Parameter(Position = 0)]
18
+ [ValidateSet('setup', 'doctor', 'start', 'stop', 'logs', 'workspaces', 'benchmark', 'evolve', 'help')]
19
+ [string]$Command = 'help',
20
+
21
+ [string]$URL,
22
+ [string]$REPO,
23
+ [string]$CONFIG,
24
+ [string]$OUTPUT,
25
+ [string]$ID,
26
+ [string]$WORKSPACE,
27
+ [string]$TARGET,
28
+ [int]$GENERATIONS = 1,
29
+ [string]$GROUND_TRUTH,
30
+ [string]$SEED,
31
+ [switch]$CLEAN,
32
+ [switch]$PIPELINE_TESTING,
33
+ [switch]$REBUILD,
34
+ [switch]$ROUTER
35
+ )
36
+
37
+ $ErrorActionPreference = 'Stop'
38
+
39
+ # Load .env if present
40
+ if (Test-Path '.env') {
41
+ Get-Content '.env' | ForEach-Object {
42
+ if ($_ -match '^\s*([^#][^=]+)=(.*)$') {
43
+ $key = $Matches[1].Trim()
44
+ $val = $Matches[2].Trim().Trim('"').Trim("'")
45
+ [Environment]::SetEnvironmentVariable($key, $val, 'Process')
46
+ }
47
+ }
48
+ }
49
+
50
+ $ComposeFile = 'docker-compose.yml'
51
+ # Docker on Windows doesn't need the extra_hosts override (host.docker.internal works natively)
52
+
53
+ function Show-Help {
54
+ Write-Host @"
55
+
56
+ ████████╗ █████╗ ██╗ ██████╗ ███╗ ██╗
57
+ ╚══██╔══╝██╔══██╗██║ ██╔═══██╗████╗ ██║
58
+ ██║ ███████║██║ ██║ ██║██╔██╗ ██║
59
+ ██║ ██╔══██║██║ ██║ ██║██║╚██╗██║
60
+ ██║ ██║ ██║███████╗╚██████╔╝██║ ╚████║
61
+ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═══╝
62
+
63
+ AI Penetration Testing Framework
64
+
65
+ Usage:
66
+ .\talon.ps1 setup Interactive setup wizard
67
+ .\talon.ps1 doctor Validate configuration and dependencies
68
+ .\talon.ps1 start -URL <url> -REPO <name> Start a pentest workflow
69
+ .\talon.ps1 workspaces List all workspaces
70
+ .\talon.ps1 logs -ID <workflow-id> Tail logs for a specific workflow
71
+ .\talon.ps1 stop Stop all containers
72
+ .\talon.ps1 help Show this help message
73
+
74
+ Options for 'start':
75
+ -REPO <name> Folder name under .\repos\ (e.g. -REPO repo-name)
76
+ -CONFIG <path> Configuration file (YAML)
77
+ -OUTPUT <path> Output directory for reports (default: .\audit-logs\)
78
+ -WORKSPACE <name> Named workspace (auto-resumes if exists)
79
+ -PIPELINE_TESTING Use minimal prompts for fast testing
80
+ -ROUTER Route through claude-code-router (multi-model support)
81
+ -REBUILD Force Docker rebuild
82
+
83
+ Options for 'stop':
84
+ -CLEAN Remove all data including volumes
85
+
86
+ Examples:
87
+ .\talon.ps1 start -URL https://example.com -REPO repo-name
88
+ .\talon.ps1 start -URL https://example.com -REPO repo-name -WORKSPACE q1-audit
89
+ .\talon.ps1 start -URL https://example.com -REPO repo-name -CONFIG .\config.yaml
90
+ .\talon.ps1 workspaces
91
+ .\talon.ps1 logs -ID example.com_talon-1234567890
92
+ .\talon.ps1 stop -CLEAN
93
+
94
+ Monitor workflows at http://localhost:8233
95
+ "@
96
+ }
97
+
98
+ function Invoke-Setup {
99
+ if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
100
+ Write-Error 'Node.js is required for the setup wizard. Install Node.js 22+: https://nodejs.org/en/download'
101
+ exit 1
102
+ }
103
+ if (-not (Test-Path 'dist\cli\setup.js')) {
104
+ Write-Host 'Building Talon...'
105
+ npm install --silent; npm run build
106
+ }
107
+ node dist/cli/setup.js
108
+ }
109
+
110
+ function Invoke-Doctor {
111
+ if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
112
+ Write-Error 'Node.js is required. Install: https://nodejs.org/en/download'
113
+ exit 1
114
+ }
115
+ if (-not (Test-Path 'dist\cli\doctor.js')) {
116
+ Write-Host 'Building Talon...'
117
+ npm install --silent; npm run build
118
+ }
119
+ node dist/cli/doctor.js
120
+ }
121
+
122
+ function Test-TemporalReady {
123
+ try {
124
+ $result = docker compose -f $ComposeFile exec -T temporal `
125
+ temporal operator cluster health --address localhost:7233 2>$null
126
+ return $result -match 'SERVING'
127
+ }
128
+ catch { return $false }
129
+ }
130
+
131
+ function Start-Containers {
132
+ if (Test-TemporalReady) {
133
+ docker compose -f $ComposeFile up -d worker 2>$null
134
+ return
135
+ }
136
+
137
+ Write-Host 'Starting Talon containers...'
138
+ if ($REBUILD) {
139
+ Write-Host 'Rebuilding with --no-cache...'
140
+ docker compose -f $ComposeFile build --no-cache worker
141
+ }
142
+ docker compose -f $ComposeFile up -d --build
143
+
144
+ Write-Host 'Waiting for Temporal to be ready...'
145
+ for ($i = 1; $i -le 30; $i++) {
146
+ if (Test-TemporalReady) {
147
+ Write-Host 'Temporal is ready!'
148
+ return
149
+ }
150
+ if ($i -eq 30) {
151
+ Write-Error 'Timeout waiting for Temporal'
152
+ exit 1
153
+ }
154
+ Start-Sleep -Seconds 2
155
+ }
156
+ }
157
+
158
+ function Invoke-Start {
159
+ if (-not $URL -or -not $REPO) {
160
+ Write-Error 'URL and REPO are required. Usage: .\talon.ps1 start -URL <url> -REPO <name>'
161
+ exit 1
162
+ }
163
+
164
+ # Check credentials
165
+ $apiKey = $env:ANTHROPIC_API_KEY
166
+ $oauthToken = $env:CLAUDE_CODE_OAUTH_TOKEN
167
+ if (-not $apiKey -and -not $oauthToken) {
168
+ if ($env:CLAUDE_CODE_USE_BEDROCK -eq '1') {
169
+ # Bedrock mode validation
170
+ $missing = @()
171
+ if (-not $env:AWS_REGION) { $missing += 'AWS_REGION' }
172
+ if (-not $env:AWS_BEARER_TOKEN_BEDROCK) { $missing += 'AWS_BEARER_TOKEN_BEDROCK' }
173
+ if (-not $env:ANTHROPIC_SMALL_MODEL) { $missing += 'ANTHROPIC_SMALL_MODEL' }
174
+ if (-not $env:ANTHROPIC_MEDIUM_MODEL) { $missing += 'ANTHROPIC_MEDIUM_MODEL' }
175
+ if (-not $env:ANTHROPIC_LARGE_MODEL) { $missing += 'ANTHROPIC_LARGE_MODEL' }
176
+ if ($missing.Count -gt 0) {
177
+ Write-Error "Bedrock mode requires: $($missing -join ', ')"
178
+ exit 1
179
+ }
180
+ }
181
+ elseif ($env:CLAUDE_CODE_USE_VERTEX -eq '1') {
182
+ # Vertex mode validation
183
+ $missing = @()
184
+ if (-not $env:CLOUD_ML_REGION) { $missing += 'CLOUD_ML_REGION' }
185
+ if (-not $env:ANTHROPIC_VERTEX_PROJECT_ID) { $missing += 'ANTHROPIC_VERTEX_PROJECT_ID' }
186
+ if (-not $env:GOOGLE_APPLICATION_CREDENTIALS) { $missing += 'GOOGLE_APPLICATION_CREDENTIALS' }
187
+ if (-not $env:ANTHROPIC_SMALL_MODEL) { $missing += 'ANTHROPIC_SMALL_MODEL' }
188
+ if (-not $env:ANTHROPIC_MEDIUM_MODEL) { $missing += 'ANTHROPIC_MEDIUM_MODEL' }
189
+ if (-not $env:ANTHROPIC_LARGE_MODEL) { $missing += 'ANTHROPIC_LARGE_MODEL' }
190
+ if ($missing.Count -gt 0) {
191
+ Write-Error "Vertex AI mode requires: $($missing -join ', ')"
192
+ exit 1
193
+ }
194
+ }
195
+ elseif ($ROUTER -and ($env:OPENAI_API_KEY -or $env:OPENROUTER_API_KEY)) {
196
+ $env:ANTHROPIC_API_KEY = 'router-mode'
197
+ }
198
+ else {
199
+ Write-Error @"
200
+ Set ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN in .env
201
+ (or use CLAUDE_CODE_USE_BEDROCK=1, CLAUDE_CODE_USE_VERTEX=1,
202
+ or -ROUTER with OPENAI_API_KEY or OPENROUTER_API_KEY)
203
+ "@
204
+ exit 1
205
+ }
206
+ }
207
+
208
+ # Determine container repo path
209
+ $containerRepo = switch -Wildcard ($REPO) {
210
+ '/benchmarks/*' { $REPO }
211
+ '/repos/*' { $REPO }
212
+ default {
213
+ if (-not (Test-Path ".\repos\$REPO")) {
214
+ Write-Error "Repository not found at .\repos\$REPO"
215
+ exit 1
216
+ }
217
+ "/repos/$REPO"
218
+ }
219
+ }
220
+
221
+ # Prepare output directory
222
+ if ($OUTPUT) {
223
+ New-Item -ItemType Directory -Path $OUTPUT -Force | Out-Null
224
+ $env:OUTPUT_DIR = $OUTPUT
225
+ }
226
+
227
+ # Handle router
228
+ if ($ROUTER) {
229
+ $env:ANTHROPIC_BASE_URL = 'http://router:3456'
230
+ if (-not $env:TALON_ROUTER_KEY) {
231
+ $bytes = New-Object byte[] 32
232
+ [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
233
+ $env:TALON_ROUTER_KEY = ($bytes | ForEach-Object { $_.ToString('x2') }) -join ''
234
+ Write-Host 'Generated router key (set TALON_ROUTER_KEY in .env to persist)'
235
+ }
236
+ $env:ANTHROPIC_AUTH_TOKEN = $env:TALON_ROUTER_KEY
237
+
238
+ Write-Host 'Starting claude-code-router...'
239
+ docker compose -f $ComposeFile --profile router up -d --build router
240
+
241
+ Write-Host 'Waiting for router...'
242
+ for ($i = 1; $i -le 15; $i++) {
243
+ $ps = docker compose -f $ComposeFile --profile router ps router 2>$null
244
+ if ($ps -match 'healthy') {
245
+ Write-Host 'Router is ready!'
246
+ break
247
+ }
248
+ if ($i -eq 15) { Write-Host 'WARNING: Router health check timed out (continuing)' }
249
+ Start-Sleep -Seconds 2
250
+ }
251
+ }
252
+
253
+ # Ensure directories
254
+ New-Item -ItemType Directory -Path '.\audit-logs', '.\credentials' -Force | Out-Null
255
+ if (Test-Path ".\repos\$REPO") {
256
+ New-Item -ItemType Directory -Path ".\repos\$REPO\deliverables" -Force | Out-Null
257
+ }
258
+
259
+ Start-Containers
260
+
261
+ # Build args
262
+ $args = @()
263
+ if ($CONFIG) { $args += '--config', $CONFIG }
264
+ if ($OUTPUT) { $args += '--output', '/app/output', '--display-output', $OUTPUT }
265
+ if ($PIPELINE_TESTING) { $args += '--pipeline-testing' }
266
+ if ($WORKSPACE) { $args += '--workspace', $WORKSPACE }
267
+
268
+ docker compose -f $ComposeFile exec -T worker `
269
+ node dist/temporal/client.js $URL $containerRepo @args
270
+ }
271
+
272
+ function Invoke-Logs {
273
+ if (-not $ID) {
274
+ Write-Error 'ID is required. Usage: .\talon.ps1 logs -ID <workflow-id>'
275
+ exit 1
276
+ }
277
+
278
+ $logPath = ".\audit-logs\$ID\workflow.log"
279
+ if (Test-Path $logPath) {
280
+ Write-Host "Tailing workflow log: $logPath"
281
+ Get-Content -Path $logPath -Wait -Tail 50
282
+ }
283
+ else {
284
+ Write-Error @"
285
+ Workflow log not found for ID: $ID
286
+
287
+ Possible causes:
288
+ - Workflow hasn't started yet
289
+ - Workflow ID is incorrect
290
+
291
+ Check the Temporal Web UI at http://localhost:8233
292
+ "@
293
+ exit 1
294
+ }
295
+ }
296
+
297
+ function Invoke-Workspaces {
298
+ Start-Containers
299
+ docker compose -f $ComposeFile exec -T worker node dist/temporal/workspaces.js
300
+ }
301
+
302
+ function Invoke-Benchmark {
303
+ if (-not $TARGET) {
304
+ Write-Error 'TARGET is required. Usage: .\talon.ps1 benchmark -TARGET <name>'
305
+ exit 1
306
+ }
307
+
308
+ Start-Containers
309
+
310
+ $benchArgs = @($TARGET, '--output', '/app/audit-logs')
311
+ if ($GROUND_TRUTH) { $benchArgs += '--ground-truth', $GROUND_TRUTH }
312
+
313
+ docker compose -f $ComposeFile exec -T worker `
314
+ node dist/backtesting/benchmark-cli.js @benchArgs
315
+ }
316
+
317
+ function Invoke-Evolve {
318
+ Start-Containers
319
+
320
+ $evolveArgs = @('--generations', $GENERATIONS)
321
+ if ($SEED) { $evolveArgs += '--seed', $SEED }
322
+
323
+ docker compose -f $ComposeFile exec -T worker `
324
+ node dist/evolution/evolve-cli.js @evolveArgs
325
+ }
326
+
327
+ function Invoke-Stop {
328
+ if ($CLEAN) {
329
+ docker compose -f $ComposeFile --profile router down -v
330
+ }
331
+ else {
332
+ docker compose -f $ComposeFile --profile router down
333
+ }
334
+ }
335
+
336
+ # Dispatch
337
+ switch ($Command) {
338
+ 'setup' { Invoke-Setup }
339
+ 'doctor' { Invoke-Doctor }
340
+ 'start' { Invoke-Start }
341
+ 'benchmark' { Invoke-Benchmark }
342
+ 'evolve' { Invoke-Evolve }
343
+ 'logs' { Invoke-Logs }
344
+ 'workspaces' { Invoke-Workspaces }
345
+ 'stop' { Invoke-Stop }
346
+ 'help' { Show-Help }
347
+ default { Show-Help }
348
+ }