Add BRAIN_DISABLED flag and fix Ollama tool call formatting

Features:
  - Add BRAIN_DISABLED feature flag to hide all Brain functionality
  - When enabled, hides Brain banner, status indicator, menu, and commands
  - Flag location: src/constants/brain.ts

  Fixes:
  - Fix Ollama 400 error by properly formatting tool_calls in messages
  - Update OllamaMessage type to include tool_calls field
  - Fix Brain menu keyboard not working (add missing modes to isMenuOpen)

  UI Changes:
  - Remove "^Tab toggle mode" hint from status bar
  - Remove "ctrl+t to hide todos" hint from status bar

  Files modified:
  - src/constants/brain.ts (add BRAIN_DISABLED flag)
  - src/types/ollama.ts (add tool_calls to OllamaMessage)
  - src/providers/ollama/chat.ts (format tool_calls in messages)
  - src/tui-solid/components/header.tsx (hide Brain UI when disabled)
  - src/tui-solid/components/status-bar.tsx (remove hints)
  - src/tui-solid/components/command-menu.tsx (filter brain command)
  - src/tui-solid/components/input-area.tsx (fix isMenuOpen modes)
  - src/tui-solid/routes/session.tsx (skip brain menu when disabled)
  - src/services/brain.ts (early return when disabled)
  - src/services/chat-tui/initialize.ts (skip brain init when disabled)
This commit is contained in:
2026-02-02 13:25:38 -05:00
parent 2eadda584a
commit c839fc4d68
114 changed files with 17243 additions and 273 deletions

View File

@@ -0,0 +1,66 @@
/**
* Agent definition constants
*/
export const AGENT_DEFINITION = {
FILE_EXTENSION: ".md",
DIRECTORY_NAME: "agents",
FRONTMATTER_DELIMITER: "---",
MAX_NAME_LENGTH: 50,
MAX_DESCRIPTION_LENGTH: 500,
MAX_TOOLS: 20,
MAX_TRIGGER_PHRASES: 10,
} as const;
export const AGENT_DEFINITION_PATHS = {
PROJECT: ".codetyper/agents",
GLOBAL: "~/.config/codetyper/agents",
BUILTIN: "src/agents",
} as const;
export const AGENT_DEFAULT_TOOLS = {
EXPLORE: ["read", "glob", "grep"],
PLAN: ["read", "glob", "grep", "web_search"],
CODE: ["read", "write", "edit", "glob", "grep", "bash"],
REVIEW: ["read", "glob", "grep", "lsp"],
BASH: ["bash", "read"],
} as const;
export const AGENT_COLORS = {
RED: "\x1b[31m",
GREEN: "\x1b[32m",
BLUE: "\x1b[34m",
YELLOW: "\x1b[33m",
CYAN: "\x1b[36m",
MAGENTA: "\x1b[35m",
WHITE: "\x1b[37m",
GRAY: "\x1b[90m",
RESET: "\x1b[0m",
} as const;
export const AGENT_TIER_CONFIG = {
fast: {
model: "gpt-4o-mini",
maxTurns: 5,
timeout: 30000,
},
balanced: {
model: "gpt-4o",
maxTurns: 10,
timeout: 60000,
},
thorough: {
model: "o1",
maxTurns: 20,
timeout: 120000,
},
} as const;
export const AGENT_MESSAGES = {
LOADING: "Loading agent definitions...",
LOADED: "Agent definitions loaded",
NOT_FOUND: "Agent definition not found",
INVALID_FRONTMATTER: "Invalid YAML frontmatter",
MISSING_REQUIRED: "Missing required field",
INVALID_TOOL: "Invalid tool specified",
} as const;

View File

@@ -0,0 +1,100 @@
/**
* Apply Patch Constants
*
* Configuration for unified diff parsing and application.
*/
/**
* Default configuration for patch application
*/
export const PATCH_DEFAULTS = {
FUZZ: 2,
MAX_FUZZ: 3,
IGNORE_WHITESPACE: false,
IGNORE_CASE: false,
CONTEXT_LINES: 3,
} as const;
/**
* Patch file patterns
*/
export const PATCH_PATTERNS = {
HUNK_HEADER: /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)$/,
FILE_HEADER_OLD: /^--- (.+?)(?:\t.*)?$/,
FILE_HEADER_NEW: /^\+\+\+ (.+?)(?:\t.*)?$/,
GIT_DIFF: /^diff --git a\/(.+) b\/(.+)$/,
INDEX_LINE: /^index [a-f0-9]+\.\.[a-f0-9]+(?: \d+)?$/,
BINARY_FILE: /^Binary files .+ differ$/,
NEW_FILE: /^new file mode \d+$/,
DELETED_FILE: /^deleted file mode \d+$/,
RENAME_FROM: /^rename from (.+)$/,
RENAME_TO: /^rename to (.+)$/,
NO_NEWLINE: /^\\ No newline at end of file$/,
} as const;
/**
* Line type prefixes
*/
export const LINE_PREFIXES = {
CONTEXT: " ",
ADDITION: "+",
DELETION: "-",
} as const;
/**
* Error messages
*/
export const PATCH_ERRORS = {
INVALID_PATCH: "Invalid patch format",
PARSE_FAILED: (detail: string) => `Failed to parse patch: ${detail}`,
HUNK_FAILED: (index: number, reason: string) =>
`Hunk #${index + 1} failed: ${reason}`,
FILE_NOT_FOUND: (path: string) => `Target file not found: ${path}`,
CONTEXT_MISMATCH: (line: number) =>
`Context mismatch at line ${line}`,
FUZZY_MATCH_FAILED: (hunk: number) =>
`Could not find match for hunk #${hunk + 1} even with fuzzy matching`,
ALREADY_APPLIED: "Patch appears to be already applied",
REVERSED_PATCH: "Patch appears to be reversed",
BINARY_NOT_SUPPORTED: "Binary patches are not supported",
WRITE_FAILED: (path: string, error: string) =>
`Failed to write patched file ${path}: ${error}`,
} as const;
/**
* Success messages
*/
export const PATCH_MESSAGES = {
PARSING: "Parsing patch...",
APPLYING: (file: string) => `Applying patch to ${file}`,
APPLIED: (files: number, hunks: number) =>
`Successfully applied ${hunks} hunk(s) to ${files} file(s)`,
DRY_RUN: (files: number, hunks: number) =>
`Dry run: ${hunks} hunk(s) would be applied to ${files} file(s)`,
FUZZY_APPLIED: (hunk: number, offset: number) =>
`Hunk #${hunk + 1} applied with fuzzy offset of ${offset}`,
ROLLBACK_AVAILABLE: "Rollback is available if needed",
SKIPPED_BINARY: (file: string) => `Skipped binary file: ${file}`,
} as const;
/**
* Tool titles
*/
export const PATCH_TITLES = {
APPLYING: (file: string) => `Patching: ${file}`,
SUCCESS: (files: number) => `Patched ${files} file(s)`,
PARTIAL: (success: number, failed: number) =>
`Partial success: ${success} patched, ${failed} failed`,
FAILED: "Patch failed",
DRY_RUN: "Patch dry run",
VALIDATING: "Validating patch",
} as const;
/**
* Special path values
*/
export const SPECIAL_PATHS = {
DEV_NULL: "/dev/null",
A_PREFIX: "a/",
B_PREFIX: "b/",
} as const;

