> ## Documentation Index
> Fetch the complete documentation index at: https://spec.conveniencepro.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Hash Generator

> Reference implementation of an async CTP tool

# Hash Generator

An asynchronous CTP tool demonstrating Web Crypto API usage and conditional warnings.

## Overview

| Property           | Value            |
| ------------------ | ---------------- |
| **ID**             | `hash-generator` |
| **Category**       | `generators`     |
| **Execution Mode** | `client`         |
| **Method**         | `POST`           |

## Parameters

| Name        | Type       | Required | Default   | Description    |
| ----------- | ---------- | -------- | --------- | -------------- |
| `input`     | `textarea` | Yes      | -         | Text to hash   |
| `algorithm` | `select`   | No       | `SHA-256` | Hash algorithm |
| `format`    | `select`   | No       | `hex`     | Output format  |

### Algorithm Options

| Value     | Bits | Security    |
| --------- | ---- | ----------- |
| `SHA-1`   | 160  | Deprecated  |
| `SHA-256` | 256  | Recommended |
| `SHA-384` | 384  | Strong      |
| `SHA-512` | 512  | Strongest   |

### Format Options

| Value    | Description           | Example       |
| -------- | --------------------- | ------------- |
| `hex`    | Lowercase hexadecimal | `b94d27b9...` |
| `base64` | Base64 encoded        | `uU0nuZ...`   |

## Example

**Input:**

```json theme={null}
{
  "input": "hello world",
  "algorithm": "SHA-256",
  "format": "hex"
}
```

**Output:**

```json theme={null}
{
  "success": true,
  "data": {
    "hash": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
    "algorithm": "SHA-256",
    "format": "hex",
    "inputLength": 11
  },
  "metadata": {
    "executionTime": 1.2,
    "warnings": null
  }
}
```

**With SHA-1 (warning):**

```json theme={null}
{
  "success": true,
  "data": {
    "hash": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
    "algorithm": "SHA-1",
    "format": "hex",
    "inputLength": 11
  },
  "metadata": {
    "warnings": ["SHA-1 is deprecated for security purposes"]
  }
}
```

## Implementation

```typescript theme={null}
import type { ToolDefinition, ToolFunction } from '@conveniencepro/ctp-core';

interface HashGeneratorResult {
  hash: string;
  algorithm: string;
  format: string;
  inputLength: number;
}

type HashAlgorithm = 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512';
type OutputFormat = 'hex' | 'base64';

export const hashGeneratorDefinition: ToolDefinition = {
  id: 'hash-generator',
  name: 'Hash Generator',
  description: 'Generate cryptographic hashes using SHA algorithms.',
  category: 'generators',
  tags: ['hash', 'sha256', 'sha512', 'checksum', 'crypto'],
  method: 'POST',
  parameters: [
    {
      name: 'input',
      type: 'textarea',
      label: 'Input Text',
      description: 'Text to hash',
      required: true,
    },
    {
      name: 'algorithm',
      type: 'select',
      label: 'Algorithm',
      description: 'Hash algorithm',
      required: false,
      defaultValue: 'SHA-256',
      options: [
        { value: 'SHA-1', label: 'SHA-1', description: 'Legacy (not secure)' },
        { value: 'SHA-256', label: 'SHA-256', description: 'Recommended' },
        { value: 'SHA-384', label: 'SHA-384' },
        { value: 'SHA-512', label: 'SHA-512', description: 'Strongest' },
      ],
      aiHint: 'Use SHA-256 unless user specifies otherwise',
    },
    {
      name: 'format',
      type: 'select',
      label: 'Output Format',
      description: 'Hash output format',
      required: false,
      defaultValue: 'hex',
      options: [
        { value: 'hex', label: 'Hexadecimal' },
        { value: 'base64', label: 'Base64' },
      ],
    },
  ],
  outputDescription: 'Cryptographic hash of the input',
  example: {
    input: { input: 'hello', algorithm: 'SHA-256', format: 'hex' },
    output: {
      hash: '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824',
      algorithm: 'SHA-256',
      format: 'hex',
      inputLength: 5,
    },
  },
  executionMode: 'client',
  aiInstructions: 'Use SHA-256 by default. Warn if user requests SHA-1.',
};

// ASYNC function - uses Web Crypto API
export const hashGeneratorFn: ToolFunction<HashGeneratorResult> = async (params) => {
  const startTime = performance.now();
  const input = params.input as string;
  const algorithm = (params.algorithm as HashAlgorithm) || 'SHA-256';
  const format = (params.format as OutputFormat) || 'hex';

  // Validation
  if (!input) {
    return {
      success: false,
      error: 'Input text is required',
      errorCode: 'MISSING_REQUIRED',
    };
  }

  try {
    // Encode input as UTF-8
    const encoder = new TextEncoder();
    const data = encoder.encode(input);

    // Generate hash using Web Crypto API
    const hashBuffer = await crypto.subtle.digest(algorithm, data);
    const hashArray = new Uint8Array(hashBuffer);

    // Format output
    let hash: string;
    if (format === 'base64') {
      let binary = '';
      hashArray.forEach(byte => {
        binary += String.fromCharCode(byte);
      });
      hash = btoa(binary);
    } else {
      hash = Array.from(hashArray)
        .map(b => b.toString(16).padStart(2, '0'))
        .join('');
    }

    return {
      success: true,
      data: {
        hash,
        algorithm,
        format,
        inputLength: input.length,
      },
      metadata: {
        executionTime: performance.now() - startTime,
        // Include warning for deprecated algorithm
        warnings: algorithm === 'SHA-1'
          ? ['SHA-1 is deprecated for security purposes']
          : undefined,
      },
    };
  } catch (e) {
    return {
      success: false,
      error: `Hash generation failed: ${(e as Error).message}`,
      errorCode: 'EXECUTION_ERROR',
    };
  }
};

export default { definition: hashGeneratorDefinition, fn: hashGeneratorFn };
```

## Key Patterns

### Async Tool Function

Uses `async/await` for Web Crypto API:

```typescript theme={null}
export const hashGeneratorFn: ToolFunction<Result> = async (params) => {
  const hashBuffer = await crypto.subtle.digest(algorithm, data);
  // ...
};
```

### Web Crypto API

Browser-native cryptographic functions:

```typescript theme={null}
// Encode string to bytes
const data = new TextEncoder().encode(input);

// Generate hash
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
```

### Conditional Warnings

Include warnings without failing:

```typescript theme={null}
metadata: {
  warnings: algorithm === 'SHA-1'
    ? ['SHA-1 is deprecated for security purposes']
    : undefined,
}
```

### AI Hints

Guide AI model behavior:

```typescript theme={null}
{
  name: 'algorithm',
  aiHint: 'Use SHA-256 unless user specifies otherwise',
}
```

### AI Instructions

Tool-level AI guidance:

```typescript theme={null}
{
  aiInstructions: 'Use SHA-256 by default. Warn if user requests SHA-1.',
}
```

## Web Crypto Support

Available in all modern browsers:

| Algorithm | Bits | Support      |
| --------- | ---- | ------------ |
| SHA-1     | 160  | All browsers |
| SHA-256   | 256  | All browsers |
| SHA-384   | 384  | All browsers |
| SHA-512   | 512  | All browsers |

**Note:** MD5 is NOT available in Web Crypto. Use a library if needed.

## Error Handling

| Error Code         | Cause                |
| ------------------ | -------------------- |
| `MISSING_REQUIRED` | `input` not provided |
| `EXECUTION_ERROR`  | Web Crypto failure   |
