@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.
- package/.env.example +72 -0
- package/Dockerfile +161 -0
- package/Dockerfile.router +16 -0
- package/LICENSE +661 -0
- package/README.md +709 -0
- package/bin/talon.js +96 -0
- package/bin/talon.mjs +96 -0
- package/configs/config-schema.json +160 -0
- package/configs/example-config.yaml +50 -0
- package/configs/mcp-allowlist.json +47 -0
- package/configs/model-routing.yaml +39 -0
- package/configs/router-config.json +73 -0
- package/configs/talon-seccomp.json +89 -0
- package/dist/cli/dependency-checker.d.ts +25 -0
- package/dist/cli/dependency-checker.d.ts.map +1 -0
- package/dist/cli/dependency-checker.js +165 -0
- package/dist/cli/dependency-checker.js.map +1 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +127 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/env-configurator.d.ts +27 -0
- package/dist/cli/env-configurator.d.ts.map +1 -0
- package/dist/cli/env-configurator.js +115 -0
- package/dist/cli/env-configurator.js.map +1 -0
- package/dist/cli/setup-renderer.d.ts +23 -0
- package/dist/cli/setup-renderer.d.ts.map +1 -0
- package/dist/cli/setup-renderer.js +71 -0
- package/dist/cli/setup-renderer.js.map +1 -0
- package/dist/cli/setup.d.ts +2 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +302 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/types/activity-logger.d.ts +10 -0
- package/dist/types/activity-logger.d.ts.map +1 -0
- package/dist/types/activity-logger.js +7 -0
- package/dist/types/activity-logger.js.map +1 -0
- package/dist/types/agents.d.ts +39 -0
- package/dist/types/agents.d.ts.map +1 -0
- package/dist/types/agents.js +28 -0
- package/dist/types/agents.js.map +1 -0
- package/dist/types/audit.d.ts +28 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +7 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/backtesting.d.ts +45 -0
- package/dist/types/backtesting.d.ts.map +1 -0
- package/dist/types/backtesting.js +3 -0
- package/dist/types/backtesting.js.map +1 -0
- package/dist/types/config.d.ts +48 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +55 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +41 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/evolution.d.ts +36 -0
- package/dist/types/evolution.d.ts.map +1 -0
- package/dist/types/evolution.js +14 -0
- package/dist/types/evolution.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/metrics.d.ts +13 -0
- package/dist/types/metrics.d.ts.map +1 -0
- package/dist/types/metrics.js +7 -0
- package/dist/types/metrics.js.map +1 -0
- package/dist/types/resilience.d.ts +30 -0
- package/dist/types/resilience.d.ts.map +1 -0
- package/dist/types/resilience.js +7 -0
- package/dist/types/resilience.js.map +1 -0
- package/dist/types/result.d.ts +42 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +30 -0
- package/dist/types/result.js.map +1 -0
- package/docker-compose.yml +91 -0
- package/package.json +75 -0
- package/prompts/exploit-auth.txt +423 -0
- package/prompts/exploit-authz.txt +425 -0
- package/prompts/exploit-injection.txt +452 -0
- package/prompts/exploit-ssrf.txt +502 -0
- package/prompts/exploit-xss.txt +442 -0
- package/prompts/pipeline-testing/exploit-auth.txt +31 -0
- package/prompts/pipeline-testing/exploit-authz.txt +31 -0
- package/prompts/pipeline-testing/exploit-injection.txt +31 -0
- package/prompts/pipeline-testing/exploit-ssrf.txt +31 -0
- package/prompts/pipeline-testing/exploit-xss.txt +31 -0
- package/prompts/pipeline-testing/pre-recon-code.txt +1 -0
- package/prompts/pipeline-testing/recon.txt +1 -0
- package/prompts/pipeline-testing/report-executive.txt +1 -0
- package/prompts/pipeline-testing/vuln-auth.txt +13 -0
- package/prompts/pipeline-testing/vuln-authz.txt +13 -0
- package/prompts/pipeline-testing/vuln-injection.txt +13 -0
- package/prompts/pipeline-testing/vuln-ssrf.txt +13 -0
- package/prompts/pipeline-testing/vuln-xss.txt +13 -0
- package/prompts/pre-recon-code.txt +403 -0
- package/prompts/recon.txt +382 -0
- package/prompts/report-executive.txt +126 -0
- package/prompts/shared/_exploit-scope.txt +14 -0
- package/prompts/shared/_rules.txt +2 -0
- package/prompts/shared/_target.txt +1 -0
- package/prompts/shared/_vuln-scope.txt +1 -0
- package/prompts/shared/login-instructions.txt +82 -0
- package/prompts/vuln-auth.txt +268 -0
- package/prompts/vuln-authz.txt +373 -0
- package/prompts/vuln-injection.txt +380 -0
- package/prompts/vuln-ssrf.txt +315 -0
- package/prompts/vuln-xss.txt +304 -0
- package/talon +459 -0
- 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
|
+
}
|