Skip to content

fix: eliminate 8 as any in MCP handlers, structured output, and stream events+Claude Soul Document 蒸馏#1258

Merged
claude-code-best merged 7 commits into
claude-code-best:mainfrom
GhostDragon124:main
Jun 7, 2026
Merged

fix: eliminate 8 as any in MCP handlers, structured output, and stream events+Claude Soul Document 蒸馏#1258
claude-code-best merged 7 commits into
claude-code-best:mainfrom
GhostDragon124:main

Conversation

@GhostDragon124
Copy link
Copy Markdown
Contributor

@GhostDragon124 GhostDragon124 commented Jun 7, 2026

feat: as-any 类型修复 + 模式人格注入(Claude Soul Document 蒸馏)

  • Group A: Add : () => AnyObjectSchema type annotations to MCP notification
    schema constants (useIdeSelection, useIdeLogging, usePrompts, channelNotification)
  • Group B: Add isStructuredOutputAttachmentMessage type guard for structured
    output attachment payloads (execAgentHook)
  • Group C: Add isMessageDeltaStreamEvent type guard for message_delta
    stream event usage extraction (forkedAgent)

These as any casts also exist in the upstream CCB source — this fix provides
real type safety without changing any runtime behavior.

Summary by CodeRabbit

  • New Features

    • Added a Claude persona and injected mode-specific persona text into generated system prompts.
  • Refactor

    • Improved internal type safety and validation across notifications and message processing for increased robustness; no user-facing behavior changes.

…m events

- Group A: Add : () => AnyObjectSchema type annotations to MCP notification
  schema constants (useIdeSelection, useIdeLogging, usePrompts, channelNotification)
- Group B: Add isStructuredOutputAttachmentMessage type guard for structured
  output attachment payloads (execAgentHook)
- Group C: Add isMessageDeltaStreamEvent type guard for message_delta
  stream event usage extraction (forkedAgent)

These as any casts also exist in the upstream CCB source — this fix provides
real type safety without changing any runtime behavior.
fix: 消除 8 个 as any — MCP 通知、结构化输出、流事件的类型安全修复
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 7, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b37590b3-4c7b-4aa3-9db9-340c69afc72b

📥 Commits

Reviewing files that changed from the base of the PR and between 090cc58 and e084d92.

📒 Files selected for processing (2)
  • src/constants/prompts.ts
  • src/modes/personas/claude.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/modes/personas/claude.ts
  • src/constants/prompts.ts

📝 Walkthrough

Walkthrough

Remove unsafe as any casts by typing notification schema factories as AnyObjectSchema, pass typed schemas to MCP handler registration, add type guards for streamed message deltas and structured-output attachments, and wire a mode-specific persona into system prompts with a new CLAUDE_PERSONA constant.

Changes

Type Safety Improvements for Notifications and Stream Events

Layer / File(s) Summary
Notification schema type definitions
src/services/mcp/channelNotification.ts, src/hooks/useIdeLogging.ts, src/hooks/useIdeSelection.ts, src/hooks/usePromptsFromClaudeInChrome.tsx
Schema factories are now explicitly typed as (): AnyObjectSchema via lazySchema, making notification schemas strongly typed.
Notification handler registration without type casts
src/entrypoints/cli.tsx, src/hooks/useIdeLogging.ts, src/hooks/useIdeSelection.ts, src/hooks/usePromptsFromClaudeInChrome.tsx
MCP notification handlers now receive typed schema instances directly (e.g., LogEventSchema()), removing previous as any casts.
Stream event delta detection type guard
src/utils/forkedAgent.ts
Adds StreamEventMessage type and isMessageDeltaStreamEvent guard; usage accumulation now reads message.event.usage only when guarded.
Structured output attachment detection type guard
src/utils/hooks/execAgentHook.ts
Introduces QueryMessage/StructuredOutputAttachmentMessage types and isStructuredOutputAttachmentMessage guard used in the agent message loop before schema parsing.
Mode persona wiring and new persona
src/constants/prompts.ts, src/modes/personas/claude.ts
Adds getModePersonaSection() and injects mode_persona into getSystemPrompt; adds CLAUDE_PERSONA constant with Claude persona text.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • KonghaYao
  • claude-code-best

Poem

