mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-09-22 17:50:50 +02:00
feat(cli): overhaul commands and add live scan status (#424)
* refactor(cli): list workspaces natively instead of via the worker image * feat(cli): preflight that Docker is installed and running * feat(cli): stop scans by workspace or --all, terminating their Temporal workflows * fix(worker): abort the running agent on cancellation so Temporal cancel takes effect * refactor(cli): split destructive teardown out of stop into a reset command * refactor(cli): centralise flag parsing and confirmation across commands * fix(cli): pass provider credentials to docker by name to keep secrets out of argv * feat(cli): add per-command help via <command> --help/-h and help <command> * feat(cli): replace raw docker output with clack spinners for infra and scan teardown * fix(cli): verify scan stop by re-querying container and workflow state instead of assuming success * fix(cli): resolve running state before prompting on stop and report no-op stops honestly * refactor(cli): show splash first and drive start with one spinner resolving to a clean line * fix(cli): validate --url up front so a bad value fails cleanly instead of a late crash * refactor(cli): centralize error reporting with fail() for expected errors and a crash handler that logs the stack and links the issue tracker * feat(cli): add --json/--plain machine-readable output to workspaces and status * refactor(cli): remove the workspaces command * refactor(cli): remove the status command * feat(cli): add 'progress <workspace>' — live scan progress from Temporal * fix(cli): mark metric-less agents as skipped in progress, not done * feat(cli): animate running agents in progress with a clack-style spinner * feat(cli): rename progress->status, reveal agents as they run, show live per-agent elapsed * fix(cli): mark passed-over phases as skipped live, not pending * style(cli): rename status footer 'Wall-clock' to 'Time Taken', drop the parenthetical * style(cli): drop '(sum of agents)' from status total cost line * style(cli): green filled circle for completed, Shannon gold for running * style(cli): use Shannon gold in place of green in status * feat(cli): suggest closest command or flag on typo * refactor(cli): single-source start help and drop ./repos bare-name shortcut * feat(cli): name providers and fix in multi-provider credential error * feat(cli): support --flag=value syntax and expand leading ~ in paths * refactor(cli): centralize ANSI color codes in colors.ts * feat(cli): add scans command listing completed scans with cost and duration * fix(cli): keep stdout clean off-TTY for logs and start * feat(cli): add repo link to top-level help * feat(worker): record auth-validation metrics and register resume attempts early * refactor(cli): share resume-aware workflow-id resolution and surface root-cause failures * feat(cli): add status --json, auth phase, dashboard link, and stable live redraw * refactor(cli): drop cost from status and scans output * feat(worker): surface both PDF and markdown report at run root * refactor(cli): normalize error/warning prefixing through fail and warn * feat(cli): add version --json for machine-readable output * refactor(cli): rename start --debug to --keep-container * refactor(cli): point start's progress hint at status instead of the Temporal dashboard * refactor(cli): centralize the mode-aware command prefix * refactor(cli): trim start and logs output to durable facts off-TTY * feat(cli): require typed confirmation for reset instead of --yes reset permanently wipes all Temporal data and volumes — a severe, irreversible action. Replace its default y/N confirm (bypassable with --yes) with a typed-word confirmation that has no bypass, so the wipe can only be triggered by a deliberate interactive answer. * feat(cli): surface logs and status hints after start on a TTY * feat(cli): exit 2 on usage errors, distinct from operational failures * feat(cli): add start --follow to stream logs and exit on scan outcome * refactor(cli): redesign splash with sunset-gradient wordmark and truecolor * refactor(cli): remove the uninstall command * docs: sync CLI docs with removed uninstall/workspaces, new scans and --follow * docs: fix reset confirmation — typed confirm, not --yes/-y * style(cli): restructure status footer with divider, aligned Logs/Temporal rows * feat(cli): show splash in the status command * fix(worker): validate auth-state shape, not entry count * docs: correct reset confirmation and add markdown report to run-root docs
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
ActivityCancellationType,
|
||||
ApplicationFailure,
|
||||
CancellationScope,
|
||||
isCancellation,
|
||||
@@ -96,6 +97,8 @@ const acts = proxyActivities<typeof activities>({
|
||||
startToCloseTimeout: '2 hours',
|
||||
heartbeatTimeout: '60 minutes', // Extended for nested pi task execution
|
||||
retry: PRODUCTION_RETRY,
|
||||
// Cancel promptly instead of waiting out startToCloseTimeout; the agent aborts on the signal.
|
||||
cancellationType: ActivityCancellationType.TRY_CANCEL,
|
||||
});
|
||||
|
||||
// Activity proxy with testing retry configuration (fast)
|
||||
@@ -103,6 +106,7 @@ const testActs = proxyActivities<typeof activities>({
|
||||
startToCloseTimeout: '30 minutes',
|
||||
heartbeatTimeout: '30 minutes', // Extended for sub-agent execution in testing
|
||||
retry: TESTING_RETRY,
|
||||
cancellationType: ActivityCancellationType.TRY_CANCEL,
|
||||
});
|
||||
|
||||
// Retry configuration for preflight validation (short timeout, few retries)
|
||||
@@ -119,6 +123,7 @@ const preflightActs = proxyActivities<typeof activities>({
|
||||
startToCloseTimeout: '2 minutes',
|
||||
heartbeatTimeout: '2 minutes',
|
||||
retry: PREFLIGHT_RETRY,
|
||||
cancellationType: ActivityCancellationType.TRY_CANCEL,
|
||||
});
|
||||
|
||||
// Credential rejection is not retryable; transient provider errors get 3 attempts.
|
||||
@@ -135,6 +140,7 @@ const authValidationActs = proxyActivities<typeof activities>({
|
||||
startToCloseTimeout: '10 minutes',
|
||||
heartbeatTimeout: '10 minutes',
|
||||
retry: AUTH_VALIDATION_RETRY,
|
||||
cancellationType: ActivityCancellationType.TRY_CANCEL,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -246,6 +252,10 @@ export async function pentestPipeline(input: PipelineInput): Promise<PipelineSta
|
||||
let resumeState: ResumeState | null = null;
|
||||
|
||||
if (input.resumeFromWorkspace) {
|
||||
// 0. Register the resume's workflow id in session.json before validation can fail, so the CLI
|
||||
// can resolve and follow it instead of polling for an entry that never lands.
|
||||
await a.registerResumeAttempt(activityInput, input.terminatedWorkflows || []);
|
||||
|
||||
// 1. Load resume state (validates workspace, cross-checks deliverables)
|
||||
resumeState = await a.loadResumeState(
|
||||
input.resumeFromWorkspace,
|
||||
@@ -277,10 +287,9 @@ export async function pentestPipeline(input: PipelineInput): Promise<PipelineSta
|
||||
return state;
|
||||
}
|
||||
|
||||
// 4. Record this resume attempt in session.json and workflow.log
|
||||
// 4. Write the resume header to workflow.log (the session.json entry was recorded in step 0)
|
||||
await a.recordResumeAttempt(
|
||||
activityInput,
|
||||
input.terminatedWorkflows || [],
|
||||
resumeState.checkpointHash,
|
||||
resumeState.originalWorkflowId,
|
||||
resumeState.completedAgents,
|
||||
@@ -480,7 +489,11 @@ export async function pentestPipeline(input: PipelineInput): Promise<PipelineSta
|
||||
// === Authentication Validation ===
|
||||
state.currentPhase = 'auth-validation';
|
||||
state.currentAgent = 'validate-authentication';
|
||||
await authValidationActs.runAuthenticationValidation(activityInput);
|
||||
const authMetrics = await authValidationActs.runAuthenticationValidation(activityInput);
|
||||
// Null when no login ran (no-auth scan); left absent so status renders it skipped, not completed.
|
||||
if (authMetrics) {
|
||||
state.agentMetrics['validate-authentication'] = authMetrics;
|
||||
}
|
||||
state.currentAgent = null;
|
||||
log.info('Authentication validation passed');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user