feat: typescript migration (#40)
* chore: initialize TypeScript configuration and build setup - Add tsconfig.json for root and mcp-server with strict type checking - Install typescript and @types/node as devDependencies - Add npm build script for TypeScript compilation - Update main entrypoint to compiled dist/shannon.js - Update Dockerfile to build TypeScript before running - Configure output directory and module resolution for Node.js * refactor: migrate codebase from JavaScript to TypeScript - Convert all 37 JavaScript files to TypeScript (.js -> .ts) - Add type definitions in src/types/ for agents, config, errors, session - Update mcp-server with proper TypeScript types - Move entry point from shannon.mjs to src/shannon.ts - Update tsconfig.json with rootDir: "./src" for cleaner dist output - Update Dockerfile to build TypeScript before runtime - Update package.json paths to use compiled dist/shannon.js No runtime behavior changes - pure type safety migration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update CLI references from ./shannon.mjs to shannon - Update help text in src/cli/ui.ts - Update usage examples in src/cli/command-handler.ts - Update setup message in src/shannon.ts - Update CLAUDE.md documentation with TypeScript file structure - Replace all ./shannon.mjs references with shannon command 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove unnecessary eslint-disable comments ESLint is not configured in this project, making these comments redundant. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
// 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.
|
||||
|
||||
import figlet from 'figlet';
|
||||
import gradient from 'gradient-string';
|
||||
import boxen from 'boxen';
|
||||
import chalk from 'chalk';
|
||||
import { fs, path } from 'zx';
|
||||
|
||||
export const displaySplashScreen = async (): Promise<void> => {
|
||||
try {
|
||||
// Get version info from package.json
|
||||
const packagePath = path.join(import.meta.dirname, '..', 'package.json');
|
||||
const packageJson = (await fs.readJSON(packagePath)) as { version?: string };
|
||||
const version = packageJson.version || '1.0.0';
|
||||
|
||||
// Create the main SHANNON ASCII art
|
||||
const shannonText = figlet.textSync('SHANNON', {
|
||||
font: 'ANSI Shadow',
|
||||
horizontalLayout: 'default',
|
||||
verticalLayout: 'default',
|
||||
});
|
||||
|
||||
// Apply golden gradient to SHANNON
|
||||
const gradientShannon = gradient(['#F4C542', '#FFD700'])(shannonText);
|
||||
|
||||
// Create minimal tagline with styling
|
||||
const tagline = chalk.bold.white('AI Penetration Testing Framework');
|
||||
const versionInfo = chalk.gray(`v${version}`);
|
||||
|
||||
// Build the complete splash content
|
||||
const content = [
|
||||
gradientShannon,
|
||||
'',
|
||||
chalk.bold.cyan(' ╔════════════════════════════════════╗'),
|
||||
chalk.bold.cyan(' ║') + ' ' + tagline + ' ' + chalk.bold.cyan('║'),
|
||||
chalk.bold.cyan(' ╚════════════════════════════════════╝'),
|
||||
'',
|
||||
` ${versionInfo}`,
|
||||
'',
|
||||
chalk.bold.yellow(' 🔐 DEFENSIVE SECURITY ONLY 🔐'),
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
// Create boxed output with minimal styling
|
||||
const boxedContent = boxen(content, {
|
||||
padding: 1,
|
||||
margin: 1,
|
||||
borderStyle: 'double',
|
||||
borderColor: 'cyan',
|
||||
dimBorder: false,
|
||||
});
|
||||
|
||||
// Clear screen and display splash
|
||||
console.clear();
|
||||
console.log(boxedContent);
|
||||
|
||||
// Add loading animation
|
||||
const loadingFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
||||
let frameIndex = 0;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const loadingInterval = setInterval(() => {
|
||||
process.stdout.write(
|
||||
`\r${chalk.cyan(loadingFrames[frameIndex])} ${chalk.dim('Initializing systems...')}`
|
||||
);
|
||||
frameIndex = (frameIndex + 1) % loadingFrames.length;
|
||||
}, 100);
|
||||
|
||||
setTimeout(() => {
|
||||
clearInterval(loadingInterval);
|
||||
process.stdout.write(`\r${chalk.green('✓')} ${chalk.dim('Systems initialized. ')}\n\n`);
|
||||
resolve();
|
||||
}, 2000);
|
||||
});
|
||||
} catch (error) {
|
||||
// Fallback to simple splash if anything fails
|
||||
const errMsg = error instanceof Error ? error.message : String(error);
|
||||
console.log(chalk.cyan.bold('\n🚀 SHANNON - AI Penetration Testing Framework\n'));
|
||||
console.log(chalk.yellow('⚠️ Could not load full splash screen:', errMsg));
|
||||
console.log('');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user