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,67 @@
|
||||
// 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 { fs, path } from 'zx';
|
||||
import chalk from 'chalk';
|
||||
import { PentestError } from '../error-handling.js';
|
||||
|
||||
interface DeliverableFile {
|
||||
name: string;
|
||||
path: string;
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
// Pure function: Assemble final report from specialist deliverables
|
||||
export async function assembleFinalReport(sourceDir: string): Promise<string> {
|
||||
const deliverableFiles: DeliverableFile[] = [
|
||||
{ name: 'Injection', path: 'injection_exploitation_evidence.md', required: false },
|
||||
{ name: 'XSS', path: 'xss_exploitation_evidence.md', required: false },
|
||||
{ name: 'Authentication', path: 'auth_exploitation_evidence.md', required: false },
|
||||
{ name: 'SSRF', path: 'ssrf_exploitation_evidence.md', required: false },
|
||||
{ name: 'Authorization', path: 'authz_exploitation_evidence.md', required: false }
|
||||
];
|
||||
|
||||
const sections: string[] = [];
|
||||
|
||||
for (const file of deliverableFiles) {
|
||||
const filePath = path.join(sourceDir, 'deliverables', file.path);
|
||||
try {
|
||||
if (await fs.pathExists(filePath)) {
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
sections.push(content);
|
||||
console.log(chalk.green(`✅ Added ${file.name} findings`));
|
||||
} else if (file.required) {
|
||||
throw new Error(`Required file ${file.path} not found`);
|
||||
} else {
|
||||
console.log(chalk.gray(`⏭️ No ${file.name} deliverable found`));
|
||||
}
|
||||
} catch (error) {
|
||||
if (file.required) {
|
||||
throw error;
|
||||
}
|
||||
const err = error as Error;
|
||||
console.log(chalk.yellow(`⚠️ Could not read ${file.path}: ${err.message}`));
|
||||
}
|
||||
}
|
||||
|
||||
const finalContent = sections.join('\n\n');
|
||||
const finalReportPath = path.join(sourceDir, 'deliverables', 'comprehensive_security_assessment_report.md');
|
||||
|
||||
try {
|
||||
await fs.writeFile(finalReportPath, finalContent);
|
||||
console.log(chalk.green(`✅ Final report assembled at ${finalReportPath}`));
|
||||
} catch (error) {
|
||||
const err = error as Error;
|
||||
throw new PentestError(
|
||||
`Failed to write final report: ${err.message}`,
|
||||
'filesystem',
|
||||
false,
|
||||
{ finalReportPath, originalError: err.message }
|
||||
);
|
||||
}
|
||||
|
||||
return finalContent;
|
||||
}
|
||||
Reference in New Issue
Block a user