[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
72
domain/chatJumpNav.ts
Normal file
72
domain/chatJumpNav.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Pure helpers for AI chat in-session jump navigation (user-turn TOC).
|
||||
*/
|
||||
|
||||
export const CHAT_JUMP_MIN_ENTRIES = 3;
|
||||
export const CHAT_JUMP_LABEL_MAX = 36;
|
||||
|
||||
export type ChatJumpMessage = {
|
||||
id: string;
|
||||
role: string;
|
||||
content?: string;
|
||||
};
|
||||
|
||||
export type ChatJumpEntry = {
|
||||
messageId: string;
|
||||
label: string;
|
||||
/** 1-based index among user turns */
|
||||
index: number;
|
||||
};
|
||||
|
||||
export function chatMessageDomId(messageId: string): string {
|
||||
return `ai-chat-msg-${messageId}`;
|
||||
}
|
||||
|
||||
export function truncateChatJumpLabel(text: string, maxLen = CHAT_JUMP_LABEL_MAX): string {
|
||||
const normalized = text.replace(/\s+/g, ' ').trim();
|
||||
if (!normalized) return '';
|
||||
if (normalized.length <= maxLen) return normalized;
|
||||
const ellipsis = '...';
|
||||
return `${normalized.slice(0, Math.max(1, maxLen - ellipsis.length)).trimEnd()}${ellipsis}`;
|
||||
}
|
||||
|
||||
export function buildChatJumpEntries(
|
||||
messages: ReadonlyArray<ChatJumpMessage>,
|
||||
options?: {
|
||||
minEntries?: number;
|
||||
maxLabelLen?: number;
|
||||
emptyLabel?: string;
|
||||
},
|
||||
): ChatJumpEntry[] {
|
||||
const minEntries = options?.minEntries ?? CHAT_JUMP_MIN_ENTRIES;
|
||||
const maxLabelLen = options?.maxLabelLen ?? CHAT_JUMP_LABEL_MAX;
|
||||
const emptyLabel = options?.emptyLabel ?? '...';
|
||||
const entries: ChatJumpEntry[] = [];
|
||||
for (const message of messages) {
|
||||
if (message.role !== 'user') continue;
|
||||
const label = truncateChatJumpLabel(message.content ?? '', maxLabelLen) || emptyLabel;
|
||||
entries.push({
|
||||
messageId: message.id,
|
||||
label,
|
||||
index: entries.length + 1,
|
||||
});
|
||||
}
|
||||
return entries.length >= minEntries ? entries : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the rendered tail window so a jump target is mounted in the DOM.
|
||||
* Call again whenever the message list grows while the jump target remains
|
||||
* active; a one-shot expand at jump time is not enough if the tail is
|
||||
* `slice(-count)` and later appends would otherwise slide the window forward.
|
||||
*/
|
||||
export function resolveTailCountForJumpTarget(
|
||||
visibleMessages: ReadonlyArray<{ id: string }>,
|
||||
targetMessageId: string,
|
||||
currentTailCount: number,
|
||||
): number {
|
||||
const targetIndex = visibleMessages.findIndex((message) => message.id === targetMessageId);
|
||||
if (targetIndex < 0) return currentTailCount;
|
||||
const requiredTail = visibleMessages.length - targetIndex;
|
||||
return Math.max(currentTailCount, requiredTail);
|
||||
}
|
||||
Reference in New Issue
Block a user