View File

@@ -0,0 +1,62 @@
/**
* Background task constants
*/
export const BACKGROUND_TASK = {
MAX_CONCURRENT: 3,
DEFAULT_TIMEOUT: 300000, // 5 minutes
MAX_TIMEOUT: 3600000, // 1 hour
POLL_INTERVAL: 1000, // 1 second
MAX_RETRIES: 3,
RETRY_DELAY: 5000, // 5 seconds
HISTORY_LIMIT: 100,
} as const;
export const BACKGROUND_TASK_STORAGE = {
DIRECTORY: ".codetyper/tasks",
FILE_EXTENSION: ".json",
MAX_FILE_SIZE: 10 * 1024 * 1024, // 10MB
} as const;
export const BACKGROUND_TASK_SHORTCUTS = {
START: "ctrl+b",
LIST: "ctrl+shift+b",
CANCEL: "ctrl+shift+c",
PAUSE: "ctrl+shift+p",
RESUME: "ctrl+shift+r",
} as const;
export const BACKGROUND_TASK_COMMANDS = {
START: "/background",
LIST: "/tasks",
CANCEL: "/task cancel",
STATUS: "/task status",
CLEAR: "/task clear",
} as const;
export const BACKGROUND_TASK_STATUS_ICONS = {
pending: "\u23F3", // hourglass
running: "\u25B6", // play
paused: "\u23F8", // pause
completed: "\u2705", // check
failed: "\u274C", // cross
cancelled: "\u23F9", // stop
} as const;
export const BACKGROUND_TASK_MESSAGES = {
STARTED: "Task started in background",
COMPLETED: "Background task completed",
FAILED: "Background task failed",
CANCELLED: "Background task cancelled",
PAUSED: "Background task paused",
RESUMED: "Background task resumed",
QUEUE_FULL: "Task queue is full",
NOT_FOUND: "Task not found",
ALREADY_RUNNING: "Task is already running",
} as const;
export const BACKGROUND_TASK_NOTIFICATIONS = {
SOUND_ENABLED: true,
DESKTOP_ENABLED: true,
INLINE_ENABLED: true,
} as const;

View File

@@ -0,0 +1,107 @@
/**
* Brain Cloud Sync Constants
*
* Configuration for cloud synchronization of brain data.
*/
import type { CloudBrainConfig } from "@/types/brain-cloud";
/**
* Default cloud configuration
*/
export const CLOUD_BRAIN_DEFAULTS: CloudBrainConfig = {
enabled: false,
endpoint: "https://brain.codetyper.dev/api/v1",
syncOnSessionEnd: true,
syncInterval: 300000, // 5 minutes
conflictStrategy: "local-wins",
retryAttempts: 3,
retryDelay: 1000,
} as const;
/**
* Cloud API endpoints
*/
export const CLOUD_ENDPOINTS = {
PUSH: "/sync/push",
PULL: "/sync/pull",
STATUS: "/sync/status",
CONFLICTS: "/sync/conflicts",
RESOLVE: "/sync/resolve",
HEALTH: "/health",
} as const;
/**
* Sync configuration
*/
export const SYNC_CONFIG = {
MAX_BATCH_SIZE: 100,
MAX_QUEUE_SIZE: 1000,
STALE_ITEM_AGE_MS: 86400000, // 24 hours
VERSION_KEY: "brain_sync_version",
QUEUE_KEY: "brain_offline_queue",
} as const;
/**
* Error messages
*/
export const CLOUD_ERRORS = {
NOT_CONFIGURED: "Cloud sync is not configured",
OFFLINE: "Device is offline",
SYNC_IN_PROGRESS: "Sync already in progress",
PUSH_FAILED: (error: string) => `Push failed: ${error}`,
PULL_FAILED: (error: string) => `Pull failed: ${error}`,
CONFLICT_UNRESOLVED: (count: number) =>
`${count} conflict(s) require manual resolution`,
QUEUE_FULL: "Offline queue is full",
VERSION_MISMATCH: "Version mismatch - full sync required",
AUTH_REQUIRED: "Authentication required for cloud sync",
INVALID_RESPONSE: "Invalid response from server",
} as const;
/**
* Status messages
*/
export const CLOUD_MESSAGES = {
STARTING_SYNC: "Starting cloud sync...",
PUSHING: (count: number) => `Pushing ${count} change(s)...`,
PULLING: (count: number) => `Pulling ${count} change(s)...`,
RESOLVING_CONFLICTS: (count: number) => `Resolving ${count} conflict(s)...`,
SYNC_COMPLETE: "Cloud sync complete",
SYNC_SKIPPED: "No changes to sync",
QUEUED_OFFLINE: (count: number) => `Queued ${count} change(s) for later sync`,
RETRYING: (attempt: number, max: number) =>
`Retrying sync (${attempt}/${max})...`,
} as const;
/**
* Titles for UI
*/
export const CLOUD_TITLES = {
SYNCING: "Syncing with cloud",
SYNCED: "Cloud sync complete",
OFFLINE: "Offline - changes queued",
CONFLICT: "Sync conflicts",
ERROR: "Sync failed",
} as const;
/**
* Conflict resolution labels
*/
export const CONFLICT_LABELS = {
"local-wins": "Keep local version",
"remote-wins": "Use remote version",
manual: "Resolve manually",
merge: "Attempt to merge",
} as const;
/**
* HTTP request configuration
*/
export const CLOUD_HTTP_CONFIG = {
TIMEOUT_MS: 30000,
HEADERS: {
"Content-Type": "application/json",
"X-Client": "codetyper-cli",
},
} as const;

View File

