Skip to content

Fixture/flick#1280

Merged
claude-code-best merged 27 commits into
mainfrom
fixture/flick
Jun 22, 2026
Merged

Fixture/flick#1280
claude-code-best merged 27 commits into
mainfrom
fixture/flick

Conversation

@claude-code-best

@claude-code-best claude-code-best commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added continuous goal-driven agent execution with pause/resume/continue/clear controls and audit/budget features.
    • Added Artifacts HTML upload support with open-source deployment details.
    • Added Ultracode multi-agent orchestration with workflow scripting and monitoring panel.
  • Improvements

    • Enhanced workflow panel: tab limiting, active run filtering, and improved UI rendering.

claude-code-best and others added 27 commits June 20, 2026 22:35
主屏幕模式下 frame 持续溢出 viewport 时,cursor-restore LF 把内容滚入 scrollback
导致相对光标追踪漂移,可见区 diff 落到错误行产生重影(重复 banner / 错位)。
扩展 log-update overflow 分支为无条件 fullReset(含 \x1b[3J 清 scrollback),
并将主屏 self-healing 清屏从 ERASE_SCREEN (CSI 2 J) 换成 ERASE_DOWN (CSI J),
避免 xterm.js / VSCode 集成终端的 scrollback 边界副作用。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- scripts/verify-autofix-pr.ts: 一次性 autofix-pr 验证脚本,全仓零引用
- scripts/smoke-test-commands.ts: 开发期冒烟测试脚本,无任何 import
- scripts/probe-subscription-endpoints.ts: 手动 endpoint 探针,无引用

均不在 package.json scripts、build.ts、vite.config.ts、CI workflows 中。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 src/self-hosted-runner/main.ts(自动生成的 Promise.resolve() stub)
- 同步移除 src/entrypoints/cli.tsx 中 feature('SELF_HOSTED_RUNNER') 守卫的 fast-path 分支
- 该 flag 不在 build.ts DEFAULT_BUILD_FEATURES 也不在 dev 默认列表,所有默认配置下整段为构建期死代码

删除 stub 单独会留下未解析的动态 import,必须协同拆除。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
移除 watchScheduledTasks、buildMissedTaskNotification、connectRemoteControl 三个 stub 函数(函数体仅 throw new Error('not implemented')),以及仅被这些 stub 引用的孤儿类型(ScheduledTasksHandle、ConnectRemoteControlOptions、RemoteControlHandle、InboundPrompt 等)。

全仓零外部引用。buildMissedTaskNotification 在 src/utils/cronScheduler.ts 有真实可用实现,未受影响。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 getKillRingItem、getKillRingSize、clearKillRing、canYankPop(全仓零引用的独立 export)
- 移除 VIM_WORD_CHAR_REGEX 的 export 关键字(仍由 isVimWordChar 内部使用,保留常量本体)

kill ring 特性本身仍活跃(getLastKill/pushToKillRing/yankPop 在 useSearchInput/useTextInput 使用),仅这几个孤儿 helper 未接入。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 deduplicateSessionBranches(全仓零调用,含 JSDoc)
- 删除 buildExportData(全仓零调用,原 S3 上传路径实际用 HTML 而非 JSON)
- InsightsExport 仅移除 export 关键字(保留类型本体,仍作为内部返回类型)

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 AUTONOMY_CLI(CLI 子命令描述对象,零引用;handler 仅用 AUTONOMY_USAGE)
- 删除 AUTONOMY_COMMAND_DESCRIPTION(值已在 main.tsx:5181 内联)
- ParsedAutonomyCommand 仅移除 export 关键字(保留类型作为 parseAutonomyArgs 返回类型)

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- binaryCheck.ts: 删除 clearBinaryCache(零调用,binaryCache 仍由 isBinaryInstalled 使用)
- claudeAiLimits.ts: 删除 RATE_LIMIT_DISPLAY_NAMES 常量 + getRateLimitDisplayName(互为唯一消费者)
- codeIndexing.ts: 删除 detectCodeIndexingFromMcpTool(同胞 detectCodeIndexingFromCommand/McpServerName 仍活跃)

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
下列符号均仅在本文件内被引用,export 关键字冗余;保留符号本体不动:

- internalLogging.ts: getContainerId(line 88 内部调用)
- api/errors.ts: isMediaSizeError(line 151 内部调用)
- api/withRetry.ts: parseMaxTokensContextOverflowError(line 389/724 内部调用)
- statsCache.ts: STATS_CACHE_VERSION(7 处内部使用)
- startupProfiler.ts: logStartupPerf(line 128 内部调用)
- bashCommandHelpers.ts: CommandIdentityCheckers(3 处内部参数类型)

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
注释代码(已死的、引用不存在符号的注释块):
- Onboarding.tsx: 注释化的 preflight if-block(引用不存在的 preflightStep)
- ultraplan.tsx: 两处引用不存在符号的注释(ULTRAPLAN_INSTRUCTIONS、getUltraplanModel)
- types/hooks.ts: 禁用的 type-fest IsEqual 类型断言块
- types/global.d.ts: 已被真实模块取代的 Ultraplan ambient declares
- types/textInputTypes.ts: 注释化的 onMessage interface 成员

legacy shim:
- cli/bg.ts: 删除 handleBgFlag 别名 export(同胞 handleBgStart 已被所有调用点使用)

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 src/utils/ccshareResume.ts(parseCcshareId 恒返回 null、loadCcshare 恒抛错的 stub)
- 同步移除 src/main.tsx 中 USER_TYPE === 'ant' 守卫下的 if (ccshareId) {...} else {...} 双分支
- 提升 else 块(文件路径 resume 处理)为直接进入 if (options.resume) 块内

ccshare 是 Anthropic 内部特性(go/ccshare URL),stub 未实现导致 ccshareId 恒为 null,整个 ccshare 分支永不进入;保留的文件路径 resume 路径不变。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
与 self-hosted-runner 相同模式的 sibling(工作流 1 verifier 建议同步处理):

- 删除 src/environment-runner/main.ts(自动生成的 Promise.resolve() stub)
- 同步移除 src/entrypoints/cli.tsx 中 feature('BYOC_ENVIRONMENT_RUNNER') 守卫的 fast-path 分支
- 清理两个空目录(src/self-hosted-runner/、src/environment-runner/)

BYOC_ENVIRONMENT_RUNNER flag 不在 build.ts DEFAULT_BUILD_FEATURES 也不在 dev 默认列表,所有默认配置下整段为构建期死代码。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
#!/usr/bin/env bun shebang 的手动诊断脚本,全仓零引用,不在 package.json/build.ts/vite.config.ts/CI workflows 中。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 src/services/api/ultrareviewPreflight.ts(自动生成的 stub)
- 删除 src/commands/review/UltrareviewPreflightDialog.tsx(依赖前者的 UI stub)
- 删除 src/services/api/__tests__/ultrareviewPreflight.test.ts(测试已删代码)
- 同步移除 ultrareviewCommand.test.tsx 中对 UltrareviewPreflightDialog 的 mock

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 src/services/compact/cachedMCConfig.ts(自动生成的 stub)
- 同步移除 src/constants/prompts.ts 中依赖该 stub 的代码:
  - getCachedMCConfigForFRC 变量(feature('CACHED_MICROCOMPACT') 守卫的 require)
  - getFunctionResultClearingSection 函数(约 18 行)
  - systemPrompt 数组中的 frc section 调用与注册

CACHED_MICROCOMPACT 不在 build.ts DEFAULT_BUILD_FEATURES 也不在 dev 默认列表,所有默认配置下整段为构建期死代码。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- 删除 src/services/goal/goalAudit.ts(导出 COMPLETION_AUDIT_RULES/BLOCKED_AUDIT_RULES/isGoalTerminal 等未引用的 stub)
- 同步移除 tests/integration/goal-lifecycle.test.ts 中对 goalAudit 的 import 和一个测试用例(budget_limited is terminal)

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
移除运行时函数体仅为 throw new Error 或 placeholder 的 stub:
- createSdkMcpToolDefinition、createSdkMcpServer
- query 函数重载与实现
- unstable_v2_* 系列函数
- session 操作 stub(getSessionMessages/listSessions/getSessionInfo/renameSession/tagSession/forkSession)
- AbortError 类

保留所有 export type 重导出和类型别名(仍是公共类型面)。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
删除 "// Re-export progress types for backwards compatibility" 注释块及其重导出语句。所有消费方已直接从 src/types/tools.js 导入,无需重导出转发。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
- clearRegisteredHooks(STATE.registeredHooks 仍由其他函数管理)
- getInvokedSkills(getInvokedSkillsForAgent 是活跃入口)
- getSessionSource(setSessionSource 仍活跃,sessionSource state 字段保留)
- markScrollActivity(scrollDraining/getIsScrollDraining/waitForScrollDrain 仍活跃)

仅删除孤儿访问器,不动模块级 state 副作用。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
涉及 18 个文件,每处均为独立的 unreferenced export 删除或 export 关键字冗余移除:

- bridge/bridgeStatusUtil.ts、components/TrustDialog/utils.ts、context/stats.tsx
- keybindings/loadUserBindings.ts、memdir/paths.ts、remote/sdkMessageAdapter.ts
- services/acp/utils.ts(删除 nodeToWebReadable,全仓零引用)
- services/api/metricsOptOut.ts、services/lsp/LSPDiagnosticRegistry.ts、services/lsp/manager.ts
- services/mcp/utils.ts、services/skillLearning/projectContext.ts
- services/teamMemorySync/secretScanner.ts、services/teamMemorySync/watcher.ts
- skills/loadSkillsDir.ts、utils/attachments.ts、utils/filePersistence/filePersistence.ts
- utils/messageQueueManager.ts

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
涉及 11 个 workspace 包文件,每处均为独立的 unreferenced export 删除或 export 关键字冗余移除:

- @ant/ink/core/termio/csi.ts(eraseLine)
- acp-link/manager/types.ts、acp-link/ws-message.ts
- builtin-tools/AgentTool/agentMemory.ts、BashTool/bashSecurity.ts、BashTool/sedEditParser.ts
- builtin-tools/ConfigTool/supportedSettings.ts、FileEditTool/utils.ts
- remote-control-server/store.ts、transport/event-bus.ts、types/messages.ts

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
回退 f69c705 中引入的 ink.tsx self-healing 机制(lastMainScreenHealTime 字段
+ 每 5 秒触发全量重绘 + needsEraseBeforePaint 主屏幕分支)。该机制在 workflow
面板持续刷新场景下表现为可见的"重复刷新",且修复效果不稳定。

alt-screen 的 needsEraseBeforePaint 路径和 prevFrameContaminated 字段保留,
它们仍服务于 handleResize / layout shift / selection 高亮。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
之前几次渲染层修复都失败,因为没动 tab 列表的数据源:打开 /workflows 会
自动 hydrate 最多 20 个历史 done/killed run,全部塞进一行 TabsBar,超出
终端宽度后 Ink 把字符画到屏外造成重影乱码。

- selectors.ts 加 filterActiveRuns(只留 status === 'running')和
  capTabsForDisplay(超额 fold 成 +N)两个 pure function
- WorkflowsPanel 接线 activeRuns:focus clamp、focused、nextTab/prevTab、
  TabsBar 全部基于过滤后的 activeRuns
- TabsBar 复用 truncateLabel 限制每个 tab 名 18 字符 + 最多 6 个 tab,
  多余显示 +N,从结构上钉死单行总宽度

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
ultracode canonical pipeline 脚本常在 agent() 直接传 opts.phase 而不调 phase()
hook,导致 phase_started 从未发出;同时 phase_done 只在下次 phase() 触发,上一
个 phase 在 run.phases 里一直停在 running。mergePhases 之前把 actual 当权威,
于是出现 "Map 8/8 全 done 还显示 running、Find 1/4 running 反而显示 pending"。

改为派生层修复:mergePhases 新增 derivePhaseStatus——actual.status==='done'
权威;否则有 agents 就按 agents 状态推(全 done→done,否则 running);否则看
actual 是否 running。再补一层遍历,让只在 agents 上出现的 phase 也进 sidebar。
不改 store 状态语义,已有 state.json 无需迁移。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
entry.ts 在 ACP 握手期调用的 applySafeConfigEnvironmentVariables 触发了
loadSettingsFromDisk,此时 getOriginalCwd() 还是进程启动 cwd(非项目目录),
导致 localSettings/projectSettings 按错误路径解析为空并被 session cache 锁住,
后续 createSession 里 setOriginalCwd 也无法纠正。在 setOriginalCwd 与 chdir
之后清缓存并重新应用,让 settings.local.json 和项目级 env 对
readSettingsPermissionMode 及下游可见。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR makes two main functional changes — improving the workflow panel to filter/cap run tabs and fix phase-status derivation, and refactoring the ANT session resume flow from ccshare URLs to file-based transcripts — alongside a broad cleanup that removes the ultrareview preflight flow, daemon/SDK primitive exports, runner stubs, and dozens of no-longer-needed exported helpers and test utilities across the codebase.

Changes

Workflow Panel: Active-Run Filtering and Tab Capping

Layer / File(s) Summary
Phase and run-list selectors
src/workflow/panel/selectors.ts
Introduces derivePhaseStatus to compute phase status from grouped agent states (including phases appearing only on agents), replaces the status-from-record approach in mergePhases, and adds filterActiveRuns and capTabsForDisplay exported helpers.
WorkflowsPanel active-run wiring
src/workflow/panel/WorkflowsPanel.tsx
Derives activeRuns from filterActiveRuns(runs), clamps activeRunId to active runs, restricts tab cycling to active runs, and gates TabsBar on activeRuns.length > 1.
TabsBar capping and overflow indicator
src/workflow/panel/TabsBar.tsx
Uses capTabsForDisplay to limit visible tabs, truncates each label, and renders a +N overflow indicator when surplus runs exist.
Selector and panel tests
src/workflow/__tests__/selectors.test.ts
Adds mergePhases regression tests for agent-derived phase status and a full suite for filterActiveRuns/capTabsForDisplay edge cases.

Session Resume, ACP Fix, SDK Pruning, and API Surface Cleanup

Layer / File(s) Summary
ANT session resume: ccshare → file transcript
src/main.tsx
Removes ccshare URL detection/loading; introduces file-based transcript resume via loadTranscriptFromFile with forkSession from options and tengu_session_resumed analytics tagged entrypoint: 'file'.
ACP createSession: settings cache reset after CWD change
src/services/acp/agent/createSessionMethod.ts
Calls resetSettingsCache() then applySafeConfigEnvironmentVariables() after process.chdir(cwd) so downstream settings reads reflect the correct project root.
Ultrareview preflight removal
src/services/api/ultrareviewPreflight.ts, src/commands/review/UltrareviewPreflightDialog.tsx, src/services/api/__tests__/ultrareviewPreflight.test.ts, src/commands/review/__tests__/ultrareviewCommand.test.tsx, src/constants/prompts.ts
Removes the fetchUltrareviewPreflight API, UltrareviewPreflightDialog component, its test file, the associated test mock, and the getFunctionResultClearingSection system-prompt injection.
SDK/daemon public API and runner stub removal
src/entrypoints/agentSdkTypes.ts, src/entrypoints/cli.tsx, src/environment-runner/main.ts, src/self-hosted-runner/main.ts, src/services/goal/goalAudit.ts, src/services/compact/cachedMCConfig.ts, tests/integration/goal-lifecycle.test.ts
Removes daemon primitives (watchScheduledTasks, connectRemoteControl, inbound prompt/remote-control types), environment-runner/self-hosted-runner stubs and CLI fast-path branches, goalAudit.ts, and cachedMCConfig stub; removes corresponding test coverage.
Ink renderer cleanup
packages/@ant/ink/src/core/ink.tsx, packages/@ant/ink/src/core/termio/csi.ts
Removes lastMainScreenHealTime tracking, periodic main-screen self-healing repaint block, and the needsEraseBeforePaint main-screen prepend branch; converts eraseLine() function to ERASE_LINE constant.
MessageQueueManager: deprecated aliases out, new helpers in
src/utils/messageQueueManager.ts, src/utils/attachments.ts
Removes eight deprecated queue-operation aliases; adds getCommandsByMaxPriority and isSlashCommand exported helpers; updates comment to reference canonical hasCommandsInQueue().
MCP code indexing detection API change
src/utils/codeIndexing.ts
Replaces detectCodeIndexingFromMcpTool (parsing mcp__serverName__toolName) with detectCodeIndexingFromMcpServerName (matching directly on the server name string).
File persistence and stream utility simplification
src/utils/filePersistence/filePersistence.ts, src/services/acp/utils.ts, src/remote/sdkMessageAdapter.ts
Removes executeCloudPersistence (BYOC-only routing now), nodeToWebReadable, and replaces getResultText with isSuccessResult predicate.
Broad export surface reduction
src/bootstrap/state.ts, src/utils/Cursor.ts, src/commands/insights.ts, src/services/teamMemorySync/..., packages/builtin-tools/src/..., packages/remote-control-server/src/..., and many more
Removes or unexports dozens of helpers, test utilities, cache-clear functions, and deprecated aliases; adds getSecretLabel and getCachedKeybindingWarnings.
README feature table additions
README.md
Adds three highlighted rows for goal-driven agent execution, Artifacts HTML upload, and Ultracode multi-agent orchestration.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • claude-code-best/claude-code#232: Both PRs touch src/commands/ultraplan.tsx — this PR removes commented-out model/analytics/teleport option stubs, while that PR added/rewired Ultraplan feature gating and prompt-identifier plumbing.
  • claude-code-best/claude-code#1275: Both PRs modify the periodic self-healing logic in packages/@ant/ink/src/core/ink.tsx — this PR removes the behavior entirely, while that PR introduced or expanded it.

Poem

🐇 Hop, hop, snip-snip, what a tidy sprint!
Dead exports swept away, like leaves in the wind.
New tab caps and filters now grace the workflow stage,
Resume from files, not URLs — turning a fresh page.
The daemon is gone, the preflight took flight,
A leaner codebase basks in the morning light. 🌿

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Fixture/flick' is vague and does not clearly convey the primary changes in this extensive changeset, which involves removing numerous deprecated APIs and helpers across multiple modules. Provide a more descriptive title that summarizes the main objective, such as 'Remove deprecated APIs and internal helpers' or 'Cleanup: remove unused exports and test utilities'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fixture/flick

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mintlify

mintlify Bot commented Jun 22, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
ccb-863780bf 🟢 Ready View Preview Jun 22, 2026, 1:38 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/workflow/__tests__/selectors.test.ts (1)

66-208: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Group these new test cases under describe() blocks.

The added cases are top-level test() calls; this file should follow describe() + test() grouping for module-level clarity and
consistency.

As per coding guidelines, **/*.test.ts: “use describe() + test() pattern with English descriptions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workflow/__tests__/selectors.test.ts` around lines 66 - 208, The test
cases added to the file are currently top-level test() calls, but the coding
guidelines require using describe() + test() grouping pattern for module-level
clarity. Organize the tests by grouping related tests under describe() blocks
based on the function they test: wrap the two mergePhases tests in
describe('mergePhases'), the filterAgentsByPhase test in
describe('filterAgentsByPhase'), the tabLabel test in describe('tabLabel'), the
four filterActiveRuns tests in describe('filterActiveRuns'), and the four
capTabsForDisplay tests in describe('capTabsForDisplay'). Move each test() call
inside its corresponding describe() block to maintain consistency with the
file's existing patterns.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main.tsx`:
- Around line 4241-4251: The code at resolvedPath attempts to load every
non-UUID resume value as a transcript file, but if a same-named local file
exists and fails to parse as a transcript, it throws an error at line 4278
instead of falling back to picker/search-term behavior. To fix this, broaden the
error handling in the catch block after loadTranscriptFromFile to catch all
errors, not just ENOENT, so that any parse or validation errors also fall
through to the session-ID handling path instead of propagating up as a hard
failure. This allows non-file-like resume values (like search terms) and
malformed files to gracefully fall back to alternative resolution methods.

In `@src/services/acp/agent/createSessionMethod.ts`:
- Around line 94-103: The applySafeConfigEnvironmentVariables() function call
can throw an error, but it is currently positioned before the try block that
contains the finally clause responsible for restoring process.cwd(). If
applySafeConfigEnvironmentVariables() throws, the finally block will never
execute, leaving the process-global CWD in a mutated state. Move both the
resetSettingsCache() and applySafeConfigEnvironmentVariables() calls inside the
try block so that the finally block is guaranteed to execute and properly
restore the original CWD regardless of whether an exception is thrown.

In `@src/workflow/panel/WorkflowsPanel.tsx`:
- Around line 130-139: The findIndex call in both nextTab and prevTab functions
can return -1 when activeRunId is not found in activeRuns (e.g., due to
transient null/invalid values), which causes incorrect index calculations when
performing the modulo math. In both the nextTab and prevTab functions,
immediately after the findIndex call that assigns to idx, add a guard condition
to normalize idx to 0 if it equals -1, ensuring the modulo arithmetic produces
the correct tab index for cycling regardless of whether the activeRunId is
temporarily invalid.

---

Nitpick comments:
In `@src/workflow/__tests__/selectors.test.ts`:
- Around line 66-208: The test cases added to the file are currently top-level
test() calls, but the coding guidelines require using describe() + test()
grouping pattern for module-level clarity. Organize the tests by grouping
related tests under describe() blocks based on the function they test: wrap the
two mergePhases tests in describe('mergePhases'), the filterAgentsByPhase test
in describe('filterAgentsByPhase'), the tabLabel test in describe('tabLabel'),
the four filterActiveRuns tests in describe('filterActiveRuns'), and the four
capTabsForDisplay tests in describe('capTabsForDisplay'). Move each test() call
inside its corresponding describe() block to maintain consistency with the
file's existing patterns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57dce4d9-b7cb-42d2-bc82-f37a425940a6

📥 Commits

Reviewing files that changed from the base of the PR and between 8db85f1 and 2746cc1.

📒 Files selected for processing (73)
  • README.md
  • packages/@ant/ink/src/core/ink.tsx
  • packages/@ant/ink/src/core/termio/csi.ts
  • packages/acp-link/src/manager/types.ts
  • packages/builtin-tools/src/tools/AgentTool/agentMemory.ts
  • packages/builtin-tools/src/tools/BashTool/bashCommandHelpers.ts
  • packages/builtin-tools/src/tools/BashTool/bashSecurity.ts
  • packages/builtin-tools/src/tools/BashTool/sedEditParser.ts
  • packages/builtin-tools/src/tools/ConfigTool/supportedSettings.ts
  • packages/builtin-tools/src/tools/FileEditTool/utils.ts
  • packages/remote-control-server/src/store.ts
  • packages/remote-control-server/src/transport/event-bus.ts
  • packages/remote-control-server/src/types/messages.ts
  • scripts/probe-local-wiring.ts
  • scripts/probe-subscription-endpoints.ts
  • scripts/smoke-test-commands.ts
  • scripts/verify-autofix-pr.ts
  • src/Tool.ts
  • src/bootstrap/state.ts
  • src/bridge/bridgeStatusUtil.ts
  • src/cli/bg.ts
  • src/commands/insights.ts
  • src/commands/review/UltrareviewPreflightDialog.tsx
  • src/commands/review/__tests__/ultrareviewCommand.test.tsx
  • src/commands/ultraplan.tsx
  • src/components/Onboarding.tsx
  • src/components/TrustDialog/utils.ts
  • src/constants/prompts.ts
  • src/context/stats.tsx
  • src/entrypoints/agentSdkTypes.ts
  • src/entrypoints/cli.tsx
  • src/environment-runner/main.ts
  • src/keybindings/loadUserBindings.ts
  • src/main.tsx
  • src/memdir/paths.ts
  • src/remote/sdkMessageAdapter.ts
  • src/self-hosted-runner/main.ts
  • src/services/acp/agent/createSessionMethod.ts
  • src/services/acp/utils.ts
  • src/services/api/__tests__/ultrareviewPreflight.test.ts
  • src/services/api/errors.ts
  • src/services/api/metricsOptOut.ts
  • src/services/api/ultrareviewPreflight.ts
  • src/services/api/withRetry.ts
  • src/services/claudeAiLimits.ts
  • src/services/compact/cachedMCConfig.ts
  • src/services/goal/goalAudit.ts
  • src/services/internalLogging.ts
  • src/services/lsp/LSPDiagnosticRegistry.ts
  • src/services/lsp/manager.ts
  • src/services/mcp/utils.ts
  • src/services/skillLearning/projectContext.ts
  • src/services/teamMemorySync/secretScanner.ts
  • src/services/teamMemorySync/watcher.ts
  • src/skills/loadSkillsDir.ts
  • src/types/global.d.ts
  • src/types/hooks.ts
  • src/types/textInputTypes.ts
  • src/utils/Cursor.ts
  • src/utils/attachments.ts
  • src/utils/autonomyCommandSpec.ts
  • src/utils/binaryCheck.ts
  • src/utils/ccshareResume.ts
  • src/utils/codeIndexing.ts
  • src/utils/filePersistence/filePersistence.ts
  • src/utils/messageQueueManager.ts
  • src/utils/startupProfiler.ts
  • src/utils/statsCache.ts
  • src/workflow/__tests__/selectors.test.ts
  • src/workflow/panel/TabsBar.tsx
  • src/workflow/panel/WorkflowsPanel.tsx
  • src/workflow/panel/selectors.ts
  • tests/integration/goal-lifecycle.test.ts
💤 Files with no reviewable changes (53)
  • src/self-hosted-runner/main.ts
  • src/environment-runner/main.ts
  • src/types/textInputTypes.ts
  • scripts/verify-autofix-pr.ts
  • src/services/goal/goalAudit.ts
  • scripts/probe-local-wiring.ts
  • src/utils/binaryCheck.ts
  • packages/remote-control-server/src/transport/event-bus.ts
  • src/types/global.d.ts
  • src/services/lsp/manager.ts
  • scripts/smoke-test-commands.ts
  • packages/remote-control-server/src/types/messages.ts
  • src/components/Onboarding.tsx
  • src/skills/loadSkillsDir.ts
  • src/services/api/ultrareviewPreflight.ts
  • src/services/compact/cachedMCConfig.ts
  • src/types/hooks.ts
  • src/utils/ccshareResume.ts
  • src/services/api/tests/ultrareviewPreflight.test.ts
  • src/services/mcp/utils.ts
  • src/services/teamMemorySync/secretScanner.ts
  • scripts/probe-subscription-endpoints.ts
  • src/commands/ultraplan.tsx
  • packages/builtin-tools/src/tools/ConfigTool/supportedSettings.ts
  • src/services/api/metricsOptOut.ts
  • src/context/stats.tsx
  • src/remote/sdkMessageAdapter.ts
  • src/keybindings/loadUserBindings.ts
  • packages/builtin-tools/src/tools/FileEditTool/utils.ts
  • tests/integration/goal-lifecycle.test.ts
  • packages/builtin-tools/src/tools/AgentTool/agentMemory.ts
  • src/commands/review/UltrareviewPreflightDialog.tsx
  • packages/acp-link/src/manager/types.ts
  • src/services/claudeAiLimits.ts
  • packages/@ant/ink/src/core/termio/csi.ts
  • packages/builtin-tools/src/tools/BashTool/sedEditParser.ts
  • src/services/lsp/LSPDiagnosticRegistry.ts
  • src/constants/prompts.ts
  • src/cli/bg.ts
  • src/Tool.ts
  • src/utils/messageQueueManager.ts
  • src/memdir/paths.ts
  • src/utils/codeIndexing.ts
  • packages/builtin-tools/src/tools/BashTool/bashSecurity.ts
  • src/bridge/bridgeStatusUtil.ts
  • src/components/TrustDialog/utils.ts
  • src/bootstrap/state.ts
  • src/services/skillLearning/projectContext.ts
  • packages/remote-control-server/src/store.ts
  • src/entrypoints/agentSdkTypes.ts
  • packages/@ant/ink/src/core/ink.tsx
  • src/services/teamMemorySync/watcher.ts
  • src/entrypoints/cli.tsx

Comment thread src/main.tsx
Comment on lines +4241 to +4251
const resolvedPath = resolve(options.resume);
try {
const resumeStart = performance.now();
let logOption;
try {
const resumeStart = performance.now();
const logOption = await loadCcshare(ccshareId);
const result = await loadConversationForResume(logOption, undefined);
// Attempt to load as a transcript file; ENOENT falls through to session-ID handling
logOption = await loadTranscriptFromFile(resolvedPath);
} catch (error) {
if (!isENOENT(error)) throw error;
// ENOENT: not a file path — fall through to session-ID handling
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid forcing every non-UUID --resume value through transcript-file parsing.

At Line 4241, any non-UUID resume value is treated as a file path first. If a same-named local file exists but is not a transcript, parse errors at Line 4278 cause a hard failure at Line 4284 instead of falling back to picker/search-term behavior.

💡 Suggested fix
-          if (options.resume && typeof options.resume === 'string' && !maybeSessionId) {
-            const resolvedPath = resolve(options.resume);
+          if (options.resume && typeof options.resume === 'string' && !maybeSessionId) {
+            const resumeArg = options.resume.trim();
+            const looksLikeTranscriptPath =
+              /[\\/]/.test(resumeArg) || resumeArg.endsWith('.json') || resumeArg.endsWith('.jsonl');
+            const resolvedPath = resolve(resumeArg);
             try {
               const resumeStart = performance.now();
               let logOption;
-              try {
+              if (looksLikeTranscriptPath) {
+                try {
                 // Attempt to load as a transcript file; ENOENT falls through to session-ID handling
                 logOption = await loadTranscriptFromFile(resolvedPath);
-              } catch (error) {
-                if (!isENOENT(error)) throw error;
-                // ENOENT: not a file path — fall through to session-ID handling
+                } catch (error) {
+                  if (!isENOENT(error)) throw error;
+                  // ENOENT: not a file path — fall through to session-ID handling
+                }
               }
               if (logOption) {

Also applies to: 4278-4286

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main.tsx` around lines 4241 - 4251, The code at resolvedPath attempts to
load every non-UUID resume value as a transcript file, but if a same-named local
file exists and fails to parse as a transcript, it throws an error at line 4278
instead of falling back to picker/search-term behavior. To fix this, broaden the
error handling in the catch block after loadTranscriptFromFile to catch all
errors, not just ENOENT, so that any parse or validation errors also fall
through to the session-ID handling path instead of propagating up as a hard
failure. This allows non-file-like resume values (like search terms) and
malformed files to gracefully fall back to alternative resolution methods.

Comment on lines +94 to +103
// entry.ts calls applySafeConfigEnvironmentVariables() during handshake so the
// API client can authenticate before createSession arrives. At that point
// getOriginalCwd() is still the spawn cwd (not the project dir), so
// loadSettingsFromDisk() resolves localSettings/projectSettings against the
// wrong root and caches the empty result. Now that we've set the real project
// cwd, drop the cache and re-apply so settings.local.json and project env
// become visible to readSettingsPermissionMode() and downstream consumers.
resetSettingsCache()
applySafeConfigEnvironmentVariables()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Move cache/env re-apply inside the try that guarantees CWD restoration.

applySafeConfigEnvironmentVariables() at Line 102 can throw. Because it runs before the Line 104 try, the finally that restores process.cwd() never executes, leaving process-global CWD mutated.

💡 Suggested fix
-  resetSettingsCache()
-  applySafeConfigEnvironmentVariables()
-
-  try {
+  try {
+    resetSettingsCache()
+    applySafeConfigEnvironmentVariables()
     // Build tools with a permissive permission context.
     const permissionContext = getEmptyToolPermissionContext()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// entry.ts calls applySafeConfigEnvironmentVariables() during handshake so the
// API client can authenticate before createSession arrives. At that point
// getOriginalCwd() is still the spawn cwd (not the project dir), so
// loadSettingsFromDisk() resolves localSettings/projectSettings against the
// wrong root and caches the empty result. Now that we've set the real project
// cwd, drop the cache and re-apply so settings.local.json and project env
// become visible to readSettingsPermissionMode() and downstream consumers.
resetSettingsCache()
applySafeConfigEnvironmentVariables()
// entry.ts calls applySafeConfigEnvironmentVariables() during handshake so the
// API client can authenticate before createSession arrives. At that point
// getOriginalCwd() is still the spawn cwd (not the project dir), so
// loadSettingsFromDisk() resolves localSettings/projectSettings against the
// wrong root and caches the empty result. Now that we've set the real project
// cwd, drop the cache and re-apply so settings.local.json and project env
// become visible to readSettingsPermissionMode() and downstream consumers.
try {
resetSettingsCache()
applySafeConfigEnvironmentVariables()
// Build tools with a permissive permission context.
const permissionContext = getEmptyToolPermissionContext()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/acp/agent/createSessionMethod.ts` around lines 94 - 103, The
applySafeConfigEnvironmentVariables() function call can throw an error, but it
is currently positioned before the try block that contains the finally clause
responsible for restoring process.cwd(). If
applySafeConfigEnvironmentVariables() throws, the finally block will never
execute, leaving the process-global CWD in a mutated state. Move both the
resetSettingsCache() and applySafeConfigEnvironmentVariables() calls inside the
try block so that the finally block is guaranteed to execute and properly
restore the original CWD regardless of whether an exception is thrown.

Comment on lines +130 to 139
if (activeRuns.length === 0) return;
const idx = activeRuns.findIndex(r => r.runId === activeRunId);
const next = activeRuns[(idx + 1) % activeRuns.length]!;
switchTab(next.runId);
};
const prevTab = (): void => {
if (runs.length === 0) return;
const idx = runs.findIndex(r => r.runId === activeRunId);
const next = runs[(idx - 1 + runs.length) % runs.length]!;
if (activeRuns.length === 0) return;
const idx = activeRuns.findIndex(r => r.runId === activeRunId);
const next = activeRuns[(idx - 1 + activeRuns.length) % activeRuns.length]!;
switchTab(next.runId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle invalid active-run index before tab cycling.

When findIndex returns -1 (e.g., transient null/invalid activeRunId), prevTab picks an unexpected entry. Normalize the
index before modulo math.

Suggested patch
   const nextTab = (): void => {
     if (activeRuns.length === 0) return;
-    const idx = activeRuns.findIndex(r => r.runId === activeRunId);
-    const next = activeRuns[(idx + 1) % activeRuns.length]!;
+    const idx = activeRuns.findIndex(r => r.runId === activeRunId);
+    const safeIdx = idx >= 0 ? idx : 0;
+    const next = activeRuns[(safeIdx + 1) % activeRuns.length]!;
     switchTab(next.runId);
   };
   const prevTab = (): void => {
     if (activeRuns.length === 0) return;
-    const idx = activeRuns.findIndex(r => r.runId === activeRunId);
-    const next = activeRuns[(idx - 1 + activeRuns.length) % activeRuns.length]!;
+    const idx = activeRuns.findIndex(r => r.runId === activeRunId);
+    const safeIdx = idx >= 0 ? idx : 0;
+    const next = activeRuns[(safeIdx - 1 + activeRuns.length) % activeRuns.length]!;
     switchTab(next.runId);
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (activeRuns.length === 0) return;
const idx = activeRuns.findIndex(r => r.runId === activeRunId);
const next = activeRuns[(idx + 1) % activeRuns.length]!;
switchTab(next.runId);
};
const prevTab = (): void => {
if (runs.length === 0) return;
const idx = runs.findIndex(r => r.runId === activeRunId);
const next = runs[(idx - 1 + runs.length) % runs.length]!;
if (activeRuns.length === 0) return;
const idx = activeRuns.findIndex(r => r.runId === activeRunId);
const next = activeRuns[(idx - 1 + activeRuns.length) % activeRuns.length]!;
switchTab(next.runId);
const nextTab = (): void => {
if (activeRuns.length === 0) return;
const idx = activeRuns.findIndex(r => r.runId === activeRunId);
const safeIdx = idx >= 0 ? idx : 0;
const next = activeRuns[(safeIdx + 1) % activeRuns.length]!;
switchTab(next.runId);
};
const prevTab = (): void => {
if (activeRuns.length === 0) return;
const idx = activeRuns.findIndex(r => r.runId === activeRunId);
const safeIdx = idx >= 0 ? idx : 0;
const next = activeRuns[(safeIdx - 1 + activeRuns.length) % activeRuns.length]!;
switchTab(next.runId);
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workflow/panel/WorkflowsPanel.tsx` around lines 130 - 139, The findIndex
call in both nextTab and prevTab functions can return -1 when activeRunId is not
found in activeRuns (e.g., due to transient null/invalid values), which causes
incorrect index calculations when performing the modulo math. In both the
nextTab and prevTab functions, immediately after the findIndex call that assigns
to idx, add a guard condition to normalize idx to 0 if it equals -1, ensuring
the modulo arithmetic produces the correct tab index for cycling regardless of
whether the activeRunId is temporarily invalid.

@claude-code-best claude-code-best merged commit cd222b8 into main Jun 22, 2026
7 checks passed
@claude-code-best claude-code-best deleted the fixture/flick branch June 25, 2026 01:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant