mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
@@ -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<void> // 建立或重连传输
|
||||
write(message: StdoutMessage): void | Promise<void> // 向上游发送一条控制/流式消息
|
||||
close(): void // 主动关闭并释放资源
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* - 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'
|
||||
|
||||
@@ -107,7 +108,10 @@ export function getAuthStatus(): AuthStatus {
|
||||
|
||||
let plan: AuthStatus['subscription']['plan'] = null
|
||||
if (subscriptionActive && oauthTokens) {
|
||||
const raw = oauthTokens.subscriptionType
|
||||
// 本地持久化或历史 token 中可能出现 'free' 等未纳入 SubscriptionType 的字符串
|
||||
const raw = oauthTokens.subscriptionType as
|
||||
| (SubscriptionType | 'free')
|
||||
| null
|
||||
if (
|
||||
raw === 'free' ||
|
||||
raw === 'pro' ||
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
isPluginEnabledAtProjectScope,
|
||||
uninstallPluginOp,
|
||||
updatePluginOp,
|
||||
type InstallableScope,
|
||||
} from '../../services/plugins/pluginOperations.js';
|
||||
import { useAppState } from '../../state/AppState.js';
|
||||
import type { Tool } from '../../Tool.js';
|
||||
@@ -76,7 +77,7 @@ 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 type { UnifiedInstalledItem, UnifiedInstalledScope } from './unifiedTypes.js';
|
||||
import { usePagination } from './usePagination.js';
|
||||
|
||||
type Props = {
|
||||
@@ -103,7 +104,7 @@ type FailedPluginInfo = {
|
||||
name: string;
|
||||
marketplace: string;
|
||||
errors: PluginError[];
|
||||
scope: PersistablePluginScope;
|
||||
scope: UnifiedInstalledScope;
|
||||
};
|
||||
|
||||
type ViewState =
|
||||
@@ -1253,7 +1254,7 @@ export function ManagePlugins({
|
||||
const isEnabled = mergedSettings?.enabledPlugins?.[pluginId] !== false;
|
||||
const pluginScope = item.scope;
|
||||
const isBuiltin = pluginScope === 'builtin';
|
||||
if (isBuiltin || isInstallableScope(pluginScope)) {
|
||||
if (isBuiltin || isInstallableScope(pluginScope as PersistablePluginScope)) {
|
||||
const newPending = new Map(pendingToggles);
|
||||
// Omit scope — see handleSingleOperation's enable/disable comment.
|
||||
if (currentPending) {
|
||||
@@ -1579,8 +1580,8 @@ 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)
|
||||
const result = isInstallableScope(pluginScope as PersistablePluginScope)
|
||||
? await uninstallPluginOp(pluginId, pluginScope as InstallableScope, false)
|
||||
: await uninstallPluginOp(pluginId, 'user', false);
|
||||
let success = result.success;
|
||||
if (!success) {
|
||||
|
||||
@@ -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 相关提示
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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/流程内触发
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ function buildStatusLineCommandInput(
|
||||
const sessionId = getSessionId();
|
||||
const sessionName = getCurrentSessionTitle(sessionId);
|
||||
const rawUtil = getRawUtilization();
|
||||
const rateLimits: StatusLineCommandInput['rate_limits'] = {
|
||||
const rateLimits: NonNullable<StatusLineCommandInput['rate_limits']> = {
|
||||
...(rawUtil.five_hour && {
|
||||
five_hour: {
|
||||
used_percentage: rawUtil.five_hour.utilization * 100,
|
||||
|
||||
@@ -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 // 确认保存前的完整代理定义草稿
|
||||
}
|
||||
|
||||
@@ -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 菜单
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
// Auto-generated stub — replace with real implementation
|
||||
export type Option = any
|
||||
/** CustomSelect / 权限规则列表等处的简单选项。 */
|
||||
export type Option = {
|
||||
label: string // 展示给用户的文本
|
||||
value: string // 选中后回传的内部值(如规则 key、占位符)
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ import { createContext, type ReactNode, useCallback, useEffect, useMemo, useStat
|
||||
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<WizardContextValue<any> | null>(null);
|
||||
export const WizardContext = createContext<WizardContextValue<Record<string, unknown>> | null>(null);
|
||||
|
||||
export function WizardProvider<T extends Record<string, unknown>>({
|
||||
steps,
|
||||
@@ -18,7 +16,7 @@ export function WizardProvider<T extends Record<string, unknown>>({
|
||||
initialData?: T;
|
||||
onComplete: (data: T) => void;
|
||||
onCancel: () => void;
|
||||
children: ReactNode;
|
||||
children?: ReactNode;
|
||||
title: string;
|
||||
showStepCounter?: boolean;
|
||||
}): ReactNode {
|
||||
@@ -123,5 +121,9 @@ export function WizardProvider<T extends Record<string, unknown>>({
|
||||
return null;
|
||||
}
|
||||
|
||||
return <WizardContext.Provider value={contextValue}>{children || <CurrentStepComponent />}</WizardContext.Provider>;
|
||||
return (
|
||||
<WizardContext.Provider value={contextValue as unknown as WizardContextValue<Record<string, unknown>>}>
|
||||
{children || <CurrentStepComponent />}
|
||||
</WizardContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
// Auto-generated stub — replace with real implementation
|
||||
export type WizardContextValue<T = any> = 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<T extends Record<string, unknown>> = {
|
||||
currentStepIndex: number // 当前步骤下标
|
||||
totalSteps: number // 步骤总数
|
||||
wizardData: T // 各步写入的聚合数据
|
||||
setWizardData: Dispatch<SetStateAction<T>> // 整体替换向导数据
|
||||
updateWizardData: (updates: Partial<T>) => void // 局部合并更新
|
||||
goNext: () => void // 下一步;末步则标记完成
|
||||
goBack: () => void // 上一步或退出
|
||||
goToStep: (index: number) => void // 非线性跳步(写入历史栈)
|
||||
cancel: () => void // 放弃并清空历史
|
||||
title: string // 与 Provider 同步的标题
|
||||
showStepCounter: boolean // 是否展示步数计数
|
||||
}
|
||||
|
||||
@@ -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 字段对齐的自由文本标签
|
||||
|
||||
@@ -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<RemoteControlHandle | null> {
|
||||
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` 逐项对应
|
||||
|
||||
@@ -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<string, unknown>
|
||||
|
||||
// Hook input types
|
||||
export type HookInput = { hook_event_name: string; [key: string]: unknown }
|
||||
export type HookJSONOutput = Record<string, unknown>
|
||||
export type AsyncHookJSONOutput = Record<string, unknown>
|
||||
export type SyncHookJSONOutput = Record<string, unknown>
|
||||
// 钩子输入类型
|
||||
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<string, unknown>
|
||||
})
|
||||
| (HookInputBase & {
|
||||
hook_event_name: 'ElicitationResult'
|
||||
mcp_server_name: string
|
||||
elicitation_id?: string
|
||||
mode?: 'form' | 'url'
|
||||
action: 'accept' | 'decline' | 'cancel'
|
||||
content?: Record<string, unknown>
|
||||
})
|
||||
| (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<string, unknown>
|
||||
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<string, unknown>
|
||||
/**
|
||||
* 注意:钩子使用的 JSON schema 为 PermissionUpdateSchema(),
|
||||
* 它是一个比传统 `{path, permission}` 结构更丰富的联合类型。
|
||||
*/
|
||||
updatedPermissions?: unknown[]
|
||||
}
|
||||
| { behavior: 'deny'; message?: string; interrupt?: boolean }
|
||||
}
|
||||
| {
|
||||
hookEventName: 'Elicitation'
|
||||
action?: 'accept' | 'decline' | 'cancel'
|
||||
content?: Record<string, unknown>
|
||||
}
|
||||
| {
|
||||
hookEventName: 'ElicitationResult'
|
||||
action?: 'accept' | 'decline' | 'cancel'
|
||||
content?: Record<string, unknown>
|
||||
}
|
||||
| { 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 }
|
||||
|
||||
@@ -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<ReturnType<typeof LspServerConfigSchema>>
|
||||
|
||||
/**
|
||||
* 插件动态注册时附带的作用域与来源插件名。
|
||||
* 与全局 user/project 配置区分,避免多插件同名冲突。
|
||||
*/
|
||||
export type ScopedLspServerConfig = LspServerConfig & {
|
||||
scope: 'dynamic' // 运行时由插件挂载的作用域标记
|
||||
source: string // 来源插件名(用于 `plugin:name:server` 前缀等)
|
||||
}
|
||||
|
||||
/** LSP 子进程生命周期状态(由 `LSPServerInstance` 维护)。 */
|
||||
export type LspServerState =
|
||||
| 'stopped' // 未启动或已完全退出
|
||||
| 'starting' // 正在拉起进程/握手
|
||||
| 'running' // 已初始化并可服务请求
|
||||
| 'stopping' // 正在优雅关闭
|
||||
| 'error' // 启动失败或运行期崩溃后的错误态
|
||||
|
||||
@@ -440,8 +440,8 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'desktop-shortcut',
|
||||
content: async (ctx: TipContext) => {
|
||||
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,
|
||||
@@ -486,24 +486,24 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'frontend-design-plugin',
|
||||
content: async (ctx: TipContext) => {
|
||||
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: TipContext) =>
|
||||
isRelevant: async (context?) =>
|
||||
isMarketplacePluginRelevant('frontend-design', context, {
|
||||
filePath: /\.(html|css|htm)$/i,
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: 'vercel-plugin',
|
||||
content: async (ctx: TipContext) => {
|
||||
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: TipContext) =>
|
||||
isRelevant: async (context?) =>
|
||||
isMarketplacePluginRelevant('vercel', context, {
|
||||
filePath: /(?:^|[/\\])vercel\.json$/i,
|
||||
cli: ['vercel'],
|
||||
@@ -511,8 +511,8 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'effort-high-nudge',
|
||||
content: async (ctx: TipContext) => {
|
||||
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'
|
||||
@@ -541,8 +541,8 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'subagent-fanout-nudge',
|
||||
content: async (ctx: TipContext) => {
|
||||
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')
|
||||
@@ -563,8 +563,8 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'loop-command-nudge',
|
||||
content: async (ctx: TipContext) => {
|
||||
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')
|
||||
@@ -586,8 +586,8 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'guest-passes',
|
||||
content: async (ctx: TipContext) => {
|
||||
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')}`
|
||||
@@ -605,8 +605,8 @@ const externalTips: Tip[] = [
|
||||
},
|
||||
{
|
||||
id: 'overage-credit',
|
||||
content: async (ctx: TipContext) => {
|
||||
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 ''
|
||||
@@ -674,7 +674,9 @@ export async function getRelevantTips(context?: TipContext): Promise<Tip[]> {
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -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<string> // 本会话出现过的 bash 子命令集合
|
||||
}
|
||||
|
||||
/** 内置或用户自定义的 Spinner 提示条目。 */
|
||||
export type Tip = {
|
||||
id: string // 稳定 id:用于冷却与历史去重
|
||||
content: (ctx?: TipContext) => Promise<string> // 异步生成 Spinner 旁提示文案
|
||||
cooldownSessions: number // 至少间隔多少会话后才可再次展示
|
||||
isRelevant?: (ctx?: TipContext) => Promise<boolean> // 可选:当前是否应展示该条
|
||||
}
|
||||
|
||||
@@ -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 // 用户当前输入的路径前缀(待补全部分)
|
||||
}
|
||||
|
||||
@@ -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<string, unknown> & {
|
||||
'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<string, unknown> // 额外元数据(编辑工具会写入)
|
||||
}
|
||||
|
||||
/** 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[] // 规范化后的输出列表
|
||||
}
|
||||
|
||||
@@ -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 // 进入前分支(可缺省)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import type { NotebookCellSource } from '../../types/notebook.js'
|
||||
import { parseCellId, mapNotebookCellsToToolResult } from '../notebook'
|
||||
|
||||
// ─── parseCellId ───────────────────────────────────────────────────────
|
||||
@@ -59,7 +60,10 @@ describe('mapNotebookCellsToToolResult', () => {
|
||||
},
|
||||
]
|
||||
|
||||
const result = mapNotebookCellsToToolResult(data, 'tool-123')
|
||||
const result = mapNotebookCellsToToolResult(
|
||||
data as NotebookCellSource[],
|
||||
'tool-123',
|
||||
)
|
||||
expect(result.tool_use_id).toBe('tool-123')
|
||||
expect(result.type).toBe('tool_result')
|
||||
})
|
||||
@@ -74,7 +78,10 @@ describe('mapNotebookCellsToToolResult', () => {
|
||||
},
|
||||
]
|
||||
|
||||
const result = mapNotebookCellsToToolResult(data, 'tool-1')
|
||||
const result = mapNotebookCellsToToolResult(
|
||||
data as NotebookCellSource[],
|
||||
'tool-1',
|
||||
)
|
||||
expect(result.content).toBeInstanceOf(Array)
|
||||
expect(result.content!.length).toBeGreaterThanOrEqual(1)
|
||||
|
||||
@@ -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 as any[]).filter(
|
||||
(b: any) => b.type === 'text',
|
||||
@@ -134,7 +144,10 @@ describe('mapNotebookCellsToToolResult', () => {
|
||||
},
|
||||
]
|
||||
|
||||
const result = mapNotebookCellsToToolResult(data, 'tool-3')
|
||||
const result = mapNotebookCellsToToolResult(
|
||||
data as NotebookCellSource[],
|
||||
'tool-3',
|
||||
)
|
||||
const types = (result.content as any[]).map((b: any) => b.type)
|
||||
expect(types).toContain('image')
|
||||
})
|
||||
@@ -148,7 +161,10 @@ describe('mapNotebookCellsToToolResult', () => {
|
||||
},
|
||||
]
|
||||
|
||||
const result = mapNotebookCellsToToolResult(data, 'tool-4')
|
||||
const result = mapNotebookCellsToToolResult(
|
||||
data as NotebookCellSource[],
|
||||
'tool-4',
|
||||
)
|
||||
const textBlock = result.content![0] as { type: string; text: string }
|
||||
expect(textBlock.text).toContain('<cell_type>markdown</cell_type>')
|
||||
})
|
||||
@@ -163,7 +179,10 @@ describe('mapNotebookCellsToToolResult', () => {
|
||||
},
|
||||
]
|
||||
|
||||
const result = mapNotebookCellsToToolResult(data, 'tool-5')
|
||||
const result = mapNotebookCellsToToolResult(
|
||||
data as NotebookCellSource[],
|
||||
'tool-5',
|
||||
)
|
||||
const textBlock = result.content![0] as { type: string; text: string }
|
||||
expect(textBlock.text).toContain('<language>scala</language>')
|
||||
})
|
||||
|
||||
@@ -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<string, unknown>
|
||||
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<string, unknown> // 钩子改写后的工具入参;可在 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 等场景是否建议用户重试当前操作
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { McpbManifestAny as McpbManifest } from '@anthropic-ai/mcpb'
|
||||
type McpbUserConfigurationOption = any
|
||||
import axios from 'axios'
|
||||
import { createHash } from 'crypto'
|
||||
import { chmod, writeFile } from 'fs/promises'
|
||||
@@ -19,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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user