clean code
This commit is contained in:
parent
59dce97350
commit
61a8ce0d22
10
AGENTS.md
10
AGENTS.md
@ -1,6 +1,6 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
This file provides guidance to Kode automation agents (including those compatible with Claude Code's `.claude` ecosystem) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
@ -46,7 +46,7 @@ SKIP_BUNDLED_CHECK=true npm publish
|
||||
## High-Level Architecture
|
||||
|
||||
### Core System Design
|
||||
Kode implements a **three-layer parallel architecture** inspired by Claude Code:
|
||||
Kode implements a **three-layer parallel architecture** refined for fast iteration across terminal workflows while remaining compatible with the Claude Code agent ecosystem:
|
||||
|
||||
1. **User Interaction Layer** (`src/screens/REPL.tsx`)
|
||||
- Interactive terminal interface using Ink (React for CLI)
|
||||
@ -74,9 +74,9 @@ Kode implements a **three-layer parallel architecture** inspired by Claude Code:
|
||||
### Agent System (`src/utils/agentLoader.ts`)
|
||||
**Dynamic Agent Configuration Loading** with 5-tier priority system:
|
||||
1. Built-in (code-embedded)
|
||||
2. `~/.claude/agents/` (Claude user)
|
||||
2. `~/.claude/agents/` (Claude Code user directory compatibility)
|
||||
3. `~/.kode/agents/` (Kode user)
|
||||
4. `./.claude/agents/` (Claude project)
|
||||
4. `./.claude/agents/` (Claude Code project directory compatibility)
|
||||
5. `./.kode/agents/` (Kode project)
|
||||
|
||||
Agents are defined as markdown files with YAML frontmatter:
|
||||
@ -99,7 +99,7 @@ Each tool follows a consistent pattern in `src/tools/[ToolName]/`:
|
||||
- Permission-aware execution
|
||||
|
||||
### Service Layer
|
||||
- **Claude Service** (`src/services/claude.ts`): Primary AI model interface
|
||||
- **Anthropic Service** (`src/services/claude.ts`): Claude API integration
|
||||
- **OpenAI Service** (`src/services/openai.ts`): OpenAI-compatible models
|
||||
- **Model Adapter Factory** (`src/services/modelAdapterFactory.ts`): Unified model interface
|
||||
- **MCP Client** (`src/services/mcpClient.ts`): Model Context Protocol for tool extensions
|
||||
|
||||
10
CLAUDE.md
10
CLAUDE.md
@ -1,6 +1,6 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
This file provides guidance to Kode automation agents (including those compatible with Claude Code's `.claude` ecosystem) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
@ -46,7 +46,7 @@ SKIP_BUNDLED_CHECK=true npm publish
|
||||
## High-Level Architecture
|
||||
|
||||
### Core System Design
|
||||
Kode implements a **three-layer parallel architecture** inspired by Claude Code:
|
||||
Kode implements a **three-layer parallel architecture** refined for fast iteration across terminal workflows while remaining compatible with the Claude Code agent ecosystem:
|
||||
|
||||
1. **User Interaction Layer** (`src/screens/REPL.tsx`)
|
||||
- Interactive terminal interface using Ink (React for CLI)
|
||||
@ -74,9 +74,9 @@ Kode implements a **three-layer parallel architecture** inspired by Claude Code:
|
||||
### Agent System (`src/utils/agentLoader.ts`)
|
||||
**Dynamic Agent Configuration Loading** with 5-tier priority system:
|
||||
1. Built-in (code-embedded)
|
||||
2. `~/.claude/agents/` (Claude user)
|
||||
2. `~/.claude/agents/` (Claude Code user directory compatibility)
|
||||
3. `~/.kode/agents/` (Kode user)
|
||||
4. `./.claude/agents/` (Claude project)
|
||||
4. `./.claude/agents/` (Claude Code project directory compatibility)
|
||||
5. `./.kode/agents/` (Kode project)
|
||||
|
||||
Agents are defined as markdown files with YAML frontmatter:
|
||||
@ -99,7 +99,7 @@ Each tool follows a consistent pattern in `src/tools/[ToolName]/`:
|
||||
- Permission-aware execution
|
||||
|
||||
### Service Layer
|
||||
- **Claude Service** (`src/services/claude.ts`): Primary AI model interface
|
||||
- **Anthropic Service** (`src/services/claude.ts`): Claude API integration
|
||||
- **OpenAI Service** (`src/services/openai.ts`): OpenAI-compatible models
|
||||
- **Model Adapter Factory** (`src/services/modelAdapterFactory.ts`): Unified model interface
|
||||
- **MCP Client** (`src/services/mcpClient.ts`): Model Context Protocol for tool extensions
|
||||
|
||||
@ -30,17 +30,17 @@ This change reflects our belief that the future of software development is colla
|
||||
### Full Compatibility with Multiple Standards
|
||||
|
||||
- ✅ **AGENTS.md** - Native support for the OpenAI-initiated standard format
|
||||
- ✅ **CLAUDE.md** - Full backward compatibility with Claude Code configurations
|
||||
- ✅ **CLAUDE.md** - Full backward compatibility with Claude Code `.claude` configurations
|
||||
- ✅ **Subagent System** - Advanced agent delegation and task orchestration
|
||||
- ✅ **Cross-platform** - Works with 20+ AI models and providers
|
||||
|
||||
Use `# Your documentation request` to generate and maintain your AGENTS.md file automatically, while maintaining full compatibility with existing Claude Code workflows.
|
||||
Use `# Your documentation request` to generate and maintain your AGENTS.md file automatically, while preserving compatibility with existing `.claude` workflows.
|
||||
|
||||
## Overview
|
||||
|
||||
Kode is a powerful AI assistant that lives in your terminal. It can understand your codebase, edit files, run commands, and handle entire workflows for you.
|
||||
|
||||
> **⚠️ Security Notice**: Kode runs in YOLO mode by default (equivalent to Claude's `--dangerously-skip-permissions` flag), bypassing all permission checks for maximum productivity. YOLO mode is recommended only for trusted, secure environments when working on non-critical projects. If you're working with important files or using models of questionable capability, we strongly recommend using `kode --safe` to enable permission checks and manual approval for all operations.
|
||||
> **⚠️ Security Notice**: Kode runs in YOLO mode by default (equivalent to Claude Code's `--dangerously-skip-permissions` flag), bypassing all permission checks for maximum productivity. YOLO mode is recommended only for trusted, secure environments when working on non-critical projects. If you're working with important files or using models of questionable capability, we strongly recommend using `kode --safe` to enable permission checks and manual approval for all operations.
|
||||
>
|
||||
> **📊 Model Performance**: For optimal performance, we recommend using newer, more capable models designed for autonomous task completion. Avoid older Q&A-focused models like GPT-4o or Gemini 2.5 Pro, which are optimized for answering questions rather than sustained independent task execution. Choose models specifically trained for agentic workflows and extended reasoning capabilities.
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
Kode 是一个强大的 AI 助手,运行在你的终端中。它能理解你的代码库、编辑文件、运行命令,并为你处理整个开发工作流。
|
||||
|
||||
> **⚠️ 安全提示**:Kode 默认以 YOLO 模式运行(等同于 Claude 的 `--dangerously-skip-permissions` 标志),跳过所有权限检查以获得最大生产力。YOLO 模式仅建议在安全可信的环境中处理非重要项目时使用。如果您正在处理重要文件或使用能力存疑的模型,我们强烈建议使用 `kode --safe` 启用权限检查和手动审批所有操作。
|
||||
> **⚠️ 安全提示**:Kode 默认以 YOLO 模式运行(等同于 Claude Code 的 `--dangerously-skip-permissions` 标志),跳过所有权限检查以获得最大生产力。YOLO 模式仅建议在安全可信的环境中处理非重要项目时使用。如果您正在处理重要文件或使用能力存疑的模型,我们强烈建议使用 `kode --safe` 启用权限检查和手动审批所有操作。
|
||||
>
|
||||
> **📊 模型性能建议**:为获得最佳体验,建议使用专为自主任务完成设计的新一代强大模型。避免使用 GPT-4o、Gemini 2.5 Pro 等较老的问答型模型,它们主要针对回答问题进行优化,而非持续的独立任务执行。请选择专门训练用于智能体工作流和扩展推理能力的模型。
|
||||
|
||||
|
||||
@ -74,8 +74,8 @@ Agents can be defined at five levels with priority order (later overrides earlie
|
||||
- Provided with Kode
|
||||
- Cannot be modified
|
||||
|
||||
2. **Claude User** (`~/.claude/agents/`)
|
||||
- Claude Code compatible user-level agents
|
||||
2. **.claude User (Claude Code)** (`~/.claude/agents/`)
|
||||
- Compatibility with Claude Code user directories
|
||||
- Personal agents available across all projects
|
||||
|
||||
3. **Kode User** (`~/.kode/agents/`)
|
||||
@ -83,8 +83,8 @@ Agents can be defined at five levels with priority order (later overrides earlie
|
||||
- Overrides Claude user agents with same name
|
||||
- Create with `/agents` command or manually
|
||||
|
||||
4. **Claude Project** (`./.claude/agents/`)
|
||||
- Claude Code compatible project-specific agents
|
||||
4. **.claude Project (Claude Code)** (`./.claude/agents/`)
|
||||
- Compatibility with Claude Code project directories
|
||||
- Overrides user-level agents
|
||||
|
||||
5. **Kode Project** (`./.kode/agents/`)
|
||||
|
||||
@ -20,7 +20,7 @@ import { randomUUID } from 'crypto'
|
||||
|
||||
const execAsync = promisify(exec)
|
||||
|
||||
// Core constants aligned with Claude Code architecture
|
||||
// Core constants aligned with the Claude Code agent architecture
|
||||
const AGENT_LOCATIONS = {
|
||||
USER: "user",
|
||||
PROJECT: "project",
|
||||
@ -324,7 +324,7 @@ function validateAgentConfig(config: Partial<CreateState>, existingAgents: Agent
|
||||
}
|
||||
}
|
||||
|
||||
// File system operations with Claude Code alignment
|
||||
// File system operations retained for Claude Code parity
|
||||
function getAgentDirectory(location: AgentLocation): string {
|
||||
if (location === AGENT_LOCATIONS.BUILT_IN || location === AGENT_LOCATIONS.ALL) {
|
||||
throw new Error(`Cannot get directory path for ${location} agents`)
|
||||
@ -545,7 +545,7 @@ async function updateAgent(
|
||||
writeFileSync(filePath, content, { encoding: 'utf-8', flag: 'w' })
|
||||
}
|
||||
|
||||
// Enhanced UI Components with Claude Code alignment
|
||||
// Enhanced UI components retained for Claude Code parity
|
||||
|
||||
interface HeaderProps {
|
||||
title: string
|
||||
@ -1574,7 +1574,7 @@ function AgentListView({
|
||||
<Box marginBottom={1}>
|
||||
<Text bold color={theme.primary}>💭 What are agents?</Text>
|
||||
</Box>
|
||||
<Text>Specialized AI assistants that Claude can delegate to for specific tasks.</Text>
|
||||
<Text>Specialized AI assistants that Kode can delegate to for specific tasks, compatible with Claude Code `.claude` agent packs.</Text>
|
||||
<Text>Each agent has its own context, prompt, and tools.</Text>
|
||||
|
||||
<Box marginTop={1} marginBottom={1}>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { Command } from '../commands'
|
||||
import { markProjectOnboardingComplete } from '../ProjectOnboarding'
|
||||
import { markProjectOnboardingComplete } from '../components/ProjectOnboarding'
|
||||
import { PROJECT_FILE } from '../constants/product'
|
||||
const command = {
|
||||
type: 'prompt',
|
||||
|
||||
@ -5,7 +5,7 @@ import chalk from 'chalk'
|
||||
import { getTheme } from '../utils/theme'
|
||||
import { env } from '../utils/env'
|
||||
import { getGlobalConfig, saveGlobalConfig } from '../utils/config'
|
||||
import { markProjectOnboardingComplete } from '../ProjectOnboarding'
|
||||
import { markProjectOnboardingComplete } from '../components/ProjectOnboarding'
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { safeParseJSON } from '../utils/json'
|
||||
|
||||
@ -175,10 +175,10 @@ export function Help({
|
||||
Custom commands loaded from:
|
||||
</Text>
|
||||
<Text color={theme.secondaryText}>
|
||||
• {getCustomCommandDirectories().userClaude} (user: prefix)
|
||||
• {getCustomCommandDirectories().userClaude} (Claude `.claude` user scope)
|
||||
</Text>
|
||||
<Text color={theme.secondaryText}>
|
||||
• {getCustomCommandDirectories().projectClaude} (project: prefix)
|
||||
• {getCustomCommandDirectories().projectClaude} (Claude `.claude` project scope)
|
||||
</Text>
|
||||
<Text color={theme.secondaryText}>
|
||||
Use /refresh-commands to reload after changes
|
||||
@ -190,10 +190,10 @@ export function Help({
|
||||
Create custom commands by adding .md files to:
|
||||
</Text>
|
||||
<Text color={theme.secondaryText}>
|
||||
• {getCustomCommandDirectories().userClaude} (user: prefix)
|
||||
• {getCustomCommandDirectories().userClaude} (Claude `.claude` user scope)
|
||||
</Text>
|
||||
<Text color={theme.secondaryText}>
|
||||
• {getCustomCommandDirectories().projectClaude} (project: prefix)
|
||||
• {getCustomCommandDirectories().projectClaude} (Claude `.claude` project scope)
|
||||
</Text>
|
||||
<Text color={theme.secondaryText}>
|
||||
Use /refresh-commands to reload after creation
|
||||
|
||||
@ -18,7 +18,7 @@ interface InvalidConfigDialogProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog shown when the Claude config file contains invalid JSON
|
||||
* Dialog shown when the Kode config file contains invalid JSON
|
||||
*/
|
||||
function InvalidConfigDialog({
|
||||
filePath,
|
||||
|
||||
@ -6,17 +6,17 @@ import {
|
||||
getGlobalConfig,
|
||||
saveCurrentProjectConfig,
|
||||
saveGlobalConfig,
|
||||
} from './utils/config.js'
|
||||
} from '../utils/config.js'
|
||||
import { existsSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { homedir } from 'os'
|
||||
import terminalSetup from './commands/terminalSetup'
|
||||
import { getTheme } from './utils/theme'
|
||||
import { RELEASE_NOTES } from './constants/releaseNotes'
|
||||
import terminalSetup from '../commands/terminalSetup'
|
||||
import { getTheme } from '../utils/theme'
|
||||
import { RELEASE_NOTES } from '../constants/releaseNotes'
|
||||
import { gt } from 'semver'
|
||||
import { isDirEmpty } from './utils/file'
|
||||
import { MACRO } from './constants/macros'
|
||||
import { PROJECT_FILE, PRODUCT_NAME } from './constants/product'
|
||||
import { isDirEmpty } from '../utils/file'
|
||||
import { MACRO } from '../constants/macros'
|
||||
import { PROJECT_FILE, PRODUCT_NAME } from '../constants/product'
|
||||
|
||||
// Function to mark onboarding as complete
|
||||
export function markProjectOnboardingComplete(): void {
|
||||
@ -74,9 +74,9 @@ export default function ProjectOnboarding({
|
||||
|
||||
// Load what we need for onboarding
|
||||
// NOTE: This whole component is statically rendered Once
|
||||
const hasClaudeMd = existsSync(join(workspaceDir, PROJECT_FILE))
|
||||
const workspaceHasProjectGuide = existsSync(join(workspaceDir, PROJECT_FILE))
|
||||
const isWorkspaceDirEmpty = isDirEmpty(workspaceDir)
|
||||
const needsClaudeMd = !hasClaudeMd && !isWorkspaceDirEmpty
|
||||
const shouldRecommendProjectGuide = !workspaceHasProjectGuide && !isWorkspaceDirEmpty
|
||||
const showTerminalTip =
|
||||
terminalSetup.isEnabled && !getGlobalConfig().shiftEnterKeyBindingInstalled
|
||||
|
||||
@ -106,9 +106,9 @@ export default function ProjectOnboarding({
|
||||
</React.Fragment>,
|
||||
)
|
||||
}
|
||||
if (needsClaudeMd) {
|
||||
if (shouldRecommendProjectGuide) {
|
||||
items.push(
|
||||
<React.Fragment key="claudemd">
|
||||
<React.Fragment key="projectGuide">
|
||||
{/* @ts-expect-error - OrderedList.Item children prop issue */}
|
||||
<OrderedList.Item>
|
||||
<Text color={theme.secondaryText}>
|
||||
@ -308,7 +308,7 @@ function PromptInput({
|
||||
addToHistory(mode === 'koding' ? `#${input}` : input)
|
||||
onInputChange('')
|
||||
|
||||
// Create additional context to inform Claude this is for KODING.md
|
||||
// Create additional context to inform the assistant this is for KODING.md
|
||||
const kodingContext =
|
||||
'The user is using Koding mode. Format your response as a comprehensive, well-structured document suitable for adding to AGENTS.md. Use proper markdown formatting with headings, lists, code blocks, etc. The response should be complete and ready to add to AGENTS.md documentation.'
|
||||
|
||||
@ -354,8 +354,8 @@ function PromptInput({
|
||||
if (messages.length) {
|
||||
await onQuery(messages)
|
||||
|
||||
// After query completes, the last message should be Claude's response
|
||||
// We'll set up a one-time listener to capture and save Claude's response
|
||||
// After query completes, the last message should be the assistant's response
|
||||
// We'll set up a one-time listener to capture and save that response
|
||||
// This will be handled by the REPL component or message handler
|
||||
}
|
||||
|
||||
@ -524,7 +524,7 @@ function PromptInput({
|
||||
onShowMessageSelector()
|
||||
}
|
||||
|
||||
// Shift+Tab for mode cycling (matching original Claude Code implementation)
|
||||
// Shift+Tab for mode cycling (retains legacy keyboard behavior)
|
||||
if (key.shift && key.tab) {
|
||||
cycleMode()
|
||||
return true // Explicitly handled
|
||||
|
||||
@ -74,7 +74,7 @@ export function AssistantTextMessage({
|
||||
}
|
||||
|
||||
switch (text) {
|
||||
// Local JSX commands don't need a response, but we still want Claude to see them
|
||||
// Local JSX commands don't need a response, but we still want the assistant to see them
|
||||
// Tool results render their own interrupt messages
|
||||
case NO_RESPONSE_REQUESTED:
|
||||
case INTERRUPT_MESSAGE_FOR_TOOL_USE:
|
||||
|
||||
@ -5,7 +5,7 @@ const pkg = require('../../package.json')
|
||||
|
||||
export const MACRO = {
|
||||
VERSION: pkg.version,
|
||||
README_URL: 'https://docs.anthropic.com/s/claude-code',
|
||||
README_URL: 'https://github.com/shareAI-lab/kode#readme',
|
||||
PACKAGE_URL: '@shareai-lab/kode',
|
||||
ISSUES_EXPLAINER: 'report the issue at https://github.com/shareAI-lab/kode/issues',
|
||||
}
|
||||
|
||||
@ -19,7 +19,8 @@ import { lastX } from './utils/generators'
|
||||
import { getGitEmail } from './utils/user'
|
||||
import { PROJECT_FILE } from './constants/product'
|
||||
/**
|
||||
* Find all AGENTS.md and CLAUDE.md files in the current working directory
|
||||
* Locate AGENTS.md and CLAUDE.md files for backward compatibility with
|
||||
* existing documentation workflows.
|
||||
*/
|
||||
export async function getClaudeFiles(): Promise<string | null> {
|
||||
const abortController = new AbortController()
|
||||
|
||||
@ -377,7 +377,6 @@ ${commandList}`,
|
||||
),
|
||||
getClients(),
|
||||
])
|
||||
// logStartup()
|
||||
const inputPrompt = [prompt, stdinContent].filter(Boolean).join('\n')
|
||||
if (print) {
|
||||
if (!inputPrompt) {
|
||||
@ -1291,7 +1290,6 @@ ${commandList}`,
|
||||
loadLogList(CACHE_PATHS.messages()),
|
||||
getClients(),
|
||||
])
|
||||
// logStartup()
|
||||
|
||||
// If a specific conversation is requested, load and resume it directly
|
||||
if (identifier !== undefined) {
|
||||
@ -1393,7 +1391,7 @@ ${commandList}`,
|
||||
})()
|
||||
})
|
||||
|
||||
// claude context (TODO: deprecate)
|
||||
// legacy context (TODO: deprecate)
|
||||
const context = program
|
||||
.command('context')
|
||||
.description(
|
||||
|
||||
@ -2,7 +2,7 @@ import { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
|
||||
import { Box, Newline, Static, Text } from 'ink'
|
||||
import ProjectOnboarding, {
|
||||
markProjectOnboardingComplete,
|
||||
} from '../ProjectOnboarding.js'
|
||||
} from '../components/ProjectOnboarding.js'
|
||||
import { CostThresholdDialog } from '../components/CostThresholdDialog'
|
||||
import * as React from 'react'
|
||||
import { useEffect, useMemo, useRef, useState, useCallback } from 'react'
|
||||
@ -337,7 +337,7 @@ export function REPL({
|
||||
|
||||
setMessages(oldMessages => [...oldMessages, ...newMessages])
|
||||
|
||||
// Mark onboarding as complete when any user message is sent to Claude
|
||||
// Mark onboarding as complete when any user message is sent to the assistant
|
||||
markProjectOnboardingComplete()
|
||||
|
||||
// The last message is an assistant message if the user input was a bash command,
|
||||
|
||||
@ -148,9 +148,9 @@ class KodeContextManager {
|
||||
|
||||
// 在调试模式下记录加载结果
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log(
|
||||
`[KodeContext] Loaded ${this.projectDocsCache.length} characters from project docs`,
|
||||
)
|
||||
debugLogger.info('KODE_CONTEXT_LOADED', {
|
||||
characters: this.projectDocsCache.length,
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[KodeContext] Failed to load project docs:', error)
|
||||
@ -1212,7 +1212,7 @@ export function formatSystemPromptWithContext(
|
||||
agentId?: string,
|
||||
skipContextReminders = false, // Parameter kept for API compatibility but not used anymore
|
||||
): { systemPrompt: string[]; reminders: string } {
|
||||
// 构建增强的系统提示 - 对齐官方 Claude Code 直接注入方式
|
||||
// 构建增强的系统提示,保持与原先直接注入方式的兼容
|
||||
const enhancedPrompt = [...systemPrompt]
|
||||
let reminders = ''
|
||||
|
||||
@ -1759,7 +1759,10 @@ function getAssistantMessageFromError(error: unknown): AssistantMessage {
|
||||
}
|
||||
if (error instanceof Error) {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log(error)
|
||||
debugLogger.error('ANTHROPIC_API_ERROR', {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
})
|
||||
}
|
||||
return createAssistantAPIErrorMessage(
|
||||
`${API_ERROR_MESSAGE_PREFIX}: ${error.message}`,
|
||||
|
||||
@ -136,7 +136,6 @@ export async function resolveFileReferences(content: string): Promise<string> {
|
||||
function validateAllowedTools(allowedTools: string[] | undefined): boolean {
|
||||
// Log allowed tools for debugging and future integration
|
||||
if (allowedTools && allowedTools.length > 0) {
|
||||
console.log('Command allowed tools:', allowedTools)
|
||||
// TODO: Integrate with src/permissions.ts tool permission system
|
||||
// TODO: Connect to Tool.tsx needsPermissions() mechanism
|
||||
}
|
||||
@ -147,8 +146,8 @@ function validateAllowedTools(allowedTools: string[] | undefined): boolean {
|
||||
* Frontmatter configuration for custom commands
|
||||
*
|
||||
* This interface defines the YAML frontmatter structure that can be used
|
||||
* to configure custom commands. It follows the same pattern as Claude Desktop's
|
||||
* custom command system but with additional fields for enhanced functionality.
|
||||
* to configure custom commands. It mirrors the Claude Desktop custom command
|
||||
* system for compatibility while adding Kode-specific enhancements.
|
||||
*/
|
||||
export interface CustomCommandFrontmatter {
|
||||
/** Display name for the command (overrides filename-based naming) */
|
||||
@ -436,10 +435,10 @@ function createCustomCommand(
|
||||
async getPromptForCommand(args: string): Promise<MessageParam[]> {
|
||||
let prompt = content.trim()
|
||||
|
||||
// Process argument substitution following Claude Code conventions
|
||||
// Process argument substitution following legacy conventions
|
||||
// This supports both the official $ARGUMENTS format and legacy {arg} format
|
||||
|
||||
// Step 1: Handle $ARGUMENTS placeholder (official Claude Code format)
|
||||
// Step 1: Handle $ARGUMENTS placeholder (legacy command format)
|
||||
if (prompt.includes('$ARGUMENTS')) {
|
||||
prompt = prompt.replace(/\$ARGUMENTS/g, args || '')
|
||||
}
|
||||
@ -650,9 +649,6 @@ export const loadCustomCommands = memoize(
|
||||
*/
|
||||
export const reloadCustomCommands = (): void => {
|
||||
loadCustomCommands.cache.clear()
|
||||
console.log(
|
||||
'Custom commands cache cleared. Commands will be reloaded on next use.',
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -9,6 +9,7 @@ import { getAvailableAgentTypes } from '../utils/agentLoader'
|
||||
import { existsSync } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
import { getCwd } from '../utils/state'
|
||||
import { debug as debugLogger } from '../utils/debugLogger'
|
||||
|
||||
export interface MentionContext {
|
||||
type: 'agent' | 'file'
|
||||
@ -159,10 +160,10 @@ class MentionProcessorService {
|
||||
|
||||
// Log cache refresh for debugging mention resolution issues
|
||||
if (agents.length !== previousCacheSize) {
|
||||
console.log('[MentionProcessor] Agent cache refreshed:', {
|
||||
debugLogger.info('MENTION_PROCESSOR_CACHE_REFRESHED', {
|
||||
agentCount: agents.length,
|
||||
previousCacheSize,
|
||||
cacheAge: now - this.lastAgentCheck
|
||||
cacheAge: now - this.lastAgentCheck,
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
@ -232,17 +233,17 @@ class MentionProcessorService {
|
||||
}
|
||||
|
||||
// Debug log for mention event emission tracking
|
||||
console.log('[MentionProcessor] Emitted mention event:', {
|
||||
debugLogger.info('MENTION_PROCESSOR_EVENT_EMITTED', {
|
||||
type: isAskModel ? 'ask-model' : 'agent',
|
||||
mention,
|
||||
agentType: isAskModel ? undefined : agentType
|
||||
agentType: isAskModel ? undefined : agentType,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[MentionProcessor] Failed to emit mention event:', {
|
||||
debugLogger.error('MENTION_PROCESSOR_EVENT_FAILED', {
|
||||
mention,
|
||||
agentType,
|
||||
isAskModel,
|
||||
error: error instanceof Error ? error.message : error
|
||||
error: error instanceof Error ? error.message : error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,12 +55,12 @@ const inputSchema = z.object({
|
||||
|
||||
export const TaskTool = {
|
||||
async prompt({ safeMode }) {
|
||||
// Match original Claude Code - prompt returns full agent descriptions
|
||||
// Ensure agent prompts remain compatible with Claude Code `.claude` agent packs
|
||||
return await getPrompt(safeMode)
|
||||
},
|
||||
name: TOOL_NAME,
|
||||
async description() {
|
||||
// Match original Claude Code exactly - simple description
|
||||
// Ensure metadata stays compatible with Claude Code `.claude` agent packs
|
||||
return "Launch a new task"
|
||||
},
|
||||
inputSchema,
|
||||
|
||||
@ -18,7 +18,7 @@ export async function getTaskTools(safeMode: boolean): Promise<Tool[]> {
|
||||
}
|
||||
|
||||
export async function getPrompt(safeMode: boolean): Promise<string> {
|
||||
// Extracted directly from original Claude Code obfuscated source
|
||||
// Maintain compatibility with Claude Code `.claude` agent descriptions
|
||||
const agents = await getActiveAgents()
|
||||
|
||||
// Format exactly as in original: (Tools: tool1, tool2)
|
||||
@ -29,7 +29,7 @@ export async function getPrompt(safeMode: boolean): Promise<string> {
|
||||
return `- ${agent.agentType}: ${agent.whenToUse} (Tools: ${toolsStr})`
|
||||
}).join('\n')
|
||||
|
||||
// 100% exact copy from original Claude Code source
|
||||
// Keep the wording aligned so shared `.claude` agent packs behave identically
|
||||
return `Launch a new agent to handle complex, multi-step tasks autonomously.
|
||||
|
||||
Available agent types and the tools they have access to:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Permission mode types based on original Claude Code implementation
|
||||
// Permission mode types retained for compatibility with earlier agent implementations
|
||||
export type PermissionMode =
|
||||
| 'default'
|
||||
| 'acceptEdits'
|
||||
@ -35,7 +35,7 @@ export interface ModeConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// Mode configuration based on original Claude Code
|
||||
// Mode configuration preserved for Claude Code parity
|
||||
export const MODE_CONFIGS: Record<PermissionMode, ModeConfig> = {
|
||||
default: {
|
||||
name: 'default',
|
||||
@ -100,7 +100,7 @@ export const MODE_CONFIGS: Record<PermissionMode, ModeConfig> = {
|
||||
},
|
||||
}
|
||||
|
||||
// Mode cycling function (based on original yg2 function)
|
||||
// Mode cycling function preserved from the Claude Code workflow
|
||||
export function getNextPermissionMode(
|
||||
currentMode: PermissionMode,
|
||||
isBypassAvailable: boolean = true,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import wrapAnsi from 'wrap-ansi'
|
||||
import { debug as debugLogger } from './debugLogger'
|
||||
|
||||
type WrappedText = string[]
|
||||
type Position = {
|
||||
@ -320,11 +321,12 @@ export class MeasuredText {
|
||||
// For non-blank lines
|
||||
const startOffset = this.text.indexOf(text, searchOffset)
|
||||
if (startOffset === -1) {
|
||||
console.log('Debug: Failed to find wrapped line in original text')
|
||||
console.log('Debug: Current text:', text)
|
||||
console.log('Debug: Full original text:', this.text)
|
||||
console.log('Debug: Search offset:', searchOffset)
|
||||
console.log('Debug: Wrapped text:', wrappedText)
|
||||
debugLogger.error('CURSOR_WRAP_MISMATCH', {
|
||||
currentText: text,
|
||||
originalText: this.text,
|
||||
searchOffset,
|
||||
wrappedText,
|
||||
})
|
||||
throw new Error('Failed to find wrapped line in original text')
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Agent configuration loader
|
||||
* Loads agent configurations from markdown files with YAML frontmatter
|
||||
* Following Claude Code's agent system architecture
|
||||
* Loads agent configurations from markdown files with YAML frontmatter.
|
||||
* Maintains compatibility with Claude Code `.claude` agent directories while
|
||||
* prioritizing Kode-specific overrides.
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, readdirSync, statSync, watch, FSWatcher } from 'fs'
|
||||
@ -231,7 +232,7 @@ let watchers: FSWatcher[] = []
|
||||
export async function startAgentWatcher(onChange?: () => void): Promise<void> {
|
||||
await stopAgentWatcher() // Clean up any existing watchers
|
||||
|
||||
// Watch both .claude and .kode directories
|
||||
// Watch both Claude (.claude) and native (.kode) directories
|
||||
const userClaudeDir = join(homedir(), '.claude', 'agents')
|
||||
const userKodeDir = join(homedir(), '.kode', 'agents')
|
||||
const projectClaudeDir = join(getCwd(), '.claude', 'agents')
|
||||
|
||||
@ -22,7 +22,7 @@ type Props = {
|
||||
verbose?: boolean
|
||||
}
|
||||
|
||||
// Sends a single prompt to the Claude API and returns the response.
|
||||
// Sends a single prompt to the Anthropic Messages API and returns the response.
|
||||
// Assumes that claude is being used non-interactively -- will not
|
||||
// ask the user for permissions or further input.
|
||||
export async function ask({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user