@@ -0,0 +1,75 @@
/**
* Brain MCP Server constants
*/
export const BRAIN_MCP_SERVER = {
DEFAULT_PORT: 5002,
DEFAULT_HOST: "localhost",
REQUEST_TIMEOUT: 30000,
MAX_CONNECTIONS: 100,
HEARTBEAT_INTERVAL: 30000,
} as const;
export const BRAIN_MCP_RATE_LIMIT = {
ENABLED: true,
MAX_REQUESTS: 100,
WINDOW_MS: 60000, // 1 minute
BLOCK_DURATION: 300000, // 5 minutes
} as const;
export const BRAIN_MCP_AUTH = {
HEADER: "X-Brain-API-Key",
TOKEN_PREFIX: "Bearer",
SESSION_DURATION: 3600000, // 1 hour
} as const;
export const BRAIN_MCP_COMMANDS = {
START: "/brain mcp start",
STOP: "/brain mcp stop",
STATUS: "/brain mcp status",
LOGS: "/brain mcp logs",
CONFIG: "/brain mcp config",
} as const;
export const BRAIN_MCP_TOOL_NAMES = {
RECALL: "brain_recall",
LEARN: "brain_learn",
SEARCH: "brain_search",
RELATE: "brain_relate",
CONTEXT: "brain_context",
STATS: "brain_stats",
PROJECTS: "brain_projects",
} as const;
export const BRAIN_MCP_MESSAGES = {
SERVER_STARTED: "Brain MCP server started",
SERVER_STOPPED: "Brain MCP server stopped",
SERVER_ALREADY_RUNNING: "Brain MCP server is already running",
SERVER_NOT_RUNNING: "Brain MCP server is not running",
CLIENT_CONNECTED: "MCP client connected",
CLIENT_DISCONNECTED: "MCP client disconnected",
TOOL_EXECUTED: "Tool executed successfully",
TOOL_FAILED: "Tool execution failed",
UNAUTHORIZED: "Unauthorized request",
RATE_LIMITED: "Rate limit exceeded",
INVALID_REQUEST: "Invalid MCP request",
} as const;
export const BRAIN_MCP_ERRORS = {
PARSE_ERROR: { code: -32700, message: "Parse error" },
INVALID_REQUEST: { code: -32600, message: "Invalid request" },
METHOD_NOT_FOUND: { code: -32601, message: "Method not found" },
INVALID_PARAMS: { code: -32602, message: "Invalid params" },
INTERNAL_ERROR: { code: -32603, message: "Internal error" },
TOOL_NOT_FOUND: { code: -32001, message: "Tool not found" },
UNAUTHORIZED: { code: -32002, message: "Unauthorized" },
RATE_LIMITED: { code: -32003, message: "Rate limited" },
BRAIN_UNAVAILABLE: { code: -32004, message: "Brain service unavailable" },
} as const;
export const BRAIN_MCP_LOG_LEVELS = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
} as const;

View File

@@ -0,0 +1,69 @@
/**
* Multi-project Brain constants
*/
export const BRAIN_PROJECT = {
MAX_PROJECTS: 100,
NAME_MIN_LENGTH: 2,
NAME_MAX_LENGTH: 100,
DESCRIPTION_MAX_LENGTH: 500,
DEFAULT_RECALL_LIMIT: 5,
DEFAULT_SYNC_INTERVAL: 30, // minutes
} as const;
export const BRAIN_PROJECT_STORAGE = {
CONFIG_FILE: "brain-projects.json",
EXPORT_EXTENSION: ".brain-export.json",
BACKUP_EXTENSION: ".brain-backup.json",
} as const;
export const BRAIN_PROJECT_PATHS = {
LOCAL: ".codetyper/brain",
GLOBAL: "~/.local/share/codetyper/brain",
EXPORTS: "~/.local/share/codetyper/brain/exports",
BACKUPS: "~/.local/share/codetyper/brain/backups",
} as const;
export const BRAIN_PROJECT_COMMANDS = {
LIST: "/brain projects",
CREATE: "/brain project create",
SWITCH: "/brain project switch",
DELETE: "/brain project delete",
EXPORT: "/brain project export",
IMPORT: "/brain project import",
SYNC: "/brain project sync",
} as const;
export const BRAIN_PROJECT_API = {
LIST: "/api/projects",
CREATE: "/api/projects",
GET: "/api/projects/:id",
UPDATE: "/api/projects/:id",
DELETE: "/api/projects/:id",
SWITCH: "/api/projects/:id/switch",
EXPORT: "/api/projects/:id/export",
IMPORT: "/api/projects/import",
SYNC: "/api/projects/:id/sync",
} as const;
export const BRAIN_PROJECT_MESSAGES = {
CREATED: "Brain project created successfully",
SWITCHED: "Switched to project",
DELETED: "Brain project deleted",
EXPORTED: "Brain project exported",
IMPORTED: "Brain project imported",
SYNCED: "Brain project synced",
NOT_FOUND: "Brain project not found",
ALREADY_EXISTS: "Project with this name already exists",
INVALID_NAME: "Invalid project name",
SWITCH_FAILED: "Failed to switch project",
EXPORT_FAILED: "Failed to export project",
IMPORT_FAILED: "Failed to import project",
} as const;
export const BRAIN_PROJECT_DEFAULTS = {
AUTO_LEARN: true,
AUTO_RECALL: true,
CONTEXT_INJECTION: true,
SYNC_ENABLED: false,
} as const;

94
src/constants/brain.ts Normal file
View File

