From b78beb7c39d659f2af78fde2039c1e5a89ab779d Mon Sep 17 00:00:00 2001 From: xiaoFjun-eng <66506420+xiaoFjun-eng@users.noreply.github.com> Date: Tue, 19 May 2026 09:05:04 +0800 Subject: [PATCH] Fix type (#1239) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 完善所有用到的type对象,并添加中文注释 * 补充遗失的type --- packages/@ant/ink/src/core/cursor.ts | 8 +- .../@ant/ink/src/core/events/paste-event.ts | 6 +- .../@ant/ink/src/core/events/resize-event.ts | 7 +- .../built-in/src/tools/WebFetchTool/prompt.ts | 2 + .../src/tools/WebSearchTool/prompt.ts | 2 + .../src/tools/AgentTool/src/Tool.ts | 8 + .../AgentTool/src/components/CtrlOToExpand.ts | 7 + .../src/tools/AgentTool/src/types/message.ts | 6 + .../src/bootstrap/state.ts | 7 + .../ExecuteTool/__tests__/ExecuteTool.test.ts | 32 +++ .../src/entrypoints/sdk/controlTypes.ts | 4 +- src/cli/transports/Transport.ts | 12 +- .../src/components/CustomSelect/index.ts | 4 +- src/commands/login/getAuthStatus.ts | 165 +++++++++++ src/commands/plugin/ManagePlugins.tsx | 81 +++--- src/commands/plugin/types.ts | 40 ++- src/commands/plugin/unifiedTypes.ts | 70 ++++- src/components/FeedbackSurvey/utils.ts | 12 +- src/components/Spinner/types.ts | 17 +- src/components/StatusLine.tsx | 8 +- .../agents/new-agent-creation/types.ts | 30 +- .../ExitPlanModeTool/ExitPlanModeV2Tool.ts | 4 +- .../src/tools/FileEditTool/FileEditTool.ts | 5 +- .../src/tools/FileWriteTool/FileWriteTool.ts | 4 +- src/components/agents/src/utils/api.ts | 4 +- src/components/mcp/src/services/mcp/types.ts | 4 +- src/components/mcp/types.ts | 80 +++++- .../src/utils/cwd.ts | 4 +- .../src/state/AppState.ts | 5 +- src/components/ui/option.ts | 7 +- src/components/wizard/WizardProvider.tsx | 25 +- src/components/wizard/types.ts | 31 +- src/constants/querySource.ts | 8 +- src/constants/src/utils/embeddedTools.ts | 4 +- src/entrypoints/agentSdkTypes.ts | 10 +- src/entrypoints/sdk/coreTypes.generated.ts | 264 +++++++++++++++++- src/hooks/notifs/src/ink.ts | 4 +- src/hooks/src/ink.ts | 4 +- src/hooks/src/utils/theme.ts | 4 +- .../handlers/src/utils/debug.ts | 5 +- .../src/tools/NotebookEditTool/constants.ts | 4 +- src/services/lsp/types.ts | 26 +- src/services/tips/tipRegistry.ts | 40 +-- src/services/tips/types.ts | 20 +- .../src/tools/NotebookEditTool/constants.ts | 4 +- .../src/tools/SendMessageTool/constants.ts | 4 +- .../built-in/src/utils/settings/settings.ts | 6 +- .../components/ConfigurableShortcutHint.ts | 5 +- .../design-system/KeyboardShortcutHint.ts | 5 +- .../AgentTool/src/utils/promptCategory.ts | 5 +- .../src/components/MessageResponse.ts | 5 +- src/tools/BashTool/src/Tool.ts | 4 +- src/tools/BashTool/src/bootstrap/state.ts | 5 +- .../src/utils/permissions/filesystem.ts | 5 +- .../src/utils/sandbox/sandbox-ui-utils.ts | 5 +- .../NotebookEditTool/NotebookEditTool.ts | 4 +- src/types/fileSuggestion.ts | 15 +- src/types/notebook.ts | 110 +++++++- src/types/statusLine.ts | 69 ++++- src/utils/__tests__/notebook.test.ts | 65 +++-- src/utils/hooks.ts | 32 +-- .../src/services/analytics/growthbook.ts | 5 +- src/utils/notebook.ts | 5 +- src/utils/plugins/mcpbHandler.ts | 18 +- .../sandbox/src/tools/FileReadTool/prompt.ts | 4 +- src/utils/settings/src/Tool.ts | 4 +- src/utils/settings/src/services/mcp/types.ts | 5 +- src/utils/src/tools/LSPTool/prompt.ts | 4 +- 68 files changed, 1239 insertions(+), 248 deletions(-) create mode 100644 packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebFetchTool/prompt.ts create mode 100644 packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebSearchTool/prompt.ts create mode 100644 packages/builtin-tools/src/tools/AgentTool/src/Tool.ts create mode 100644 packages/builtin-tools/src/tools/AgentTool/src/components/CtrlOToExpand.ts create mode 100644 packages/builtin-tools/src/tools/AgentTool/src/types/message.ts create mode 100644 packages/builtin-tools/src/tools/AskUserQuestionTool/src/bootstrap/state.ts create mode 100644 packages/builtin-tools/src/tools/ExecuteTool/__tests__/ExecuteTool.test.ts create mode 100644 src/commands/login/getAuthStatus.ts diff --git a/packages/@ant/ink/src/core/cursor.ts b/packages/@ant/ink/src/core/cursor.ts index dc58a0eec..6b80c7bf2 100644 --- a/packages/@ant/ink/src/core/cursor.ts +++ b/packages/@ant/ink/src/core/cursor.ts @@ -1,2 +1,6 @@ -// Auto-generated stub — replace with real implementation -export type Cursor = any; +/** 渲染帧中虚拟终端光标的状态(列/行坐标与是否绘制),供 diff 与光标 preamble 使用。 */ +export type Cursor = { + x: number // 光标所在列,从 0 开始计 + y: number // 光标所在行,从 0 开始计 + visible: boolean // 本帧是否应在终端绘制光标(隐藏时不发射光标移动序列) +} diff --git a/packages/@ant/ink/src/core/events/paste-event.ts b/packages/@ant/ink/src/core/events/paste-event.ts index 14136e76a..2419a8078 100644 --- a/packages/@ant/ink/src/core/events/paste-event.ts +++ b/packages/@ant/ink/src/core/events/paste-event.ts @@ -1,2 +1,4 @@ -// Auto-generated stub — replace with real implementation -export type PasteEvent = any; +/** Box 等组件上 `onPaste` / `onPasteCapture` 收到的粘贴事件形状(与括号粘贴解析结果对齐的占位约定)。 */ +export type PasteEvent = { + pastedText: string // 终端括号粘贴模式下解析出的 UTF-8 文本;允许为空字符串以表示空粘贴 +} diff --git a/packages/@ant/ink/src/core/events/resize-event.ts b/packages/@ant/ink/src/core/events/resize-event.ts index 99d596988..45452f884 100644 --- a/packages/@ant/ink/src/core/events/resize-event.ts +++ b/packages/@ant/ink/src/core/events/resize-event.ts @@ -1,2 +1,5 @@ -// Auto-generated stub — replace with real implementation -export type ResizeEvent = any; +/** 终端尺寸变化时 `onResize` 回调收到的事件载荷(与 `stdout.columns` / `stdout.rows` 一致)。 */ +export type ResizeEvent = { + columns: number // 当前终端列数(宽度) + rows: number // 当前终端行数(高度) +} diff --git a/packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebFetchTool/prompt.ts b/packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebFetchTool/prompt.ts new file mode 100644 index 000000000..36cd7ca85 --- /dev/null +++ b/packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebFetchTool/prompt.ts @@ -0,0 +1,2 @@ +/** WebFetch(拉取并处理 URL 内容)工具在 API 中的注册名称字面量(与 `WEB_FETCH_TOOL_NAME` 常量一致)。 */ +export type WEB_FETCH_TOOL_NAME = 'WebFetch' diff --git a/packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebSearchTool/prompt.ts b/packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebSearchTool/prompt.ts new file mode 100644 index 000000000..df3924dd3 --- /dev/null +++ b/packages/builtin-tools/src/tools/AgentTool/built-in/src/tools/WebSearchTool/prompt.ts @@ -0,0 +1,2 @@ +/** WebSearch(联网搜索)工具在 API 中的注册名称字面量(与 `WEB_SEARCH_TOOL_NAME` 常量一致)。 */ +export type WEB_SEARCH_TOOL_NAME = 'WebSearch' diff --git a/packages/builtin-tools/src/tools/AgentTool/src/Tool.ts b/packages/builtin-tools/src/tools/AgentTool/src/Tool.ts new file mode 100644 index 000000000..da31957be --- /dev/null +++ b/packages/builtin-tools/src/tools/AgentTool/src/Tool.ts @@ -0,0 +1,8 @@ +/** 根据工具定义装配宿主侧可调用 `Tool` 实例的工厂函数类型。 */ +export type buildTool = typeof import('src/Tool.js').buildTool + +/** 工具定义泛型(输入 Schema、权限、进度等);与宿主 `ToolDef` 一致。 */ +export type ToolDef = import('src/Tool.js').ToolDef + +/** 判断工具主名称或别名是否与查询名称相等;与宿主 `toolMatchesName` 一致。 */ +export type toolMatchesName = typeof import('src/Tool.js').toolMatchesName diff --git a/packages/builtin-tools/src/tools/AgentTool/src/components/CtrlOToExpand.ts b/packages/builtin-tools/src/tools/AgentTool/src/components/CtrlOToExpand.ts new file mode 100644 index 000000000..07b073bee --- /dev/null +++ b/packages/builtin-tools/src/tools/AgentTool/src/components/CtrlOToExpand.ts @@ -0,0 +1,7 @@ +/** 「Ctrl+O 展开」提示组件;与宿主 `src/components/CtrlOToExpand.tsx` 中 `CtrlOToExpand` 一致。 */ +export type CtrlOToExpand = + typeof import('src/components/CtrlOToExpand.js').CtrlOToExpand + +/** 标记子 Agent 输出上下文,用于抑制重复的展开提示;与宿主 `SubAgentProvider` 一致。 */ +export type SubAgentProvider = + typeof import('src/components/CtrlOToExpand.js').SubAgentProvider diff --git a/packages/builtin-tools/src/tools/AgentTool/src/types/message.ts b/packages/builtin-tools/src/tools/AgentTool/src/types/message.ts new file mode 100644 index 000000000..521e2a206 --- /dev/null +++ b/packages/builtin-tools/src/tools/AgentTool/src/types/message.ts @@ -0,0 +1,6 @@ +/** 对话消息联合类型(含用户/助手/系统等);与宿主 `src/types/message.js` 重导出一致。 */ +export type Message = import('src/types/message.js').Message + +/** 归一化后的用户消息形状;与宿主 `src/types/message.js` 中 `NormalizedUserMessage` 一致。 */ +export type NormalizedUserMessage = + import('src/types/message.js').NormalizedUserMessage diff --git a/packages/builtin-tools/src/tools/AskUserQuestionTool/src/bootstrap/state.ts b/packages/builtin-tools/src/tools/AskUserQuestionTool/src/bootstrap/state.ts new file mode 100644 index 000000000..c7a961c02 --- /dev/null +++ b/packages/builtin-tools/src/tools/AskUserQuestionTool/src/bootstrap/state.ts @@ -0,0 +1,7 @@ +/** 返回当前允许展示的通道列表(含名称、连接状态等);与宿主 `src/bootstrap/state.js` 中 `getAllowedChannels` 一致。 */ +export type getAllowedChannels = + typeof import('src/bootstrap/state.js').getAllowedChannels + +/** 返回问题预览渲染格式(Markdown/HTML)或未配置;与宿主 `getQuestionPreviewFormat` 一致。 */ +export type getQuestionPreviewFormat = + typeof import('src/bootstrap/state.js').getQuestionPreviewFormat diff --git a/packages/builtin-tools/src/tools/ExecuteTool/__tests__/ExecuteTool.test.ts b/packages/builtin-tools/src/tools/ExecuteTool/__tests__/ExecuteTool.test.ts new file mode 100644 index 000000000..ad1ccc3b3 --- /dev/null +++ b/packages/builtin-tools/src/tools/ExecuteTool/__tests__/ExecuteTool.test.ts @@ -0,0 +1,32 @@ +/** + * ExecuteTool.test.ts + * + * 薄层子进程包装器,在独立的 bun:test 进程中运行实际测试。 + * 这样可以防止其他测试文件的 mock.module() 漏出(例如 agentToolUtils.test.ts + * 对 src/Tool.js 的 mock)影响 ExecuteTool 的测试。 + */ +import { describe, test, expect } from 'bun:test' +import { resolve, relative } from 'path' + +const PROJECT_ROOT = resolve(__dirname, '..', '..', '..', '..', '..') +const RUNNER_ABS = resolve(__dirname, 'ExecuteTool.runner.ts') +const RUNNER_REL = './' + relative(PROJECT_ROOT, RUNNER_ABS).replace(/\\/g, '/') + +describe('ExecuteTool', () => { + test('runs all ExecuteTool tests in isolated subprocess', async () => { + const proc = Bun.spawn(['bun', 'test', RUNNER_REL], { + cwd: PROJECT_ROOT, + stdout: 'pipe', + stderr: 'pipe', + }) + const code = await proc.exited + if (code !== 0) { + const stderr = await new Response(proc.stderr).text() + const stdout = await new Response(proc.stdout).text() + const output = (stderr + '\n' + stdout).slice(-3000) + throw new Error( + `ExecuteTool test subprocess failed (exit ${code}):\n${output}`, + ) + } + }, 60_000) +}) diff --git a/src/bridge/src/entrypoints/sdk/controlTypes.ts b/src/bridge/src/entrypoints/sdk/controlTypes.ts index bd1b0590d..7924df8cc 100644 --- a/src/bridge/src/entrypoints/sdk/controlTypes.ts +++ b/src/bridge/src/entrypoints/sdk/controlTypes.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type StdoutMessage = any; +/** Bash 工具在 API 与 Agent 提示串中的注册名称字面量(与 `@claude-code-best/builtin-tools` 中 `BASH_TOOL_NAME` 常量一致)。 */ +export type BASH_TOOL_NAME = 'Bash' diff --git a/src/cli/transports/Transport.ts b/src/cli/transports/Transport.ts index d63bcb00e..55135b342 100644 --- a/src/cli/transports/Transport.ts +++ b/src/cli/transports/Transport.ts @@ -1,2 +1,10 @@ -// Auto-generated stub — replace with real implementation -export type Transport = any; +import type { StdoutMessage } from 'src/entrypoints/sdk/controlTypes.js' + +/** WebSocket / SSE+POST / Hybrid 等会话上行传输的共有接口。 */ +export type Transport = { + setOnData(callback: (data: string) => void): void // 注册下行数据回调(按行文本) + setOnClose(callback: (closeCode?: number) => void): void // 连接关闭时回调(可选关闭码) + connect(): void | Promise // 建立或重连传输 + write(message: StdoutMessage): void | Promise // 向上游发送一条控制/流式消息 + close(): void // 主动关闭并释放资源 +} diff --git a/src/commands/install-github-app/src/components/CustomSelect/index.ts b/src/commands/install-github-app/src/components/CustomSelect/index.ts index d95b49c7a..5e1130298 100644 --- a/src/commands/install-github-app/src/components/CustomSelect/index.ts +++ b/src/commands/install-github-app/src/components/CustomSelect/index.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type Select = any; +/** 同步记录分析事件(未附加 sink 时入队);与宿主 `src/services/analytics/index.js` 中 `logEvent` 一致。 */ +export type logEvent = typeof import('src/services/analytics/index.js').logEvent diff --git a/src/commands/login/getAuthStatus.ts b/src/commands/login/getAuthStatus.ts new file mode 100644 index 000000000..e031aa6f5 --- /dev/null +++ b/src/commands/login/getAuthStatus.ts @@ -0,0 +1,165 @@ +/** + * getAuthStatus — pure function; no network calls. + * + * Reads process.env + the local OAuth credential file (via the already-memoized + * getClaudeAIOAuthTokens()) + globalConfig.workspaceApiKey to produce an + * AuthStatus snapshot used by AuthPlaneSummary for the /login UI. + * + * Security contract: + * - ANTHROPIC_API_KEY / workspaceApiKey values are NEVER returned raw; only + * masked previews are exposed. + * - Third-party API key values are NEVER included; only boolean presence flags. + */ + +import type { SubscriptionType } from '../../services/oauth/types.js' +import { getClaudeAIOAuthTokens } from '../../utils/auth.js' +import { getGlobalConfig } from '../../utils/config.js' + +// --------------------------------------------------------------------------- +// Public types +// --------------------------------------------------------------------------- + +export interface AuthStatus { + subscription: { + /** true when a claude.ai OAuth token is present in local storage */ + active: boolean + /** subscription tier, or null when not logged in / API-key-only mode */ + plan: 'free' | 'pro' | 'max' | 'team' | 'enterprise' | 'unknown' | null + /** reserved — always null for security (email not included in masked output) */ + accountEmail: null + } + workspaceKey: { + /** + * true when a workspace API key is available from either the env var or + * saved settings (workspaceApiKey in ~/.claude.json). + */ + set: boolean + /** true when key begins with the expected 'sk-ant-api03-' prefix */ + prefixValid: boolean + /** + * Masked preview of the key, e.g. 'sk-a...67 (48 chars)', or null when unset. + * NEVER contains the raw key value. + */ + keyPreview: string | null + /** + * Where the key came from: + * 'env' — ANTHROPIC_API_KEY environment variable + * 'settings' — workspaceApiKey saved in ~/.claude.json via /login UI + * null — not set + */ + source: 'env' | 'settings' | null + } +} + +// thirdParty was removed 2026-05-06: fork's existing /login → "Anthropic +// Compatible Setup" form is the single source of truth for OpenAI-compat +// configuration. The summary intentionally only shows Anthropic-side planes +// (subscription / workspace key) which the fork form does not surface. + +// --------------------------------------------------------------------------- +// Constants +// --------------------------------------------------------------------------- + +const WORKSPACE_KEY_PREFIX = 'sk-ant-api03-' + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +/** + * Produce a masked preview of an API key value. + * Format: first4 + '...' + last2 + ' (N chars)' + * e.g.: 'sk-a...67 (48 chars)' + * + * E3 fix: keys shorter than 20 chars expose a high % of entropy per char + * (e.g. 6/14 = 43% exposed). For short/malformed keys, show [redacted] only. + * + * Never returns the raw key value. + */ +function maskApiKey(key: string): string { + const len = key.length + // E3: short keys — show only length, no prefix + if (len < 20) return `[redacted] (${len} chars)` + const first4 = key.slice(0, 4) + const last2 = key.slice(-2) + return `${first4}...${last2} (${len} chars)` +} + +// --------------------------------------------------------------------------- +// Main export +// --------------------------------------------------------------------------- + +/** + * Returns a snapshot of the current auth state by reading: + * - process.env.ANTHROPIC_API_KEY (workspace key) + * - getClaudeAIOAuthTokens() from the local credential file (subscription OAuth) + * + * Third-party provider config (Cerebras / Groq / Qwen / DeepSeek) is owned by + * fork's existing /login → "Anthropic Compatible Setup" form; the parallel + * surface here was removed 2026-05-06. + * + * This function never throws and never makes network calls. + */ +export function getAuthStatus(): AuthStatus { + // ---- 1. Subscription OAuth plane ---- + const oauthTokens = getClaudeAIOAuthTokens() + const subscriptionActive = + oauthTokens !== null && Boolean(oauthTokens.accessToken) + + let plan: AuthStatus['subscription']['plan'] = null + if (subscriptionActive && oauthTokens) { + // 本地持久化或历史 token 中可能出现 'free' 等未纳入 SubscriptionType 的字符串 + const raw = oauthTokens.subscriptionType as + | (SubscriptionType | 'free') + | null + if ( + raw === 'free' || + raw === 'pro' || + raw === 'max' || + raw === 'team' || + raw === 'enterprise' + ) { + plan = raw + } else if (raw !== null && raw !== undefined) { + plan = 'unknown' + } else { + plan = null + } + } + + // ---- 2. Workspace API key plane (dual-source: env var > settings) ---- + const envKey = (process.env.ANTHROPIC_API_KEY ?? '').trim() + const settingsKey = getGlobalConfig().workspaceApiKey?.trim() ?? '' + + let rawKey: string + let keySource: 'env' | 'settings' | null + + if (envKey.length > 0) { + rawKey = envKey + keySource = 'env' + } else if (settingsKey.length > 0) { + rawKey = settingsKey + keySource = 'settings' + } else { + rawKey = '' + keySource = null + } + + const keySet = rawKey.length > 0 + const prefixValid = rawKey.startsWith(WORKSPACE_KEY_PREFIX) + const keyPreview = keySet ? maskApiKey(rawKey) : null + + return { + subscription: { + active: subscriptionActive, + plan, + accountEmail: null, + }, + workspaceKey: { + set: keySet, + prefixValid, + keyPreview, + source: keySource, + }, + } +} diff --git a/src/commands/plugin/ManagePlugins.tsx b/src/commands/plugin/ManagePlugins.tsx index a3524724c..50fdde4a3 100644 --- a/src/commands/plugin/ManagePlugins.tsx +++ b/src/commands/plugin/ManagePlugins.tsx @@ -43,18 +43,19 @@ import { isPluginEnabledAtProjectScope, uninstallPluginOp, updatePluginOp, -} from '../../services/plugins/pluginOperations.js' -import { useAppState } from '../../state/AppState.js' -import type { Tool } from '../../Tool.js' -import type { LoadedPlugin, PluginError } from '../../types/plugin.js' -import { count } from '../../utils/array.js' -import { openBrowser } from '../../utils/browser.js' -import { logForDebugging } from '../../utils/debug.js' -import { errorMessage, toError } from '../../utils/errors.js' -import { logError } from '../../utils/log.js' -import { clearAllCaches } from '../../utils/plugins/cacheUtils.js' -import { loadInstalledPluginsV2 } from '../../utils/plugins/installedPluginsManager.js' -import { getMarketplace } from '../../utils/plugins/marketplaceManager.js' + type InstallableScope, +} from '../../services/plugins/pluginOperations.js'; +import { useAppState } from '../../state/AppState.js'; +import type { Tool } from '../../Tool.js'; +import type { LoadedPlugin, PluginError } from '../../types/plugin.js'; +import { count } from '../../utils/array.js'; +import { openBrowser } from '../../utils/browser.js'; +import { logForDebugging } from '../../utils/debug.js'; +import { errorMessage, toError } from '../../utils/errors.js'; +import { logError } from '../../utils/log.js'; +import { clearAllCaches } from '../../utils/plugins/cacheUtils.js'; +import { loadInstalledPluginsV2 } from '../../utils/plugins/installedPluginsManager.js'; +import { getMarketplace } from '../../utils/plugins/marketplaceManager.js'; import { isMcpbSource, loadMcpbFile, @@ -86,16 +87,16 @@ import { getSettings_DEPRECATED, getSettingsForSource, updateSettingsForSource, -} from '../../utils/settings/settings.js' -import { jsonParse } from '../../utils/slowOperations.js' -import { plural } from '../../utils/stringUtils.js' -import { formatErrorMessage, getErrorGuidance } from './PluginErrors.js' -import { PluginOptionsDialog } from './PluginOptionsDialog.js' -import { PluginOptionsFlow } from './PluginOptionsFlow.js' -import type { ViewState as ParentViewState } from './types.js' -import { UnifiedInstalledCell } from './UnifiedInstalledCell.js' -import type { UnifiedInstalledItem } from './unifiedTypes.js' -import { usePagination } from './usePagination.js' +} from '../../utils/settings/settings.js'; +import { jsonParse } from '../../utils/slowOperations.js'; +import { plural } from '../../utils/stringUtils.js'; +import { formatErrorMessage, getErrorGuidance } from './PluginErrors.js'; +import { PluginOptionsDialog } from './PluginOptionsDialog.js'; +import { PluginOptionsFlow } from './PluginOptionsFlow.js'; +import type { ViewState as ParentViewState } from './types.js'; +import { UnifiedInstalledCell } from './UnifiedInstalledCell.js'; +import type { UnifiedInstalledItem, UnifiedInstalledScope } from './unifiedTypes.js'; +import { usePagination } from './usePagination.js'; type Props = { setViewState: (state: ParentViewState) => void @@ -117,12 +118,12 @@ type FlaggedPluginInfo = { } type FailedPluginInfo = { - id: string - name: string - marketplace: string - errors: PluginError[] - scope: PersistablePluginScope -} + id: string; + name: string; + marketplace: string; + errors: PluginError[]; + scope: UnifiedInstalledScope; +}; type ViewState = | 'plugin-list' @@ -1388,14 +1389,14 @@ export function ManagePlugins({ const item = filteredItems[selectedIndex] if (item?.type === 'flagged-plugin') return if (item?.type === 'plugin') { - const pluginId = `${item.plugin.name}@${item.marketplace}` - const mergedSettings = getSettings_DEPRECATED() - const currentPending = pendingToggles.get(pluginId) - const isEnabled = mergedSettings?.enabledPlugins?.[pluginId] !== false - const pluginScope = item.scope - const isBuiltin = pluginScope === 'builtin' - if (isBuiltin || isInstallableScope(pluginScope)) { - const newPending = new Map(pendingToggles) + const pluginId = `${item.plugin.name}@${item.marketplace}`; + const mergedSettings = getSettings_DEPRECATED(); + const currentPending = pendingToggles.get(pluginId); + const isEnabled = mergedSettings?.enabledPlugins?.[pluginId] !== false; + const pluginScope = item.scope; + const isBuiltin = pluginScope === 'builtin'; + if (isBuiltin || isInstallableScope(pluginScope as PersistablePluginScope)) { + const newPending = new Map(pendingToggles); // Omit scope — see handleSingleOperation's enable/disable comment. if (currentPending) { // Cancel: reverse the operation back to the original state @@ -1752,10 +1753,10 @@ export function ManagePlugins({ // is a recovery path for a plugin that failed to load — it may // be reinstallable, so don't nuke ${CLAUDE_PLUGIN_DATA} silently. // The normal uninstall path prompts; this one preserves. - const result = isInstallableScope(pluginScope) - ? await uninstallPluginOp(pluginId, pluginScope, false) - : await uninstallPluginOp(pluginId, 'user', false) - let success = result.success + const result = isInstallableScope(pluginScope as PersistablePluginScope) + ? await uninstallPluginOp(pluginId, pluginScope as InstallableScope, false) + : await uninstallPluginOp(pluginId, 'user', false); + let success = result.success; if (!success) { // Plugin was never installed (only in enabledPlugins settings). // Remove directly from all editable settings sources. diff --git a/src/commands/plugin/types.ts b/src/commands/plugin/types.ts index 436f786ee..68dc97957 100644 --- a/src/commands/plugin/types.ts +++ b/src/commands/plugin/types.ts @@ -1,3 +1,37 @@ -// Auto-generated stub — replace with real implementation -export type ViewState = any; -export type PluginSettingsProps = any; +import type { LocalJSXCommandOnDone } from 'src/types/command.js' + +/** + * `/plugin` 根视图在子面板之间的导航状态。 + * 各分支对应不同子界面或从 CLI 参数解析出的初始路由。 + */ +export type ViewState = + | { type: 'menu' } // 返回插件功能总菜单 + | { type: 'help' } // 展示帮助说明 + | { type: 'validate'; path?: string } // 校验指定路径下的插件包 + | { + type: 'browse-marketplace' // 在指定市场中浏览/安装插件 + targetMarketplace: string // 目标市场标识 + targetPlugin?: string // 可选:预选插件名 + } + | { type: 'discover-plugins'; targetPlugin?: string } // 发现页;可预选搜索插件名 + | { + type: 'manage-plugins' // 已安装插件管理(启用/禁用/卸载) + targetPlugin?: string // 可选:聚焦某插件 + targetMarketplace?: string // 可选:与 targetPlugin 联用的市场 + action?: 'uninstall' | 'enable' | 'disable' // 可选:打开时直接执行的操作 + } + | { type: 'marketplace-list' } // 列出已配置市场 + | { type: 'marketplace-menu' } // 市场相关子菜单 + | { type: 'add-marketplace'; initialValue?: string } // 添加市场;可预填 URL/名称 + | { + type: 'manage-marketplaces' // 管理已保存的市场源 + targetMarketplace?: string // 可选:聚焦某市场 + action?: 'remove' | 'update' // 可选:移除或刷新该市场 + } + +/** `/plugin` Ink 命令入口的 props。 */ +export type PluginSettingsProps = { + onComplete: LocalJSXCommandOnDone // 子流程结束回调(可带结果文案与展示方式) + args?: string // CLI 透传的子命令参数字符串 + showMcpRedirectMessage?: boolean // 从 `/mcp` 跳转时展示 MCP 相关提示 +} diff --git a/src/commands/plugin/unifiedTypes.ts b/src/commands/plugin/unifiedTypes.ts index 7100863b2..3dab3fe4e 100644 --- a/src/commands/plugin/unifiedTypes.ts +++ b/src/commands/plugin/unifiedTypes.ts @@ -1,2 +1,68 @@ -// Auto-generated stub — replace with real implementation -export type UnifiedInstalledItem = any; +import type { + ConfigScope, + MCPServerConnection, +} from '../../services/mcp/types.js' +import type { LoadedPlugin, PluginError } from '../../types/plugin.js' + +import type { PersistablePluginScope } from '../../utils/plugins/pluginIdentifier.js' + +/** 列表项作用域:含 MCP 的 `builtin` 与已下架插件的 `flagged`。 */ +export type UnifiedInstalledScope = ConfigScope | 'builtin' | 'flagged' + +/** 插件管理列表中 MCP 连接行的连接状态摘要。 */ +export type McpRowStatus = + | 'connected' // 已连接且可用 + | 'disabled' // 用户或策略禁用 + | 'pending' // 正在连接或重连 + | 'needs-auth' // 需 OAuth 等鉴权 + | 'failed' // 连接或握手失败 + +/** + * 「已安装」统一列表中的一行:插件、失败占位、下架标记或 MCP 服务器。 + * 用于分页与键盘导航的同一数据源。 + */ +export type UnifiedInstalledItem = + | { + type: 'plugin' // 正常加载的插件 + id: string // `name@marketplace` 唯一键 + name: string // 插件短名 + description: string | undefined // manifest 描述 + marketplace: string // 所属市场 + scope: PersistablePluginScope | 'builtin' // 安装/展示作用域(内置单独标) + isEnabled: boolean // 是否在 merged settings 中启用 + errorCount: number // 与该插件关联的错误条数 + errors: PluginError[] // 结构化错误列表 + plugin: LoadedPlugin // 已解析的 manifest 与路径等 + pendingEnable?: boolean // UI:等待启用完成 + pendingUpdate?: boolean // UI:等待更新完成 + pendingToggle?: 'will-enable' | 'will-disable' // 用户已选、尚未落盘的启用切换 + } + | { + type: 'failed-plugin' // 未能加载的插件占位行 + id: string // 与错误 source 对齐的 id + name: string // 展示用名称 + marketplace: string // 推断或 unknown + scope: UnifiedInstalledScope // 推断的安装作用域 + errorCount: number + errors: PluginError[] + } + | { + type: 'flagged-plugin' // 市场已下架但仍出现在设置中的插件 + id: string + name: string + marketplace: string + scope: 'flagged' // 固定为下架分组 + reason: string // 下架原因码(如 delisted) + text: string // 面向用户的说明文案 + flaggedAt: string // 标记时间(ISO 等) + } + | { + type: 'mcp' // 独立 MCP 或插件子 MCP 行 + id: string // 列表稳定 id(如 mcp:name) + name: string // 展示名(子 MCP 可为 server 段) + description: string | undefined // 可选副标题 + scope: UnifiedInstalledScope // 来自 server config 或父插件推导 + status: McpRowStatus // 连接态摘要 + client: MCPServerConnection // 底层连接对象(供详情/工具视图) + indented?: boolean // true 表示挂在某插件下的子 MCP + } diff --git a/src/components/FeedbackSurvey/utils.ts b/src/components/FeedbackSurvey/utils.ts index bce6606fb..8a6c47aac 100644 --- a/src/components/FeedbackSurvey/utils.ts +++ b/src/components/FeedbackSurvey/utils.ts @@ -1,3 +1,9 @@ -// Auto-generated stub — replace with real implementation -export type FeedbackSurveyResponse = any; -export type FeedbackSurveyType = any; +/** 会话内满意度调查的选项(与数字键 0–3 映射一致)。 */ +export type FeedbackSurveyResponse = + | 'dismissed' // 0:关闭不反馈 + | 'bad' // 1:不满意 + | 'fine' // 2:一般 + | 'good' // 3:满意 + +/** 调查场景;当前仅实现会话级提示。 */ +export type FeedbackSurveyType = 'session' // 主会话 Spinner/流程内触发 diff --git a/src/components/Spinner/types.ts b/src/components/Spinner/types.ts index 78a11f342..4ccc06e39 100644 --- a/src/components/Spinner/types.ts +++ b/src/components/Spinner/types.ts @@ -1,3 +1,14 @@ -// Auto-generated stub — replace with real implementation -export type SpinnerMode = any; -export type RGBColor = any; +/** 主循环/流式输出旁路指示器所处的交互阶段。 */ +export type SpinnerMode = + | 'tool-input' // 等待用户对工具输入的响应 + | 'tool-use' // 工具执行中 + | 'responding' // 模型正在输出回复 + | 'thinking' // 模型思考/规划(不区分 provider 细节) + | 'requesting' // 请求已发出、等待首包(含 shimmer 较快节奏) + +/** 终端 24 位色(与 Ink `RGBColor` 及渐变插值工具一致)。 */ +export type RGBColor = { + r: number // 红 0–255 + g: number // 绿 0–255 + b: number // 蓝 0–255 +} diff --git a/src/components/StatusLine.tsx b/src/components/StatusLine.tsx index b2f2c7c91..d6762dcb1 100644 --- a/src/components/StatusLine.tsx +++ b/src/components/StatusLine.tsx @@ -91,10 +91,10 @@ function buildStatusLineCommandInput( contextWindowSize, ) - const sessionId = getSessionId() - const sessionName = getCurrentSessionTitle(sessionId) - const rawUtil = getRawUtilization() - const rateLimits: StatusLineCommandInput['rate_limits'] = { + const sessionId = getSessionId(); + const sessionName = getCurrentSessionTitle(sessionId); + const rawUtil = getRawUtilization(); + const rateLimits: NonNullable = { ...(rawUtil.five_hour && { five_hour: { used_percentage: rawUtil.five_hour.utilization * 100, diff --git a/src/components/agents/new-agent-creation/types.ts b/src/components/agents/new-agent-creation/types.ts index a592768c1..587ed7a6a 100644 --- a/src/components/agents/new-agent-creation/types.ts +++ b/src/components/agents/new-agent-creation/types.ts @@ -1,2 +1,28 @@ -// Auto-generated stub — replace with real implementation -export type AgentWizardData = any; +import type { CustomAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js' +import type { AgentMemoryScope } from '@claude-code-best/builtin-tools/tools/AgentTool/agentMemory.js' +import type { SettingSource } from '../../../utils/settings/constants.js' + +/** + * 「新建代理」向导在各步骤之间传递的可变状态。 + * 字段随步骤渐进填充;`finalAgent` 在确认前由 Color 步骤合成。 + */ +export type AgentWizardData = { + systemPrompt?: string // 系统提示词终稿 + agentType?: string // 代理类型 slug(目录名) + generationPrompt?: string // 「生成模式」下用户输入的说明全文 + selectedTools?: string[] // 限制可用工具;undefined 表示全量 + whenToUse?: string // 「何时调用」描述(whenToUse) + location?: SettingSource // 落盘位置:项目或个人 settings + selectedModel?: string // 覆盖默认模型(可选) + selectedColor?: string // 终端高亮色(可选) + wasGenerated?: boolean // 是否经模型一键生成过配置 + method?: 'generate' | 'manual' // 创建路径:生成 vs 手工 + isGenerating?: boolean // 生成请求进行中(用于 UI 防抖) + generatedAgent?: { + identifier: string // 生成器返回的 agentType 候选 + whenToUse: string // 生成器返回的描述 + systemPrompt: string // 生成器返回的系统提示 + } + selectedMemory?: AgentMemoryScope // Memory 步骤选择的记忆作用域 + finalAgent?: CustomAgentDefinition // 确认保存前的完整代理定义草稿 +} diff --git a/src/components/agents/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts b/src/components/agents/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts index f9708d2b3..8370105b3 100644 --- a/src/components/agents/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts +++ b/src/components/agents/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type ExitPlanModeV2Tool = any; +/** Edit(文件编辑)工具在 API 中的注册名称字面量(与 `FILE_EDIT_TOOL_NAME` 常量 `'Edit'` 一致)。 */ +export type FILE_EDIT_TOOL_NAME = 'Edit' diff --git a/src/components/agents/src/tools/FileEditTool/FileEditTool.ts b/src/components/agents/src/tools/FileEditTool/FileEditTool.ts index 0d3bc60eb..acbe2a20c 100644 --- a/src/components/agents/src/tools/FileEditTool/FileEditTool.ts +++ b/src/components/agents/src/tools/FileEditTool/FileEditTool.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type FileEditTool = any; +/** 设置文件来源层级标识(用户/项目/本地等);与宿主 `src/utils/settings/constants.js` 中 `SettingSource` 一致。 */ +export type SettingSource = + import('src/utils/settings/constants.js').SettingSource diff --git a/src/components/agents/src/tools/FileWriteTool/FileWriteTool.ts b/src/components/agents/src/tools/FileWriteTool/FileWriteTool.ts index 9417a7a94..655a26149 100644 --- a/src/components/agents/src/tools/FileWriteTool/FileWriteTool.ts +++ b/src/components/agents/src/tools/FileWriteTool/FileWriteTool.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type FileWriteTool = any; +/** Grep(内容搜索)工具在 API 中的注册名称字面量(与 `GREP_TOOL_NAME` 常量 `'Grep'` 一致)。 */ +export type GREP_TOOL_NAME = 'Grep' diff --git a/src/components/agents/src/utils/api.ts b/src/components/agents/src/utils/api.ts index d5a1bbc37..280a7ac39 100644 --- a/src/components/agents/src/utils/api.ts +++ b/src/components/agents/src/utils/api.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type prependUserContext = any; +/** Read(文件读取)工具在 API 中的注册名称字面量(与 `FILE_READ_TOOL_NAME` 常量 `'Read'` 一致)。 */ +export type FILE_READ_TOOL_NAME = 'Read' diff --git a/src/components/mcp/src/services/mcp/types.ts b/src/components/mcp/src/services/mcp/types.ts index f604edd2e..7e792d8b6 100644 --- a/src/components/mcp/src/services/mcp/types.ts +++ b/src/components/mcp/src/services/mcp/types.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type ConfigScope = any; +/** 工具调用权限判定回调(交互/自动模式分支);与宿主 `src/hooks/useCanUseTool.tsx` 中 `CanUseToolFn` 一致。 */ +export type CanUseToolFn = import('src/hooks/useCanUseTool.js').CanUseToolFn diff --git a/src/components/mcp/types.ts b/src/components/mcp/types.ts index cd22d6bf2..6a3de6ec8 100644 --- a/src/components/mcp/types.ts +++ b/src/components/mcp/types.ts @@ -1,8 +1,72 @@ -// Auto-generated stub — replace with real implementation -export type ServerInfo = any; -export type AgentMcpServerInfo = any; -export type MCPViewState = any; -export type StdioServerInfo = any; -export type ClaudeAIServerInfo = any; -export type HTTPServerInfo = any; -export type SSEServerInfo = any; +import type { + ConfigScope, + MCPServerConnection, + McpClaudeAIProxyServerConfig, + McpHTTPServerConfig, + McpSSEServerConfig, + McpStdioServerConfig, +} from '../../services/mcp/types.js' + +/** `/mcp` 列表与菜单共用的服务器行基类字段。 */ +type ServerInfoBase = { + name: string // MCP 服务器规范化名称 + client: MCPServerConnection // 连接态与配置载体 + scope: ConfigScope // 配置来源作用域 +} + +/** stdio MCP 服务器在 `/mcp` 与插件管理 UI 中的展示形态。 */ +export type StdioServerInfo = ServerInfoBase & { + transport: 'stdio' // 标准输入输出子进程 + config: McpStdioServerConfig // stdio 启动参数 +} + +/** SSE MCP 服务器(含 OAuth 会话态)。 */ +export type SSEServerInfo = ServerInfoBase & { + transport: 'sse' // 服务端推送事件流 + isAuthenticated: boolean | undefined // OAuth/会话是否已就绪(未知时为 undefined) + config: McpSSEServerConfig // SSE URL 与头等 +} + +/** Streamable HTTP MCP 服务器。 */ +export type HTTPServerInfo = ServerInfoBase & { + transport: 'http' // HTTP 流式或轮询类远端 + isAuthenticated: boolean | undefined // 远端鉴权是否完成 + config: McpHTTPServerConfig // HTTP 端点配置 +} + +/** Claude.ai 代理型 MCP 端点。 */ +export type ClaudeAIServerInfo = ServerInfoBase & { + transport: 'claudeai-proxy' // 经 Claude.ai 的代理通道 + isAuthenticated: boolean | undefined // 代理侧鉴权展示用 + config: McpClaudeAIProxyServerConfig // 代理 id/url 等 +} + +/** 非 agent 声明的、已连接 MCP 在 UI 中的判别联合。 */ +export type ServerInfo = + | StdioServerInfo + | SSEServerInfo + | HTTPServerInfo + | ClaudeAIServerInfo + +/** + * 从 Agent frontmatter 提取、用于 `/mcp`「Agents」分组的 MCP 声明。 + * 字段按传输方式可选出现,便于菜单统一读取。 + */ +export type AgentMcpServerInfo = { + name: string // 在 agent 内声明的服务器名 + sourceAgents: string[] // 引用该声明的 agentType 列表 + transport: 'stdio' | 'sse' | 'http' | 'ws' // 传输类别 + command?: string // stdio:启动命令 + url?: string // 远端:基础 URL + needsAuth: boolean // 是否依赖 OAuth/令牌 + /** 远程传输在 UI 中展示的 OAuth 状态(agent 声明路径下通常未知)。 */ + isAuthenticated?: boolean // UI 展示用;可选 +} + +/** `/mcp` 设置面板的视图状态机。 */ +export type MCPViewState = + | { type: 'list'; defaultTab?: string } // 服务器/Agents 列表;可选默认 tab + | { type: 'server-menu'; server: ServerInfo } // 选中某服务器后的操作菜单 + | { type: 'server-tools'; server: ServerInfo } // 该服务器的工具列表 + | { type: 'server-tool-detail'; server: ServerInfo; toolIndex: number } // 单个工具详情 + | { type: 'agent-server-menu'; agentServer: AgentMcpServerInfo } // agent 声明的 MCP 菜单 diff --git a/src/components/permissions/FileEditPermissionRequest/src/utils/cwd.ts b/src/components/permissions/FileEditPermissionRequest/src/utils/cwd.ts index 76c192ed8..67a6608fa 100644 --- a/src/components/permissions/FileEditPermissionRequest/src/utils/cwd.ts +++ b/src/components/permissions/FileEditPermissionRequest/src/utils/cwd.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type getCwd = any; +/** REPL 全局 UI 与权限等状态快照类型;与宿主 `src/state/AppStateStore.js` 中 `AppState` 一致。 */ +export type AppState = import('src/state/AppStateStore.js').AppState diff --git a/src/components/permissions/FilePermissionDialog/src/state/AppState.ts b/src/components/permissions/FilePermissionDialog/src/state/AppState.ts index 3c93608d8..29265e73e 100644 --- a/src/components/permissions/FilePermissionDialog/src/state/AppState.ts +++ b/src/components/permissions/FilePermissionDialog/src/state/AppState.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type useAppState = any; +/** 将权限模式映射为 Ink 主题颜色键,用于状态行等 UI;与宿主 `getModeColor` 一致。 */ +export type getModeColor = + typeof import('src/utils/permissions/PermissionMode.js').getModeColor diff --git a/src/components/ui/option.ts b/src/components/ui/option.ts index 794027d0b..7ca679c15 100644 --- a/src/components/ui/option.ts +++ b/src/components/ui/option.ts @@ -1,2 +1,5 @@ -// Auto-generated stub — replace with real implementation -export type Option = any; +/** CustomSelect / 权限规则列表等处的简单选项。 */ +export type Option = { + label: string // 展示给用户的文本 + value: string // 选中后回传的内部值(如规则 key、占位符) +} diff --git a/src/components/wizard/WizardProvider.tsx b/src/components/wizard/WizardProvider.tsx index 6707cb95a..69b50b365 100644 --- a/src/components/wizard/WizardProvider.tsx +++ b/src/components/wizard/WizardProvider.tsx @@ -9,9 +9,7 @@ import React, { import { useExitOnCtrlCDWithKeybindings } from '../../hooks/useExitOnCtrlCDWithKeybindings.js' import type { WizardContextValue, WizardProviderProps } from './types.js' -// Use any here for the context since it will be cast properly when used -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const WizardContext = createContext | null>(null) +export const WizardContext = createContext> | null>(null); export function WizardProvider>({ steps, @@ -21,11 +19,18 @@ export function WizardProvider>({ children, title, showStepCounter = true, -}: WizardProviderProps): ReactNode { - const [currentStepIndex, setCurrentStepIndex] = useState(0) - const [wizardData, setWizardData] = useState(initialData) - const [isCompleted, setIsCompleted] = useState(false) - const [navigationHistory, setNavigationHistory] = useState([]) +}: WizardProviderProps & { + initialData?: T; + onComplete: (data: T) => void; + onCancel: () => void; + children?: ReactNode; + title: string; + showStepCounter?: boolean; +}): ReactNode { + const [currentStepIndex, setCurrentStepIndex] = useState(0); + const [wizardData, setWizardData] = useState(initialData); + const [isCompleted, setIsCompleted] = useState(false); + const [navigationHistory, setNavigationHistory] = useState([]); useExitOnCtrlCDWithKeybindings() @@ -124,8 +129,8 @@ export function WizardProvider>({ } return ( - + >}> {children || } - ) + ); } diff --git a/src/components/wizard/types.ts b/src/components/wizard/types.ts index 2e1c20222..7a444e46f 100644 --- a/src/components/wizard/types.ts +++ b/src/components/wizard/types.ts @@ -1,4 +1,27 @@ -// Auto-generated stub — replace with real implementation -export type WizardContextValue = any; -export type WizardProviderProps = any; -export type WizardStepComponent = any; +import type { Dispatch, ReactNode, SetStateAction } from 'react' + +/** 向导中每一步的组件(无 props 或由 Wizard 包裹后注入上下文)。 */ +export type WizardStepComponent = (() => ReactNode) | React.ComponentType + +/** `WizardProvider` 的声明 props(与实现处交叉类型合并)。 */ +export type WizardProviderProps = { + steps: WizardStepComponent[] // 步骤组件序列 + children?: ReactNode // 可选:自定义包裹层;缺省时渲染当前步组件 + title: string // 标题栏文案 + showStepCounter?: boolean // 是否显示「第 n / 共 m 步」 +} + +/** 向导上下文:当前步骤索引、累积数据与导航。 */ +export type WizardContextValue> = { + currentStepIndex: number // 当前步骤下标 + totalSteps: number // 步骤总数 + wizardData: T // 各步写入的聚合数据 + setWizardData: Dispatch> // 整体替换向导数据 + updateWizardData: (updates: Partial) => void // 局部合并更新 + goNext: () => void // 下一步;末步则标记完成 + goBack: () => void // 上一步或退出 + goToStep: (index: number) => void // 非线性跳步(写入历史栈) + cancel: () => void // 放弃并清空历史 + title: string // 与 Provider 同步的标题 + showStepCounter: boolean // 是否展示步数计数 +} diff --git a/src/constants/querySource.ts b/src/constants/querySource.ts index b79de64ca..3567922b2 100644 --- a/src/constants/querySource.ts +++ b/src/constants/querySource.ts @@ -1,2 +1,6 @@ -// Auto-generated stub — replace with real implementation -export type QuerySource = any; +/** + * 标识一次模型/API 调用的业务来源,用于遥测拆分、缓存控制与 529 重试策略。 + * 值域随功能增长而扩展(含 `repl_main_thread:*`、`agent:*` 等前缀),故使用 `string`; + * 常见字面量见各调用点及 `withRetry.ts` 中的 `FOREGROUND_529_RETRY_SOURCES`。 + */ +export type QuerySource = string // 与日志/统计中的 source 字段对齐的自由文本标签 diff --git a/src/constants/src/utils/embeddedTools.ts b/src/constants/src/utils/embeddedTools.ts index c0160dbf9..1588e9b27 100644 --- a/src/constants/src/utils/embeddedTools.ts +++ b/src/constants/src/utils/embeddedTools.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type hasEmbeddedSearchTools = any; +/** 当前构建是否将 Glob/Grep 嵌入其它工具而不单独注册;与仓库根 `src/utils/embeddedTools.ts` 中 `hasEmbeddedSearchTools` 一致。 */ +export type hasEmbeddedSearchTools = () => boolean // 返回 true 时工具列表不包含独立的 Glob/Grep 工具名 diff --git a/src/entrypoints/agentSdkTypes.ts b/src/entrypoints/agentSdkTypes.ts index 842490372..a2fee8b27 100644 --- a/src/entrypoints/agentSdkTypes.ts +++ b/src/entrypoints/agentSdkTypes.ts @@ -60,6 +60,8 @@ import type { SessionMessage, SessionMutationOptions, } from './sdk/runtimeTypes.js' +// 与 settings / hooks schema 共用的钩子事件与 SessionEnd 退出原因字面量表 +import { EXIT_REASONS, HOOK_EVENTS } from './sdk/coreSchemas.js' export type { ListSessionsOptions, @@ -441,5 +443,9 @@ export async function connectRemoteControl( ): Promise { throw new Error('not implemented') } -export type HookEvent = any; -export type ExitReason = any; + +/** 会话钩子事件名(与 `HOOK_EVENTS` / settings schema 一致)。 */ +export type HookEvent = (typeof HOOK_EVENTS)[number] // 与 `coreSchemas.HOOK_EVENTS` 逐项对应 + +/** `SessionEnd` 钩子等使用的进程退出原因枚举。 */ +export type ExitReason = (typeof EXIT_REASONS)[number] // 与 `coreSchemas.EXIT_REASONS` 逐项对应 diff --git a/src/entrypoints/sdk/coreTypes.generated.ts b/src/entrypoints/sdk/coreTypes.generated.ts index a0ac6dc3d..9a63d1d38 100644 --- a/src/entrypoints/sdk/coreTypes.generated.ts +++ b/src/entrypoints/sdk/coreTypes.generated.ts @@ -1,8 +1,8 @@ /** - * Stub: Generated SDK core types. + * Stub:自动生成的 SDK Core 类型。 * - * In the full build, this is auto-generated from coreSchemas.ts Zod schemas. - * Here we provide typed stubs for all the types referenced throughout the codebase. + * 在完整构建中,这些类型会基于 coreSchemas.ts 中的 Zod schema 自动生成。 + * 这里提供的是类型化的 stub,用于覆盖代码库中引用到的所有相关类型。 */ import type { UUID } from 'crypto' @@ -65,11 +65,259 @@ export type RewindFilesResult = { // Account export type AccountInfo = Record -// Hook input types -export type HookInput = { hook_event_name: string; [key: string]: unknown } -export type HookJSONOutput = Record -export type AsyncHookJSONOutput = Record -export type SyncHookJSONOutput = Record +// 钩子输入类型 +export type HookInputBase = { + session_id: string // 会话 ID + transcript_path: string // 转录文件路径 + cwd: string // 当前工作目录 + permission_mode?: string // 权限模式(可选) + /** 仅在从子代理触发的钩子中存在 */ + agent_id?: string + /** 在子代理钩子中存在,或在使用 --agent 启动的主线程会话中存在 */ + agent_type?: string +} + +export type HookInput = + | (HookInputBase & { + hook_event_name: 'PreToolUse' + tool_name: string + tool_input: unknown + tool_use_id: string + }) + | (HookInputBase & { + hook_event_name: 'PermissionRequest' + tool_name: string + tool_input: unknown + permission_suggestions?: PermissionUpdate[] + }) + | (HookInputBase & { + hook_event_name: 'PostToolUse' + tool_name: string + tool_input: unknown + tool_response: unknown + tool_use_id: string + }) + | (HookInputBase & { + hook_event_name: 'PostToolUseFailure' + tool_name: string + tool_input: unknown + tool_use_id: string + error: string + is_interrupt?: boolean + }) + | (HookInputBase & { + hook_event_name: 'PermissionDenied' + tool_name: string + tool_input: unknown + tool_use_id: string + reason: string + }) + | (HookInputBase & { + hook_event_name: 'Notification' + message: string + title?: string + notification_type: string + }) + | (HookInputBase & { hook_event_name: 'UserPromptSubmit'; prompt: string }) + | (HookInputBase & { + hook_event_name: 'SessionStart' + source: 'startup' | 'resume' | 'clear' | 'compact' + agent_type?: string + model?: string + }) + | (HookInputBase & { + hook_event_name: 'SessionEnd' + reason: + | 'clear' + | 'resume' + | 'logout' + | 'prompt_input_exit' + | 'other' + | 'bypass_permissions_disabled' + }) + | (HookInputBase & { + hook_event_name: 'Setup' + trigger: 'init' | 'maintenance' + }) + | (HookInputBase & { + hook_event_name: 'Stop' + stop_hook_active: boolean + last_assistant_message?: string + }) + | (HookInputBase & { + hook_event_name: 'StopFailure' + error: string + error_details?: unknown + last_assistant_message?: string + }) + | (HookInputBase & { + hook_event_name: 'SubagentStart' + agent_id: string + agent_type: string + }) + | (HookInputBase & { + hook_event_name: 'SubagentStop' + stop_hook_active: boolean + agent_id: string + agent_transcript_path: string + agent_type: string + last_assistant_message?: string + }) + | (HookInputBase & { + hook_event_name: 'PreCompact' + trigger: 'manual' | 'auto' + custom_instructions: string | null + }) + | (HookInputBase & { + hook_event_name: 'PostCompact' + trigger: 'manual' | 'auto' + compact_summary: string + }) + | (HookInputBase & { + hook_event_name: 'TeammateIdle' + teammate_name: string + team_name: string + }) + | (HookInputBase & { + hook_event_name: 'TaskCreated' + task_id: string + task_subject: string + task_description?: string + teammate_name?: string + team_name?: string + }) + | (HookInputBase & { + hook_event_name: 'TaskCompleted' + task_id: string + task_subject: string + task_description?: string + teammate_name?: string + team_name?: string + }) + | (HookInputBase & { + hook_event_name: 'Elicitation' + mcp_server_name: string + message: string + mode?: 'form' | 'url' + url?: string + elicitation_id?: string + requested_schema?: Record + }) + | (HookInputBase & { + hook_event_name: 'ElicitationResult' + mcp_server_name: string + elicitation_id?: string + mode?: 'form' | 'url' + action: 'accept' | 'decline' | 'cancel' + content?: Record + }) + | (HookInputBase & { + hook_event_name: 'ConfigChange' + source: + | 'user_settings' + | 'project_settings' + | 'local_settings' + | 'policy_settings' + | 'skills' + file_path?: string + }) + | (HookInputBase & { + hook_event_name: 'InstructionsLoaded' + file_path: string + memory_type: 'User' | 'Project' | 'Local' | 'Managed' + load_reason: + | 'session_start' + | 'nested_traversal' + | 'path_glob_match' + | 'include' + | 'compact' + globs?: string[] + trigger_file_path?: string + parent_file_path?: string + }) + | (HookInputBase & { hook_event_name: 'WorktreeCreate'; name: string }) + | (HookInputBase & { + hook_event_name: 'WorktreeRemove' + worktree_path: string + }) + | (HookInputBase & { + hook_event_name: 'CwdChanged' + old_cwd: string + new_cwd: string + }) + | (HookInputBase & { + hook_event_name: 'FileChanged' + file_path: string + event: 'change' | 'add' | 'unlink' + }) + +export type AsyncHookJSONOutput = { + async: true + asyncTimeout?: number +} + +export type SyncHookJSONOutput = { + continue?: boolean + suppressOutput?: boolean + stopReason?: string + decision?: 'approve' | 'block' + systemMessage?: string + reason?: string + hookSpecificOutput?: + | { + hookEventName: 'PreToolUse' + permissionDecision?: string + permissionDecisionReason?: string + updatedInput?: Record + additionalContext?: string + } + | { hookEventName: 'UserPromptSubmit'; additionalContext?: string } + | { + hookEventName: 'SessionStart' + additionalContext?: string + initialUserMessage?: string + watchPaths?: string[] + } + | { hookEventName: 'Setup'; additionalContext?: string } + | { hookEventName: 'SubagentStart'; additionalContext?: string } + | { + hookEventName: 'PostToolUse' + additionalContext?: string + updatedMCPToolOutput?: unknown + } + | { hookEventName: 'PostToolUseFailure'; additionalContext?: string } + | { hookEventName: 'PermissionDenied'; retry?: boolean } + | { hookEventName: 'Notification'; additionalContext?: string } + | { + hookEventName: 'PermissionRequest' + decision: + | { + behavior: 'allow' + updatedInput?: Record + /** + * 注意:钩子使用的 JSON schema 为 PermissionUpdateSchema(), + * 它是一个比传统 `{path, permission}` 结构更丰富的联合类型。 + */ + updatedPermissions?: unknown[] + } + | { behavior: 'deny'; message?: string; interrupt?: boolean } + } + | { + hookEventName: 'Elicitation' + action?: 'accept' | 'decline' | 'cancel' + content?: Record + } + | { + hookEventName: 'ElicitationResult' + action?: 'accept' | 'decline' | 'cancel' + content?: Record + } + | { hookEventName: 'CwdChanged'; watchPaths?: string[] } + | { hookEventName: 'FileChanged'; watchPaths?: string[] } + | { hookEventName: 'WorktreeCreate'; worktreePath: string } +} + +export type HookJSONOutput = AsyncHookJSONOutput | SyncHookJSONOutput export type PreToolUseHookInput = HookInput & { tool_name: string } export type PostToolUseHookInput = HookInput & { tool_name: string } diff --git a/src/hooks/notifs/src/ink.ts b/src/hooks/notifs/src/ink.ts index 9fa0986a6..6d54a8522 100644 --- a/src/hooks/notifs/src/ink.ts +++ b/src/hooks/notifs/src/ink.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type Text = any; +/** 返回当前 Shell/会话逻辑工作目录字符串;与宿主 `src/utils/cwd.js` 中 `getCwd` 一致。 */ +export type getCwd = typeof import('src/utils/cwd.js').getCwd diff --git a/src/hooks/src/ink.ts b/src/hooks/src/ink.ts index 9fa0986a6..75eb2ceff 100644 --- a/src/hooks/src/ink.ts +++ b/src/hooks/src/ink.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type Text = any; +/** 将 Shell 会话当前目录设为解析后的物理路径;与宿主 `src/utils/Shell.js` 中 `setCwd` 一致。 */ +export type setCwd = typeof import('src/utils/Shell.js').setCwd diff --git a/src/hooks/src/utils/theme.ts b/src/hooks/src/utils/theme.ts index c6999a678..b0b4abaef 100644 --- a/src/hooks/src/utils/theme.ts +++ b/src/hooks/src/utils/theme.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type Theme = any; +/** Ink 底部快捷键说明行容器组件;与 `@anthropic/ink` 导出的 `Byline` 一致。 */ +export type Byline = typeof import('@anthropic/ink').Byline diff --git a/src/hooks/toolPermission/handlers/src/utils/debug.ts b/src/hooks/toolPermission/handlers/src/utils/debug.ts index c64d5960c..4e7f16f28 100644 --- a/src/hooks/toolPermission/handlers/src/utils/debug.ts +++ b/src/hooks/toolPermission/handlers/src/utils/debug.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type logForDebugging = any; +/** 写入调试日志文件(受日志级别与过滤规则约束);与宿主 `src/utils/debug.js` 中 `logForDebugging` 一致。 */ +export type logForDebugging = + typeof import('src/utils/debug.js').logForDebugging diff --git a/src/services/compact/src/tools/NotebookEditTool/constants.ts b/src/services/compact/src/tools/NotebookEditTool/constants.ts index 6c6c94bad..734860b74 100644 --- a/src/services/compact/src/tools/NotebookEditTool/constants.ts +++ b/src/services/compact/src/tools/NotebookEditTool/constants.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type NOTEBOOK_EDIT_TOOL_NAME = any; +/** ExitPlanMode 工具在 API 中的注册名称字面量(与内置 ExitPlanMode 工具 `name` 一致)。 */ +export type EXIT_PLAN_MODE_TOOL_NAME = 'ExitPlanMode' diff --git a/src/services/lsp/types.ts b/src/services/lsp/types.ts index 1dfa79379..3b53695c5 100644 --- a/src/services/lsp/types.ts +++ b/src/services/lsp/types.ts @@ -1,4 +1,22 @@ -// Auto-generated stub — replace with real implementation -export type LspServerConfig = any; -export type ScopedLspServerConfig = any; -export type LspServerState = any; +import type { z } from 'zod/v4' +import { LspServerConfigSchema } from '../../utils/plugins/schemas.js' + +/** 插件 manifest / `.lsp.json` 中的单条 LSP 服务器配置(由 Zod schema 推导)。 */ +export type LspServerConfig = z.infer> + +/** + * 插件动态注册时附带的作用域与来源插件名。 + * 与全局 user/project 配置区分,避免多插件同名冲突。 + */ +export type ScopedLspServerConfig = LspServerConfig & { + scope: 'dynamic' // 运行时由插件挂载的作用域标记 + source: string // 来源插件名(用于 `plugin:name:server` 前缀等) +} + +/** LSP 子进程生命周期状态(由 `LSPServerInstance` 维护)。 */ +export type LspServerState = + | 'stopped' // 未启动或已完全退出 + | 'starting' // 正在拉起进程/握手 + | 'running' // 已初始化并可服务请求 + | 'stopping' // 正在优雅关闭 + | 'error' // 启动失败或运行期崩溃后的错误态 diff --git a/src/services/tips/tipRegistry.ts b/src/services/tips/tipRegistry.ts index 05b727dcc..8e37b454b 100644 --- a/src/services/tips/tipRegistry.ts +++ b/src/services/tips/tipRegistry.ts @@ -443,8 +443,8 @@ const externalTips: Tip[] = [ }, { id: 'desktop-shortcut', - content: async ctx => { - const blue = color('suggestion', ctx.theme) + content: async (ctx?) => { + const blue = color('suggestion', ctx?.theme ?? 'dark') return `Continue your session in Claude Code Desktop with ${blue('/desktop')}` }, cooldownSessions: 15, @@ -489,24 +489,24 @@ const externalTips: Tip[] = [ }, { id: 'frontend-design-plugin', - content: async ctx => { - const blue = color('suggestion', ctx.theme) + content: async (ctx?) => { + const blue = color('suggestion', ctx?.theme ?? 'dark') return `Working with HTML/CSS? Install the frontend-design plugin:\n${blue(`/plugin install frontend-design@${OFFICIAL_MARKETPLACE_NAME}`)}` }, cooldownSessions: 3, - isRelevant: async context => + isRelevant: async (context?) => isMarketplacePluginRelevant('frontend-design', context, { filePath: /\.(html|css|htm)$/i, }), }, { id: 'vercel-plugin', - content: async ctx => { - const blue = color('suggestion', ctx.theme) + content: async (ctx?) => { + const blue = color('suggestion', ctx?.theme ?? 'dark') return `Working with Vercel? Install the vercel plugin:\n${blue(`/plugin install vercel@${OFFICIAL_MARKETPLACE_NAME}`)}` }, cooldownSessions: 3, - isRelevant: async context => + isRelevant: async (context?) => isMarketplacePluginRelevant('vercel', context, { filePath: /(?:^|[/\\])vercel\.json$/i, cli: ['vercel'], @@ -514,8 +514,8 @@ const externalTips: Tip[] = [ }, { id: 'effort-high-nudge', - content: async ctx => { - const blue = color('suggestion', ctx.theme) + content: async (ctx?) => { + const blue = color('suggestion', ctx?.theme ?? 'dark') const cmd = blue('/effort high') const variant = getFeatureValue_CACHED_MAY_BE_STALE< 'off' | 'copy_a' | 'copy_b' @@ -544,8 +544,8 @@ const externalTips: Tip[] = [ }, { id: 'subagent-fanout-nudge', - content: async ctx => { - const blue = color('suggestion', ctx.theme) + content: async (ctx?) => { + const blue = color('suggestion', ctx?.theme ?? 'dark') const variant = getFeatureValue_CACHED_MAY_BE_STALE< 'off' | 'copy_a' | 'copy_b' >('tengu_tern_alloy', 'off') @@ -566,8 +566,8 @@ const externalTips: Tip[] = [ }, { id: 'loop-command-nudge', - content: async ctx => { - const blue = color('suggestion', ctx.theme) + content: async (ctx?) => { + const blue = color('suggestion', ctx?.theme ?? 'dark') const variant = getFeatureValue_CACHED_MAY_BE_STALE< 'off' | 'copy_a' | 'copy_b' >('tengu_timber_lark', 'off') @@ -589,8 +589,8 @@ const externalTips: Tip[] = [ }, { id: 'guest-passes', - content: async ctx => { - const claude = color('claude', ctx.theme) + content: async (ctx?) => { + const claude = color('claude', ctx?.theme ?? 'dark') const reward = getCachedReferrerReward() return reward ? `Share Claude Code and earn ${claude(formatCreditAmount(reward))} of extra usage · ${claude('/passes')}` @@ -608,8 +608,8 @@ const externalTips: Tip[] = [ }, { id: 'overage-credit', - content: async ctx => { - const claude = color('claude', ctx.theme) + content: async (ctx?) => { + const claude = color('claude', ctx?.theme ?? 'dark') const info = getCachedOverageCreditGrant() const amount = info ? formatGrantAmount(info) : null if (!amount) return '' @@ -677,7 +677,9 @@ export async function getRelevantTips(context?: TipContext): Promise { // Otherwise, filter built-in tips as before and combine with custom const tips = [...externalTips, ...internalOnlyTips] - const isRelevant = await Promise.all(tips.map(_ => _.isRelevant(context))) + const isRelevant = await Promise.all( + tips.map(_ => _.isRelevant?.(context) ?? Promise.resolve(true)), + ) const filtered = tips .filter((_, index) => isRelevant[index]) .filter(_ => getSessionsSinceLastShown(_.id) >= _.cooldownSessions) diff --git a/src/services/tips/types.ts b/src/services/tips/types.ts index 35071c25f..ebb0fad38 100644 --- a/src/services/tips/types.ts +++ b/src/services/tips/types.ts @@ -1,3 +1,17 @@ -// Auto-generated stub — replace with real implementation -export type Tip = any; -export type TipContext = any; +import type { ThemeName } from '@anthropic/ink' +import type { FileStateCache } from '../../utils/fileStateCache.js' + +/** Spinner 提示评估时可用的会话上下文(字段可按调用场景部分提供)。 */ +export type TipContext = { + theme?: ThemeName // 当前终端主题名,用于 `color()` 等着色 + readFileState?: FileStateCache // 近期已读文件 LRU,用于文件类相关性判断 + bashTools?: Set // 本会话出现过的 bash 子命令集合 +} + +/** 内置或用户自定义的 Spinner 提示条目。 */ +export type Tip = { + id: string // 稳定 id:用于冷却与历史去重 + content: (ctx?: TipContext) => Promise // 异步生成 Spinner 旁提示文案 + cooldownSessions: number // 至少间隔多少会话后才可再次展示 + isRelevant?: (ctx?: TipContext) => Promise // 可选:当前是否应展示该条 +} diff --git a/src/tools/AgentTool/built-in/src/tools/NotebookEditTool/constants.ts b/src/tools/AgentTool/built-in/src/tools/NotebookEditTool/constants.ts index 6c6c94bad..a072c1c6a 100644 --- a/src/tools/AgentTool/built-in/src/tools/NotebookEditTool/constants.ts +++ b/src/tools/AgentTool/built-in/src/tools/NotebookEditTool/constants.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type NOTEBOOK_EDIT_TOOL_NAME = any; +/** SendMessage(向用户/通道发消息)工具在 API 中的注册名称字面量(与 `SEND_MESSAGE_TOOL_NAME` 常量一致)。 */ +export type SEND_MESSAGE_TOOL_NAME = 'SendMessage' diff --git a/src/tools/AgentTool/built-in/src/tools/SendMessageTool/constants.ts b/src/tools/AgentTool/built-in/src/tools/SendMessageTool/constants.ts index efd60265b..6635c4702 100644 --- a/src/tools/AgentTool/built-in/src/tools/SendMessageTool/constants.ts +++ b/src/tools/AgentTool/built-in/src/tools/SendMessageTool/constants.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type SEND_MESSAGE_TOOL_NAME = any; +/** NotebookEdit(笔记本单元格编辑)工具在 API 中的注册名称字面量(与 `NOTEBOOK_EDIT_TOOL_NAME` 常量一致)。 */ +export type NOTEBOOK_EDIT_TOOL_NAME = 'NotebookEdit' diff --git a/src/tools/AgentTool/built-in/src/utils/settings/settings.ts b/src/tools/AgentTool/built-in/src/utils/settings/settings.ts index 4b9b819d5..bf339b37c 100644 --- a/src/tools/AgentTool/built-in/src/utils/settings/settings.ts +++ b/src/tools/AgentTool/built-in/src/utils/settings/settings.ts @@ -1,2 +1,4 @@ -// Auto-generated type stub — replace with real implementation -export type getSettings_DEPRECATED = any; +import type { SettingsJson } from 'src/utils/settings/types.js' + +/** 返回各设置来源合并后的快照(已废弃函数名,行为同 `getInitialSettings`);与 `src/utils/settings/settings.ts` 一致。 */ +export type getSettings_DEPRECATED = () => SettingsJson // 无参数;至少得到可空字段填充后的合并设置对象 diff --git a/src/tools/AgentTool/src/components/ConfigurableShortcutHint.ts b/src/tools/AgentTool/src/components/ConfigurableShortcutHint.ts index d68e6f6e0..cc519a52b 100644 --- a/src/tools/AgentTool/src/components/ConfigurableShortcutHint.ts +++ b/src/tools/AgentTool/src/components/ConfigurableShortcutHint.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type ConfigurableShortcutHint = any; +/** 可配置快捷键提示组件(从 keybindings 解析展示文案);与宿主 `ConfigurableShortcutHint` 组件类型一致。 */ +export type ConfigurableShortcutHint = + typeof import('src/components/ConfigurableShortcutHint.js').ConfigurableShortcutHint diff --git a/src/tools/AgentTool/src/components/design-system/KeyboardShortcutHint.ts b/src/tools/AgentTool/src/components/design-system/KeyboardShortcutHint.ts index ab506bb31..3a4891538 100644 --- a/src/tools/AgentTool/src/components/design-system/KeyboardShortcutHint.ts +++ b/src/tools/AgentTool/src/components/design-system/KeyboardShortcutHint.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type KeyboardShortcutHint = any; +/** Ink 快捷键「按键 + 动作」展示组件;与 `@anthropic/ink` 导出的 `KeyboardShortcutHint` 一致。 */ +export type KeyboardShortcutHint = + typeof import('@anthropic/ink').KeyboardShortcutHint diff --git a/src/tools/AgentTool/src/utils/promptCategory.ts b/src/tools/AgentTool/src/utils/promptCategory.ts index 207db7233..921f96e88 100644 --- a/src/tools/AgentTool/src/utils/promptCategory.ts +++ b/src/tools/AgentTool/src/utils/promptCategory.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type getQuerySourceForAgent = any; +/** 按内置/自定义 Agent 类型解析用于遥测或分类的 `QuerySource`;与宿主 `getQuerySourceForAgent` 一致。 */ +export type getQuerySourceForAgent = + typeof import('src/utils/promptCategory.js').getQuerySourceForAgent diff --git a/src/tools/AskUserQuestionTool/src/components/MessageResponse.ts b/src/tools/AskUserQuestionTool/src/components/MessageResponse.ts index cc1c024e1..513cff447 100644 --- a/src/tools/AskUserQuestionTool/src/components/MessageResponse.ts +++ b/src/tools/AskUserQuestionTool/src/components/MessageResponse.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type MessageResponse = any; +/** 工具结果在消息流中的外层布局组件;与宿主 `src/components/MessageResponse.js` 中 `MessageResponse` 一致。 */ +export type MessageResponse = + typeof import('src/components/MessageResponse.js').MessageResponse diff --git a/src/tools/BashTool/src/Tool.ts b/src/tools/BashTool/src/Tool.ts index f9e7f2b14..1f92c73cb 100644 --- a/src/tools/BashTool/src/Tool.ts +++ b/src/tools/BashTool/src/Tool.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type ToolPermissionContext = any; +/** 工具权限检查用的不可变上下文快照;与宿主 `src/Tool.js` 中 `ToolPermissionContext` 一致。 */ +export type ToolPermissionContext = import('src/Tool.js').ToolPermissionContext diff --git a/src/tools/BashTool/src/bootstrap/state.ts b/src/tools/BashTool/src/bootstrap/state.ts index 132db390b..47871a257 100644 --- a/src/tools/BashTool/src/bootstrap/state.ts +++ b/src/tools/BashTool/src/bootstrap/state.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type getOriginalCwd = any; +/** 返回进程启动时的原始工作目录(不受中途切换工作区影响);与宿主 `getOriginalCwd` 一致。 */ +export type getOriginalCwd = + typeof import('src/bootstrap/state.js').getOriginalCwd diff --git a/src/tools/BashTool/src/utils/permissions/filesystem.ts b/src/tools/BashTool/src/utils/permissions/filesystem.ts index a29d05e83..396decf97 100644 --- a/src/tools/BashTool/src/utils/permissions/filesystem.ts +++ b/src/tools/BashTool/src/utils/permissions/filesystem.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type pathInAllowedWorkingPath = any; +/** 判断路径是否落在当前工具允许的合并工作目录内;与宿主 `pathInAllowedWorkingPath` 一致。 */ +export type pathInAllowedWorkingPath = + typeof import('src/utils/permissions/filesystem.js').pathInAllowedWorkingPath diff --git a/src/tools/BashTool/src/utils/sandbox/sandbox-ui-utils.ts b/src/tools/BashTool/src/utils/sandbox/sandbox-ui-utils.ts index f514e53a9..fc61ab5bb 100644 --- a/src/tools/BashTool/src/utils/sandbox/sandbox-ui-utils.ts +++ b/src/tools/BashTool/src/utils/sandbox/sandbox-ui-utils.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type removeSandboxViolationTags = any; +/** 从展示文本中剥离沙箱违规相关的标记标签,避免 UI 噪音;与宿主 `removeSandboxViolationTags` 一致。 */ +export type removeSandboxViolationTags = + typeof import('src/utils/sandbox/sandbox-ui-utils.js').removeSandboxViolationTags diff --git a/src/tools/NotebookEditTool/NotebookEditTool.ts b/src/tools/NotebookEditTool/NotebookEditTool.ts index 4551412fa..c98a87575 100644 --- a/src/tools/NotebookEditTool/NotebookEditTool.ts +++ b/src/tools/NotebookEditTool/NotebookEditTool.ts @@ -379,8 +379,8 @@ export const NotebookEditTool = buildTool({ const language = notebook.metadata.language_info?.name ?? 'python' let new_cell_id = undefined if ( - notebook.nbformat > 4 || - (notebook.nbformat === 4 && notebook.nbformat_minor >= 5) + (notebook.nbformat ?? 4) > 4 || + ((notebook.nbformat ?? 4) === 4 && (notebook.nbformat_minor ?? 0) >= 5) ) { if (edit_mode === 'insert') { new_cell_id = Math.random().toString(36).substring(2, 15) diff --git a/src/types/fileSuggestion.ts b/src/types/fileSuggestion.ts index c92a18b96..4c14c31c1 100644 --- a/src/types/fileSuggestion.ts +++ b/src/types/fileSuggestion.ts @@ -1,2 +1,13 @@ -// Auto-generated stub — replace with real implementation -export type FileSuggestionCommandInput = any; +/** + * `FileSuggestion` 自定义命令通过 stdin 接收的 JSON 负载, + * 字段与 `createBaseHookInput()` 一致并附加当前路径前缀 `query`。 + */ +export type FileSuggestionCommandInput = { + session_id: string // 当前会话 id + transcript_path: string // 会话 transcript 文件路径 + cwd: string // 工作目录 + permission_mode?: string // 权限模式快照(若有) + agent_id?: string // 子代理 id(若在 agent 内触发) + agent_type?: string // 子代理类型或主线程类型 + query: string // 用户当前输入的路径前缀(待补全部分) +} diff --git a/src/types/notebook.ts b/src/types/notebook.ts index 3ac9b2a02..87c14e2f9 100644 --- a/src/types/notebook.ts +++ b/src/types/notebook.ts @@ -1,8 +1,102 @@ -// Auto-generated stub — replace with real implementation -export type NotebookCell = any; -export type NotebookContent = any; -export type NotebookCellOutput = any; -export type NotebookCellSource = any; -export type NotebookCellSourceOutput = any; -export type NotebookOutputImage = any; -export type NotebookCellType = any; +/** Jupyter / nbformat 单元格类型。 */ +export type NotebookCellType = + | 'code' // 可执行代码格 + | 'markdown' // 文档格 + | 'raw' // 原始文本格 + +/** 原始 notebook 中的流式输出单元。 */ +export type NotebookStreamCellOutput = { + output_type: 'stream' // stdout/stderr 流 + text?: string | string[] // 流片段,可为多段拼接 +} + +/** execute_result / display_data 的 data 载荷(节选常用键)。 */ +export type NotebookDisplayData = Record & { + 'text/plain'?: string | string[] // 纯文本回退表示 +} + +/** 原始 notebook 中的执行结果或展示型输出。 */ +export type NotebookRichCellOutput = { + output_type: 'execute_result' | 'display_data' // 执行结果或富展示 + data?: NotebookDisplayData // MIME 桶(含图片/png 等) +} + +/** 原始 notebook 中的错误输出。 */ +export type NotebookErrorCellOutput = { + output_type: 'error' // 内核报错 + ename: string // 异常类型名 + evalue: string // 异常消息 + traceback: string[] // 栈跟踪行数组 +} + +/** 单元格原始输出联合(解析自 ipynb)。 */ +export type NotebookCellOutput = + | NotebookStreamCellOutput + | NotebookRichCellOutput + | NotebookErrorCellOutput + +/** 解析前的 notebook 单元格(nbformat 子集)。 */ +export type NotebookCell = { + id?: string // 单元格 id(nbformat≥4.5 常见) + cell_type: NotebookCellType // 单元类型 + source: string | string[] // 单元源码 + execution_count?: number | null // 代码格执行计数 + outputs?: NotebookCellOutput[] // 代码格输出列表 + metadata?: Record // 额外元数据(编辑工具会写入) +} + +/** Notebook 顶层 metadata 中与语言相关的子集。 */ +export type NotebookMetadata = { + language_info?: { + name?: string // 默认内核语言名(如 python) + } +} + +/** 磁盘上的 `.ipynb` 根结构(用于读入与增量编辑)。 */ +export type NotebookContent = { + nbformat?: number // 主版本号(缺省按 4 处理) + nbformat_minor?: number // 次版本号(影响 id 策略等) + cells: NotebookCell[] // 单元序列 + metadata: NotebookMetadata // 文档级元数据 +} + +/** 规范化后的内联图片载荷(送入模型 image block)。 */ +export type NotebookOutputImage = { + image_data: string // base64 无空白 + media_type: 'image/png' | 'image/jpeg' // MIME 子类型 +} + +/** 经 `processOutput` 规范化后的流式输出(供工具消息使用)。 */ +export type NotebookCellSourceStreamOutput = { + output_type: 'stream' + text: string // 已截断/拼接后的文本 +} + +/** 经 `processOutput` 规范化后的富输出。 */ +export type NotebookCellSourceRichOutput = { + output_type: 'execute_result' | 'display_data' + text?: string // 从 text/plain 提取的正文 + image?: NotebookOutputImage // 若有 image/png 或 jpeg +} + +/** 经 `processOutput` 规范化后的错误输出。 */ +export type NotebookCellSourceErrorOutput = { + output_type: 'error' + text: string // 合并 ename/evalue/traceback 后的单段文本 +} + +/** 送入工具链前的单元输出联合。 */ +export type NotebookCellSourceOutput = + | NotebookCellSourceStreamOutput + | NotebookCellSourceRichOutput + | NotebookCellSourceErrorOutput + +/** 送入模型工具结果的单元摘要结构。 */ +export type NotebookCellSource = { + cellType: NotebookCellType // 与源 cell 对齐的类型 + source: string // 拼接后的单元源码字符串 + execution_count?: number // 代码格保留执行计数 + cell_id: string // 稳定单元 id(无则生成 cell-{index}) + language?: string // 代码格语言 id(非 python 时标注) + outputs?: NotebookCellSourceOutput[] // 规范化后的输出列表 +} diff --git a/src/types/statusLine.ts b/src/types/statusLine.ts index 059480875..44a0e4be5 100644 --- a/src/types/statusLine.ts +++ b/src/types/statusLine.ts @@ -1,2 +1,67 @@ -// Auto-generated stub — replace with real implementation -export type StatusLineCommandInput = any; +/** + * 自定义状态行命令(`settings.statusLine.command`)通过 stdin 接收的 JSON。 + * 与 `buildStatusLineCommandInput` 输出形状一致。 + */ +export type StatusLineCommandInput = { + session_id: string // 会话 id + transcript_path: string // transcript 路径 + cwd: string // 当前工作目录 + permission_mode?: string // 工具权限模式快照 + agent_id?: string // 子代理 id(若有) + agent_type?: string // 子代理类型或主线程类型 + session_name?: string // 用户可见会话标题(若有) + model: { + id: string // 当前主循环模型 id + display_name: string // 已本地化的展示名 + } + workspace: { + current_dir: string // 进程 cwd + project_dir: string // 项目根(原始 cwd) + added_dirs: string[] // 附加工作区目录列表 + } + version: string // CLI 版本号(MACRO.VERSION) + output_style: { + name: string // 当前输出样式名 + } + cost: { + total_cost_usd: number // 累计美元成本估计 + total_duration_ms: number // 会话墙钟时长 + total_api_duration_ms: number // API 往返累计 + total_lines_added: number // 归因新增行数 + total_lines_removed: number // 归因删除行数 + } + context_window: { + total_input_tokens: number | null // 累计输入 token(未知为 null) + total_output_tokens: number | null // 累计输出 token + context_window_size: number // 当前模型上下文上限 + current_usage: { + input_tokens: number // 最近一条用量快照:输入 + output_tokens: number // 最近一条用量快照:输出 + cache_creation_input_tokens: number // 缓存写入 token + cache_read_input_tokens: number // 缓存命中读取 token + } | null // 尚无有效用量时为 null + used_percentage: number | null // 已用上下文占比 + remaining_percentage: number | null // 剩余占比 + } + exceeds_200k_tokens: boolean // 是否超过 200k 输入警戒 + rate_limits?: { + five_hour?: { used_percentage: number; resets_at: number } // 5 小时窗口用量与重置时间戳 + seven_day?: { used_percentage: number; resets_at: number } // 7 天窗口 + } + vim?: { + mode: string // 当前 Vim 模式标签(如 INSERT) + } + agent?: { + name: string // `--agent` 或子代理类型名 + } + remote?: { + session_id: string // 远程/桥接会话标识 + } + worktree?: { + name: string // worktree 展示名 + path: string // worktree 根路径 + branch?: string // 当前分支(可缺省) + original_cwd: string // 进入 worktree 前 cwd + original_branch?: string // 进入前分支(可缺省) + } +} diff --git a/src/utils/__tests__/notebook.test.ts b/src/utils/__tests__/notebook.test.ts index 5ced480ec..d1fa9683d 100644 --- a/src/utils/__tests__/notebook.test.ts +++ b/src/utils/__tests__/notebook.test.ts @@ -1,5 +1,6 @@ -import { describe, expect, test } from "bun:test"; -import { parseCellId, mapNotebookCellsToToolResult } from "../notebook"; +import { describe, expect, test } from 'bun:test' +import type { NotebookCellSource } from '../../types/notebook.js' +import { parseCellId, mapNotebookCellsToToolResult } from '../notebook' // ─── parseCellId ─────────────────────────────────────────────────────── @@ -59,10 +60,13 @@ describe("mapNotebookCellsToToolResult", () => { }, ]; - const result = mapNotebookCellsToToolResult(data, "tool-123"); - expect(result.tool_use_id).toBe("tool-123"); - expect(result.type).toBe("tool_result"); - }); + const result = mapNotebookCellsToToolResult( + data as NotebookCellSource[], + 'tool-123', + ) + expect(result.tool_use_id).toBe('tool-123') + expect(result.type).toBe('tool_result') + }) test("content array contains text blocks for cell content", () => { const data = [ @@ -74,9 +78,12 @@ describe("mapNotebookCellsToToolResult", () => { }, ]; - const result = mapNotebookCellsToToolResult(data, "tool-1"); - expect(result.content).toBeInstanceOf(Array); - expect(result.content!.length).toBeGreaterThanOrEqual(1); + const result = mapNotebookCellsToToolResult( + data as NotebookCellSource[], + 'tool-1', + ) + expect(result.content).toBeInstanceOf(Array) + expect(result.content!.length).toBeGreaterThanOrEqual(1) const firstBlock = result.content![0] as { type: string; text: string }; expect(firstBlock.type).toBe("text"); @@ -100,7 +107,10 @@ describe("mapNotebookCellsToToolResult", () => { }, ]; - const result = mapNotebookCellsToToolResult(data, "tool-2"); + const result = mapNotebookCellsToToolResult( + data as NotebookCellSource[], + 'tool-2', + ) // Two adjacent text blocks should be merged into one const textBlocks = result.content!.filter( (b: any) => b.type === "text" @@ -134,10 +144,13 @@ describe("mapNotebookCellsToToolResult", () => { }, ]; - const result = mapNotebookCellsToToolResult(data, "tool-3"); - const types = result.content!.map((b: any) => b.type); - expect(types).toContain("image"); - }); + const result = mapNotebookCellsToToolResult( + data as NotebookCellSource[], + 'tool-3', + ) + const types = (result.content as any[]).map((b: any) => b.type) + expect(types).toContain('image') + }) test("markdown cell includes cell_type metadata", () => { const data = [ @@ -148,10 +161,13 @@ describe("mapNotebookCellsToToolResult", () => { }, ]; - const result = mapNotebookCellsToToolResult(data, "tool-4"); - const textBlock = result.content![0] as { type: string; text: string }; - expect(textBlock.text).toContain("markdown"); - }); + const result = mapNotebookCellsToToolResult( + data as NotebookCellSource[], + 'tool-4', + ) + const textBlock = result.content![0] as { type: string; text: string } + expect(textBlock.text).toContain('markdown') + }) test("non-python code cell includes language metadata", () => { const data = [ @@ -163,8 +179,11 @@ describe("mapNotebookCellsToToolResult", () => { }, ]; - const result = mapNotebookCellsToToolResult(data, "tool-5"); - const textBlock = result.content![0] as { type: string; text: string }; - expect(textBlock.text).toContain("scala"); - }); -}); + const result = mapNotebookCellsToToolResult( + data as NotebookCellSource[], + 'tool-5', + ) + const textBlock = result.content![0] as { type: string; text: string } + expect(textBlock.text).toContain('scala') + }) +}) diff --git a/src/utils/hooks.ts b/src/utils/hooks.ts index e380583a3..4446633d8 100644 --- a/src/utils/hooks.ts +++ b/src/utils/hooks.ts @@ -358,22 +358,22 @@ export interface HookResult { } export type AggregatedHookResult = { - message?: HookResultMessage - blockingError?: HookBlockingError - preventContinuation?: boolean - stopReason?: string - hookPermissionDecisionReason?: string - hookSource?: string - permissionBehavior?: PermissionResult['behavior'] - additionalContexts?: string[] - initialUserMessage?: string - updatedInput?: Record - updatedMCPToolOutput?: unknown - permissionRequestResult?: PermissionRequestResult - watchPaths?: string[] - elicitationResponse?: ElicitationResponse - elicitationResultResponse?: ElicitationResponse - retry?: boolean + message?: HookResultMessage // 插入会话的钩子消息(含系统/附件类),供 UI 与后续轮次展示 + blockingError?: HookBlockingError // 致命阻塞:附带命令与错误文案,调用方应中止当前工具/流程 + preventContinuation?: boolean // 为 true 时请求不再继续后续对话轮次(与 stopReason 配套) + stopReason?: string // 停止继续时的可读原因,用于日志、遥测或向用户解释为何结束 + hookPermissionDecisionReason?: string // 钩子对权限决策的补充说明,常与 permissionBehavior 一同产出 + hookSource?: string // 产生本次权限/改参结果的定义来源(如 settings 与 policy 合并后的条目来源) + permissionBehavior?: PermissionResult['behavior'] // 多钩并行时按 deny > ask > allow 聚合后的权限行为 + additionalContexts?: string[] // 注入模型上下文的补充片段(如 UserPromptSubmit),可与多条钩子结果合并 + initialUserMessage?: string // 会话启动等场景预置的首条用户侧文案,供首轮上下文使用 + updatedInput?: Record // 钩子改写后的工具入参;可在 allow/ask 时与权限一起产出,也可单独改参 + updatedMCPToolOutput?: unknown // PostToolUse 钩子对 MCP 工具原始输出的替换内容 + permissionRequestResult?: PermissionRequestResult // PermissionRequest 事件钩子的 allow/deny 及可选改参 + watchPaths?: string[] // SessionStart 等声明的监视路径,供文件变更相关逻辑使用 + elicitationResponse?: ElicitationResponse // Elicitation 钩子的交互/采集结果(MCP elicit 流程) + elicitationResultResponse?: ElicitationResponse // ElicitationResult 钩子对上一轮引导的后续响应数据 + retry?: boolean // PermissionDenied 等场景是否建议用户重试当前操作 } /** diff --git a/src/utils/model/src/services/analytics/growthbook.ts b/src/utils/model/src/services/analytics/growthbook.ts index e380906ea..88ccc5f7f 100644 --- a/src/utils/model/src/services/analytics/growthbook.ts +++ b/src/utils/model/src/services/analytics/growthbook.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type getFeatureValue_CACHED_MAY_BE_STALE = any; +/** 从磁盘缓存读取 GrowthBook/门控配置(可能略旧);与宿主 `getFeatureValue_CACHED_MAY_BE_STALE` 一致。 */ +export type getFeatureValue_CACHED_MAY_BE_STALE = + typeof import('src/services/analytics/growthbook.js').getFeatureValue_CACHED_MAY_BE_STALE diff --git a/src/utils/notebook.ts b/src/utils/notebook.ts index 3630b0980..699e647e1 100644 --- a/src/utils/notebook.ts +++ b/src/utils/notebook.ts @@ -25,7 +25,8 @@ function isLargeOutputs( let size = 0 for (const o of outputs) { if (!o) continue - size += (o.text?.length ?? 0) + (o.image?.image_data.length ?? 0) + const imageLen = 'image' in o && o.image ? o.image.image_data.length : 0 + size += (o.text?.length ?? 0) + imageLen if (size > LARGE_OUTPUT_THRESHOLD) return true } return false @@ -139,7 +140,7 @@ function cellOutputToToolResult(output: NotebookCellSourceOutput) { type: 'text', }) } - if (output.image) { + if ('image' in output && output.image) { outputs.push({ type: 'image', source: { diff --git a/src/utils/plugins/mcpbHandler.ts b/src/utils/plugins/mcpbHandler.ts index ff344e60e..143cca2e3 100644 --- a/src/utils/plugins/mcpbHandler.ts +++ b/src/utils/plugins/mcpbHandler.ts @@ -1,7 +1,4 @@ -import type { - McpbManifestAny as McpbManifest, -} from '@anthropic-ai/mcpb' -type McpbUserConfigurationOption = any +import type { McpbManifestAny as McpbManifest } from '@anthropic-ai/mcpb' import axios from 'axios' import { createHash } from 'crypto' import { chmod, writeFile } from 'fs/promises' @@ -21,6 +18,19 @@ import { import { jsonParse, jsonStringify } from '../slowOperations.js' import { getSystemDirectories } from '../systemDirectories.js' import { classifyFetchError, logPluginFetch } from './fetchTelemetry.js' + +/** DXT / MCPB `user_config` 中单字段的 JSON Schema 式描述(校验见 `validateUserConfig`)。 */ +export type McpbUserConfigurationOption = { + type: 'string' | 'number' | 'boolean' | 'file' | 'directory' // 控件/校验类型 + required?: boolean // 是否必填 + title?: string // 表单标签(缺省用 key) + description?: string // 帮助说明 + sensitive?: boolean // true 时写入安全存储而非明文 settings + multiple?: boolean // string 类型时是否允许多值(数组) + min?: number // 数值下限 + max?: number // 数值上限 +} + /** * User configuration values for MCPB */ diff --git a/src/utils/sandbox/src/tools/FileReadTool/prompt.ts b/src/utils/sandbox/src/tools/FileReadTool/prompt.ts index fac6439fc..0d71da435 100644 --- a/src/utils/sandbox/src/tools/FileReadTool/prompt.ts +++ b/src/utils/sandbox/src/tools/FileReadTool/prompt.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type FILE_READ_TOOL_NAME = any; +/** Write(文件写入)工具在 API 中的注册名称字面量(与 `FILE_WRITE_TOOL_NAME` 常量 `'Write'` 一致)。 */ +export type FILE_WRITE_TOOL_NAME = 'Write' diff --git a/src/utils/settings/src/Tool.ts b/src/utils/settings/src/Tool.ts index ed896638d..8f1bbb06c 100644 --- a/src/utils/settings/src/Tool.ts +++ b/src/utils/settings/src/Tool.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type ValidationResult = any; +/** 是否正在使用第三方(非 Anthropic 直连)API 或服务;与仓库根 `src/utils/auth.ts` 中 `isUsing3PServices` 签名一致。 */ +export type isUsing3PServices = () => boolean // 返回 true 表示当前配置走兼容层或第三方模型端点 diff --git a/src/utils/settings/src/services/mcp/types.ts b/src/utils/settings/src/services/mcp/types.ts index f604edd2e..d93beeb8d 100644 --- a/src/utils/settings/src/services/mcp/types.ts +++ b/src/utils/settings/src/services/mcp/types.ts @@ -1,2 +1,3 @@ -// Auto-generated type stub — replace with real implementation -export type ConfigScope = any; +/** 列表/状态行中使用的实心圆点字符(平台相关);与宿主 `src/constants/figures.js` 中 `BLACK_CIRCLE` 常量类型一致。 */ +export type BLACK_CIRCLE = + typeof import('src/constants/figures.js').BLACK_CIRCLE diff --git a/src/utils/src/tools/LSPTool/prompt.ts b/src/utils/src/tools/LSPTool/prompt.ts index 9be378e3c..fd8d07c20 100644 --- a/src/utils/src/tools/LSPTool/prompt.ts +++ b/src/utils/src/tools/LSPTool/prompt.ts @@ -1,2 +1,2 @@ -// Auto-generated type stub — replace with real implementation -export type LSP_TOOL_NAME = any; +/** Glob(文件名模式匹配)工具在 API 中的注册名称字面量(与 `GLOB_TOOL_NAME` 常量 `'Glob'` 一致)。 */ +export type GLOB_TOOL_NAME = 'Glob'