Compare commits

...
2 Commits
2 changed files with 38 additions and 34 deletions

No files matched your search

+4 -1
View File
@@ -11,7 +11,9 @@ import path from 'node:path';
import * as p from '@clack/prompts';
import { type ShannonConfig, saveConfig } from '../config/writer.js';
import { CURATED_PROVIDERS, type CuratedProviderId, isCuratedProvider, type OpenAiFormat } from '../model-spec.js';
import { displaySplash } from '../splash.js';
import { requireInteractive } from '../tty.js';
import { getVersion } from '../version.js';
const SHANNON_HOME = path.join(os.homedir(), '.shannon');
@@ -63,7 +65,8 @@ function modelIdPlaceholder(provider: string): string | undefined {
export async function setup(): Promise<void> {
requireInteractive('setup', 'For non-interactive use, export credentials as env vars (e.g. ANTHROPIC_API_KEY).');
p.intro('Shannon Setup');
displaySplash(getVersion());
p.intro('Setup');
// 1. Select provider. "Custom Base URL" is a route, not a provider — it asks
// which API dialect the gateway speaks and configures that provider. "Other
+34 -33
View File
@@ -20,7 +20,8 @@ import { status } from './commands/status.js';
import { stop } from './commands/stop.js';
import { crash, fail, failUsage } from './errors.js';
import { availableCommands, isHelpableCommand, printCommandHelp, START_OPTIONS } from './help.js';
import { commandPrefix, getMode } from './mode.js';
import { commandPrefix, getMode, isLocal, type Mode } from './mode.js';
import { displaySplash } from './splash.js';
import { closestMatch } from './suggest.js';
import { getVersion, getVersionLine } from './version.js';
@@ -50,33 +51,38 @@ function renderStartOptions(): string {
return START_OPTIONS.map(([flag, desc]) => ` ${flag.padEnd(flagWidth)} ${desc}`).join('\n');
}
function showHelp(): void {
/**
* Render the command list with the description column aligned. Padding is computed from the
* widest command, so it lines up regardless of the prefix (`npx @keygraph/shannon` vs `./shannon`).
*/
function renderUsage(prefix: string, mode: Mode): string {
const rows: ReadonlyArray<readonly [string, string]> = [
...(mode === 'local' ? [] : [[`${prefix} setup`, 'Configure credentials'] as const]),
[`${prefix} start --url <url> --repo <path> [options]`, 'Start a pentest scan'],
[`${prefix} stop <workspace> [--yes]`, 'Stop one scan'],
[`${prefix} stop --all [--yes]`, 'Stop all scans (Temporal stays up)'],
[`${prefix} reset`, 'Stop everything and wipe all Temporal data'],
[`${prefix} logs <workspace>`, "Show a scan's live log"],
[`${prefix} status <workspace> [--json]`, 'Live phase/agent progress of one scan'],
[`${prefix} scans [--json]`, 'List completed scans and their reports'],
...(mode === 'local' ? [[`${prefix} build [--no-cache]`, 'Build worker image'] as const] : []),
[`${prefix} version [--json]`, 'Show version'],
[`${prefix} help`, 'Show this help'],
];
const commandWidth = Math.max(...rows.map(([command]) => command.length));
return rows.map(([command, desc]) => ` ${command.padEnd(commandWidth)} ${desc}`).join('\n');
}
function showHelp(withSplash: boolean): void {
const mode = getMode();
const prefix = commandPrefix();
console.log(`
Shannon - AI Penetration Testing Framework
const header = withSplash ? '' : '\nShannon - AI Penetration Testing Framework\n';
Usage:${
mode === 'local'
? ''
: `
${prefix} setup Configure credentials`
}
${prefix} start --url <url> --repo <path> [options] Start a pentest scan
${prefix} stop <workspace> [--yes] Stop one scan
${prefix} stop --all [--yes] Stop all scans (Temporal stays up)
${prefix} reset Stop everything and wipe all Temporal data
${prefix} logs <workspace> Show a scan's live log
${prefix} status <workspace> [--json] Live phase/agent progress of one scan
${prefix} scans [--json] List completed scans and their reports${
mode === 'local'
? `
${prefix} build [--no-cache] Build worker image`
: ''
}
${prefix} version [--json] Show version
${prefix} help Show this help
console.log(`${header}
Usage:
${renderUsage(prefix, mode)}
Options for 'start':
${renderStartOptions()}
@@ -89,14 +95,7 @@ Examples:
${prefix} reset
Run '${prefix} <command> --help' for help on a specific command.
${
mode === 'local'
? `
State directory: ./workspaces/`
: `
State directory: ~/.shannon/`
}
Monitor scans at http://localhost:8233
Docs & source: https://github.com/KeygraphHQ/shannon
`);
}
@@ -174,7 +173,9 @@ async function main(): Promise<void> {
if (topic && isHelpableCommand(topic)) {
printCommandHelp(topic);
} else {
showHelp();
const bare = command === undefined;
if (bare) displaySplash(isLocal() ? undefined : getVersion());
showHelp(bare);
}
return;
}