Commit graph

2357 commits

Author SHA1 Message Date
iliya
7842b5a01f fix(team): clarify teammate first-contact wording 2026-04-07 10:59:39 +03:00
iliya
3b0fe0bcbf fix(team): stop counting inbox noise as check-ins 2026-04-07 10:48:59 +03:00
iliya
a641d263c0 fix(team): route teammate replies back through inbox 2026-04-07 10:34:18 +03:00
iliya
c20fc1a312 feat(team): clarify teammate check-ins and retry state 2026-04-07 10:28:00 +03:00
iliya
cb9eb5f701 refactor(team): drop dead lead bootstrap launch fields 2026-04-07 02:39:39 +03:00
iliya
bc3b6ae4e6 refactor(team): drop dead bootstrap skip-permissions field 2026-04-07 02:36:35 +03:00
iliya
8c136f0a41 refactor(team): drop dead bootstrap prompt field 2026-04-07 02:34:06 +03:00
iliya
31b5c31df8 refactor(team): declare bootstrap permission seeds in app specs 2026-04-07 02:21:46 +03:00
iliya
233e01847c fix(team): harden bootstrap state reads 2026-04-07 02:04:28 +03:00
iliya
ad56f0e337 fix(team): ignore replayed bootstrap progress events 2026-04-07 01:49:37 +03:00
iliya
ac3475d3be fix(team): support runtime bootstrap prompt sanitizing 2026-04-07 01:33:04 +03:00
iliya
0064380160 refactor(team): move bootstrap prompts into runtime 2026-04-07 01:30:38 +03:00
iliya
d4331300c4 fix(team): harden deterministic bootstrap rollout 2026-04-07 01:13:00 +03:00
iliya
d5ee7717e7 feat(team): move launch path to deterministic bootstrap 2026-04-07 01:06:49 +03:00
iliya
c92bf3a6a5 feat(team): improve degraded bootstrap recovery 2026-04-07 00:49:30 +03:00
iliya
d484f1d62d fix(team): surface unreadable bootstrap journal warnings 2026-04-07 00:46:05 +03:00
iliya
8ef89eefce feat(team): add bootstrap recovery and app integration 2026-04-07 00:43:38 +03:00
iliya
d2cd655c11 fix(team): harden provisioning and team UI state 2026-04-06 21:28:22 +03:00
iliya
ae2ccf2386 fix(team): preserve desktop teammate fallback semantics 2026-04-06 15:58:48 +03:00
iliya
5402ddfe97 fix(team): narrow process teammate override 2026-04-06 15:35:01 +03:00
iliya
d549006aaf fix(team): prefer tmux teammates for desktop launches 2026-04-06 15:13:03 +03:00
iliya
cf8df6b306 feat(app): show tmux install guidance on dashboard 2026-04-06 15:02:11 +03:00
iliya
84e0bdb03e fix member messages empty pagination state 2026-04-05 22:13:45 +03:00
iliya
9296ce3988 refine member message pagination 2026-04-05 22:07:09 +03:00
iliya
0531fc1dbf fix worker lifecycle edge cases 2026-04-05 22:03:11 +03:00
iliya
dc0627c285 fix message pagination consumers 2026-04-05 21:54:52 +03:00
Artem Rootman
8570ed13fd
fix: stabilize flaky ChangeExtractorService invalidation test
The test races stale and fresh worker calls to verify that invalidation
prevents stale results from populating the cache. On slow CI, the
fresh worker mock could be reached before the stale deferred was
resolved, causing the version guard to mismatch.

Flush microtasks after starting freshPromise so it advances past
internal awaits and reaches the worker mock before we resolve the
stale deferred.
2026-04-05 18:25:43 +00:00
Artem Rootman
5efc3dd63f
fix: pagination correctness and message enrichment
P1: Poller no longer overwrites nextCursor/hasMore — those belong
to the "Load older" flow. Both poller and loadOlder now dedup
messages by messageId or timestamp+from fingerprint.

P1: Cursor is now compound (timestamp|messageId) with stable
tie-breaking sort. Messages sharing the same timestamp at page
boundaries are no longer lost.

P2: getMessagesPage now applies the same enrichment as getTeamData:
leadSessionId propagation and slash-command-result annotation.

