|
@@ -10,10 +10,10 @@ import { cwd } from 'process'
|
|
|
import type { HookEvent, ModelUsage } from 'src/entrypoints/agentSdkTypes.js'
|
|
import type { HookEvent, ModelUsage } from 'src/entrypoints/agentSdkTypes.js'
|
|
|
import type { AgentColorName } from 'src/tools/AgentTool/agentColorManager.js'
|
|
import type { AgentColorName } from 'src/tools/AgentTool/agentColorManager.js'
|
|
|
import type { HookCallbackMatcher } from 'src/types/hooks.js'
|
|
import type { HookCallbackMatcher } from 'src/types/hooks.js'
|
|
|
-// Indirection for browser-sdk build (package.json "browser" field swaps
|
|
|
|
|
-// crypto.ts for crypto.browser.ts). Pure leaf re-export of node:crypto —
|
|
|
|
|
-// zero circular-dep risk. Path-alias import bypasses bootstrap-isolation
|
|
|
|
|
-// (rule only checks ./ and / prefixes); explicit disable documents intent.
|
|
|
|
|
|
|
+// 用于浏览器端构建的间接引用(package.json 的 "browser" 字段会将
|
|
|
|
|
+// crypto.ts 替换为 crypto.browser.ts)。纯叶子节点重新导出 node:crypto —
|
|
|
|
|
+// 零循环依赖风险。路径别名导入绕过了启动隔离(
|
|
|
|
|
+// 规则仅检查 ./ 和 / 前缀);显式禁用说明了意图。
|
|
|
// eslint-disable-next-line custom-rules/bootstrap-isolation
|
|
// eslint-disable-next-line custom-rules/bootstrap-isolation
|
|
|
import { randomUUID } from 'src/utils/crypto.js'
|
|
import { randomUUID } from 'src/utils/crypto.js'
|
|
|
import type { ModelSetting } from 'src/utils/model/model.js'
|
|
import type { ModelSetting } from 'src/utils/model/model.js'
|
|
@@ -23,17 +23,16 @@ import { resetSettingsCache } from 'src/utils/settings/settingsCache.js'
|
|
|
import type { PluginHookMatcher } from 'src/utils/settings/types.js'
|
|
import type { PluginHookMatcher } from 'src/utils/settings/types.js'
|
|
|
import { createSignal } from 'src/utils/signal.js'
|
|
import { createSignal } from 'src/utils/signal.js'
|
|
|
|
|
|
|
|
-// Union type for registered hooks - can be SDK callbacks or native plugin hooks
|
|
|
|
|
|
|
+// 注册钩子的联合类型——可以是 SDK 回调或原生插件钩子
|
|
|
type RegisteredHookMatcher = HookCallbackMatcher | PluginHookMatcher
|
|
type RegisteredHookMatcher = HookCallbackMatcher | PluginHookMatcher
|
|
|
|
|
|
|
|
import type { SessionId } from 'src/types/ids.js'
|
|
import type { SessionId } from 'src/types/ids.js'
|
|
|
|
|
|
|
|
-// DO NOT ADD MORE STATE HERE - BE JUDICIOUS WITH GLOBAL STATE
|
|
|
|
|
|
|
+// 不要再加状态了——请谨慎对待全局状态
|
|
|
|
|
|
|
|
-// dev: true on entries that came via --dangerously-load-development-channels.
|
|
|
|
|
-// The allowlist gate checks this per-entry (not the session-wide
|
|
|
|
|
-// hasDevChannels bit) so passing both flags doesn't let the dev dialog's
|
|
|
|
|
-// acceptance leak allowlist-bypass to the --channels entries.
|
|
|
|
|
|
|
+// dev: 对于通过 --dangerously-load-development-channels 传入的条目为 true。
|
|
|
|
|
+// 白名单门控逐条目检查此项(而非会话范围的 hasDevChannels 标志),
|
|
|
|
|
+// 因此同时传入两个标志不会让开发对话框的接受行为泄漏白名单绕过权限到 --channels 条目。
|
|
|
export type ChannelEntry =
|
|
export type ChannelEntry =
|
|
|
| { kind: 'plugin'; name: string; marketplace: string; dev?: boolean }
|
|
| { kind: 'plugin'; name: string; marketplace: string; dev?: boolean }
|
|
|
| { kind: 'server'; name: string; dev?: boolean }
|
|
| { kind: 'server'; name: string; dev?: boolean }
|
|
@@ -44,9 +43,9 @@ export type AttributedCounter = {
|
|
|
|
|
|
|
|
type State = {
|
|
type State = {
|
|
|
originalCwd: string
|
|
originalCwd: string
|
|
|
- // Stable project root - set once at startup (including by --worktree flag),
|
|
|
|
|
- // never updated by mid-session EnterWorktreeTool.
|
|
|
|
|
- // Use for project identity (history, skills, sessions) not file operations.
|
|
|
|
|
|
|
+ // 稳定的项目根目录 - 启动时设置一次(包括 --worktree 标志),
|
|
|
|
|
+ // 会话中途的 EnterWorktreeTool 永远不会更新它。
|
|
|
|
|
+ // 用于项目标识(历史记录、技能、会话),不用于文件操作。
|
|
|
projectRoot: string
|
|
projectRoot: string
|
|
|
totalCostUSD: number
|
|
totalCostUSD: number
|
|
|
totalAPIDuration: number
|
|
totalAPIDuration: number
|
|
@@ -70,10 +69,9 @@ type State = {
|
|
|
modelStrings: ModelStrings | null
|
|
modelStrings: ModelStrings | null
|
|
|
isInteractive: boolean
|
|
isInteractive: boolean
|
|
|
kairosActive: boolean
|
|
kairosActive: boolean
|
|
|
- // When true, ensureToolResultPairing throws on mismatch instead of
|
|
|
|
|
- // repairing with synthetic placeholders. HFI opts in at startup so
|
|
|
|
|
- // trajectories fail fast rather than conditioning the model on fake
|
|
|
|
|
- // tool_results.
|
|
|
|
|
|
|
+ // 当为 true 时,ensureToolResultPairing 在不匹配时抛出异常,
|
|
|
|
|
+ // 而不是用合成占位符修复。HFI 在启动时选择加入,因此
|
|
|
|
|
+ // 轨迹会快速失败,而不是用假的 tool_result 训练模型。
|
|
|
strictToolResultPairing: boolean
|
|
strictToolResultPairing: boolean
|
|
|
sdkAgentProgressSummariesEnabled: boolean
|
|
sdkAgentProgressSummariesEnabled: boolean
|
|
|
userMsgOptIn: boolean
|
|
userMsgOptIn: boolean
|
|
@@ -98,7 +96,7 @@ type State = {
|
|
|
activeTimeCounter: AttributedCounter | null
|
|
activeTimeCounter: AttributedCounter | null
|
|
|
statsStore: { observe(name: string, value: number): void } | null
|
|
statsStore: { observe(name: string, value: number): void } | null
|
|
|
sessionId: SessionId
|
|
sessionId: SessionId
|
|
|
- // Parent session ID for tracking session lineage (e.g., plan mode -> implementation)
|
|
|
|
|
|
|
+ // 父会话 ID,用于跟踪会话谱系(例如,规划模式 -> 实现)
|
|
|
parentSessionId: SessionId | undefined
|
|
parentSessionId: SessionId | undefined
|
|
|
// Logger state
|
|
// Logger state
|
|
|
loggerProvider: LoggerProvider | null
|
|
loggerProvider: LoggerProvider | null
|
|
@@ -112,69 +110,68 @@ type State = {
|
|
|
agentColorIndex: number
|
|
agentColorIndex: number
|
|
|
// Last API request for bug reports
|
|
// Last API request for bug reports
|
|
|
lastAPIRequest: Omit<BetaMessageStreamParams, 'messages'> | null
|
|
lastAPIRequest: Omit<BetaMessageStreamParams, 'messages'> | null
|
|
|
- // Messages from the last API request (ant-only; reference, not clone).
|
|
|
|
|
- // Captures the exact post-compaction, CLAUDE.md-injected message set sent
|
|
|
|
|
- // to the API so /share's serialized_conversation.json reflects reality.
|
|
|
|
|
|
|
+ // 上次 API 请求的消息(ant 专用;引用,非克隆)。
|
|
|
|
|
+ // 捕获发送给 API 的压缩后、CLAUDE.md 注入的确切消息集,
|
|
|
|
|
+ // 以便 /share 的 serialized_conversation.json 反映实际情况。
|
|
|
lastAPIRequestMessages: BetaMessageStreamParams['messages'] | null
|
|
lastAPIRequestMessages: BetaMessageStreamParams['messages'] | null
|
|
|
// Last auto-mode classifier request(s) for /share transcript
|
|
// Last auto-mode classifier request(s) for /share transcript
|
|
|
lastClassifierRequests: unknown[] | null
|
|
lastClassifierRequests: unknown[] | null
|
|
|
- // CLAUDE.md content cached by context.ts for the auto-mode classifier.
|
|
|
|
|
- // Breaks the yoloClassifier → claudemd → filesystem → permissions cycle.
|
|
|
|
|
|
|
+ // CLAUDE.md 内容缓存,供自动模式分类器使用。
|
|
|
|
|
+ // 打破 yoloClassifier → claudemd → 文件系统 → 权限的循环。
|
|
|
cachedClaudeMdContent: string | null
|
|
cachedClaudeMdContent: string | null
|
|
|
// In-memory error log for recent errors
|
|
// In-memory error log for recent errors
|
|
|
inMemoryErrorLog: Array<{ error: string; timestamp: string }>
|
|
inMemoryErrorLog: Array<{ error: string; timestamp: string }>
|
|
|
- // Session-only plugins from --plugin-dir flag
|
|
|
|
|
|
|
+ // 来自 --plugin-dir 标志的仅会话插件
|
|
|
inlinePlugins: Array<string>
|
|
inlinePlugins: Array<string>
|
|
|
- // Explicit --chrome / --no-chrome flag value (undefined = not set on CLI)
|
|
|
|
|
|
|
+ // 显式 --chrome / --no-chrome 标志值(undefined = 未在 CLI 设置)
|
|
|
chromeFlagOverride: boolean | undefined
|
|
chromeFlagOverride: boolean | undefined
|
|
|
- // Use cowork_plugins directory instead of plugins (--cowork flag or env var)
|
|
|
|
|
|
|
+ // 使用 cowork_plugins 目录代替 plugins(--cowork 标志或环境变量)
|
|
|
useCoworkPlugins: boolean
|
|
useCoworkPlugins: boolean
|
|
|
- // Session-only bypass permissions mode flag (not persisted)
|
|
|
|
|
|
|
+ // 仅会话的绕过权限模式标志(不持久化)
|
|
|
sessionBypassPermissionsMode: boolean
|
|
sessionBypassPermissionsMode: boolean
|
|
|
- // Session-only flag gating the .claude/scheduled_tasks.json watcher
|
|
|
|
|
- // (useScheduledTasks). Set by cronScheduler.start() when the JSON has
|
|
|
|
|
- // entries, or by CronCreateTool. Not persisted.
|
|
|
|
|
|
|
+ // 仅会话的标志,用于控制 .claude/scheduled_tasks.json 监视器
|
|
|
|
|
+ // (useScheduledTasks)。当 JSON 有条目时由 cronScheduler.start() 设置,
|
|
|
|
|
+ // 或由 CronCreateTool 设置。不持久化。
|
|
|
scheduledTasksEnabled: boolean
|
|
scheduledTasksEnabled: boolean
|
|
|
- // Session-only cron tasks created via CronCreate with durable: false.
|
|
|
|
|
- // Fire on schedule like file-backed tasks but are never written to
|
|
|
|
|
- // .claude/scheduled_tasks.json — they die with the process. Typed via
|
|
|
|
|
- // SessionCronTask below (not importing from cronTasks.ts keeps
|
|
|
|
|
- // bootstrap a leaf of the import DAG).
|
|
|
|
|
|
|
+ // 通过 CronCreate 以 durable: false 创建的仅会话定时任务。
|
|
|
|
|
+ // 按调度触发,类似文件支持的任务,但永远不会写入
|
|
|
|
|
+ // .claude/scheduled_tasks.json —— 它们随进程终止而消失。类型通过
|
|
|
|
|
+ // 下面的 SessionCronTask 定义(不从 cronTasks.ts 导入以保持
|
|
|
|
|
+ // bootstrap 为导入 DAG 的叶子节点)。
|
|
|
sessionCronTasks: SessionCronTask[]
|
|
sessionCronTasks: SessionCronTask[]
|
|
|
- // Teams created this session via TeamCreate. cleanupSessionTeams()
|
|
|
|
|
- // removes these on gracefulShutdown so subagent-created teams don't
|
|
|
|
|
- // persist on disk forever (gh-32730). TeamDelete removes entries to
|
|
|
|
|
- // avoid double-cleanup. Lives here (not teamHelpers.ts) so
|
|
|
|
|
- // resetStateForTests() clears it between tests.
|
|
|
|
|
|
|
+ // 本会话通过 TeamCreate 创建的团队。cleanupSessionTeams()
|
|
|
|
|
+ // 在优雅关闭时移除它们,以避免子代理创建的团队永远残留在磁盘上
|
|
|
|
|
+ // (gh-32730)。TeamDelete 移除条目以避免重复清理。
|
|
|
|
|
+ // 放在这里(而非 teamHelpers.ts)以便 resetStateForTests() 在测试间清除。
|
|
|
sessionCreatedTeams: Set<string>
|
|
sessionCreatedTeams: Set<string>
|
|
|
- // Session-only trust flag for home directory (not persisted to disk)
|
|
|
|
|
- // When running from home dir, trust dialog is shown but not saved to disk.
|
|
|
|
|
- // This flag allows features requiring trust to work during the session.
|
|
|
|
|
|
|
+ // 仅会话的家庭目录信任标志(不持久化到磁盘)
|
|
|
|
|
+ // 从家庭目录运行时,显示信任对话框但不保存到磁盘。
|
|
|
|
|
+ // 此标志允许需要信任的功能在会话期间正常工作。
|
|
|
sessionTrustAccepted: boolean
|
|
sessionTrustAccepted: boolean
|
|
|
- // Session-only flag to disable session persistence to disk
|
|
|
|
|
|
|
+ // 仅会话的标志,禁用会话持久化到磁盘
|
|
|
sessionPersistenceDisabled: boolean
|
|
sessionPersistenceDisabled: boolean
|
|
|
- // Track if user has exited plan mode in this session (for re-entry guidance)
|
|
|
|
|
|
|
+ // 跟踪用户是否在此会话中退出了规划模式(用于重新进入引导)
|
|
|
hasExitedPlanMode: boolean
|
|
hasExitedPlanMode: boolean
|
|
|
- // Track if we need to show the plan mode exit attachment (one-time notification)
|
|
|
|
|
|
|
+ // 跟踪是否需要显示规划模式退出附件(一次性通知)
|
|
|
needsPlanModeExitAttachment: boolean
|
|
needsPlanModeExitAttachment: boolean
|
|
|
- // Track if we need to show the auto mode exit attachment (one-time notification)
|
|
|
|
|
|
|
+ // 跟踪是否需要显示自动模式退出附件(一次性通知)
|
|
|
needsAutoModeExitAttachment: boolean
|
|
needsAutoModeExitAttachment: boolean
|
|
|
- // Track if LSP plugin recommendation has been shown this session (only show once)
|
|
|
|
|
|
|
+ // 跟踪 LSP 插件推荐是否已在本会话中显示(仅显示一次)
|
|
|
lspRecommendationShownThisSession: boolean
|
|
lspRecommendationShownThisSession: boolean
|
|
|
- // SDK init event state - jsonSchema for structured output
|
|
|
|
|
|
|
+ // SDK 初始化事件状态 - 结构化输出的 jsonSchema
|
|
|
initJsonSchema: Record<string, unknown> | null
|
|
initJsonSchema: Record<string, unknown> | null
|
|
|
- // Registered hooks - SDK callbacks and plugin native hooks
|
|
|
|
|
|
|
+ // 已注册的钩子 - SDK 回调和插件原生钩子
|
|
|
registeredHooks: Partial<Record<HookEvent, RegisteredHookMatcher[]>> | null
|
|
registeredHooks: Partial<Record<HookEvent, RegisteredHookMatcher[]>> | null
|
|
|
- // Cache for plan slugs: sessionId -> wordSlug
|
|
|
|
|
|
|
+ // 规划 slug 缓存:sessionId -> wordSlug
|
|
|
planSlugCache: Map<string, string>
|
|
planSlugCache: Map<string, string>
|
|
|
- // Track teleported session for reliability logging
|
|
|
|
|
|
|
+ // 跟踪远程连接会话以进行可靠性日志记录
|
|
|
teleportedSessionInfo: {
|
|
teleportedSessionInfo: {
|
|
|
isTeleported: boolean
|
|
isTeleported: boolean
|
|
|
hasLoggedFirstMessage: boolean
|
|
hasLoggedFirstMessage: boolean
|
|
|
sessionId: string | null
|
|
sessionId: string | null
|
|
|
} | null
|
|
} | null
|
|
|
- // Track invoked skills for preservation across compaction
|
|
|
|
|
- // Keys are composite: `${agentId ?? ''}:${skillName}` to prevent cross-agent overwrites
|
|
|
|
|
|
|
+ // 跟踪调用的技能,以便在压缩时保留
|
|
|
|
|
+ // 键是组合的:`${agentId ?? ''}:${skillName}` 以防止跨代理覆盖
|
|
|
invokedSkills: Map<
|
|
invokedSkills: Map<
|
|
|
string,
|
|
string,
|
|
|
{
|
|
{
|
|
@@ -185,81 +182,74 @@ type State = {
|
|
|
agentId: string | null
|
|
agentId: string | null
|
|
|
}
|
|
}
|
|
|
>
|
|
>
|
|
|
- // Track slow operations for dev bar display (ant-only)
|
|
|
|
|
|
|
+ // 跟踪慢速操作以在开发栏显示(仅 ant)
|
|
|
slowOperations: Array<{
|
|
slowOperations: Array<{
|
|
|
operation: string
|
|
operation: string
|
|
|
durationMs: number
|
|
durationMs: number
|
|
|
timestamp: number
|
|
timestamp: number
|
|
|
}>
|
|
}>
|
|
|
- // SDK-provided betas (e.g., context-1m-2025-08-07)
|
|
|
|
|
|
|
+ // SDK 提供的 beta 功能(例如,context-1m-2025-08-07)
|
|
|
sdkBetas: string[] | undefined
|
|
sdkBetas: string[] | undefined
|
|
|
- // Main thread agent type (from --agent flag or settings)
|
|
|
|
|
|
|
+ // 主线程代理类型(来自 --agent 标志或设置)
|
|
|
mainThreadAgentType: string | undefined
|
|
mainThreadAgentType: string | undefined
|
|
|
- // Remote mode (--remote flag)
|
|
|
|
|
|
|
+ // 远程模式(--remote 标志)
|
|
|
isRemoteMode: boolean
|
|
isRemoteMode: boolean
|
|
|
- // Direct connect server URL (for display in header)
|
|
|
|
|
|
|
+ // 直连服务器 URL(用于在头部显示)
|
|
|
directConnectServerUrl: string | undefined
|
|
directConnectServerUrl: string | undefined
|
|
|
- // System prompt section cache state
|
|
|
|
|
|
|
+ // 系统提示片段缓存状态
|
|
|
systemPromptSectionCache: Map<string, string | null>
|
|
systemPromptSectionCache: Map<string, string | null>
|
|
|
- // Last date emitted to the model (for detecting midnight date changes)
|
|
|
|
|
|
|
+ // 上次向模型发送的日期(用于检测午夜日期变化)
|
|
|
lastEmittedDate: string | null
|
|
lastEmittedDate: string | null
|
|
|
- // Additional directories from --add-dir flag (for CLAUDE.md loading)
|
|
|
|
|
|
|
+ // 来自 --add-dir 标志的额外目录(用于 CLAUDE.md 加载)
|
|
|
additionalDirectoriesForClaudeMd: string[]
|
|
additionalDirectoriesForClaudeMd: string[]
|
|
|
- // Channel server allowlist from --channels flag (servers whose channel
|
|
|
|
|
- // notifications should register this session). Parsed once in main.tsx —
|
|
|
|
|
- // the tag decides trust model: 'plugin' → marketplace verification +
|
|
|
|
|
- // allowlist, 'server' → allowlist always fails (schema is plugin-only).
|
|
|
|
|
- // Either kind needs entry.dev to bypass allowlist.
|
|
|
|
|
|
|
+ // 来自 --channels 标志的通道服务器白名单(其通道通知应注册到本会话的服务器)
|
|
|
|
|
+ // 在 main.tsx 中解析一次——标签决定信任模型:'plugin' → 市场验证 +
|
|
|
|
|
+ // 白名单,'server' → 白名单始终失败(schema 仅限插件)。
|
|
|
|
|
+ // 两种类型都需要 entry.dev 来绕过白名单。
|
|
|
allowedChannels: ChannelEntry[]
|
|
allowedChannels: ChannelEntry[]
|
|
|
- // True if any entry in allowedChannels came from
|
|
|
|
|
- // --dangerously-load-development-channels (so ChannelsNotice can name the
|
|
|
|
|
- // right flag in policy-blocked messages)
|
|
|
|
|
|
|
+ // 如果 allowedChannels 中任何条目来自
|
|
|
|
|
+ // --dangerously-load-development-channels(以便 ChannelsNotice 可在被策略拦截的消息中
|
|
|
|
|
+ // 指出正确的标志名称)
|
|
|
hasDevChannels: boolean
|
|
hasDevChannels: boolean
|
|
|
- // Dir containing the session's `.jsonl`; null = derive from originalCwd.
|
|
|
|
|
|
|
+ // 包含会话 `.jsonl` 的目录;null = 从 originalCwd 推导。
|
|
|
sessionProjectDir: string | null
|
|
sessionProjectDir: string | null
|
|
|
- // Cached prompt cache 1h TTL allowlist from GrowthBook (session-stable)
|
|
|
|
|
|
|
+ // GrowthBook 缓存的 prompt cache 1h TTL 白名单(会话稳定)
|
|
|
promptCache1hAllowlist: string[] | null
|
|
promptCache1hAllowlist: string[] | null
|
|
|
- // Cached 1h TTL user eligibility (session-stable). Latched on first
|
|
|
|
|
- // evaluation so mid-session overage flips don't change the cache_control
|
|
|
|
|
- // TTL, which would bust the server-side prompt cache.
|
|
|
|
|
|
|
+ // 缓存的 1h TTL 用户资格(会话稳定)。首次评估时锁定,使会话中的超额翻转
|
|
|
|
|
+ // 不会改变 cache_control TTL,否则会破坏服务器端 prompt 缓存。
|
|
|
promptCache1hEligible: boolean | null
|
|
promptCache1hEligible: boolean | null
|
|
|
- // Sticky-on latch for AFK_MODE_BETA_HEADER. Once auto mode is first
|
|
|
|
|
- // activated, keep sending the header for the rest of the session so
|
|
|
|
|
- // Shift+Tab toggles don't bust the ~50-70K token prompt cache.
|
|
|
|
|
|
|
+ // AFK_MODE_BETA_HEADER 的粘性开启锁存。首次激活自动模式后,
|
|
|
|
|
+ // 会话剩余时间持续发送此标头,使 Shift+Tab 切换不会破坏 ~50-70K 令牌的 prompt 缓存。
|
|
|
afkModeHeaderLatched: boolean | null
|
|
afkModeHeaderLatched: boolean | null
|
|
|
- // Sticky-on latch for FAST_MODE_BETA_HEADER. Once fast mode is first
|
|
|
|
|
- // enabled, keep sending the header so cooldown enter/exit doesn't
|
|
|
|
|
- // double-bust the prompt cache. The `speed` body param stays dynamic.
|
|
|
|
|
|
|
+ // FAST_MODE_BETA_HEADER 的粘性开启锁存。首次启用快速模式后,
|
|
|
|
|
+ // 保持发送标头,避免冷启动进出双重破坏 prompt 缓存。`speed` body 参数保持动态。
|
|
|
fastModeHeaderLatched: boolean | null
|
|
fastModeHeaderLatched: boolean | null
|
|
|
- // Sticky-on latch for the cache-editing beta header. Once cached
|
|
|
|
|
- // microcompact is first enabled, keep sending the header so mid-session
|
|
|
|
|
- // GrowthBook/settings toggles don't bust the prompt cache.
|
|
|
|
|
|
|
+ // 缓存编辑 beta 标头的粘性开启锁存。首次启用缓存微压缩后,
|
|
|
|
|
+ // 保持发送标头,避免会话中的 GrowthBook/设置切换破坏 prompt 缓存。
|
|
|
cacheEditingHeaderLatched: boolean | null
|
|
cacheEditingHeaderLatched: boolean | null
|
|
|
- // Sticky-on latch for clearing thinking from prior tool loops. Triggered
|
|
|
|
|
- // when >1h since last API call (confirmed cache miss — no cache-hit
|
|
|
|
|
- // benefit to keeping thinking). Once latched, stays on so the newly-warmed
|
|
|
|
|
- // thinking-cleared cache isn't busted by flipping back to keep:'all'.
|
|
|
|
|
- thinkingClearLatched: boolean | null
|
|
|
|
|
- // Current prompt ID (UUID) correlating a user prompt with subsequent OTel events
|
|
|
|
|
|
|
+ // 清除之前工具循环思考的粘性开启锁存。当距上次 API 调用超过 1h 时触发
|
|
|
|
|
+ // (确认缓存未命中——保留思考无缓存命中好处)。锁定后保持开启,
|
|
|
|
|
+ // 使新预热的清除思考缓存不会因切回 keep:'all' 而被破坏。
|
|
|
|
|
+ // 当前提示 ID (UUID),将用户提示与后续 OTel 事件关联
|
|
|
promptId: string | null
|
|
promptId: string | null
|
|
|
- // Last API requestId for the main conversation chain (not subagents).
|
|
|
|
|
- // Updated after each successful API response for main-session queries.
|
|
|
|
|
- // Read at shutdown to send cache eviction hints to inference.
|
|
|
|
|
|
|
+ // 主对话链的最后 API requestId(不含子代理)。
|
|
|
|
|
+ // 在每次主会话查询的 API 响应成功后更新。
|
|
|
|
|
+ // 在关闭时读取,以向推理端发送缓存驱逐提示。
|
|
|
lastMainRequestId: string | undefined
|
|
lastMainRequestId: string | undefined
|
|
|
- // Timestamp (Date.now()) of the last successful API call completion.
|
|
|
|
|
- // Used to compute timeSinceLastApiCallMs in tengu_api_success for
|
|
|
|
|
- // correlating cache misses with idle time (cache TTL is ~5min).
|
|
|
|
|
|
|
+ // 上次成功 API 调用完成的时间戳(Date.now())。
|
|
|
|
|
+ // 用于在 tengu_api_success 中计算 timeSinceLastApiCallMs,
|
|
|
|
|
+ // 以将缓存未命中与空闲时间关联(缓存 TTL 约 5 分钟)。
|
|
|
lastApiCompletionTimestamp: number | null
|
|
lastApiCompletionTimestamp: number | null
|
|
|
- // Set to true after compaction (auto or manual /compact). Consumed by
|
|
|
|
|
- // logAPISuccess to tag the first post-compaction API call so we can
|
|
|
|
|
- // distinguish compaction-induced cache misses from TTL expiry.
|
|
|
|
|
|
|
+ // 压缩(自动或手动 /compact)后设置为 true。由
|
|
|
|
|
+ // logAPISuccess 消费,以标记压缩后的第一次 API 调用,使我们能
|
|
|
|
|
+ // 区分压缩导致的缓存未命中与 TTL 过期。
|
|
|
pendingPostCompaction: boolean
|
|
pendingPostCompaction: boolean
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// ALSO HERE - THINK THRICE BEFORE MODIFYING
|
|
|
|
|
|
|
+// 这里是——修改前三思
|
|
|
function getInitialState(): State {
|
|
function getInitialState(): State {
|
|
|
- // Resolve symlinks in cwd to match behavior of shell.ts setCwd
|
|
|
|
|
- // This ensures consistency with how paths are sanitized for session storage
|
|
|
|
|
|
|
+ // 解析 cwd 中的符号链接,以匹配 shell.ts 的 setCwd 行为
|
|
|
|
|
+ // 这确保路径清理的一致性,以便会话存储
|
|
|
let resolvedCwd = ''
|
|
let resolvedCwd = ''
|
|
|
if (
|
|
if (
|
|
|
typeof process !== 'undefined' &&
|
|
typeof process !== 'undefined' &&
|
|
@@ -270,7 +260,7 @@ function getInitialState(): State {
|
|
|
try {
|
|
try {
|
|
|
resolvedCwd = realpathSync(rawCwd).normalize('NFC')
|
|
resolvedCwd = realpathSync(rawCwd).normalize('NFC')
|
|
|
} catch {
|
|
} catch {
|
|
|
- // File Provider EPERM on CloudStorage mounts (lstat per path component).
|
|
|
|
|
|
|
+ // CloudStorage 挂载时文件提供程序 EPERM(逐路径组件 lstat)。
|
|
|
resolvedCwd = rawCwd.normalize('NFC')
|
|
resolvedCwd = rawCwd.normalize('NFC')
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -317,7 +307,7 @@ function getInitialState(): State {
|
|
|
'flagSettings',
|
|
'flagSettings',
|
|
|
'policySettings',
|
|
'policySettings',
|
|
|
],
|
|
],
|
|
|
- // Telemetry state
|
|
|
|
|
|
|
+ // 遥测状态
|
|
|
meter: null,
|
|
meter: null,
|
|
|
sessionCounter: null,
|
|
sessionCounter: null,
|
|
|
locCounter: null,
|
|
locCounter: null,
|
|
@@ -330,92 +320,92 @@ function getInitialState(): State {
|
|
|
statsStore: null,
|
|
statsStore: null,
|
|
|
sessionId: randomUUID() as SessionId,
|
|
sessionId: randomUUID() as SessionId,
|
|
|
parentSessionId: undefined,
|
|
parentSessionId: undefined,
|
|
|
- // Logger state
|
|
|
|
|
|
|
+ // 日志记录器状态
|
|
|
loggerProvider: null,
|
|
loggerProvider: null,
|
|
|
eventLogger: null,
|
|
eventLogger: null,
|
|
|
- // Meter provider state
|
|
|
|
|
|
|
+ // Meter 提供者状态
|
|
|
meterProvider: null,
|
|
meterProvider: null,
|
|
|
tracerProvider: null,
|
|
tracerProvider: null,
|
|
|
- // Agent color state
|
|
|
|
|
|
|
+ // 代理颜色状态
|
|
|
agentColorMap: new Map(),
|
|
agentColorMap: new Map(),
|
|
|
agentColorIndex: 0,
|
|
agentColorIndex: 0,
|
|
|
- // Last API request for bug reports
|
|
|
|
|
|
|
+ // 用于 bug 报告的上次 API 请求
|
|
|
lastAPIRequest: null,
|
|
lastAPIRequest: null,
|
|
|
lastAPIRequestMessages: null,
|
|
lastAPIRequestMessages: null,
|
|
|
- // Last auto-mode classifier request(s) for /share transcript
|
|
|
|
|
|
|
+ // 用于 /share 转录的上次自动模式分类器请求
|
|
|
lastClassifierRequests: null,
|
|
lastClassifierRequests: null,
|
|
|
cachedClaudeMdContent: null,
|
|
cachedClaudeMdContent: null,
|
|
|
- // In-memory error log for recent errors
|
|
|
|
|
|
|
+ // 最近错误的内存日志
|
|
|
inMemoryErrorLog: [],
|
|
inMemoryErrorLog: [],
|
|
|
- // Session-only plugins from --plugin-dir flag
|
|
|
|
|
|
|
+ // 来自 --plugin-dir 标志的仅会话插件
|
|
|
inlinePlugins: [],
|
|
inlinePlugins: [],
|
|
|
- // Explicit --chrome / --no-chrome flag value (undefined = not set on CLI)
|
|
|
|
|
|
|
+ // 显式 --chrome / --no-chrome 标志值(undefined = 未在 CLI 设置)
|
|
|
chromeFlagOverride: undefined,
|
|
chromeFlagOverride: undefined,
|
|
|
- // Use cowork_plugins directory instead of plugins
|
|
|
|
|
|
|
+ // 使用 cowork_plugins 目录代替 plugins
|
|
|
useCoworkPlugins: false,
|
|
useCoworkPlugins: false,
|
|
|
- // Session-only bypass permissions mode flag (not persisted)
|
|
|
|
|
|
|
+ // 仅会话的绕过权限模式标志(不持久化)
|
|
|
sessionBypassPermissionsMode: false,
|
|
sessionBypassPermissionsMode: false,
|
|
|
- // Scheduled tasks disabled until flag or dialog enables them
|
|
|
|
|
|
|
+ // 定时任务默认禁用,直到标志或对话框启用
|
|
|
scheduledTasksEnabled: false,
|
|
scheduledTasksEnabled: false,
|
|
|
sessionCronTasks: [],
|
|
sessionCronTasks: [],
|
|
|
sessionCreatedTeams: new Set(),
|
|
sessionCreatedTeams: new Set(),
|
|
|
- // Session-only trust flag (not persisted to disk)
|
|
|
|
|
|
|
+ // 仅会话的信任标志(不持久化到磁盘)
|
|
|
sessionTrustAccepted: false,
|
|
sessionTrustAccepted: false,
|
|
|
- // Session-only flag to disable session persistence to disk
|
|
|
|
|
|
|
+ // 仅会话的标志,禁用会话持久化到磁盘
|
|
|
sessionPersistenceDisabled: false,
|
|
sessionPersistenceDisabled: false,
|
|
|
- // Track if user has exited plan mode in this session
|
|
|
|
|
|
|
+ // 跟踪用户是否在此会话中退出了规划模式
|
|
|
hasExitedPlanMode: false,
|
|
hasExitedPlanMode: false,
|
|
|
- // Track if we need to show the plan mode exit attachment
|
|
|
|
|
|
|
+ // 跟踪是否需要显示规划模式退出附件
|
|
|
needsPlanModeExitAttachment: false,
|
|
needsPlanModeExitAttachment: false,
|
|
|
- // Track if we need to show the auto mode exit attachment
|
|
|
|
|
|
|
+ // 跟踪是否需要显示自动模式退出附件
|
|
|
needsAutoModeExitAttachment: false,
|
|
needsAutoModeExitAttachment: false,
|
|
|
- // Track if LSP plugin recommendation has been shown this session
|
|
|
|
|
|
|
+ // 跟踪 LSP 插件推荐是否已在本会话中显示
|
|
|
lspRecommendationShownThisSession: false,
|
|
lspRecommendationShownThisSession: false,
|
|
|
- // SDK init event state
|
|
|
|
|
|
|
+ // SDK 初始化事件状态
|
|
|
initJsonSchema: null,
|
|
initJsonSchema: null,
|
|
|
registeredHooks: null,
|
|
registeredHooks: null,
|
|
|
- // Cache for plan slugs
|
|
|
|
|
|
|
+ // 规划 slug 缓存
|
|
|
planSlugCache: new Map(),
|
|
planSlugCache: new Map(),
|
|
|
- // Track teleported session for reliability logging
|
|
|
|
|
|
|
+ // 跟踪远程连接会话以进行可靠性日志记录
|
|
|
teleportedSessionInfo: null,
|
|
teleportedSessionInfo: null,
|
|
|
- // Track invoked skills for preservation across compaction
|
|
|
|
|
|
|
+ // 跟踪调用的技能以在压缩时保留
|
|
|
invokedSkills: new Map(),
|
|
invokedSkills: new Map(),
|
|
|
- // Track slow operations for dev bar display
|
|
|
|
|
|
|
+ // 跟踪开发栏显示的慢速操作
|
|
|
slowOperations: [],
|
|
slowOperations: [],
|
|
|
- // SDK-provided betas
|
|
|
|
|
|
|
+ // SDK 提供的 beta 功能
|
|
|
sdkBetas: undefined,
|
|
sdkBetas: undefined,
|
|
|
- // Main thread agent type
|
|
|
|
|
|
|
+ // 主线程代理类型
|
|
|
mainThreadAgentType: undefined,
|
|
mainThreadAgentType: undefined,
|
|
|
- // Remote mode
|
|
|
|
|
|
|
+ // 远程模式
|
|
|
isRemoteMode: false,
|
|
isRemoteMode: false,
|
|
|
...(process.env.USER_TYPE === 'ant'
|
|
...(process.env.USER_TYPE === 'ant'
|
|
|
? {
|
|
? {
|
|
|
replBridgeActive: false,
|
|
replBridgeActive: false,
|
|
|
}
|
|
}
|
|
|
: {}),
|
|
: {}),
|
|
|
- // Direct connect server URL
|
|
|
|
|
|
|
+ // 直连服务器 URL
|
|
|
directConnectServerUrl: undefined,
|
|
directConnectServerUrl: undefined,
|
|
|
- // System prompt section cache state
|
|
|
|
|
|
|
+ // 系统提示片段缓存状态
|
|
|
systemPromptSectionCache: new Map(),
|
|
systemPromptSectionCache: new Map(),
|
|
|
- // Last date emitted to the model
|
|
|
|
|
|
|
+ // 上次向模型发送的日期
|
|
|
lastEmittedDate: null,
|
|
lastEmittedDate: null,
|
|
|
- // Additional directories from --add-dir flag (for CLAUDE.md loading)
|
|
|
|
|
|
|
+ // 来自 --add-dir 标志的额外目录(用于 CLAUDE.md 加载)
|
|
|
additionalDirectoriesForClaudeMd: [],
|
|
additionalDirectoriesForClaudeMd: [],
|
|
|
- // Channel server allowlist from --channels flag
|
|
|
|
|
|
|
+ // 来自 --channels 标志的通道服务器白名单
|
|
|
allowedChannels: [],
|
|
allowedChannels: [],
|
|
|
hasDevChannels: false,
|
|
hasDevChannels: false,
|
|
|
- // Session project dir (null = derive from originalCwd)
|
|
|
|
|
|
|
+ // 会话项目目录(null = 从 originalCwd 推导)
|
|
|
sessionProjectDir: null,
|
|
sessionProjectDir: null,
|
|
|
- // Prompt cache 1h allowlist (null = not yet fetched from GrowthBook)
|
|
|
|
|
|
|
+ // Prompt cache 1h 白名单(null = 尚未从 GrowthBook 获取)
|
|
|
promptCache1hAllowlist: null,
|
|
promptCache1hAllowlist: null,
|
|
|
- // Prompt cache 1h eligibility (null = not yet evaluated)
|
|
|
|
|
|
|
+ // Prompt cache 1h 资格(null = 尚未评估)
|
|
|
promptCache1hEligible: null,
|
|
promptCache1hEligible: null,
|
|
|
- // Beta header latches (null = not yet triggered)
|
|
|
|
|
|
|
+ // Beta 标头锁存(null = 尚未触发)
|
|
|
afkModeHeaderLatched: null,
|
|
afkModeHeaderLatched: null,
|
|
|
fastModeHeaderLatched: null,
|
|
fastModeHeaderLatched: null,
|
|
|
cacheEditingHeaderLatched: null,
|
|
cacheEditingHeaderLatched: null,
|
|
|
thinkingClearLatched: null,
|
|
thinkingClearLatched: null,
|
|
|
- // Current prompt ID
|
|
|
|
|
|
|
+ // 当前提示 ID
|
|
|
promptId: null,
|
|
promptId: null,
|
|
|
lastMainRequestId: undefined,
|
|
lastMainRequestId: undefined,
|
|
|
lastApiCompletionTimestamp: null,
|
|
lastApiCompletionTimestamp: null,
|
|
@@ -425,7 +415,7 @@ function getInitialState(): State {
|
|
|
return state
|
|
return state
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// AND ESPECIALLY HERE
|
|
|
|
|
|
|
+// 特别是这里
|
|
|
const STATE: State = getInitialState()
|
|
const STATE: State = getInitialState()
|
|
|
|
|
|
|
|
export function getSessionId(): SessionId {
|
|
export function getSessionId(): SessionId {
|