@@ -0,0 +1,94 @@
/**
* Brain API Constants
*
* Configuration constants for the CodeTyper Brain service
*/
/**
* Feature flag to disable all Brain functionality.
* Set to true to hide Brain menu, disable Brain API calls,
* and remove Brain-related UI elements.
*/
export const BRAIN_DISABLED = true;
export const BRAIN_PROVIDER_NAME = "brain" as const;
export const BRAIN_DISPLAY_NAME = "CodeTyper Brain";
export const BRAIN_DEFAULTS = {
BASE_URL: "http://localhost:5001",
PROJECT_ID: 1,
} as const;
export const BRAIN_ENDPOINTS = {
// Health
HEALTH: "/",
// Authentication
AUTH_REGISTER: "/auth/register",
AUTH_LOGIN: "/auth/login",
AUTH_LOGOUT: "/auth/logout",
AUTH_REFRESH: "/auth/refresh",
AUTH_ME: "/auth/me",
// Knowledge Graph
KNOWLEDGE_LEARN: "/api/knowledge/learn",
KNOWLEDGE_RECALL: "/api/knowledge/recall",
KNOWLEDGE_RELATE: "/api/knowledge/relate",
KNOWLEDGE_EXTRACT: "/api/knowledge/extract",
KNOWLEDGE_CONTEXT: "/api/knowledge/context",
KNOWLEDGE_CONCEPTS: "/api/knowledge/concepts",
KNOWLEDGE_STATS: "/api/knowledge/stats",
// Memory
MEMORY_STATUS: "/api/memory/status",
MEMORY_STATS: "/api/memory/stats",
MEMORY_SEARCH: "/api/memory/search",
MEMORY_STORE: "/api/memory/store",
MEMORY_TOP: "/api/memory/top",
MEMORY_FEEDBACK: "/api/memory/feedback",
// GraphQL (unified endpoint)
GRAPHQL: "/graphql",
} as const;
export const BRAIN_TIMEOUTS = {
HEALTH: 3000,
AUTH: 10000,
KNOWLEDGE: 15000,
MEMORY: 10000,
EXTRACT: 30000,
} as const;
export const BRAIN_ERRORS = {
NOT_RUNNING: "Brain service not available. Start the API server at localhost:5001",
NOT_AUTHENTICATED: "Not authenticated. Please login or set an API key.",
INVALID_API_KEY: "Invalid API key. Please check your credentials.",
CONNECTION_FAILED: "Failed to connect to Brain service.",
RECALL_FAILED: "Failed to recall knowledge from Brain.",
LEARN_FAILED: "Failed to store knowledge in Brain.",
EXTRACT_FAILED: "Failed to extract concepts from content.",
} as const;
export const BRAIN_MESSAGES = {
CONNECTED: "Brain connected",
CONNECTING: "Connecting to Brain...",
DISCONNECTED: "Brain disconnected",
LEARNING: "Learning concept...",
RECALLING: "Recalling knowledge...",
EXTRACTING: "Extracting concepts...",
} as const;
export const BRAIN_BANNER = {
TITLE: "CodeTyper has a Brain!",
CTA: "Login and get an API key to enable long-term memory",
URL: "http://localhost:5001",
LOGIN_URL: "http://localhost:5173/docs/login",
EMOJI_CONNECTED: "🧠",
EMOJI_DISCONNECTED: "💤",
} as const;
export const BRAIN_HEADERS = {
API_KEY: "api-key",
AUTHORIZATION: "Authorization",
CONTENT_TYPE: "Content-Type",
} as const;

View File

@@ -0,0 +1,33 @@
/**
* Confidence filtering constants
*/
export const CONFIDENCE_FILTER = {
DEFAULT_THRESHOLD: 80,
MIN_THRESHOLD: 0,
MAX_THRESHOLD: 100,
VALIDATION_TIMEOUT: 30000,
MAX_BATCH_SIZE: 50,
} as const;
export const CONFIDENCE_WEIGHTS = {
PATTERN_MATCH: 0.3,
CONTEXT_RELEVANCE: 0.25,
SEVERITY_LEVEL: 0.2,
CODE_ANALYSIS: 0.15,
HISTORICAL_ACCURACY: 0.1,
} as const;
export const CONFIDENCE_MESSAGES = {
BELOW_THRESHOLD: "Filtered out due to low confidence",
VALIDATION_FAILED: "Confidence adjusted after validation",
VALIDATION_PASSED: "Confidence validated successfully",
NO_FACTORS: "No confidence factors available",
} as const;
export const CONFIDENCE_COLORS = {
LOW: "#808080",
MEDIUM: "#FFA500",
HIGH: "#00FF00",
CRITICAL: "#FF0000",
} as const;

View File

@@ -0,0 +1,275 @@
/**
* Feature-Dev Workflow Constants
*
* Configuration and prompts for the 7-phase development workflow.
*/
import type { FeatureDevPhase, FeatureDevConfig } from "@/types/feature-dev";
/**
* Default workflow configuration
*/
export const FEATURE_DEV_CONFIG: FeatureDevConfig = {
requireCheckpoints: true,
autoRunTests: true,
autoCommit: false,
maxExplorationDepth: 3,
parallelExplorations: 3,
} as const;
/**
* Phase order for workflow progression
*/
export const PHASE_ORDER: FeatureDevPhase[] = [
"understand",
"explore",
"plan",
"implement",
"verify",
"review",
"finalize",
] as const;
/**
* Phase descriptions
*/
export const PHASE_DESCRIPTIONS: Record<FeatureDevPhase, string> = {
understand: "Clarify requirements and gather context",
explore: "Search codebase for relevant code and patterns",
plan: "Design the implementation approach",
implement: "Write the code changes",
verify: "Run tests and validate changes",
review: "Self-review the implementation",
finalize: "Commit changes and cleanup",
} as const;
/**
* Phase prompts for guiding the agent
*/
export const PHASE_PROMPTS: Record<FeatureDevPhase, string> = {
understand: `You are in the UNDERSTAND phase of feature development.
Your goal is to fully understand what needs to be built before writing any code.
Tasks:
1. Analyze the user's feature request
2. Identify unclear or ambiguous requirements
3. Ask clarifying questions if needed
4. Document the understood requirements
Output a summary of:
- What the feature should do
- User-facing behavior
- Technical requirements
- Edge cases to consider
- Any assumptions made
If anything is unclear, ask the user for clarification before proceeding.`,
explore: `You are in the EXPLORE phase of feature development.
Your goal is to understand the existing codebase before making changes.
Tasks:
1. Search for related code using grep and glob
2. Identify files that will need to be modified
3. Understand existing patterns and conventions
4. Find similar implementations to reference
5. Identify potential dependencies or impacts
Run multiple parallel searches to gather context efficiently.
Document your findings:
- Relevant files and their purposes
- Existing patterns to follow
- Code that might be affected
- Useful examples in the codebase`,
plan: `You are in the PLAN phase of feature development.
Your goal is to create a detailed implementation plan before writing code.
Tasks:
1. Design the solution architecture
2. List files to create, modify, or delete
3. Define the order of changes
4. Identify risks and dependencies
5. Plan the testing approach
Create a plan that includes:
- Summary of the approach
- Step-by-step implementation order
- File changes with descriptions
- Potential risks and mitigations
- Test cases to verify the feature
Present this plan for user approval before proceeding.`,
implement: `You are in the IMPLEMENT phase of feature development.
Your goal is to write the code according to the approved plan.
Tasks:
1. Follow the implementation plan step by step
2. Write clean, well-documented code
3. Follow existing code patterns and conventions
4. Create necessary files and make required changes
5. Track all changes made
Guidelines:
- Implement one step at a time
- Test each change locally if possible
- Keep changes focused and minimal
- Add comments for complex logic
- Update imports and exports as needed`,
verify: `You are in the VERIFY phase of feature development.
Your goal is to ensure the implementation works correctly.
Tasks:
1. Run the test suite
2. Add new tests for the feature
3. Fix any failing tests
4. Check for regressions
5. Verify edge cases
Report:
- Test results (pass/fail counts)
- Coverage information if available
- Any issues discovered
- Additional tests needed`,
review: `You are in the REVIEW phase of feature development.
Your goal is to self-review the implementation for quality.
Tasks:
1. Review all changes made
2. Check for code quality issues
3. Verify documentation is complete
4. Look for potential bugs
5. Ensure best practices are followed
Review criteria:
- Code clarity and readability
- Error handling
- Edge cases covered
- Performance considerations
- Security implications
- Documentation completeness
Report any findings that need attention.`,
finalize: `You are in the FINALIZE phase of feature development.
Your goal is to complete the feature implementation.
Tasks:
1. Create a commit with appropriate message
2. Update any documentation
3. Clean up temporary files
4. Prepare summary of changes
Output:
- Final list of changes
- Commit message (if committing)
- Any follow-up tasks recommended
- Success confirmation`,
} as const;
/**
* Checkpoint configuration per phase
*/
export const PHASE_CHECKPOINTS: Record<
FeatureDevPhase,
{ required: boolean; title: string }
> = {
understand: {
required: true,
title: "Requirements Confirmation",
},
explore: {
required: false,
title: "Exploration Summary",
},
plan: {
required: true,
title: "Implementation Plan Approval",
},
implement: {
required: false,
title: "Implementation Progress",
},
verify: {
required: true,
title: "Test Results Review",
},
review: {
required: true,
title: "Code Review Findings",
},
finalize: {
required: true,
title: "Final Approval",
},
} as const;
/**
* Error messages
*/
export const FEATURE_DEV_ERRORS = {
INVALID_PHASE: (phase: string) => `Invalid phase: ${phase}`,
INVALID_TRANSITION: (from: FeatureDevPhase, to: FeatureDevPhase) =>
`Cannot transition from ${from} to ${to}`,
CHECKPOINT_REQUIRED: (phase: FeatureDevPhase) =>
`User approval required for ${phase} phase`,
PHASE_FAILED: (phase: FeatureDevPhase, reason: string) =>
`Phase ${phase} failed: ${reason}`,
WORKFLOW_ABORTED: (reason: string) => `Workflow aborted: ${reason}`,
NO_PLAN: "Cannot implement without an approved plan",
TEST_FAILURE: "Tests failed - review required before proceeding",
} as const;
/**
* Status messages
*/
export const FEATURE_DEV_MESSAGES = {
STARTING: (phase: FeatureDevPhase) => `Starting ${phase} phase...`,
COMPLETED: (phase: FeatureDevPhase) => `Completed ${phase} phase`,
AWAITING_APPROVAL: (phase: FeatureDevPhase) =>
`Awaiting approval for ${phase}`,
CHECKPOINT: (title: string) => `Checkpoint: ${title}`,
EXPLORING: (query: string) => `Exploring: ${query}`,
IMPLEMENTING_STEP: (step: number, total: number) =>
`Implementing step ${step}/${total}`,
RUNNING_TESTS: "Running tests...",
REVIEWING: "Reviewing changes...",
FINALIZING: "Finalizing changes...",
} as const;
/**
* Allowed phase transitions
*/
export const ALLOWED_TRANSITIONS: Record<FeatureDevPhase, FeatureDevPhase[]> = {
understand: ["explore", "plan"], // Can skip explore if simple
explore: ["plan", "understand"], // Can go back to understand
plan: ["implement", "explore", "understand"], // Can go back
implement: ["verify", "plan"], // Can revise plan
verify: ["review", "implement"], // Can fix issues
review: ["finalize", "implement"], // Can fix issues
finalize: [], // Terminal state
} as const;
/**
* Phase timeout configuration (in ms)
*/
export const PHASE_TIMEOUTS: Record<FeatureDevPhase, number> = {
understand: 120000,
explore: 180000,
plan: 120000,
implement: 600000,
verify: 300000,
review: 120000,
finalize: 60000,
} as const;