P3: Added 3 tests for getMessagesPage covering pagination, cursor
stability with same-timestamp messages, and slash command annotation.
2026-04-05 18:18:03 +00:00
Artem Rootman
bc7981f6b9
fix: use full intervals content in worker cache key, not just length
Two different interval sets with the same length would produce
the same cache key, returning stale results. Serialize each
interval's startedAt~completedAt into the key.
2026-04-05 18:09:59 +00:00
Artem Rootman
270eb547cb
merge: add paginated messages API into oom-issues branch 2026-04-05 18:07:21 +00:00
Artem Rootman
54198e6598
fix: remove capTimerMap that silently drops pending refreshes
capTimerMap was cancelling oldest pending throttle/debounce timers
when the Map exceeded a size limit. Since the schedulers don't
replay dropped keys, this silently lost refresh callbacks — leaving
session/team state stale after high-volume file change events.

These Maps are self-cleaning (entries delete themselves when their
callback fires) and hold ~100 bytes per entry. Even 200 entries
is negligible memory. Removing the cap fixes the data freshness
issue without any memory concern.
2026-04-05 18:06:31 +00:00
Artem Rootman
7d2282c35c
fix: keep 50 messages in getTeamData for backward compatibility
Returning messages: [] broke the slash command annotation test and
any code relying on getTeamData.messages (notifications, dedup).

Keep a small batch (50 newest) in getTeamData for compatibility.
Full message history is available via getMessagesPage() API.
2026-04-05 17:45:44 +00:00
Artem Rootman
0c0e0240a3
feat: paginated messages API (team:getMessagesPage)
New cursor-based IPC endpoint for the messages timeline panel:
- team:getMessagesPage(teamName, { beforeTimestamp?, limit? })
  returns { messages, nextCursor, hasMore }
- Cursor is timestamp-based — stable under live message insertion
- Default page size 50, max 200

getTeamData no longer includes messages in its response, eliminating
the ~1MB messages payload from every team refresh. Messages are now
fetched independently by MessagesPanel.