🐰 I hopped through types with gentle paws,
I nudged the any away because—claws?
Guards now watch streams and prompts in line,
Schemas tidy, signals align—
Carrots for CI, a hop and a twine!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% 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 addresses the main objective of removing as any casts and adding type guards, but includes unclear elements like the Chinese character 蒸馏 and the phrase 'Claude Soul Document' which obscure the primary technical change. Simplify the title to focus on the primary change: 'fix: eliminate as any casts in MCP handlers and stream event type guards' or similar, removing cryptic elements that don't clarify the changeset.
✅ 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 unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/utils/forkedAgent.ts (1)

505-515: ⚡ Quick win

Simplify type guard to avoid repeated internal casts.

The guard repeatedly casts to StreamEventMessage (lines 510, 511, 512, 513). Refactor using progressive narrowing with the in operator and const extraction to avoid type assertions within the guard body.

♻️ Cleaner implementation without internal casts
 function isMessageDeltaStreamEvent(
   message: Message | StreamEvent,
 ): message is StreamEventMessage & { event: BetaRawMessageDeltaEvent } {
-  return (
-    message.type === 'stream_event' &&
-    typeof (message as StreamEventMessage).event === 'object' &&
-    (message as StreamEventMessage).event !== null &&
-    'type' in (message as StreamEventMessage).event &&
-    (message as StreamEventMessage).event.type === 'message_delta'
-  )
+  if (message.type !== 'stream_event') return false
+  if (!('event' in message)) return false
+  const event = message.event
+  if (typeof event !== 'object' || event === null) return false
+  if (!('type' in event)) return false
+  return event.type === 'message_delta'
 }
🤖 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/utils/forkedAgent.ts` around lines 505 - 515, The type guard
isMessageDeltaStreamEvent currently repeats casts to StreamEventMessage;
refactor it to progressively narrow the union by first checking message.type ===
'stream_event', then using the `in` operator to assert the presence of 'event'
and extract it into a const (e.g., const event = (message as any).event) to
perform the remaining checks (typeof event === 'object' && event !== null &&
'type' in event && event.type === 'message_delta'), eliminating repeated
(message as StreamEventMessage) casts and keeping the function signature and
return type unchanged.
src/utils/hooks/execAgentHook.ts (1)

49-54: 💤 Low value

Consider using in operator to avoid cast.

Line 53 casts to Message to access the attachment property. After checking message.type === 'attachment' at line 52, you can use the in operator to narrow without casting.

♻️ Alternative without cast
 function isStructuredOutputAttachmentMessage(
   message: QueryMessage,
 ): message is StructuredOutputAttachmentMessage {
   if (message.type !== 'attachment') return false
-  return (message as Message).attachment?.type === 'structured_output'
+  if (!('attachment' in message)) return false
+  return message.attachment?.type === 'structured_output'
 }
🤖 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/utils/hooks/execAgentHook.ts` around lines 49 - 54, The type-guard
isStructuredOutputAttachmentMessage currently casts message to Message to read
attachment; replace the cast with an 'in' property check to let TypeScript
narrow the union: after confirming message.type === 'attachment', test
"'attachment' in message" and then check message.attachment?.type ===
'structured_output' so no (message as Message) cast is needed; update the
isStructuredOutputAttachmentMessage function accordingly referencing
QueryMessage, StructuredOutputAttachmentMessage and the attachment property.
🤖 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.

Nitpick comments:
In `@src/utils/forkedAgent.ts`:
- Around line 505-515: The type guard isMessageDeltaStreamEvent currently
repeats casts to StreamEventMessage; refactor it to progressively narrow the
union by first checking message.type === 'stream_event', then using the `in`
operator to assert the presence of 'event' and extract it into a const (e.g.,
const event = (message as any).event) to perform the remaining checks (typeof
event === 'object' && event !== null && 'type' in event && event.type ===
'message_delta'), eliminating repeated (message as StreamEventMessage) casts and
keeping the function signature and return type unchanged.

In `@src/utils/hooks/execAgentHook.ts`:
- Around line 49-54: The type-guard isStructuredOutputAttachmentMessage
currently casts message to Message to read attachment; replace the cast with an
'in' property check to let TypeScript narrow the union: after confirming
message.type === 'attachment', test "'attachment' in message" and then check
message.attachment?.type === 'structured_output' so no (message as Message) cast
is needed; update the isStructuredOutputAttachmentMessage function accordingly
referencing QueryMessage, StructuredOutputAttachmentMessage and the attachment
property.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6cb8c686-574a-4fe4-8eb3-238278464965

