Conversation
* feat(history): allow selecting history display limit (50-250) Issue #701 - Add HistoryDisplayLimit selector (50/100/150/200/250) to HistoryPane header - Persist selection in localStorage (commandmate:historyDisplayLimit) - Raise messages API upper bound from 100 to MAX_MESSAGES_LIMIT (250) - Centralize options/MAX/DEFAULT in src/config/history-display-config.ts - Propagate selection through WorktreeDetailRefactored (PC + Mobile) - worktreeApi.getMessages: optional limit argument - useInfiniteMessages: default pageSize references DEFAULT_MESSAGES_LIMIT - Tests: boundary (1/250/251/0/abc), DB getMessages limit=250, useInfiniteMessages hasMore at pageSize=250, config Single Source of Truth Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(history-display-config): derive MAX_MESSAGES_LIMIT from union type - Replace brittle `as 250` literal cast with `HistoryDisplayLimit` type derivation so extending HISTORY_DISPLAY_LIMIT_OPTIONS no longer requires touching MAX_MESSAGES_LIMIT. - Tighten comments and adjust wording for clarity. Issue #701 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(claude-md): add history-display-config.ts to module reference (#701) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…line (#704) (#705) Claude Code v2.1.142 renders trailing summary lines like "… +1 pending" below the real options in skill approval prompts ("Use skill ...?"). NORMAL_OPTION_PATTERN was matching these as option N with label="pending", which poisoned isValidPrecedingOption() and caused every real option above (1./2./3.) to be rejected — collectedOptions ended up with length < 2, returning no_prompt. As a result Yes/No UI never appeared and Auto-Yes did not fire. Defense-in-depth fix: - S1: SUMMARY_LINE_PATTERN early-continue in Pass 2 loop (tight anchored pattern, no free `(.+)` capture, keyword whitelist pending|more) so legitimate labels mentioning these words are preserved. - S2: CLAUDE_PROMPT_FOOTER_PATTERN trims effectiveEnd to the "Esc to cancel · Tab to amend" footer, putting the summary line outside the scan window entirely. Fallback-safe: no footer found => effectiveEnd untouched, so Codex/Gemini/OpenCode/Copilot detection paths are unaffected. - S3: 3-layer regression tests across prompt-detector, status-detector, and auto-yes-resolver covering the real Claude v2.1.142 fixture plus FP-suppression for option labels containing "pending"/"more". Quality gates: lint 0/0, tsc 0, unit 6486 passed / 7 skipped, build OK.
- FileTreeView: limit full-screen loading/error to initial mount (rootItems empty) - FileTreeView: add non-destructive refetch indicator (aria-live=polite) and error banner with retry button - FileTreeView: extract reloadTreeWithExpandedDirs via useCallback + mountedRef guard - WorktreeDetailRefactored: skip first-poll false-positive refresh by treating null prevTreeHashRef as baseline-only - tests: add 5 new tests for refetch indicator / non-destructive error / retry path Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…led (#711) (#712) Each `git worktree list` spawns an independent child process, so running them sequentially via `for ... await` made the sync endpoint scale linearly in the number of repositories. Switch to `Promise.allSettled(...map(...))` so all repository scans run concurrently while preserving the prior "one failure does not abort the rest" semantics. Logs continue to include `repoPath` so the (now unordered) output can still be correlated. The unit test mock for `child_process` had to be switched from auto-mock to a factory mock: vitest's auto-mock preserves `util.promisify.custom` from the real `exec`, which made `promisify(exec)` bypass `mockImplementation` entirely. The factory returns a fresh `vi.fn()` without that symbol so callback-style mocking works. Closes #711 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…710) (#713) useWorktreesCache のポーリング間隔(active=5s/idle=30s)が startPolling() 呼び出し時点で固定され、worktrees の active/idle 状態が遷移しても interval が更新されない問題を修正。 - currentIntervalRef: useRef<number | null> を追加し活動中の interval を追跡 - startPolling/stopPolling/hasActiveSession を useCallback でフック直下にリフトアップ - worktrees-change useEffect で desired interval を再計算し差分時のみ startPolling を再実行 - document.hidden 中・初期化前(ref === null)はガードして no-op - 既存の visibilitychange ハンドラの責務は維持 Closes #710 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…) (#714) Sessions ページが useWorktreesCache() を直接呼び出していたため、 WorktreesCacheProvider と合わせて /api/worktrees ポーリングが2系統 並行で動いていた問題を解消。 - WorktreesCacheProvider に WorktreesCacheContext を新設し useWorktreesCacheContext() フックを export - src/app/sessions/page.tsx を Context 経由参照に変更 - useWorktreesCache フック自体は不変 (テスト/単体利用は維持) - 新規テスト tests/unit/components/providers/WorktreesCacheProvider.test.tsx Closes #709 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…708) (#715) chat_messages の相関サブクエリ (role='assistant'/'user' AND archived=0 の MAX(timestamp)/ORDER BY timestamp DESC LIMIT 1) が、既存 idx_messages_archived(worktree_id, archived, timestamp DESC) では role 列を 含まないため行スキャンに陥り、件数増加に伴い線形劣化していた。 Migration v32 で複合インデックス idx_messages_worktree_role_archived_time(worktree_id, role, archived, timestamp DESC) を新設し、既存 idx_messages_archived を DROP。 他の role なしクエリ (getMessages, getLastMessage, deleteAllMessages) は idx_messages_worktree_time(worktree_id, timestamp DESC) で従来同等に動作する。 - src/lib/db/migrations/v32-add-messages-role-composite-index.ts: 新規 - src/lib/db/migrations/index.ts / runner.ts: v32 登録、CURRENT_SCHEMA_VERSION = 32 - src/lib/db/init-db.ts: 初期化パスを新インデックスへ置換 - tests/unit/lib/db-migrations.test.ts: v32 describe ブロック追加、 v22 旧インデックスアサーションを rollback to 31 経由に修正 - tests/unit/lib/db/chat-db-explain-plan.test.ts: EXPLAIN QUERY PLAN で対象4クエリが新インデックスを使うことを検証 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(history): add text search to HistoryPane (#716) Adds a per-pane text search bar to Worktree HistoryPane with namespace-isolated CSS Custom Highlight API rendering so it can coexist with the TerminalPane search (Issue #47). Key design choices (3-stage reviewed): - Preserve OCP: existing applyTerminalHighlights / clearTerminalHighlights signatures unchanged. New applyHistoryHighlights / clearHistoryHighlights share the internal engine via HighlightNamespace. - ConversationPairCard receives no new props; only data-message-id is added so memo is preserved. useConversationHistory is untouched. - HistoryPane manages autoExpandedIds internally to force-expand truncated assistant messages that contain hits, then applies highlights with a strict useLayoutEffect order (save scroll → restore scroll (skipped during search) → autoExpandedIds → applyHistoryHighlights) so textContent stays aligned with message.content. - Debounce (300ms), min-query length (2), and max-matches (500) are shared via newly exported SEARCH_DEBOUNCE_MS / SEARCH_MIN_QUERY_LENGTH / TERMINAL_SEARCH_MAX_MATCHES from useTerminalSearch. Tests: 47 new cases across useHistorySearch, HistorySearchBar, terminal- highlight, and HistoryPane. Full unit suite: 6558 passed / 0 failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(history-search): DRY debounce timer + unify selector escape (#716) Small post-implementation cleanups identified during the refactoring phase. No behavior changes; all 6558 unit tests still pass. useHistorySearch.ts: - Extract clearDebounceTimer() helper (DRY: clearTimeout/null pattern was duplicated across scheduleSearch / closeSearch / onCompositionStart / unmount cleanup). HistoryPane.tsx: - Replace custom escapeAttrValue() with native CSS.escape() via a small findMessageElement() helper. Removes a homemade escape function that duplicated standards-track functionality and unifies the two inconsistent selector-building sites (one used CSS.escape, the other the custom helper). - Capture the current match element during the highlight loop so the scrollIntoView path no longer issues a second querySelector for the same node. Constraints preserved: - terminal-highlight.ts public API untouched (OCP). - ConversationPairCard props unchanged (memo preserved). - Effect declaration order (1)->(2)->(3)->(4) and HISTORY_SEARCH_NAMESPACE isolation unchanged (design policy v1.2 core). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(history): update CLAUDE.md and implementation-history for #716 Add HistoryPane text search feature entry and document new modules: useHistorySearch hook, HistorySearchBar component, terminal-highlight namespace separation (HISTORY_SEARCH_NAMESPACE), and data-message-id attribution in ConversationPairCard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
developブランチをmainへマージするリリースPRです。Issue #701 のマージ(PR #703)以降に develop に積まれた 1機能追加 + 4パフォーマンス改善 + 2不具合修正 をまとめて本番ブランチへ反映します。Included PRs (develop merge order)
Closes
主要変更
Feature
useHistorySearch.ts/HistorySearchBar.tsx新設、terminal-highlight.tsをHISTORY_SEARCH_NAMESPACE/TERMINAL_SEARCH_NAMESPACE抽象化、CSS Custom Highlight API(青/カレントマッチ)でハイライト表示、47テスト追加Performance
chat_messages(worktree_id, archived, role)複合インデックス追加、相関サブクエリ高速化WorktreesCacheProviderContext経由に統一、useWorktreesCacheの重複fetch解消Promise.allSettledでリポジトリスキャン並列化Bug Fix
Test plan
npm run lint/npx tsc --noEmit/npm run test:unit(6558 passed / 7 skipped / 347 files)npm run build成功・本番サーバー(CM_PORT=3000)起動確認(HTTP 200)バージョン
現在:
v0.5.7。本PRはバージョンバンプを含まないため、必要であれば main マージ後に/releaseで次バージョンタグ作成を推奨。🤖 Generated with Claude Code