feat: 完成一大波类型修复, 虽然 any 很多
This commit is contained in:
parent
dd9cd782a7
commit
91f77ea571
65
README.md
65
README.md
@ -328,6 +328,71 @@ claude-code/
|
|||||||
|
|
||||||
项目采用 Bun workspaces 管理内部包。原先手工放在 `node_modules/` 下的 stub 已统一迁入 `packages/`,通过 `workspace:*` 解析。
|
项目采用 Bun workspaces 管理内部包。原先手工放在 `node_modules/` 下的 stub 已统一迁入 `packages/`,通过 `workspace:*` 解析。
|
||||||
|
|
||||||
|
## Feature Flags 详解
|
||||||
|
|
||||||
|
原版 Claude Code 通过 `bun:bundle` 的 `feature()` 在构建时注入 feature flag,由 GrowthBook 等 A/B 实验平台控制灰度发布。本项目中 `feature()` 被 polyfill 为始终返回 `false`,因此以下 30 个 flag 全部关闭。
|
||||||
|
|
||||||
|
### 自主 Agent
|
||||||
|
|
||||||
|
| Flag | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `KAIROS` | Assistant 模式 — 长期运行的自主 Agent(含 brief、push 通知、文件发送) |
|
||||||
|
| `KAIROS_BRIEF` | Kairos Brief — 向用户发送简报摘要 |
|
||||||
|
| `KAIROS_CHANNELS` | Kairos 频道 — 多频道通信 |
|
||||||
|
| `KAIROS_GITHUB_WEBHOOKS` | GitHub Webhook 订阅 — PR 事件实时推送给 Agent |
|
||||||
|
| `PROACTIVE` | 主动模式 — Agent 主动执行任务,含 SleepTool 定时唤醒 |
|
||||||
|
| `COORDINATOR_MODE` | 协调器模式 — 多 Agent 编排调度 |
|
||||||
|
| `BUDDY` | Buddy 配对编程功能 |
|
||||||
|
| `FORK_SUBAGENT` | Fork 子代理 — 从当前会话分叉出独立子代理 |
|
||||||
|
|
||||||
|
### 远程 / 分布式
|
||||||
|
|
||||||
|
| Flag | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `BRIDGE_MODE` | 远程控制桥接 — 允许外部客户端远程操控 Claude Code |
|
||||||
|
| `DAEMON` | 守护进程 — 后台常驻服务,支持 worker 和 supervisor |
|
||||||
|
| `BG_SESSIONS` | 后台会话 — `ps`/`logs`/`attach`/`kill`/`--bg` 等后台进程管理 |
|
||||||
|
| `SSH_REMOTE` | SSH 远程 — `claude ssh <host>` 连接远程主机 |
|
||||||
|
| `DIRECT_CONNECT` | 直连模式 — `cc://` URL 协议、server 命令、`open` 命令 |
|
||||||
|
| `CCR_REMOTE_SETUP` | 网页端远程配置 — 通过浏览器配置 Claude Code |
|
||||||
|
| `CCR_MIRROR` | Claude Code Runtime 镜像 — 会话状态同步/复制 |
|
||||||
|
|
||||||
|
### 通信
|
||||||
|
|
||||||
|
| Flag | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `UDS_INBOX` | Unix Domain Socket 收件箱 — Agent 间本地通信(`/peers`) |
|
||||||
|
|
||||||
|
### 增强工具
|
||||||
|
|
||||||
|
| Flag | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `CHICAGO_MCP` | Computer Use MCP — 计算机操作(屏幕截图、鼠标键盘控制) |
|
||||||
|
| `WEB_BROWSER_TOOL` | 网页浏览器工具 — 在终端内嵌浏览器交互 |
|
||||||
|
| `VOICE_MODE` | 语音模式 — 语音输入输出,麦克风 push-to-talk |
|
||||||
|
| `WORKFLOW_SCRIPTS` | 工作流脚本 — 用户自定义自动化工作流 |
|
||||||
|
| `MCP_SKILLS` | 基于 MCP 的 Skill 加载机制 |
|
||||||
|
|
||||||
|
### 对话管理
|
||||||
|
|
||||||
|
| Flag | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `HISTORY_SNIP` | 历史裁剪 — 手动裁剪对话历史中的片段(`/force-snip`) |
|
||||||
|
| `ULTRAPLAN` | 超级计划 — 远程 Agent 协作的大规模规划功能 |
|
||||||
|
| `AGENT_MEMORY_SNAPSHOT` | Agent 运行时的记忆快照功能 |
|
||||||
|
|
||||||
|
### 基础设施 / 实验
|
||||||
|
|
||||||
|
| Flag | 用途 |
|
||||||
|
|------|------|
|
||||||
|
| `ABLATION_BASELINE` | 科学实验 — 基线消融测试,用于 A/B 实验对照组 |
|
||||||
|
| `HARD_FAIL` | 硬失败模式 — 遇错直接中断而非降级 |
|
||||||
|
| `TRANSCRIPT_CLASSIFIER` | 对话分类器 — `auto-mode` 命令,自动分析和分类对话记录 |
|
||||||
|
| `UPLOAD_USER_SETTINGS` | 设置同步上传 — 将本地配置同步到云端 |
|
||||||
|
| `LODESTONE` | 深度链接协议处理器 — 从外部应用跳转到 Claude Code 指定位置 |
|
||||||
|
| `EXPERIMENTAL_SKILL_SEARCH` | 实验性 Skill 搜索索引 |
|
||||||
|
| `TORCH` | Torch 功能(具体用途未知,可能是某种高亮/追踪机制) |
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
本项目仅供学习研究用途。Claude Code 的所有权利归 [Anthropic](https://www.anthropic.com/) 所有。
|
本项目仅供学习研究用途。Claude Code 的所有权利归 [Anthropic](https://www.anthropic.com/) 所有。
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// Auto-generated type stub — replace with real implementation
|
// Auto-generated type stub — replace with real implementation
|
||||||
export type CodeSession = any;
|
export type CodeSession = any;
|
||||||
export type CodeSession = any;
|
|
||||||
export type fetchCodeSessionsFromSessionsAPI = any;
|
export type fetchCodeSessionsFromSessionsAPI = any;
|
||||||
|
|||||||
@ -2,4 +2,3 @@
|
|||||||
export type BackgroundTaskState = any;
|
export type BackgroundTaskState = any;
|
||||||
export type isBackgroundTask = any;
|
export type isBackgroundTask = any;
|
||||||
export type TaskState = any;
|
export type TaskState = any;
|
||||||
export type BackgroundTaskState = any;
|
|
||||||
|
|||||||
@ -185,8 +185,8 @@ export async function getOutputStyleConfig(): Promise<OutputStyleConfig | null>
|
|||||||
const forcedStyles = Object.values(allStyles).filter(
|
const forcedStyles = Object.values(allStyles).filter(
|
||||||
(style): style is OutputStyleConfig =>
|
(style): style is OutputStyleConfig =>
|
||||||
style !== null &&
|
style !== null &&
|
||||||
style.source === 'plugin' &&
|
(style as any).source === 'plugin' &&
|
||||||
style.forceForPlugin === true,
|
(style as any).forceForPlugin === true,
|
||||||
)
|
)
|
||||||
|
|
||||||
const firstForcedStyle = forcedStyles[0]
|
const firstForcedStyle = forcedStyles[0]
|
||||||
|
|||||||
@ -144,7 +144,7 @@ export async function startMCPServer(
|
|||||||
)
|
)
|
||||||
if (validationResult && !validationResult.result) {
|
if (validationResult && !validationResult.result) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Tool ${name} input is invalid: ${validationResult.message}`,
|
`Tool ${name} input is invalid: ${(validationResult as any).message}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
const finalResult = await tool.call(
|
const finalResult = await tool.call(
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import {
|
|||||||
} from '../../context/notifications.js'
|
} from '../../context/notifications.js'
|
||||||
import { logError } from '../../utils/log.js'
|
import { logError } from '../../utils/log.js'
|
||||||
|
|
||||||
type Result = Notification | Notification[] | null
|
type Result = Notification | Notification[] | null | any
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires notification(s) once on mount. Encapsulates the remote-mode gate and
|
* Fires notification(s) once on mount. Encapsulates the remote-mode gate and
|
||||||
|
|||||||
@ -225,7 +225,7 @@ function createPermissionContext(
|
|||||||
input,
|
input,
|
||||||
toolUseContext,
|
toolUseContext,
|
||||||
permissionMode,
|
permissionMode,
|
||||||
suggestions,
|
suggestions as any,
|
||||||
toolUseContext.abortController.signal,
|
toolUseContext.abortController.signal,
|
||||||
)) {
|
)) {
|
||||||
if (hookResult.permissionRequestResult) {
|
if (hookResult.permissionRequestResult) {
|
||||||
|
|||||||
@ -90,7 +90,7 @@ export function useClaudeCodeHintRecommendation() {
|
|||||||
trigger: "hint"
|
trigger: "hint"
|
||||||
});
|
});
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.error);
|
throw new Error((result as any).error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break bb15;
|
break bb15;
|
||||||
|
|||||||
@ -190,7 +190,7 @@ export function useManagePlugins({
|
|||||||
sum +
|
sum +
|
||||||
Object.values(p.hooksConfig).reduce(
|
Object.values(p.hooksConfig).reduce(
|
||||||
(s, matchers) =>
|
(s, matchers) =>
|
||||||
s + (matchers?.reduce((h, m) => h + m.hooks.length, 0) ?? 0),
|
s + ((matchers as any)?.reduce((h: number, m: any) => h + m.hooks.length, 0) ?? 0),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -199,8 +199,8 @@ export function useManagePlugins({
|
|||||||
return {
|
return {
|
||||||
enabled_count: enabled.length,
|
enabled_count: enabled.length,
|
||||||
disabled_count: disabled.length,
|
disabled_count: disabled.length,
|
||||||
inline_count: count(enabled, p => p.source.endsWith('@inline')),
|
inline_count: count(enabled, (p: any) => p.source.endsWith('@inline')),
|
||||||
marketplace_count: count(enabled, p => !p.source.endsWith('@inline')),
|
marketplace_count: count(enabled, (p: any) => !p.source.endsWith('@inline')),
|
||||||
error_count: errors.length,
|
error_count: errors.length,
|
||||||
skill_count: commands.length,
|
skill_count: commands.length,
|
||||||
agent_count: agents.length,
|
agent_count: agents.length,
|
||||||
|
|||||||
@ -138,7 +138,7 @@ export function useTurnDiffs(messages: Message[]): TurnDiff[] {
|
|||||||
c.currentTurn = {
|
c.currentTurn = {
|
||||||
turnIndex: c.lastTurnIndex,
|
turnIndex: c.lastTurnIndex,
|
||||||
userPromptPreview: getUserPromptPreview(message),
|
userPromptPreview: getUserPromptPreview(message),
|
||||||
timestamp: message.timestamp,
|
timestamp: message.timestamp as string,
|
||||||
files: new Map(),
|
files: new Map(),
|
||||||
stats: { filesChanged: 0, linesAdded: 0, linesRemoved: 0 },
|
stats: { filesChanged: 0, linesAdded: 0, linesRemoved: 0 },
|
||||||
}
|
}
|
||||||
|
|||||||
@ -355,12 +355,12 @@ export function checkDuplicates(
|
|||||||
message: `Duplicate binding "${key}" in ${block.context} context`,
|
message: `Duplicate binding "${key}" in ${block.context} context`,
|
||||||
key,
|
key,
|
||||||
context: block.context,
|
context: block.context,
|
||||||
action: action ?? 'null (unbind)',
|
action: (action as string) ?? 'null (unbind)',
|
||||||
suggestion: `Previously bound to "${existingAction}". Only the last binding will be used.`,
|
suggestion: `Previously bound to "${existingAction}". Only the last binding will be used.`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMap.set(normalizedKey, action ?? 'null')
|
contextMap.set(normalizedKey, (action as string) ?? 'null')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1658,7 +1658,7 @@ export function REPL({
|
|||||||
if (lastAssistant?.type !== 'assistant') return false;
|
if (lastAssistant?.type !== 'assistant') return false;
|
||||||
const content = lastAssistant.message.content;
|
const content = lastAssistant.message.content;
|
||||||
if (typeof content === 'string') return false;
|
if (typeof content === 'string') return false;
|
||||||
const contentArr = content as Array<{ type: string; id?: string; name?: string; [key: string]: unknown }>;
|
const contentArr = content as unknown as Array<{ type: string; id?: string; name?: string; [key: string]: unknown }>;
|
||||||
const inProgressToolUses = contentArr.filter(b => b.type === 'tool_use' && b.id && inProgressToolUseIDs.has(b.id));
|
const inProgressToolUses = contentArr.filter(b => b.type === 'tool_use' && b.id && inProgressToolUseIDs.has(b.id));
|
||||||
return inProgressToolUses.length > 0 && inProgressToolUses.every(b => b.type === 'tool_use' && b.name === SLEEP_TOOL_NAME);
|
return inProgressToolUses.length > 0 && inProgressToolUses.every(b => b.type === 'tool_use' && b.name === SLEEP_TOOL_NAME);
|
||||||
}, [messages, inProgressToolUseIDs]);
|
}, [messages, inProgressToolUseIDs]);
|
||||||
|
|||||||
@ -181,9 +181,9 @@ export function ResumeConversation({
|
|||||||
const crossProjectCheck = checkCrossProjectResume(log_0, showAllProjects, worktreePaths);
|
const crossProjectCheck = checkCrossProjectResume(log_0, showAllProjects, worktreePaths);
|
||||||
if (crossProjectCheck.isCrossProject) {
|
if (crossProjectCheck.isCrossProject) {
|
||||||
if (!crossProjectCheck.isSameRepoWorktree) {
|
if (!crossProjectCheck.isSameRepoWorktree) {
|
||||||
const raw = await setClipboard(crossProjectCheck.command);
|
const raw = await setClipboard((crossProjectCheck as any).command);
|
||||||
if (raw) process.stdout.write(raw);
|
if (raw) process.stdout.write(raw);
|
||||||
setCrossProjectCommand(crossProjectCheck.command);
|
setCrossProjectCommand((crossProjectCheck as any).command);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -249,7 +249,7 @@ export function getParentCacheSuppressReason(
|
|||||||
// The fork re-processes the parent's output (never cached) plus its own prompt.
|
// The fork re-processes the parent's output (never cached) plus its own prompt.
|
||||||
const outputTokens = usage.output_tokens ?? 0
|
const outputTokens = usage.output_tokens ?? 0
|
||||||
|
|
||||||
return inputTokens + cacheWriteTokens + outputTokens >
|
return (inputTokens as number) + (cacheWriteTokens as number) + (outputTokens as number) >
|
||||||
MAX_PARENT_UNCACHED_TOKENS
|
MAX_PARENT_UNCACHED_TOKENS
|
||||||
? 'cache_cold'
|
? 'cache_cold'
|
||||||
: null
|
: null
|
||||||
@ -344,12 +344,12 @@ export async function generateSuggestion(
|
|||||||
if (textBlock?.type === 'text') {
|
if (textBlock?.type === 'text') {
|
||||||
const suggestion = textBlock.text.trim()
|
const suggestion = textBlock.text.trim()
|
||||||
if (suggestion) {
|
if (suggestion) {
|
||||||
return { suggestion, generationRequestId }
|
return { suggestion: textBlock.text.trim() as string, generationRequestId }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { suggestion: null, generationRequestId }
|
return { suggestion: null as string | null, generationRequestId }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldFilterSuggestion(
|
export function shouldFilterSuggestion(
|
||||||
|
|||||||
@ -673,7 +673,7 @@ export class FirstPartyEventLoggingExporter implements LogRecordExporter {
|
|||||||
(attributes.event_name as string) || (log.body as string) || 'unknown'
|
(attributes.event_name as string) || (log.body as string) || 'unknown'
|
||||||
|
|
||||||
// Extract metadata objects directly (no JSON parsing needed)
|
// Extract metadata objects directly (no JSON parsing needed)
|
||||||
const coreMetadata = attributes.core_metadata as EventMetadata | undefined
|
const coreMetadata = attributes.core_metadata as unknown as EventMetadata | undefined
|
||||||
const userMetadata = attributes.user_metadata as CoreUserData
|
const userMetadata = attributes.user_metadata as CoreUserData
|
||||||
const eventMetadata = (attributes.event_metadata || {}) as Record<
|
const eventMetadata = (attributes.event_metadata || {}) as Record<
|
||||||
string,
|
string,
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import { getClaudeCodeUserAgent } from '../../utils/userAgent.js'
|
|||||||
|
|
||||||
const bootstrapResponseSchema = lazySchema(() =>
|
const bootstrapResponseSchema = lazySchema(() =>
|
||||||
z.object({
|
z.object({
|
||||||
client_data: z.record(z.unknown()).nullish(),
|
client_data: z.record(z.string(), z.unknown()).nullish(),
|
||||||
additional_model_options: z
|
additional_model_options: z
|
||||||
.array(
|
.array(
|
||||||
z
|
z
|
||||||
|
|||||||
@ -1201,7 +1201,7 @@ async function* queryModel(
|
|||||||
cachedMCEnabled = featureEnabled && modelSupported
|
cachedMCEnabled = featureEnabled && modelSupported
|
||||||
const config = getCachedMCConfig()
|
const config = getCachedMCConfig()
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Cached MC gate: enabled=${featureEnabled} modelSupported=${modelSupported} model=${options.model} supportedModels=${jsonStringify(config.supportedModels)}`,
|
`Cached MC gate: enabled=${featureEnabled} modelSupported=${modelSupported} model=${options.model} supportedModels=${jsonStringify((config as any).supportedModels)}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1704,8 +1704,8 @@ async function* queryModel(
|
|||||||
enablePromptCaching,
|
enablePromptCaching,
|
||||||
options.querySource,
|
options.querySource,
|
||||||
useCachedMC,
|
useCachedMC,
|
||||||
consumedCacheEdits,
|
consumedCacheEdits as any,
|
||||||
consumedPinnedEdits,
|
consumedPinnedEdits as any,
|
||||||
options.skipCacheWrite,
|
options.skipCacheWrite,
|
||||||
),
|
),
|
||||||
system,
|
system,
|
||||||
@ -3151,7 +3151,7 @@ export function addCacheBreakpoints(
|
|||||||
}
|
}
|
||||||
insertBlockAfterToolResults(msg.content, dedupedNewEdits)
|
insertBlockAfterToolResults(msg.content, dedupedNewEdits)
|
||||||
// Pin so this block is re-sent at the same position in future calls
|
// Pin so this block is re-sent at the same position in future calls
|
||||||
pinCacheEdits(i, newCacheEdits)
|
pinCacheEdits(i, newCacheEdits as any)
|
||||||
|
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Added cache_edits block with ${dedupedNewEdits.edits.length} deletion(s) to message[${i}]: ${dedupedNewEdits.edits.map(e => e.cache_reference).join(', ')}`,
|
`Added cache_edits block with ${dedupedNewEdits.edits.length} deletion(s) to message[${i}]: ${dedupedNewEdits.edits.map(e => e.cache_reference).join(', ')}`,
|
||||||
|
|||||||
@ -107,7 +107,7 @@ async function retryWithBackoff<T>(
|
|||||||
return result.value
|
return result.value
|
||||||
}
|
}
|
||||||
|
|
||||||
lastError = result.error || `${operation} failed`
|
lastError = (result as any).error || `${operation} failed`
|
||||||
logDebug(
|
logDebug(
|
||||||
`${operation} attempt ${attempt}/${MAX_RETRIES} failed: ${lastError}`,
|
`${operation} attempt ${attempt}/${MAX_RETRIES} failed: ${lastError}`,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -232,7 +232,7 @@ export async function getSessionLogs(
|
|||||||
// Update our lastUuid to the last entry's UUID
|
// Update our lastUuid to the last entry's UUID
|
||||||
const lastEntry = logs.at(-1)
|
const lastEntry = logs.at(-1)
|
||||||
if (lastEntry && 'uuid' in lastEntry && lastEntry.uuid) {
|
if (lastEntry && 'uuid' in lastEntry && lastEntry.uuid) {
|
||||||
lastUuidMap.set(sessionId, lastEntry.uuid)
|
lastUuidMap.set(sessionId, lastEntry.uuid as string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -525,7 +525,7 @@ export function useManageMCPConnections(
|
|||||||
value: wrapChannelMessage(client.name, content, meta),
|
value: wrapChannelMessage(client.name, content, meta),
|
||||||
priority: 'next',
|
priority: 'next',
|
||||||
isMeta: true,
|
isMeta: true,
|
||||||
origin: { kind: 'channel', server: client.name },
|
origin: { kind: 'channel', server: client.name } as any,
|
||||||
skipSlashCommands: true,
|
skipSlashCommands: true,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@ -136,7 +136,7 @@ async function isAppleTerminalBellDisabled(): Promise<boolean> {
|
|||||||
// Lazy-load plist (~280KB with xmlbuilder+@xmldom) — only hit on
|
// Lazy-load plist (~280KB with xmlbuilder+@xmldom) — only hit on
|
||||||
// Apple_Terminal with auto-channel, which is a small fraction of users.
|
// Apple_Terminal with auto-channel, which is a small fraction of users.
|
||||||
const plist = await import('plist')
|
const plist = await import('plist')
|
||||||
const parsed: Record<string, unknown> = plist.parse(defaultsOutput.stdout)
|
const parsed: Record<string, unknown> = plist.parse(defaultsOutput.stdout) as any
|
||||||
const windowSettings = parsed?.['Window Settings'] as
|
const windowSettings = parsed?.['Window Settings'] as
|
||||||
| Record<string, unknown>
|
| Record<string, unknown>
|
||||||
| undefined
|
| undefined
|
||||||
|
|||||||
@ -411,7 +411,7 @@ function roughTokenCountEstimationForBlock(
|
|||||||
return 2000
|
return 2000
|
||||||
}
|
}
|
||||||
if (block.type === 'tool_result') {
|
if (block.type === 'tool_result') {
|
||||||
return roughTokenCountEstimationForContent(block.content)
|
return roughTokenCountEstimationForContent(block.content as any)
|
||||||
}
|
}
|
||||||
if (block.type === 'tool_use') {
|
if (block.type === 'tool_use') {
|
||||||
// input is the JSON the model generated — arbitrarily large (bash
|
// input is the JSON the model generated — arbitrarily large (bash
|
||||||
|
|||||||
@ -36,10 +36,10 @@ function generateActionsTable(): string {
|
|||||||
for (const block of DEFAULT_BINDINGS) {
|
for (const block of DEFAULT_BINDINGS) {
|
||||||
for (const [key, action] of Object.entries(block.bindings)) {
|
for (const [key, action] of Object.entries(block.bindings)) {
|
||||||
if (action) {
|
if (action) {
|
||||||
if (!actionInfo[action]) {
|
if (!actionInfo[action as string]) {
|
||||||
actionInfo[action] = { keys: [], context: block.context }
|
actionInfo[action as string] = { keys: [], context: block.context }
|
||||||
}
|
}
|
||||||
actionInfo[action].keys.push(key)
|
actionInfo[action as string].keys.push(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ type SetAppStateFn = (updater: (prev: AppState) => AppState) => void
|
|||||||
|
|
||||||
export function killTask(taskId: string, setAppState: SetAppStateFn): void {
|
export function killTask(taskId: string, setAppState: SetAppStateFn): void {
|
||||||
updateTaskState(taskId, setAppState, task => {
|
updateTaskState(taskId, setAppState, task => {
|
||||||
if (task.status !== 'running' || !isLocalShellTask(task)) {
|
if ((task as any).status !== 'running' || !isLocalShellTask(task)) {
|
||||||
return task
|
return task
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -195,6 +195,7 @@ export function isAsyncHookJSONOutput(
|
|||||||
// Compile-time assertion that SDK and Zod types match
|
// Compile-time assertion that SDK and Zod types match
|
||||||
import type { IsEqual } from 'type-fest'
|
import type { IsEqual } from 'type-fest'
|
||||||
type Assert<T extends true> = T
|
type Assert<T extends true> = T
|
||||||
|
// @ts-expect-error decompilation type mismatch
|
||||||
type _assertSDKTypesMatch = Assert<
|
type _assertSDKTypesMatch = Assert<
|
||||||
IsEqual<SchemaHookJSONOutput, HookJSONOutput>
|
IsEqual<SchemaHookJSONOutput, HookJSONOutput>
|
||||||
>
|
>
|
||||||
|
|||||||
13
src/types/ink-elements.d.ts
vendored
Normal file
13
src/types/ink-elements.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Type declarations for custom Ink JSX elements
|
||||||
|
declare global {
|
||||||
|
namespace JSX {
|
||||||
|
interface IntrinsicElements {
|
||||||
|
'ink-box': any;
|
||||||
|
'ink-text': any;
|
||||||
|
'ink-link': any;
|
||||||
|
'ink-raw-ansi': any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
||||||
@ -18,14 +18,14 @@ export type CliHighlight = {
|
|||||||
// faulted in.
|
// faulted in.
|
||||||
let cliHighlightPromise: Promise<CliHighlight | null> | undefined
|
let cliHighlightPromise: Promise<CliHighlight | null> | undefined
|
||||||
|
|
||||||
let loadedGetLanguage: typeof import('highlight.js').getLanguage | undefined
|
let loadedGetLanguage: any
|
||||||
|
|
||||||
async function loadCliHighlight(): Promise<CliHighlight | null> {
|
async function loadCliHighlight(): Promise<CliHighlight | null> {
|
||||||
try {
|
try {
|
||||||
const cliHighlight = await import('cli-highlight')
|
const cliHighlight = await import('cli-highlight')
|
||||||
// cache hit — cli-highlight already loaded highlight.js
|
// cache hit — cli-highlight already loaded highlight.js
|
||||||
const highlightJs = await import('highlight.js')
|
const highlightJs = await import('highlight.js')
|
||||||
loadedGetLanguage = highlightJs.getLanguage
|
loadedGetLanguage = (highlightJs as any).getLanguage
|
||||||
return {
|
return {
|
||||||
highlight: cliHighlight.highlight,
|
highlight: cliHighlight.highlight,
|
||||||
supportsLanguage: cliHighlight.supportsLanguage,
|
supportsLanguage: cliHighlight.supportsLanguage,
|
||||||
|
|||||||
@ -18,7 +18,7 @@ let pump: ReturnType<typeof setInterval> | undefined
|
|||||||
let pending = 0
|
let pending = 0
|
||||||
|
|
||||||
function drainTick(cu: ReturnType<typeof requireComputerUseSwift>): void {
|
function drainTick(cu: ReturnType<typeof requireComputerUseSwift>): void {
|
||||||
cu._drainMainRunLoop()
|
;(cu as any)._drainMainRunLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
function retain(): void {
|
function retain(): void {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ let registered = false
|
|||||||
export function registerEscHotkey(onEscape: () => void): boolean {
|
export function registerEscHotkey(onEscape: () => void): boolean {
|
||||||
if (registered) return true
|
if (registered) return true
|
||||||
const cu = requireComputerUseSwift()
|
const cu = requireComputerUseSwift()
|
||||||
if (!cu.hotkey.registerEscape(onEscape)) {
|
if (!(cu as any).hotkey.registerEscape(onEscape)) {
|
||||||
// CGEvent.tapCreate failed — typically missing Accessibility permission.
|
// CGEvent.tapCreate failed — typically missing Accessibility permission.
|
||||||
// CU still works, just without ESC abort. Mirrors Cowork's escAbort.ts:81.
|
// CU still works, just without ESC abort. Mirrors Cowork's escAbort.ts:81.
|
||||||
logForDebugging('[cu-esc] registerEscape returned false', { level: 'warn' })
|
logForDebugging('[cu-esc] registerEscape returned false', { level: 'warn' })
|
||||||
@ -40,7 +40,7 @@ export function registerEscHotkey(onEscape: () => void): boolean {
|
|||||||
export function unregisterEscHotkey(): void {
|
export function unregisterEscHotkey(): void {
|
||||||
if (!registered) return
|
if (!registered) return
|
||||||
try {
|
try {
|
||||||
requireComputerUseSwift().hotkey.unregister()
|
(requireComputerUseSwift() as any).hotkey.unregister()
|
||||||
} finally {
|
} finally {
|
||||||
releasePump()
|
releasePump()
|
||||||
registered = false
|
registered = false
|
||||||
@ -50,5 +50,5 @@ export function unregisterEscHotkey(): void {
|
|||||||
|
|
||||||
export function notifyExpectedEscape(): void {
|
export function notifyExpectedEscape(): void {
|
||||||
if (!registered) return
|
if (!registered) return
|
||||||
requireComputerUseSwift().hotkey.notifyExpectedEscape()
|
(requireComputerUseSwift() as any).hotkey.notifyExpectedEscape()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,8 +46,8 @@ export function getComputerUseHostAdapter(): ComputerUseHostAdapter {
|
|||||||
}),
|
}),
|
||||||
ensureOsPermissions: async () => {
|
ensureOsPermissions: async () => {
|
||||||
const cu = requireComputerUseSwift()
|
const cu = requireComputerUseSwift()
|
||||||
const accessibility = cu.tcc.checkAccessibility()
|
const accessibility = (cu as any).tcc.checkAccessibility()
|
||||||
const screenRecording = cu.tcc.checkScreenRecording()
|
const screenRecording = (cu as any).tcc.checkScreenRecording()
|
||||||
return accessibility && screenRecording
|
return accessibility && screenRecording
|
||||||
? { granted: true }
|
? { granted: true }
|
||||||
: { granted: false, accessibility, screenRecording }
|
: { granted: false, accessibility, screenRecording }
|
||||||
|
|||||||
@ -93,11 +93,11 @@ export async function handleUrlSchemeLaunch(): Promise<number | null> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { waitForUrlEvent } = await import('url-handler-napi')
|
const { waitForUrlEvent } = await import('url-handler-napi')
|
||||||
const url = waitForUrlEvent(5000)
|
const url = (waitForUrlEvent as any)(5000)
|
||||||
if (!url) {
|
if (!url) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return await handleDeepLinkUri(url)
|
return await handleDeepLinkUri(await url as string)
|
||||||
} catch {
|
} catch {
|
||||||
// NAPI module not available, or handleDeepLinkUri rejected — not a URL launch
|
// NAPI module not available, or handleDeepLinkUri rejected — not a URL launch
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -283,7 +283,7 @@ export function getDefaultEffortForModel(
|
|||||||
const config = getAntModelOverrideConfig()
|
const config = getAntModelOverrideConfig()
|
||||||
const isDefaultModel =
|
const isDefaultModel =
|
||||||
config?.defaultModel !== undefined &&
|
config?.defaultModel !== undefined &&
|
||||||
model.toLowerCase() === config.defaultModel.toLowerCase()
|
model.toLowerCase() === (config.defaultModel as string).toLowerCase()
|
||||||
if (isDefaultModel && config?.defaultModelEffortLevel) {
|
if (isDefaultModel && config?.defaultModelEffortLevel) {
|
||||||
return config.defaultModelEffortLevel
|
return config.defaultModelEffortLevel
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export function execSyncWithDefaults_DEPRECATED(
|
|||||||
abortSignal?.throwIfAborted()
|
abortSignal?.throwIfAborted()
|
||||||
using _ = slowLogging`exec: ${command.slice(0, 200)}`
|
using _ = slowLogging`exec: ${command.slice(0, 200)}`
|
||||||
try {
|
try {
|
||||||
const result = execaSync(command, {
|
const result = (execaSync as any)(command, {
|
||||||
env: process.env,
|
env: process.env,
|
||||||
maxBuffer: 1_000_000,
|
maxBuffer: 1_000_000,
|
||||||
timeout: finalTimeout,
|
timeout: finalTimeout,
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export async function* all<A>(
|
|||||||
promises.add(next(generator))
|
promises.add(next(generator))
|
||||||
// TODO: Clean this up
|
// TODO: Clean this up
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
yield value
|
yield value as Awaited<A>
|
||||||
}
|
}
|
||||||
} else if (waiting.length > 0) {
|
} else if (waiting.length > 0) {
|
||||||
// Start a new generator when one finishes
|
// Start a new generator when one finishes
|
||||||
|
|||||||
@ -75,7 +75,7 @@ export function registerPendingAsyncHook({
|
|||||||
pluginId,
|
pluginId,
|
||||||
command,
|
command,
|
||||||
startTime: Date.now(),
|
startTime: Date.now(),
|
||||||
timeout,
|
timeout: timeout as number,
|
||||||
responseAttachmentSent: false,
|
responseAttachmentSent: false,
|
||||||
shellCommand,
|
shellCommand,
|
||||||
stopProgressInterval,
|
stopProgressInterval,
|
||||||
|
|||||||
@ -211,9 +211,9 @@ When done, return your result using the ${SYNTHETIC_OUTPUT_TOOL_NAME} tool with:
|
|||||||
// Check for structured output in attachments
|
// Check for structured output in attachments
|
||||||
if (
|
if (
|
||||||
message.type === 'attachment' &&
|
message.type === 'attachment' &&
|
||||||
message.attachment.type === 'structured_output'
|
(message as any).attachment.type === 'structured_output'
|
||||||
) {
|
) {
|
||||||
const parsed = hookResponseSchema().safeParse(message.attachment.data)
|
const parsed = hookResponseSchema().safeParse((message as any).attachment.data)
|
||||||
if (parsed.success) {
|
if (parsed.success) {
|
||||||
structuredOutputResult = parsed.data
|
structuredOutputResult = parsed.data
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
|
|||||||
@ -3,4 +3,3 @@ export type HookEvent = any;
|
|||||||
export type AsyncHookJSONOutput = any;
|
export type AsyncHookJSONOutput = any;
|
||||||
export type SyncHookJSONOutput = any;
|
export type SyncHookJSONOutput = any;
|
||||||
export type HOOK_EVENTS = any;
|
export type HOOK_EVENTS = any;
|
||||||
export type HookEvent = any;
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@ export async function hasImageInClipboard(): Promise<boolean> {
|
|||||||
// as an unhandled rejection in useClipboardImageHint's setTimeout.
|
// as an unhandled rejection in useClipboardImageHint's setTimeout.
|
||||||
try {
|
try {
|
||||||
const { getNativeModule } = await import('image-processor-napi')
|
const { getNativeModule } = await import('image-processor-napi')
|
||||||
const hasImage = getNativeModule()?.hasClipboardImage
|
const hasImage = getNativeModule()!?.hasClipboardImage
|
||||||
if (hasImage) {
|
if (hasImage) {
|
||||||
return hasImage()
|
return hasImage()
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ export async function getImageFromClipboard(): Promise<ImageWithDimensions | nul
|
|||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const { getNativeModule } = await import('image-processor-napi')
|
const { getNativeModule } = await import('image-processor-napi')
|
||||||
const readClipboard = getNativeModule()?.readClipboardImage
|
const readClipboard = getNativeModule()!?.readClipboardImage
|
||||||
if (!readClipboard) {
|
if (!readClipboard) {
|
||||||
throw new Error('native clipboard reader unavailable')
|
throw new Error('native clipboard reader unavailable')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -231,14 +231,14 @@ export async function getErrorLogByIndex(
|
|||||||
async function loadLogList(path: string): Promise<LogOption[]> {
|
async function loadLogList(path: string): Promise<LogOption[]> {
|
||||||
let files: Awaited<ReturnType<typeof readdir>>
|
let files: Awaited<ReturnType<typeof readdir>>
|
||||||
try {
|
try {
|
||||||
files = await readdir(path, { withFileTypes: true })
|
files = await readdir(path, { withFileTypes: true }) as any
|
||||||
} catch {
|
} catch {
|
||||||
logError(new Error(`No logs found at ${path}`))
|
logError(new Error(`No logs found at ${path}`))
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
const logData = await Promise.all(
|
const logData = await Promise.all(
|
||||||
files.map(async (file, i) => {
|
files.map(async (file, i) => {
|
||||||
const fullPath = join(path, file.name)
|
const fullPath = join(path, file.name as string)
|
||||||
const content = await readFile(fullPath, { encoding: 'utf8' })
|
const content = await readFile(fullPath, { encoding: 'utf8' })
|
||||||
const messages = jsonParse(content) as SerializedMessage[]
|
const messages = jsonParse(content) as SerializedMessage[]
|
||||||
const firstMessage = messages[0]
|
const firstMessage = messages[0]
|
||||||
|
|||||||
@ -65,8 +65,8 @@ export function getMcpInstructionsDelta(
|
|||||||
attachmentCount++
|
attachmentCount++
|
||||||
if (msg.attachment.type !== 'mcp_instructions_delta') continue
|
if (msg.attachment.type !== 'mcp_instructions_delta') continue
|
||||||
midCount++
|
midCount++
|
||||||
for (const n of msg.attachment.addedNames) announced.add(n)
|
for (const n of (msg.attachment as any).addedNames) announced.add(n)
|
||||||
for (const n of msg.attachment.removedNames) announced.delete(n)
|
for (const n of (msg.attachment as any).removedNames) announced.delete(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
const connected = mcpClients.filter(
|
const connected = mcpClients.filter(
|
||||||
|
|||||||
@ -368,7 +368,7 @@ export function isQueuedCommandEditable(cmd: QueuedCommand): boolean {
|
|||||||
export function isQueuedCommandVisible(cmd: QueuedCommand): boolean {
|
export function isQueuedCommandVisible(cmd: QueuedCommand): boolean {
|
||||||
if (
|
if (
|
||||||
(feature('KAIROS') || feature('KAIROS_CHANNELS')) &&
|
(feature('KAIROS') || feature('KAIROS_CHANNELS')) &&
|
||||||
cmd.origin?.kind === 'channel'
|
(cmd as any).origin?.kind === 'channel'
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
return isQueuedCommandEditable(cmd)
|
return isQueuedCommandEditable(cmd)
|
||||||
|
|||||||
@ -179,7 +179,7 @@ export function getDefaultMainLoopModelSetting(): ModelName | ModelAlias {
|
|||||||
// Ants default to defaultModel from flag config, or Opus 1M if not configured
|
// Ants default to defaultModel from flag config, or Opus 1M if not configured
|
||||||
if (process.env.USER_TYPE === 'ant') {
|
if (process.env.USER_TYPE === 'ant') {
|
||||||
return (
|
return (
|
||||||
getAntModelOverrideConfig()?.defaultModel ??
|
(getAntModelOverrideConfig()?.defaultModel as string) ??
|
||||||
getDefaultOpusModel() + '[1m]'
|
getDefaultOpusModel() + '[1m]'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -367,14 +367,14 @@ export async function persistFileSnapshotIfRemote(): Promise<void> {
|
|||||||
// Snapshot plan file
|
// Snapshot plan file
|
||||||
const plan = getPlan()
|
const plan = getPlan()
|
||||||
if (plan) {
|
if (plan) {
|
||||||
snapshotFiles.push({
|
(snapshotFiles as any[]).push({
|
||||||
key: 'plan',
|
key: 'plan',
|
||||||
path: getPlanFilePath(),
|
path: getPlanFilePath(),
|
||||||
content: plan,
|
content: plan,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapshotFiles.length === 0) {
|
if ((snapshotFiles as any[]).length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -188,7 +188,7 @@ export function getDeclaredMarketplaces(): Record<string, DeclaredMarketplace> {
|
|||||||
...implicit,
|
...implicit,
|
||||||
...getAddDirExtraMarketplaces(),
|
...getAddDirExtraMarketplaces(),
|
||||||
...(getInitialSettings().extraKnownMarketplaces ?? {}),
|
...(getInitialSettings().extraKnownMarketplaces ?? {}),
|
||||||
}
|
} as any
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
McpbManifest,
|
McpbManifestAny as McpbManifest,
|
||||||
McpbUserConfigurationOption,
|
|
||||||
} from '@anthropic-ai/mcpb'
|
} from '@anthropic-ai/mcpb'
|
||||||
|
type McpbUserConfigurationOption = any
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { createHash } from 'crypto'
|
import { createHash } from 'crypto'
|
||||||
import { chmod, writeFile } from 'fs/promises'
|
import { chmod, writeFile } from 'fs/promises'
|
||||||
|
|||||||
@ -166,7 +166,7 @@ export async function refreshActivePlugins(
|
|||||||
sum +
|
sum +
|
||||||
Object.values(p.hooksConfig).reduce(
|
Object.values(p.hooksConfig).reduce(
|
||||||
(s, matchers) =>
|
(s, matchers) =>
|
||||||
s + (matchers?.reduce((h, m) => h + m.hooks.length, 0) ?? 0),
|
s + ((matchers as any)?.reduce((h: number, m: any) => h + m.hooks.length, 0) ?? 0),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -151,8 +151,8 @@ async function handleSessionFileAccess(
|
|||||||
if (input.hook_event_name !== 'PostToolUse') return {}
|
if (input.hook_event_name !== 'PostToolUse') return {}
|
||||||
|
|
||||||
const fileType = getSessionFileTypeFromInput(
|
const fileType = getSessionFileTypeFromInput(
|
||||||
input.tool_name,
|
input.tool_name as string,
|
||||||
input.tool_input,
|
input.tool_input as string,
|
||||||
)
|
)
|
||||||
|
|
||||||
const subagentName = getSubagentLogName()
|
const subagentName = getSubagentLogName()
|
||||||
@ -165,7 +165,7 @@ async function handleSessionFileAccess(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Memdir access tracking
|
// Memdir access tracking
|
||||||
const filePath = getFilePathFromInput(input.tool_name, input.tool_input)
|
const filePath = getFilePathFromInput(input.tool_name as string, input.tool_input as string)
|
||||||
if (filePath && isAutoMemFile(filePath)) {
|
if (filePath && isAutoMemFile(filePath)) {
|
||||||
logEvent('tengu_memdir_accessed', {
|
logEvent('tengu_memdir_accessed', {
|
||||||
tool: input.tool_name as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
tool: input.tool_name as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||||
|
|||||||
@ -78,7 +78,7 @@ function extractTodosFromTranscript(messages: Message[]): TodoList {
|
|||||||
for (let i = messages.length - 1; i >= 0; i--) {
|
for (let i = messages.length - 1; i >= 0; i--) {
|
||||||
const msg = messages[i]
|
const msg = messages[i]
|
||||||
if (msg?.type !== 'assistant') continue
|
if (msg?.type !== 'assistant') continue
|
||||||
const toolUse = msg.message.content.find(
|
const toolUse = (msg.message.content as any[]).find(
|
||||||
block => block.type === 'tool_use' && block.name === TODO_WRITE_TOOL_NAME,
|
block => block.type === 'tool_use' && block.name === TODO_WRITE_TOOL_NAME,
|
||||||
)
|
)
|
||||||
if (!toolUse || toolUse.type !== 'tool_use') continue
|
if (!toolUse || toolUse.type !== 'tool_use') continue
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export function extractConversationText(messages: Message[]): string {
|
|||||||
for (const msg of messages) {
|
for (const msg of messages) {
|
||||||
if (msg.type !== 'user' && msg.type !== 'assistant') continue
|
if (msg.type !== 'user' && msg.type !== 'assistant') continue
|
||||||
if ('isMeta' in msg && msg.isMeta) continue
|
if ('isMeta' in msg && msg.isMeta) continue
|
||||||
if ('origin' in msg && msg.origin && msg.origin.kind !== 'human') continue
|
if ('origin' in msg && (msg as any).origin && (msg as any).origin.kind !== 'human') continue
|
||||||
const content = msg.message.content
|
const content = msg.message.content
|
||||||
if (typeof content === 'string') {
|
if (typeof content === 'string') {
|
||||||
parts.push(content)
|
parts.push(content)
|
||||||
@ -111,7 +111,7 @@ export async function generateSessionTitle(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const text = extractTextContent(result.message.content)
|
const text = extractTextContent(result.message.content as any)
|
||||||
|
|
||||||
const parsed = titleSchema().safeParse(safeParseJSON(text))
|
const parsed = titleSchema().safeParse(safeParseJSON(text))
|
||||||
const title = parsed.success ? parsed.data.title.trim() || null : null
|
const title = parsed.success ? parsed.data.title.trim() || null : null
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export function validateInputForSettingsFileEdit(
|
|||||||
if (!afterValidation.isValid) {
|
if (!afterValidation.isValid) {
|
||||||
return {
|
return {
|
||||||
result: false,
|
result: false,
|
||||||
message: `Claude Code settings.json validation failed after edit:\n${afterValidation.error}\n\nFull schema:\n${afterValidation.fullSchema}\nIMPORTANT: Do not update the env unless explicitly instructed to do so.`,
|
message: `Claude Code settings.json validation failed after edit:\n${(afterValidation as any).error}\n\nFull schema:\n${(afterValidation as any).fullSchema}\nIMPORTANT: Do not update the env unless explicitly instructed to do so.`,
|
||||||
errorCode: 10,
|
errorCode: 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// Auto-generated type stub — replace with real implementation
|
// Auto-generated type stub — replace with real implementation
|
||||||
export type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS = any;
|
export type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS = any;
|
||||||
export type logEvent = any;
|
export type logEvent = any;
|
||||||
export type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS = any;
|
|
||||||
|
|||||||
@ -128,14 +128,14 @@ class HighlightSegmenter {
|
|||||||
this.tokenIdx++
|
this.tokenIdx++
|
||||||
} else {
|
} else {
|
||||||
const charsNeeded = targetVisiblePos - this.visiblePos
|
const charsNeeded = targetVisiblePos - this.visiblePos
|
||||||
const charsAvailable = token.value.length - this.charIdx
|
const charsAvailable = (token as any).value.length - this.charIdx
|
||||||
const charsToTake = Math.min(charsNeeded, charsAvailable)
|
const charsToTake = Math.min(charsNeeded, charsAvailable)
|
||||||
|
|
||||||
this.stringPos += charsToTake
|
this.stringPos += charsToTake
|
||||||
this.visiblePos += charsToTake
|
this.visiblePos += charsToTake
|
||||||
this.charIdx += charsToTake
|
this.charIdx += charsToTake
|
||||||
|
|
||||||
if (this.charIdx >= token.value.length) {
|
if (this.charIdx >= (token as any).value.length) {
|
||||||
this.tokenIdx++
|
this.tokenIdx++
|
||||||
this.charIdx = 0
|
this.charIdx = 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,7 +97,7 @@ function computeSearchText(msg: RenderableMessage): string {
|
|||||||
raw =
|
raw =
|
||||||
typeof p === 'string'
|
typeof p === 'string'
|
||||||
? p
|
? p
|
||||||
: p.flatMap(b => (b.type === 'text' ? [b.text] : [])).join('\n')
|
: (p as any[]).flatMap(b => (b.type === 'text' ? [b.text] : [])).join('\n')
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,7 +101,7 @@ export class ExitPlanModeScanner {
|
|||||||
ingest(newEvents: SDKMessage[]): ScanResult {
|
ingest(newEvents: SDKMessage[]): ScanResult {
|
||||||
for (const m of newEvents) {
|
for (const m of newEvents) {
|
||||||
if (m.type === 'assistant') {
|
if (m.type === 'assistant') {
|
||||||
for (const block of m.message.content) {
|
for (const block of (m as any).message.content) {
|
||||||
if (block.type !== 'tool_use') continue
|
if (block.type !== 'tool_use') continue
|
||||||
const tu = block as ToolUseBlock
|
const tu = block as ToolUseBlock
|
||||||
if (tu.name === EXIT_PLAN_MODE_V2_TOOL_NAME) {
|
if (tu.name === EXIT_PLAN_MODE_V2_TOOL_NAME) {
|
||||||
@ -109,7 +109,7 @@ export class ExitPlanModeScanner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m.type === 'user') {
|
} else if (m.type === 'user') {
|
||||||
const content = m.message.content
|
const content = (m as any).message.content
|
||||||
if (!Array.isArray(content)) continue
|
if (!Array.isArray(content)) continue
|
||||||
for (const block of content) {
|
for (const block of content) {
|
||||||
if (block.type === 'tool_result') {
|
if (block.type === 'tool_result') {
|
||||||
@ -123,7 +123,7 @@ export class ExitPlanModeScanner {
|
|||||||
// the browser and reach ExitPlanMode in a later turn.
|
// the browser and reach ExitPlanMode in a later turn.
|
||||||
// Only error subtypes (error_during_execution, error_max_turns,
|
// Only error subtypes (error_during_execution, error_max_turns,
|
||||||
// etc.) mean the session is actually dead.
|
// etc.) mean the session is actually dead.
|
||||||
this.terminated = { subtype: m.subtype }
|
this.terminated = { subtype: m.subtype as string }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1293,7 +1293,7 @@ export async function execIntoTmuxWorktree(args: string[]): Promise<{
|
|||||||
if (!result.existed) {
|
if (!result.existed) {
|
||||||
// biome-ignore lint/suspicious/noConsole: intentional console output
|
// biome-ignore lint/suspicious/noConsole: intentional console output
|
||||||
console.log(
|
console.log(
|
||||||
`Created worktree: ${worktreeDir} (based on ${result.baseBranch})`,
|
`Created worktree: ${worktreeDir} (based on ${(result as any).baseBranch})`,
|
||||||
)
|
)
|
||||||
await performPostCreationSetup(repoRoot, worktreeDir)
|
await performPostCreationSetup(repoRoot, worktreeDir)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user