📥 Commits

Reviewing files that changed from the base of the PR and between a972ed7 and faa03d3.

📒 Files selected for processing (7)
  • src/entrypoints/cli.tsx
  • src/hooks/useIdeLogging.ts
  • src/hooks/useIdeSelection.ts
  • src/hooks/usePromptsFromClaudeInChrome.tsx
  • src/services/mcp/channelNotification.ts
  • src/utils/forkedAgent.ts
  • src/utils/hooks/execAgentHook.ts

…to system prompt

- prompts.ts: add getModePersonaSection() → injects current mode's
  systemPrompt as 'mode_persona' dynamic section (first in order,
  before operational instructions). Previously modes had systemPrompt
  fields but they were never sent to the model.
- modes/personas/claude.ts: 3KB distilled Claude persona from
  Anthropic's leaked Claude 4.5 Opus Soul Document (70KB → operational
  extract): core traits, 7 honesty principles, helpfulness/caution
  balance, collaboration stance, identity stability.
- With custom mode YAML (~/.claude/modes/claude.yaml), 7 modes total
  including the new Claude persona — fully operational at /mode claude.

Co-Authored-By: James Feng <47167674+GhostDragon124@users.noreply.github.com>
feat: wire mode persona injection — Claude Soul Document distilled into system prompt
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/constants/prompts.ts`:
- Line 66: Replace the relative import of getCurrentMode with the project alias
pattern: change the import that currently reads from '../modes/store.js' to use
the src/* alias (e.g. import { getCurrentMode } from 'src/modes/store') so it
matches the other imports in this file and project conventions; keep the
imported symbol name getCurrentMode unchanged and drop the .js extension if
other imports omit it.

In `@src/modes/personas/claude.ts`:
- Around line 1-8: Update the JSDoc at the top of src/modes/personas/claude.ts
(the Claude persona comment) to remove or clarify the word "leaked": either
state the source as "publicly available" or "inspired by public descriptions" if
not from an unauthorized disclosure, or explicitly note that the document was
obtained and reviewed for confidentiality/IP compliance if it truly derives from
a leak; include a short provenance line indicating whether legal/IP review was
completed and who approved it (or a note that it was not used for legal reasons)
so readers are not left with an implication of unauthorized disclosure.
🪄 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: 68f41393-f0b4-4983-b464-d76832e84da7

📥 Commits

Reviewing files that changed from the base of the PR and between faa03d3 and 8b758ee.

📒 Files selected for processing (2)
  • src/constants/prompts.ts
  • src/modes/personas/claude.ts

Comment thread src/constants/prompts.ts Outdated
Comment thread src/modes/personas/claude.ts
@GhostDragon124 GhostDragon124 changed the title fix: eliminate 8 as any in MCP handlers, structured output, and stream events fix: eliminate 8 as any in MCP handlers, structured output, and stream events+Claude Soul Document 蒸馏 Jun 7, 2026
@GhostDragon124
Copy link
Copy Markdown
Contributor Author

两个问题都修了:

问题 修复
Import 路径不规范 '../modes/store.js''src/modes/store.js'
"leaked" 措辞 "publicly available reference document"

- prompts.ts: use 'src/modes/store.js' alias instead of relative '../modes/store.js'
  to match the file's existing import convention
- claude.ts: reword JSDoc to say 'based on publicly available reference document'
  instead of 'leaked', addressing CodeRabbit review concern
…mplate for YAML config

CodeRabbit noted that CLAUDE_PERSONA has no direct imports. This is
intentional — it's a reference template for users defining custom modes
via ~/.claude/modes/claude.yaml, not a programmatically imported constant.
@claude-code-best
Copy link
Copy Markdown
Owner

@GhostDragon124 你的几个分支冲突了,解决一下合并为一个 pr 吧

@GhostDragon124
Copy link
Copy Markdown
Contributor Author

@GhostDragon124 你的几个分支冲突了,解决一下合并为一个 pr 吧

已解决冲突,ccb大佬

@claude-code-best claude-code-best merged commit 1faedff into claude-code-best:main Jun 7, 2026
2 checks passed
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.

2 participants