🔍 Duplicate Code Detected: Devtools message scaffold boilerplate
Analysis of commit 92bb957
Assignee: @copilot
Summary
The devtools-core messaging layer repeats the same message “scaffold” (namespace wrapper, MessageType, MessageData, Message extends IDevtoolsMessage, and createMessage) across many message definition files.
This is a high-frequency, structurally-identical pattern that is a good candidate for extraction into a shared helper (or generation), reducing maintenance overhead and risk of inconsistent tweaks across message types.
Duplication Details
Pattern: MessageType + typed Message + createMessage repeated across message types
-
Severity: Medium
-
Occurrences: 23 files under packages/tools/devtools/devtools-core/src/messaging/** match the full scaffold (MessageType + Message extends IDevtoolsMessage + createMessage).
-
Representative locations (all show the same scaffold structure with only message-specific data/docs varying):
packages/tools/devtools/devtools-core/src/messaging/container-devtools-messages/CloseContainer.ts (lines 9-52)
packages/tools/devtools/devtools-core/src/messaging/container-devtools-messages/ConnectContainer.ts (lines 9-52)
packages/tools/devtools/devtools-core/src/messaging/devtools-messages/ContainerList.ts (lines 9-59)
packages/tools/devtools/devtools-core/src/messaging/telemetry-messages/TelemetryEvent.ts (lines 9-58)
-
Code sample (duplicated scaffold excerpt):
export namespace CloseContainer {
export const MessageType = "CLOSE_CONTAINER";
export type MessageData = HasContainerKey;
export interface Message extends IDevtoolsMessage(MessageData) {
type: typeof MessageType;
}
export function createMessage(data: MessageData): Message {
return {
data,
type: MessageType,
};
}
}
Impact Analysis
- Maintainability: Any future change to the message envelope (e.g., adding common fields, changing creation semantics, updating typing/docs patterns) must be replicated across 20+ files.
- Bug Risk: Small divergences are easy to introduce (e.g., inconsistent typing of
type, different return shape, differing docs/behavior).
- Code Bloat: The scaffold itself is ~20–40 lines per message, contributing a few hundred lines of repetitive code.
Refactoring Recommendations
-
Extract a shared typed helper in the messaging layer
- Suggested location:
packages/tools/devtools/devtools-core/src/messaging/messageUtils.ts (or colocate in Messages.ts if appropriate)
- Example API:
export type TypedDevtoolsMessage(TType extends string, TData) =
IDevtoolsMessage(TData) & { type: TType };
export function createDevtoolsMessage(TType extends string, TData)(
type: TType,
data: TData,
): TypedDevtoolsMessage(TType, TData) {
return { type, data };
}
- Then each message file can reduce to:
export type Message = TypedDevtoolsMessage(typeof MessageType, MessageData)
export const createMessage = (data: MessageData): Message => createDevtoolsMessage(MessageType, data)
- Estimated effort: Medium (mechanical refactor across ~23 files)
- Benefits: Centralized typing + creation logic; reduces duplication substantially.
-
(Optional) Consider code generation for message definitions
- If the project already uses generation elsewhere, a small generator could emit these message files from a declarative list (message type string + data shape reference).
- Estimated effort: Higher; best if many more message types are expected.
Implementation Checklist
Analysis Metadata
- Analyzed Files: 2804 (non-test
.ts/.cjs/.mjs, excluding workflows)
- Detection Method: Serena semantic inspection + structural pattern scan
- Commit: 92bb957
- Analysis Date: 2026-03-14T07:57:22.835Z
AI generated by Duplicate Code Detector
To add this workflow in your repository, run gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4. See usage guide.
🔍 Duplicate Code Detected: Devtools message scaffold boilerplate
Analysis of commit 92bb957
Assignee:
@copilotSummary
The
devtools-coremessaging layer repeats the same message “scaffold” (namespace wrapper,MessageType,MessageData,Message extends IDevtoolsMessage, andcreateMessage) across many message definition files.This is a high-frequency, structurally-identical pattern that is a good candidate for extraction into a shared helper (or generation), reducing maintenance overhead and risk of inconsistent tweaks across message types.
Duplication Details
Pattern:
MessageType+ typedMessage+createMessagerepeated across message typesSeverity: Medium
Occurrences: 23 files under
packages/tools/devtools/devtools-core/src/messaging/**match the full scaffold (MessageType+Message extends IDevtoolsMessage+createMessage).Representative locations (all show the same scaffold structure with only message-specific data/docs varying):
packages/tools/devtools/devtools-core/src/messaging/container-devtools-messages/CloseContainer.ts(lines 9-52)packages/tools/devtools/devtools-core/src/messaging/container-devtools-messages/ConnectContainer.ts(lines 9-52)packages/tools/devtools/devtools-core/src/messaging/devtools-messages/ContainerList.ts(lines 9-59)packages/tools/devtools/devtools-core/src/messaging/telemetry-messages/TelemetryEvent.ts(lines 9-58)Code sample (duplicated scaffold excerpt):
Impact Analysis
type, different return shape, differing docs/behavior).Refactoring Recommendations
Extract a shared typed helper in the messaging layer
packages/tools/devtools/devtools-core/src/messaging/messageUtils.ts(or colocate inMessages.tsif appropriate)export type Message = TypedDevtoolsMessage(typeof MessageType, MessageData)export const createMessage = (data: MessageData): Message => createDevtoolsMessage(MessageType, data)(Optional) Consider code generation for message definitions
Implementation Checklist
Analysis Metadata
.ts/.cjs/.mjs, excluding workflows)