From 45e9f305eaf259c0c4a33bf5ac2b6f07266102a8 Mon Sep 17 00:00:00 2001 From: ezl-keygraph Date: Tue, 17 Feb 2026 00:19:24 +0530 Subject: [PATCH] refactor: remove ./shannon query CLI command Query functionality is redundant with the Temporal Web UI at http://localhost:8233. Removes query.ts, CLI handler, npm script, and all documentation references. --- CLAUDE.md | 3 - package.json | 3 +- shannon | 21 +----- src/temporal/client.ts | 1 - src/temporal/query.ts | 158 ----------------------------------------- 5 files changed, 2 insertions(+), 184 deletions(-) delete mode 100644 src/temporal/query.ts diff --git a/CLAUDE.md b/CLAUDE.md index 41572ca..70555c0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,7 +26,6 @@ git clone https://github.com/org/repo.git ./repos/my-repo # Monitor ./shannon logs # Real-time worker logs -./shannon query ID= # Query workflow progress # Temporal Web UI: http://localhost:8233 # Stop @@ -57,8 +56,6 @@ Durable workflow orchestration with crash recovery, queryable progress, intellig - `src/temporal/worker.ts` — Worker entry point - `src/temporal/client.ts` — CLI client for starting workflows - `src/temporal/shared.ts` — Types, interfaces, query definitions -- `src/temporal/query.ts` — Query tool for progress inspection - ### Five-Phase Pipeline 1. **Pre-Recon** (`pre-recon`) — External scans (nmap, subfinder, whatweb) + source code analysis diff --git a/package.json b/package.json index c38b5dd..78a50ee 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,7 @@ "temporal:server": "docker compose -f docker/docker-compose.temporal.yml up temporal -d", "temporal:server:stop": "docker compose -f docker/docker-compose.temporal.yml down", "temporal:worker": "node dist/temporal/worker.js", - "temporal:start": "node dist/temporal/client.js", - "temporal:query": "node dist/temporal/query.js" + "temporal:start": "node dist/temporal/client.js" }, "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.38", diff --git a/shannon b/shannon index 2dc3cda..ab136e6 100755 --- a/shannon +++ b/shannon @@ -38,7 +38,6 @@ Usage: ./shannon start URL= REPO= Start a pentest workflow ./shannon workspaces List all workspaces ./shannon logs ID= Tail logs for a specific workflow - ./shannon query ID= Query workflow progress ./shannon stop Stop all containers ./shannon help Show this help message @@ -60,7 +59,6 @@ Examples: ./shannon start URL=https://example.com REPO=repo-name OUTPUT=./my-reports ./shannon workspaces ./shannon logs ID=example.com_shannon-1234567890 - ./shannon query ID=shannon-1234567890 ./shannon stop CLEAN=true Monitor workflows at http://localhost:8233 @@ -287,24 +285,11 @@ cmd_logs() { echo " - Workflow hasn't started yet" echo " - Workflow ID is incorrect" echo "" - echo "Check: ./shannon query ID=$ID for workflow details" + echo "Check the Temporal Web UI at http://localhost:8233 for workflow details" exit 1 fi } -cmd_query() { - parse_args "$@" - - if [ -z "$ID" ]; then - echo "ERROR: ID is required" - echo "Usage: ./shannon query ID=" - exit 1 - fi - - docker compose -f "$COMPOSE_FILE" $COMPOSE_OVERRIDE exec -T worker \ - node dist/temporal/query.js "$ID" -} - cmd_workspaces() { # Ensure containers are running (need worker to execute node) ensure_containers @@ -333,10 +318,6 @@ case "${1:-help}" in shift cmd_logs "$@" ;; - query) - shift - cmd_query "$@" - ;; workspaces) shift cmd_workspaces diff --git a/src/temporal/client.ts b/src/temporal/client.ts index 3ea690a..243197e 100644 --- a/src/temporal/client.ts +++ b/src/temporal/client.ts @@ -326,7 +326,6 @@ async function startPipeline(): Promise { console.log(chalk.bold('Monitor progress:')); console.log(chalk.white(' Web UI: ') + chalk.blue(`http://localhost:8233/namespaces/default/workflows/${workflowId}`)); console.log(chalk.white(' Logs: ') + chalk.gray(`./shannon logs ID=${workflowId}`)); - console.log(chalk.white(' Query: ') + chalk.gray(`./shannon query ID=${workflowId}`)); console.log(); console.log(chalk.bold('Output:')); console.log(chalk.white(' Reports: ') + chalk.cyan(outputDir)); diff --git a/src/temporal/query.ts b/src/temporal/query.ts deleted file mode 100644 index bf058a7..0000000 --- a/src/temporal/query.ts +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env node -// Copyright (C) 2025 Keygraph, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License version 3 -// as published by the Free Software Foundation. - -/** - * Temporal query tool for inspecting Shannon workflow progress. - * - * Queries a running or completed workflow and displays its state. - * - * Usage: - * npm run temporal:query -- - * # or - * node dist/temporal/query.js - * - * Environment: - * TEMPORAL_ADDRESS - Temporal server address (default: localhost:7233) - */ - -import { Connection, Client } from '@temporalio/client'; -import dotenv from 'dotenv'; -import chalk from 'chalk'; - -dotenv.config(); - -// Query name must match the one defined in workflows.ts -const PROGRESS_QUERY = 'getProgress'; - -// Types duplicated from shared.ts to avoid importing workflow APIs -interface AgentMetrics { - durationMs: number; - inputTokens: number | null; - outputTokens: number | null; - costUsd: number | null; - numTurns: number | null; - model?: string | undefined; -} - -interface PipelineProgress { - status: 'running' | 'completed' | 'failed'; - currentPhase: string | null; - currentAgent: string | null; - completedAgents: string[]; - failedAgent: string | null; - error: string | null; - startTime: number; - agentMetrics: Record; - workflowId: string; - elapsedMs: number; -} - -function showUsage(): void { - console.log(chalk.cyan.bold('\nShannon Temporal Query Tool')); - console.log(chalk.gray('Query progress of a running workflow\n')); - console.log(chalk.yellow('Usage:')); - console.log(' node dist/temporal/query.js \n'); - console.log(chalk.yellow('Examples:')); - console.log(' node dist/temporal/query.js shannon-1704672000000\n'); -} - -function getStatusColor(status: string): string { - switch (status) { - case 'running': - return chalk.yellow(status); - case 'completed': - return chalk.green(status); - case 'failed': - return chalk.red(status); - default: - return status; - } -} - -function formatDuration(ms: number): string { - const seconds = Math.floor(ms / 1000); - const minutes = Math.floor(seconds / 60); - const hours = Math.floor(minutes / 60); - - if (hours > 0) { - return `${hours}h ${minutes % 60}m`; - } else if (minutes > 0) { - return `${minutes}m ${seconds % 60}s`; - } - return `${seconds}s`; -} - -async function queryWorkflow(): Promise { - const workflowId = process.argv[2]; - - if (!workflowId || workflowId === '--help' || workflowId === '-h') { - showUsage(); - process.exit(workflowId ? 0 : 1); - } - - const address = process.env.TEMPORAL_ADDRESS || 'localhost:7233'; - - const connection = await Connection.connect({ address }); - const client = new Client({ connection }); - - try { - const handle = client.workflow.getHandle(workflowId); - const progress = await handle.query(PROGRESS_QUERY); - - console.log(chalk.cyan.bold('\nWorkflow Progress')); - console.log(chalk.gray('\u2500'.repeat(40))); - console.log(`${chalk.white('Workflow ID:')} ${progress.workflowId}`); - console.log(`${chalk.white('Status:')} ${getStatusColor(progress.status)}`); - console.log( - `${chalk.white('Current Phase:')} ${progress.currentPhase || 'none'}` - ); - console.log( - `${chalk.white('Current Agent:')} ${progress.currentAgent || 'none'}` - ); - console.log(`${chalk.white('Elapsed:')} ${formatDuration(progress.elapsedMs)}`); - console.log( - `${chalk.white('Completed:')} ${progress.completedAgents.length}/13 agents` - ); - - if (progress.completedAgents.length > 0) { - console.log(chalk.gray('\nCompleted agents:')); - for (const agent of progress.completedAgents) { - const metrics = progress.agentMetrics[agent]; - const duration = metrics ? formatDuration(metrics.durationMs) : 'unknown'; - const cost = metrics?.costUsd ? `$${metrics.costUsd.toFixed(4)}` : ''; - const model = metrics?.model ? ` [${metrics.model}]` : ''; - console.log( - chalk.green(` - ${agent}`) + - chalk.blue(model) + - chalk.gray(` (${duration}${cost ? ', ' + cost : ''})`) - ); - } - } - - if (progress.error) { - console.log(chalk.red(`\nError: ${progress.error}`)); - console.log(chalk.red(`Failed agent: ${progress.failedAgent}`)); - } - - console.log(); - } catch (error) { - const err = error as Error; - if (err.message?.includes('not found')) { - console.log(chalk.red(`Workflow not found: ${workflowId}`)); - } else { - console.error(chalk.red('Query failed:'), err.message); - } - process.exit(1); - } finally { - await connection.close(); - } -} - -queryWorkflow().catch((err) => { - console.error(chalk.red('Query error:'), err); - process.exit(1); -});