View File

@@ -89,7 +89,7 @@ export const HELP_TOPICS: HelpTopic[] = [
fullDescription:
"Switch between Agent (full access), Ask (read-only), and Code Review modes.",
usage: "/mode",
shortcuts: ["Ctrl+Tab"],
shortcuts: ["Ctrl+M"],
category: "commands",
},
{
@@ -166,11 +166,11 @@ export const HELP_TOPICS: HelpTopic[] = [
category: "shortcuts",
},
{
id: "shortcut-ctrltab",
name: "Ctrl+Tab",
id: "shortcut-ctrlm",
name: "Ctrl+M",
shortDescription: "Cycle modes",
fullDescription: "Cycle through interaction modes.",
shortcuts: ["Ctrl+Tab"],
shortcuts: ["Ctrl+M"],
category: "shortcuts",
},
];

View File

@@ -1,4 +1,23 @@
export const HOME_VARS = {
title: "Welcome to CodeTyper - Your AI Coding Assistant",
subTitle: "Type a prompt below to start a new session",
subTitle: "Type a prompt below to start",
};
/** CODETYPER text logo */
export const ASCII_LOGO = [
" ██████╗ ██████╗ ██████╗ ███████╗ ████████╗ ██╗ ██╗ ██████╗ ███████╗ ██████╗ ",
"██╔════╝ ██╔═══██╗ ██╔══██╗ ██╔════╝ ╚══██╔══╝ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝ ██╔══██╗",
"██║ ██║ ██║ ██║ ██║ █████╗ ██║ ╚████╔╝ ██████╔╝ █████╗ ██████╔╝",
"██║ ██║ ██║ ██║ ██║ ██╔══╝ ██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ██╔══██╗",
"╚██████╗ ╚██████╔╝ ██████╔╝ ███████╗ ██║ ██║ ██║ ███████╗ ██║ ██║",
" ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝",
];
/** Gradient colors for CODETYPER text - from top to bottom */
export const ASCII_LOGO_GRADIENT = [
"#00FFFF", // Cyan
"#00D4FF", // Light blue
"#00AAFF", // Blue
"#0080FF", // Medium blue
"#0055FF", // Deep blue
"#AA00FF", // Purple
];

View File