MessagesPanel changes:
- Fetches initial page on mount via getMessagesPage API
- Auto-refreshes newest page every 5s when team is alive
- "Load older messages" button for pagination
- Falls back to prop messages if API fails (graceful degradation)
2026-04-05 17:37:26 +00:00
Artem Rootman
a92390dcc6
style: fix import order in ExtensionStoreView
Move useShallow and lucide-react imports above @renderer/* imports
to follow the project import order convention.
2026-04-05 17:36:03 +00:00
Artem Rootman
f07eb914ae
merge: resolve conflicts with main (ExtensionStoreView, InstallButton)
Merged new fields from main (fetchCliStatus, cliStatusLoading,
openDashboard, authMissing, disableReason) into our useShallow
selectors.
2026-04-05 17:19:41 +00:00
iliya
0e1381ce37 test: seed cli status in extensions install tests 2026-04-05 20:16:25 +03:00
Artem Rootman
f2e1d0e944
fix: suppress worker-not-found warnings in test environment
The TeamDataWorkerClient logged console.warn when the worker file
was not found, which is expected during tests (no build output).
The test setup treats unexpected warnings as failures.

Downgrade to logger.debug for the "not found" message and remove
the eager warning from resolveWorkerPath().
2026-04-05 17:10:03 +00:00
Artem Rootman
e81116b85e
fix: apply exact reviewer suggestions for MemberLogsTab
- Move endRefreshing() outside the !cancelled guard in finally block
  so it always runs even when the effect is torn down mid-refresh.
- Only call load() when isTabActive or on first load — prevents
  unnecessary fetches when a hidden tab's effect re-runs.
2026-04-05 17:01:36 +00:00
Artem Rootman
0e83d99e0a
fix: address PR review feedback (6 issues)
Critical:
- findLogsForTask: call worker directly instead of wrapping in
  wrapTeamHandler, so failures propagate to catch and trigger the
  main-thread fallback correctly.
- TeamDataWorkerClient: scope error/exit handlers to the specific
  worker instance to prevent a stale worker's exit event from
  rejecting pending requests on a replacement worker (race condition).

Major:
- TeamDataWorkerClient: validate teamName and taskId before forwarding
  to worker thread (input sanitization).
- team-data-worker: include status, since, and intervals length in
  cache key to prevent stale results after filter changes.
- team-data-worker: move logsInFlight.delete() into .finally() so
  rejected lookups don't poison the in-flight map permanently.
- MemberLogsTab: reset refreshCountRef and refreshing state in effect
  cleanup to prevent the refresh indicator from latching on permanently
  when the effect tears down mid-refresh (e.g. on tab switch).
2026-04-05 16:59:44 +00:00
iliya
9f7cfb04fa merge: sync origin/main into dev 2026-04-05 19:51:26 +03:00
Илия
9477a7b418
Merge pull request #41 from artemrootman/arootman/fix-remove-member
fix: filter out system inboxes from team member list
2026-04-05 19:50:05 +03:00
Artem Rootman
23796cddc3
fix: only filter broadcast inbox (*), keep user inbox
The user inbox (user.json) contains real teammate-to-user messages
generated by Claude Code CLI. Filtering it as a system inbox was
incorrect — it broke message aggregation for user-directed messages.

Only the broadcast inbox (*.json) needs to be excluded since '*'
is not a valid member name and causes a phantom member in the UI.
2026-04-05 16:45:31 +00:00
Artem Rootman
fdc49f475e
fix: filter out system inboxes (*, user) from team member list
The broadcast inbox file (inboxes/*.json) was being parsed by
listInboxNames() as a member named "*", which appeared in the UI
as a phantom team member. Since "*" fails the MEMBER_NAME_PATTERN
validation, it could not be removed through the UI.

Filter system inbox names (*, user) from listInboxNames() so they
are not treated as real team members.
2026-04-05 16:38:09 +00:00
Artem Rootman
da58917032
perf: offload heavy I/O to worker thread, reduce renderer re-renders
Main process — worker thread for team data:
- New team-data-worker thread handles getTeamData and findLogsForTask,
  isolating heavy file I/O (scanning 300+ subagent JSONL files) from
  Electron's main event loop. getTeamData dropped from ~2000ms on the
  main thread to ~110ms via the worker.
- Worker-side dedup and 10s result cache for findLogsForTask prevents
  redundant scans when the same task is queried multiple times.
- Discovery cache TTL raised from 5s to 30s — avoids re-scanning the
  entire project directory on every call.
- Message cap at 200 in TeamDataService to keep IPC payloads under 1MB
  (was sending 2200+ messages / ~3MB, stalling Chromium IPC serialization).
- IPC handlers fall back to main-thread execution if the worker is
  unavailable (graceful degradation).

Renderer — useShallow and memoization (55 files):
- Added useShallow to store selectors across 55 renderer files. Batched
  individual useStore() calls (e.g. 17 calls in ExtensionStoreView,
  10 in ConnectionSection) into single useShallow selectors, cutting
  unnecessary re-render checks on every store update.
- MemberLogsTab: three 5-second polling intervals now pause when the
  parent tab is hidden (display:none). Previously 5 hidden tabs × 3
  intervals = 15 polling timers firing continuously.
- KanbanColumn wrapped in React.memo to skip re-renders when props
  haven't changed.
- MemberList: memoized activeMembers/removedMembers/colorMap; replaced
  O(n×m) per-member task scan with a pre-computed reviewer map.
- Bounded timer Maps in store initialization to prevent unbounded growth
  of debounce/throttle tracking maps during long sessions.
2026-04-05 16:21:05 +00:00
iliya
30fb2501d3 Persist launch-state and duplicate no-op handling 2026-04-05 15:23:41 +03:00
iliya
2959a3d074 Refine launch status and Gemini staging flow 2026-04-05 12:08:13 +03:00
iliya
e9c08c4b6d Stage Gemini team launch hydration 2026-04-04 20:44:33 +03:00
iliya
a591ccf297 Stabilize team provisioning and runtime diagnostics 2026-04-04 20:04:16 +03:00
iliya
074b614469 feat: improve team launch model and status UX 2026-04-02 15:15:32 +03:00
iliya
759cae2669 fix(pricing): include codex and gemini model costs 2026-04-02 10:23:57 +03:00