mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-07-06 05:07:59 +02:00
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:
@@ -15,7 +15,7 @@
|
||||
import { tool } from '@anthropic-ai/claude-agent-sdk';
|
||||
import { createHmac } from 'crypto';
|
||||
import { z } from 'zod';
|
||||
import { createToolResult } from '../types/tool-responses.js';
|
||||
import { createToolResult, type ToolResult, type GenerateTotpResponse } from '../types/tool-responses.js';
|
||||
import { base32Decode, validateTotpSecret } from '../validation/totp-validator.js';
|
||||
import { createCryptoError, createGenericError } from '../utils/error-formatter.js';
|
||||
|
||||
@@ -30,16 +30,13 @@ export const GenerateTotpInputSchema = z.object({
|
||||
.describe('Base32-encoded TOTP secret'),
|
||||
});
|
||||
|
||||
export type GenerateTotpInput = z.infer<typeof GenerateTotpInputSchema>;
|
||||
|
||||
/**
|
||||
* Generate HOTP code (RFC 4226)
|
||||
* Ported from generate-totp-standalone.mjs (lines 74-99)
|
||||
*
|
||||
* @param {string} secret - Base32-encoded secret
|
||||
* @param {number} counter - Counter value
|
||||
* @param {number} [digits=6] - Number of digits in OTP
|
||||
* @returns {string} OTP code
|
||||
*/
|
||||
function generateHOTP(secret, counter, digits = 6) {
|
||||
function generateHOTP(secret: string, counter: number, digits: number = 6): string {
|
||||
const key = base32Decode(secret);
|
||||
|
||||
// Convert counter to 8-byte buffer (big-endian)
|
||||
@@ -52,12 +49,12 @@ function generateHOTP(secret, counter, digits = 6) {
|
||||
const hash = hmac.digest();
|
||||
|
||||
// Dynamic truncation
|
||||
const offset = hash[hash.length - 1] & 0x0f;
|
||||
const offset = hash[hash.length - 1]! & 0x0f;
|
||||
const code =
|
||||
((hash[offset] & 0x7f) << 24) |
|
||||
((hash[offset + 1] & 0xff) << 16) |
|
||||
((hash[offset + 2] & 0xff) << 8) |
|
||||
(hash[offset + 3] & 0xff);
|
||||
((hash[offset]! & 0x7f) << 24) |
|
||||
((hash[offset + 1]! & 0xff) << 16) |
|
||||
((hash[offset + 2]! & 0xff) << 8) |
|
||||
(hash[offset + 3]! & 0xff);
|
||||
|
||||
// Generate digits
|
||||
const otp = (code % Math.pow(10, digits)).toString().padStart(digits, '0');
|
||||
@@ -67,13 +64,8 @@ function generateHOTP(secret, counter, digits = 6) {
|
||||
/**
|
||||
* Generate TOTP code (RFC 6238)
|
||||
* Ported from generate-totp-standalone.mjs (lines 101-106)
|
||||
*
|
||||
* @param {string} secret - Base32-encoded secret
|
||||
* @param {number} [timeStep=30] - Time step in seconds
|
||||
* @param {number} [digits=6] - Number of digits in OTP
|
||||
* @returns {string} OTP code
|
||||
*/
|
||||
function generateTOTP(secret, timeStep = 30, digits = 6) {
|
||||
function generateTOTP(secret: string, timeStep: number = 30, digits: number = 6): string {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
const counter = Math.floor(currentTime / timeStep);
|
||||
return generateHOTP(secret, counter, digits);
|
||||
@@ -81,23 +73,16 @@ function generateTOTP(secret, timeStep = 30, digits = 6) {
|
||||
|
||||
/**
|
||||
* Get seconds until TOTP code expires
|
||||
*
|
||||
* @param {number} [timeStep=30] - Time step in seconds
|
||||
* @returns {number} Seconds until expiration
|
||||
*/
|
||||
function getSecondsUntilExpiration(timeStep = 30) {
|
||||
function getSecondsUntilExpiration(timeStep: number = 30): number {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
return timeStep - (currentTime % timeStep);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate_totp tool implementation
|
||||
*
|
||||
* @param {Object} args
|
||||
* @param {string} args.secret - Base32-encoded TOTP secret
|
||||
* @returns {Promise<Object>} Tool result
|
||||
*/
|
||||
export async function generateTotp(args) {
|
||||
export async function generateTotp(args: GenerateTotpInput): Promise<ToolResult> {
|
||||
try {
|
||||
const { secret } = args;
|
||||
|
||||
@@ -110,7 +95,7 @@ export async function generateTotp(args) {
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// Success response
|
||||
const successResponse = {
|
||||
const successResponse: GenerateTotpResponse = {
|
||||
status: 'success',
|
||||
message: 'TOTP code generated successfully',
|
||||
totpCode,
|
||||
@@ -14,7 +14,7 @@
|
||||
import { tool } from '@anthropic-ai/claude-agent-sdk';
|
||||
import { z } from 'zod';
|
||||
import { DeliverableType, DELIVERABLE_FILENAMES, isQueueType } from '../types/deliverables.js';
|
||||
import { createToolResult } from '../types/tool-responses.js';
|
||||
import { createToolResult, type ToolResult, type SaveDeliverableResponse } from '../types/tool-responses.js';
|
||||
import { validateQueueJson } from '../validation/queue-validator.js';
|
||||
import { saveDeliverableFile } from '../utils/file-operations.js';
|
||||
import { createValidationError, createGenericError } from '../utils/error-formatter.js';
|
||||
@@ -27,15 +27,12 @@ export const SaveDeliverableInputSchema = z.object({
|
||||
content: z.string().min(1).describe('File content (markdown for analysis/evidence, JSON for queues)'),
|
||||
});
|
||||
|
||||
export type SaveDeliverableInput = z.infer<typeof SaveDeliverableInputSchema>;
|
||||
|
||||
/**
|
||||
* save_deliverable tool implementation
|
||||
*
|
||||
* @param {Object} args
|
||||
* @param {string} args.deliverable_type - Type of deliverable to save
|
||||
* @param {string} args.content - File content
|
||||
* @returns {Promise<Object>} Tool result
|
||||
*/
|
||||
export async function saveDeliverable(args) {
|
||||
export async function saveDeliverable(args: SaveDeliverableInput): Promise<ToolResult> {
|
||||
try {
|
||||
const { deliverable_type, content } = args;
|
||||
|
||||
@@ -44,7 +41,7 @@ export async function saveDeliverable(args) {
|
||||
const queueValidation = validateQueueJson(content);
|
||||
if (!queueValidation.valid) {
|
||||
const errorResponse = createValidationError(
|
||||
queueValidation.message,
|
||||
queueValidation.message ?? 'Invalid queue JSON',
|
||||
true,
|
||||
{
|
||||
deliverableType: deliverable_type,
|
||||
@@ -60,7 +57,7 @@ export async function saveDeliverable(args) {
|
||||
const filepath = saveDeliverableFile(filename, content);
|
||||
|
||||
// Success response
|
||||
const successResponse = {
|
||||
const successResponse: SaveDeliverableResponse = {
|
||||
status: 'success',
|
||||
message: `Deliverable saved successfully: ${filename}`,
|
||||
filepath,
|
||||
Reference in New Issue
Block a user