@@ -0,0 +1,54 @@
/**
* MultiEdit Tool Constants
*
* Configuration for batch file editing operations
*/
export const MULTI_EDIT_DEFAULTS = {
MAX_EDITS: 50, // Maximum number of edits in a single batch
MAX_FILE_SIZE: 1024 * 1024, // 1MB max file size
} as const;
export const MULTI_EDIT_TITLES = {
VALIDATING: (count: number) => `Validating ${count} edits...`,
APPLYING: (current: number, total: number) =>
`Applying edit ${current}/${total}`,
SUCCESS: (count: number) => `Applied ${count} edits`,
PARTIAL: (success: number, failed: number) =>
`Applied ${success} edits, ${failed} failed`,
FAILED: "Multi-edit failed",
ROLLBACK: "Rolling back changes...",
} as const;
export const MULTI_EDIT_MESSAGES = {
NO_EDITS: "No edits provided",
TOO_MANY_EDITS: (max: number) => `Too many edits (max: ${max})`,
VALIDATION_FAILED: "Validation failed for one or more edits",
ATOMIC_FAILURE: "Atomic edit failed - all changes rolled back",
DUPLICATE_FILE: (path: string) =>
`Multiple edits to same file must be ordered: ${path}`,
OLD_STRING_NOT_FOUND: (path: string, preview: string) =>
`Old string not found in ${path}: "${preview}..."`,
OLD_STRING_NOT_UNIQUE: (path: string, count: number) =>
`Old string found ${count} times in ${path} (must be unique)`,
FILE_NOT_FOUND: (path: string) => `File not found: ${path}`,
FILE_TOO_LARGE: (path: string) => `File too large: ${path}`,
} as const;
export const MULTI_EDIT_DESCRIPTION = `Edit multiple files in a single atomic operation.
Use this tool when you need to:
- Make related changes across multiple files
- Refactor code that spans several files
- Apply consistent changes to many files
All edits are validated before any changes are applied.
If any edit fails validation, no changes are made.
Each edit requires:
- file_path: Absolute path to the file
- old_string: The exact text to find and replace
- new_string: The replacement text
The old_string must be unique in the file. If it appears multiple times,
provide more context to make it unique.`;

108
src/constants/parallel.ts Normal file
View File

@@ -0,0 +1,108 @@
/**
* Parallel Agent Execution Constants
*
* Configuration for concurrent task execution, resource limits,
* and conflict detection.
*/
import type { ResourceLimits, TaskPriority } from "@/types/parallel";
/**
* Default resource limits
*/
export const PARALLEL_DEFAULTS: ResourceLimits = {
maxConcurrentTasks: 5,
maxQueueSize: 50,
defaultTimeout: 60000,
maxRetries: 2,
} as const;
/**
* Priority weights for task ordering
*/
export const PRIORITY_WEIGHTS: Record<TaskPriority, number> = {
critical: 100,
high: 75,
normal: 50,
low: 25,
} as const;
/**
* Task type concurrency limits
* Some task types should have lower concurrency
*/
export const TASK_TYPE_LIMITS = {
explore: 5,
analyze: 4,
execute: 2,
search: 3,
} as const;
/**
* Conflict detection configuration
*/
export const CONFLICT_CONFIG = {
ENABLE_PATH_CONFLICT: true,
CONFLICT_CHECK_TIMEOUT_MS: 5000,
AUTO_RESOLVE_READ_CONFLICTS: true,
} as const;
/**
* Timeout values for different task types
*/
export const TASK_TIMEOUTS = {
explore: 30000,
analyze: 45000,
execute: 120000,
search: 15000,
} as const;
/**
* Error messages for parallel execution
*/
export const PARALLEL_ERRORS = {
QUEUE_FULL: "Task queue is full",
TIMEOUT: (taskId: string) => `Task ${taskId} timed out`,
CONFLICT: (taskId: string, paths: string[]) =>
`Task ${taskId} conflicts with paths: ${paths.join(", ")}`,
MAX_RETRIES: (taskId: string, retries: number) =>
`Task ${taskId} failed after ${retries} retries`,
CANCELLED: (taskId: string) => `Task ${taskId} was cancelled`,
INVALID_TASK: "Invalid task configuration",
EXECUTOR_ABORTED: "Executor was aborted",
} as const;
/**
* Status messages for parallel execution
*/
export const PARALLEL_MESSAGES = {
STARTING: (count: number) => `Starting ${count} parallel task(s)`,
COMPLETED: (success: number, failed: number) =>
`Completed: ${success} successful, ${failed} failed`,
QUEUED: (taskId: string, position: number) =>
`Task ${taskId} queued at position ${position}`,
RUNNING: (taskId: string) => `Running task: ${taskId}`,
WAITING_CONFLICT: (taskId: string) =>
`Task ${taskId} waiting for conflict resolution`,
RETRYING: (taskId: string, attempt: number) =>
`Retrying task ${taskId} (attempt ${attempt})`,
} as const;
/**
* Deduplication configuration
*/
export const DEDUP_CONFIG = {
ENABLE_CONTENT_DEDUP: true,
SIMILARITY_THRESHOLD: 0.95,
MAX_RESULTS_PER_TYPE: 100,
} as const;
/**
* Read-only task types (no conflict with each other)
*/
export const READ_ONLY_TASK_TYPES = new Set(["explore", "analyze", "search"]);
/**
* Modifying task types (conflict with all tasks on same paths)
*/
export const MODIFYING_TASK_TYPES = new Set(["execute"]);

View File

