From 79a954c16e67af0bccfe9c29c59b558cccc6288f Mon Sep 17 00:00:00 2001 From: Marty Martin Date: Mon, 17 Nov 2025 16:56:59 -0500 Subject: [PATCH] Add Claude Code Session ID widget (#111) * feat: Add Claude Session ID widget * Add ClaudeSessionIdWidget to widget registry, add label, support raw mode, fix cross-platform issues by using session ID directly from statusline JSON --------- Co-authored-by: Marty Co-authored-by: Matthew Breedlove --- src/utils/widgets.ts | 5 +++-- src/widgets/ClaudeSessionId.ts | 31 +++++++++++++++++++++++++++++++ src/widgets/index.ts | 3 ++- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 src/widgets/ClaudeSessionId.ts diff --git a/src/utils/widgets.ts b/src/utils/widgets.ts index cff713d..fc98f47 100644 --- a/src/utils/widgets.ts +++ b/src/utils/widgets.ts @@ -26,7 +26,8 @@ const widgetRegistry = new Map([ ['terminal-width', new widgets.TerminalWidthWidget()], ['version', new widgets.VersionWidget()], ['custom-text', new widgets.CustomTextWidget()], - ['custom-command', new widgets.CustomCommandWidget()] + ['custom-command', new widgets.CustomCommandWidget()], + ['claude-session-id', new widgets.ClaudeSessionIdWidget()] ]); export function getWidget(type: WidgetItemType): Widget | null { @@ -51,4 +52,4 @@ export function isKnownWidgetType(type: string): boolean { return widgetRegistry.has(type) || type === 'separator' || type === 'flex-separator'; -} \ No newline at end of file +} diff --git a/src/widgets/ClaudeSessionId.ts b/src/widgets/ClaudeSessionId.ts new file mode 100644 index 0000000..193201f --- /dev/null +++ b/src/widgets/ClaudeSessionId.ts @@ -0,0 +1,31 @@ +import type { RenderContext } from '../types/RenderContext'; +import type { Settings } from '../types/Settings'; +import type { + Widget, + WidgetEditorDisplay, + WidgetItem +} from '../types/Widget'; + +export class ClaudeSessionIdWidget implements Widget { + getDefaultColor(): string { return 'cyan'; } + getDescription(): string { return 'Shows the current Claude Code session ID reported in status JSON'; } + getDisplayName(): string { return 'Claude Session ID'; } + getEditorDisplay(item: WidgetItem): WidgetEditorDisplay { + return { displayText: this.getDisplayName() }; + } + + render(item: WidgetItem, context: RenderContext, settings: Settings): string | null { + if (context.isPreview) { + return item.rawValue ? 'preview-session-id' : 'Session ID: preview-session-id'; + } else { + const sessionId = context.data?.session_id; + if (!sessionId) { + return null; + } + return item.rawValue ? sessionId : `Session ID: ${sessionId}`; + } + } + + supportsRawValue(): boolean { return true; } + supportsColors(item: WidgetItem): boolean { return true; } +} diff --git a/src/widgets/index.ts b/src/widgets/index.ts index fda3e31..faaa705 100644 --- a/src/widgets/index.ts +++ b/src/widgets/index.ts @@ -17,4 +17,5 @@ export { VersionWidget } from './Version'; export { CustomTextWidget } from './CustomText'; export { CustomCommandWidget } from './CustomCommand'; export { BlockTimerWidget } from './BlockTimer'; -export { CurrentWorkingDirWidget } from './CurrentWorkingDir'; \ No newline at end of file +export { CurrentWorkingDirWidget } from './CurrentWorkingDir'; +export { ClaudeSessionIdWidget } from './ClaudeSessionId'; \ No newline at end of file