@@ -58,12 +58,18 @@ export const FILES = {
/** Provider credentials (stored in data, not config) */
credentials: join(DIRS.data, "credentials.json"),
/** Environment variables and tokens (API keys, JWT tokens, etc.) */
vars: join(DIRS.config, "vars.json"),
/** Command history */
history: join(DIRS.data, "history.json"),
/** Models cache */
modelsCache: join(DIRS.cache, "models.json"),
/** Copilot token cache */
copilotTokenCache: join(DIRS.cache, "copilot-token.json"),
/** Frecency cache for file/command suggestions */
frecency: join(DIRS.cache, "frecency.json"),

207
src/constants/pr-review.ts Normal file
View File

@@ -0,0 +1,207 @@
/**
* PR Review Toolkit Constants
*
* Configuration for multi-agent code review.
*/
import type {
PRReviewConfig,
ReviewSeverity,
ReviewFindingType,
} from "@/types/pr-review";
/**
* Minimum confidence threshold for reporting findings
* Only report findings with confidence >= 80%
*/
export const MIN_CONFIDENCE_THRESHOLD = 80;
/**
* Default review configuration
*/
export const DEFAULT_REVIEW_CONFIG: PRReviewConfig = {
minConfidence: MIN_CONFIDENCE_THRESHOLD,
reviewers: [
{ name: "security", type: "security", enabled: true, minConfidence: 80 },
{ name: "performance", type: "performance", enabled: true, minConfidence: 80 },
{ name: "style", type: "style", enabled: true, minConfidence: 85 },
{ name: "logic", type: "logic", enabled: true, minConfidence: 80 },
],
security: {
checkInjection: true,
checkXSS: true,
checkAuth: true,
checkSecrets: true,
checkDependencies: true,
},
performance: {
checkComplexity: true,
checkMemory: true,
checkQueries: true,
checkCaching: true,
checkRenders: true,
},
style: {
checkNaming: true,
checkFormatting: true,
checkConsistency: true,
checkComments: true,
},
logic: {
checkEdgeCases: true,
checkNullHandling: true,
checkErrorHandling: true,
checkConcurrency: true,
checkTypes: true,
},
excludePatterns: [
"**/node_modules/**",
"**/*.min.js",
"**/*.bundle.js",
"**/dist/**",
"**/build/**",
"**/*.lock",
"**/package-lock.json",
"**/yarn.lock",
"**/pnpm-lock.yaml",
],
maxFindings: 50,
} as const;
/**
* Severity emoji indicators
*/
export const SEVERITY_ICONS: Record<ReviewSeverity, string> = {
critical: "🔴",
warning: "🟠",
suggestion: "🟡",
nitpick: "🟢",
} as const;
/**
* Severity labels
*/
export const SEVERITY_LABELS: Record<ReviewSeverity, string> = {
critical: "CRITICAL",
warning: "WARNING",
suggestion: "SUGGESTION",
nitpick: "NITPICK",
} as const;
/**
* Finding type labels
*/
export const FINDING_TYPE_LABELS: Record<ReviewFindingType, string> = {
security: "Security",
performance: "Performance",
style: "Style",
logic: "Logic",
documentation: "Documentation",
testing: "Testing",
} as const;
/**
* Reviewer prompts
*/
export const REVIEWER_PROMPTS: Record<string, string> = {
security: `You are a security reviewer. Analyze the code changes for:
- SQL injection, XSS, command injection vulnerabilities
- Authentication and authorization issues
- Sensitive data exposure (API keys, passwords, tokens)
- Input validation and sanitization problems
- Insecure dependencies
Only report findings with high confidence (≥80%). For each issue:
- Describe the vulnerability
- Explain the potential impact
- Suggest a specific fix`,
performance: `You are a performance reviewer. Analyze the code changes for:
- Algorithmic complexity issues (O(n²) or worse operations)
- Memory usage problems (leaks, excessive allocations)
- Database query efficiency (N+1 queries, missing indexes)
- Unnecessary re-renders (React) or DOM manipulations
- Missing caching opportunities
Only report findings with high confidence (≥80%). For each issue:
- Describe the performance impact
- Provide complexity analysis if applicable
- Suggest optimization`,
style: `You are a code style reviewer. Analyze the code changes for:
- Naming convention violations
- Inconsistent formatting
- Code organization issues
- Missing or unclear documentation
- Deviations from project patterns
Only report significant style issues that affect readability or maintainability.
Skip minor formatting issues that could be auto-fixed.`,
logic: `You are a logic reviewer. Analyze the code changes for:
- Edge cases not handled
- Null/undefined reference risks
- Error handling gaps
- Race conditions or concurrency issues
- Type safety violations
Only report findings with high confidence (≥80%). For each issue:
- Describe the bug or potential bug
- Explain how it could manifest
- Suggest a fix with example code`,
} as const;
/**
* Rating thresholds
*/
export const RATING_THRESHOLDS = {
5: { maxCritical: 0, maxWarning: 0 },
4: { maxCritical: 0, maxWarning: 3 },
3: { maxCritical: 0, maxWarning: 10 },
2: { maxCritical: 1, maxWarning: 20 },
1: { maxCritical: Infinity, maxWarning: Infinity },
} as const;
/**
* Recommendation thresholds
*/
export const RECOMMENDATION_THRESHOLDS = {
approve: { maxCritical: 0, maxWarning: 0, maxSuggestion: 5 },
approve_with_suggestions: { maxCritical: 0, maxWarning: 3, maxSuggestion: Infinity },
request_changes: { maxCritical: 1, maxWarning: Infinity, maxSuggestion: Infinity },
needs_discussion: { maxCritical: Infinity, maxWarning: Infinity, maxSuggestion: Infinity },
} as const;
/**
* Error messages
*/
export const PR_REVIEW_ERRORS = {
NO_DIFF: "No diff content to review",
PARSE_FAILED: (error: string) => `Failed to parse diff: ${error}`,
REVIEWER_FAILED: (reviewer: string, error: string) =>
`Reviewer ${reviewer} failed: ${error}`,
NO_FILES: "No files in diff to review",
EXCLUDED_ALL: "All files excluded by pattern",
} as const;
/**
* Status messages
*/
export const PR_REVIEW_MESSAGES = {
STARTING: "Starting PR review...",
PARSING_DIFF: "Parsing diff...",
REVIEWING: (reviewer: string) => `Running ${reviewer} review...`,
AGGREGATING: "Aggregating results...",
COMPLETED: (findings: number) => `Review complete: ${findings} finding(s)`,
NO_FINDINGS: "No issues found",
} as const;
/**
* Report titles
*/
export const PR_REVIEW_TITLES = {
REPORT: "Pull Request Review",
FINDINGS: "Findings",
SUMMARY: "Summary",
RECOMMENDATION: "Recommendation",
} as const;

132
src/constants/skills.ts Normal file
View File

@@ -0,0 +1,132 @@
/**
* Skill System Constants
*
* Constants for skill loading, matching, and execution.
*/
import { join } from "path";
import { DIRS } from "@constants/paths";
/**
* Skill file configuration
*/
export const SKILL_FILE = {
NAME: "SKILL.md",
FRONTMATTER_DELIMITER: "---",
ENCODING: "utf-8",
} as const;
/**
* Skill directories
*/
export const SKILL_DIRS = {
BUILTIN: join(__dirname, "..", "skills"),
USER: join(DIRS.config, "skills"),
PROJECT: ".codetyper/skills",
} as const;
/**
* Skill loading configuration
*/
export const SKILL_LOADING = {
CACHE_TTL_MS: 60000,
MAX_SKILLS: 100,
MAX_FILE_SIZE_BYTES: 100000,
} as const;
/**
* Skill matching configuration
*/
export const SKILL_MATCHING = {
MIN_CONFIDENCE: 0.7,
EXACT_MATCH_BONUS: 0.3,
COMMAND_PREFIX: "/",
FUZZY_THRESHOLD: 0.6,
} as const;
/**
* Default skill metadata values
*/
export const SKILL_DEFAULTS = {
VERSION: "1.0.0",
TRIGGER_TYPE: "command" as const,
AUTO_TRIGGER: false,
REQUIRED_TOOLS: [] as string[],
} as const;
/**
* Skill error messages
*/
export const SKILL_ERRORS = {
NOT_FOUND: (id: string) => `Skill not found: ${id}`,
INVALID_FRONTMATTER: (file: string) => `Invalid frontmatter in: ${file}`,
MISSING_REQUIRED_FIELD: (field: string, file: string) =>
`Missing required field '${field}' in: ${file}`,
LOAD_FAILED: (file: string, error: string) =>
`Failed to load skill from ${file}: ${error}`,
NO_MATCH: "No matching skill found for input",
EXECUTION_FAILED: (id: string, error: string) =>
`Skill execution failed for ${id}: ${error}`,
} as const;
/**
* Skill titles for UI
*/
export const SKILL_TITLES = {
LOADING: (name: string) => `Loading skill: ${name}`,
EXECUTING: (name: string) => `Executing skill: ${name}`,
MATCHED: (name: string, confidence: number) =>
`Matched skill: ${name} (${(confidence * 100).toFixed(0)}%)`,
COMPLETED: (name: string) => `Skill completed: ${name}`,
FAILED: (name: string) => `Skill failed: ${name}`,
} as const;
/**
* Built-in skill IDs
*/
export const BUILTIN_SKILLS = {
COMMIT: "commit",
REVIEW_PR: "review-pr",
EXPLAIN: "explain",
FEATURE_DEV: "feature-dev",
} as const;
/**
* Skill trigger patterns for common commands
*/
export const SKILL_TRIGGER_PATTERNS = {
COMMIT: [
"/commit",
"commit changes",
"commit this",
"git commit",
"make a commit",
],
REVIEW_PR: [
"/review-pr",
"/review",
"review pr",
"review this pr",
"review pull request",
"code review",
],
EXPLAIN: [
"/explain",
"explain this",
"explain code",
"what does this do",
"how does this work",
],
FEATURE_DEV: [
"/feature",
"/feature-dev",
"implement feature",
"new feature",
"build feature",
],
} as const;
/**
* Required fields in skill frontmatter
*/
export const SKILL_REQUIRED_FIELDS = ["id", "name", "description", "triggers"] as const;

55
src/constants/token.ts Normal file
View File

@@ -0,0 +1,55 @@
/**
* Token Counting Constants
*
* Configuration for token estimation and context management
*/
// Token estimation ratios
export const CHARS_PER_TOKEN = 4;
export const TOKENS_PER_CHAR = 0.25;
// Context warning thresholds
export const TOKEN_WARNING_THRESHOLD = 0.75; // 75% - yellow warning
export const TOKEN_CRITICAL_THRESHOLD = 0.90; // 90% - red warning
export const TOKEN_OVERFLOW_THRESHOLD = 0.95; // 95% - trigger compaction
// Pruning thresholds (following OpenCode pattern)
export const PRUNE_MINIMUM_TOKENS = 20000; // Min tokens to actually prune
export const PRUNE_PROTECT_TOKENS = 40000; // Threshold before marking for pruning
export const PRUNE_RECENT_TURNS = 2; // Protect last N user turns
// Protected tools that should never be pruned
export const PRUNE_PROTECTED_TOOLS = new Set([
"skill",
"todo_read",
"todo_write",
]);
// Default context sizes
export const DEFAULT_MAX_CONTEXT_TOKENS = 128000;
export const DEFAULT_OUTPUT_TOKENS = 16000;
// Token display formatting
export const TOKEN_DISPLAY = {
SEPARATOR: "/",
UNIT_K: "K",
FORMAT_DECIMALS: 1,
} as const;
// Token status colors (semantic keys for theme lookup)
export const TOKEN_STATUS_COLORS = {
NORMAL: "textDim",
WARNING: "warning",
CRITICAL: "error",
COMPACTING: "info",
} as const;
// Messages
export const TOKEN_MESSAGES = {
CONTEXT_LOW: "Context running low",
CONTEXT_CRITICAL: "Context nearly full",
COMPACTION_STARTING: "Starting context compaction...",
COMPACTION_COMPLETE: (saved: number) =>
`Compaction complete: ${saved.toLocaleString()} tokens freed`,
OVERFLOW_WARNING: "Context overflow detected",
} as const;

View File

@@ -49,6 +49,8 @@ export const MODE_DISPLAY_CONFIG: Record<string, ModeDisplayConfig> = {
learning_prompt: { text: "Save Learning?", color: "cyan" },
help_menu: { text: "Help", color: "cyan" },
help_detail: { text: "Help Detail", color: "cyan" },
brain_menu: { text: "Brain Settings", color: "magenta" },
brain_login: { text: "Brain Login", color: "magenta" },
} as const;
export const DEFAULT_MODE_DISPLAY: ModeDisplayConfig = {
@@ -219,6 +221,11 @@ export const SLASH_COMMANDS: SlashCommand[] = [
description: "Sign out from provider",
category: "account",
},
{
name: "brain",
description: "Configure CodeTyper Brain (memory & knowledge)",
category: "account",
},
];
export const COMMAND_CATEGORIES = [

View File

@@ -0,0 +1,75 @@
/**
* WebFetch Tool Constants
*
* Configuration for the web content fetching tool
*/
export const WEB_FETCH_DEFAULTS = {
TIMEOUT_MS: 30000,
MAX_CONTENT_LENGTH: 500000, // 500KB max
USER_AGENT:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
} as const;
export const WEB_FETCH_TITLES = {
FETCHING: (url: string) => `Fetching: ${url}`,
SUCCESS: "Content fetched",
FAILED: "Fetch failed",
TIMEOUT: "Fetch timed out",
} as const;
export const WEB_FETCH_MESSAGES = {
URL_REQUIRED: "URL is required",
INVALID_URL: (url: string) => `Invalid URL: ${url}`,
TIMEOUT: "Request timed out",
FETCH_ERROR: (error: string) => `Fetch failed: ${error}`,
CONTENT_TOO_LARGE: "Content exceeds maximum size limit",
REDIRECT_DETECTED: (from: string, to: string) =>
`Redirected from ${from} to ${to}`,
} as const;
export const WEB_FETCH_DESCRIPTION = `Fetch content from a URL and convert HTML to markdown.
Use this tool when you need to:
- Read documentation from a URL
- Fetch API responses
- Get content from web pages
The content will be converted to markdown for readability.
HTML will be cleaned and converted. JSON responses are formatted.
Note: This tool cannot access authenticated or private URLs.
For GitHub URLs, prefer using the \`bash\` tool with \`gh\` CLI instead.`;
// Supported content types for conversion
export const SUPPORTED_CONTENT_TYPES = {
HTML: ["text/html", "application/xhtml+xml"],
JSON: ["application/json", "text/json"],
TEXT: ["text/plain", "text/markdown", "text/csv"],
XML: ["text/xml", "application/xml"],
} as const;
// HTML elements to remove (scripts, styles, etc.)
export const HTML_REMOVE_ELEMENTS = [
"script",
"style",
"noscript",
"iframe",
"svg",
"canvas",
"video",
"audio",
"nav",
"footer",
"aside",
];
// HTML elements to convert to markdown
export const HTML_BLOCK_ELEMENTS = [
"p",
"div",
"section",
"article",
"main",
"header",
];