Skip to content

Feat/copilot mentions translations#154

Closed
agualdron wants to merge 14 commits into
mainfrom
feat/copilot_mentions_translations
Closed

Feat/copilot mentions translations#154
agualdron wants to merge 14 commits into
mainfrom
feat/copilot_mentions_translations

Conversation

@agualdron

Copy link
Copy Markdown
Collaborator

Summary

Localizes the Copilot mention menu and mention search flow across the apps/tradinggoose workspace. This centralizes mention copy, replaces display-string-based mention option keys with stable internal ids, makes submenu and aggregated search match localized labels and fallback names, and reloads block/workflow-block mention sources when the locale changes. It also adds focused Vitest coverage for localized rendering, filtering, and keyboard selection behavior.

Why

Non-English locales could still show hardcoded English mention labels and empty states, localized queries did not reliably match mention items, and block-based mention labels could become stale after switching locale. This change makes mention discovery and selection behave consistently in translated workspaces.

Type of Changes

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: i18n copy updates and targeted test coverage

Affected Areas

  • apps/tradinggoose
  • apps/docs
  • packages/*
  • Workflows / execution
  • Realtime / sockets
  • Market data / charting
  • Dev tooling / CI / infra
  • Documentation only
  • Other: Copilot mention menu / localization

Validation

bunx biome check apps/tradinggoose/widgets/widgets/copilot/components/user-input/components/mention-menu.tsx apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.ts apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.ts apps/tradinggoose/widgets/widgets/copilot/components/user-input/mention-copy.ts apps/tradinggoose/widgets/widgets/copilot/components/user-input/mention-utils.ts apps/tradinggoose/widgets/widgets/copilot/components/user-input/types.ts apps/tradinggoose/widgets/widgets/copilot/components/user-input/workspace-entity-mentions.ts apps/tradinggoose/widgets/widgets/copilot/workspace-entities.ts apps/tradinggoose/i18n/messages/en.json apps/tradinggoose/i18n/messages/es.json apps/tradinggoose/i18n/messages/zh.json apps/tradinggoose/widgets/widgets/copilot/components/user-input/mention-utils.test.ts apps/tradinggoose/widgets/widgets/copilot/components/user-input/components/mention-menu.test.tsx apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.test.tsx apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.test.tsx
# passed: Checked 15 files in 104ms. No fixes applied.

bun run test -- ./widgets/widgets/copilot/components/user-input/mention-utils.test.ts ./widgets/widgets/copilot/components/user-input/components/mention-menu.test.tsx ./widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.test.tsx ./widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.test.tsx
# run from apps/tradinggoose
# passed: 4 files, 21 tests

Reviewer Focus

  • Verify localized mention labels, submenu titles, empty states, and inserted mention labels in non-English locales.
  • Verify aggregated and submenu search with localized text, accent-insensitive Spanish queries, and localized log trigger labels.
  • Verify locale-switch behavior for block and workflow-block mention sources while the mention menu remains open.

Risk / Rollout Notes

Low risk and scoped to client-side Copilot mention UX plus locale message files. The main regression surface is mention filtering and selection when switching locales mid-session; no backend, schema, or rollout changes are required.

Config / Data Changes

  • Env vars added or changed: None
  • Database schema or migration impact: None
  • External services or provider behavior changed: None

Screenshots / Video

Not included in this draft.

Checklist

  • I kept the change focused and reviewed my own diff
  • I validated the change locally and documented the results above
  • I updated docs, examples, or copy if behavior/user-facing flows changed
  • I called out any env, schema, provider, or rollout impact
  • I did not include secrets, tokens, or private credentials in this PR

BWJ2310-backup and others added 14 commits June 11, 2026 17:35
…edits (#141)

* fix(copilot): update context usage handling and remove unnecessary billing logic

* feat(copilot): record local completion usage

Add local completion usage flushing for chat and mark-complete flows, with retryable reservation locks for the local billing path.\n\nCo-authored-by: Codex <codex@openai.com>

* feat(copilot): switch workflow edits to graph-only mermaid

Rewrite edit_workflow to accept minimal Mermaid graphs, add removedBlockIds for intentional deletions, and update the matching manifest and error mapping.\n\nCo-authored-by: Codex <codex@openai.com>

* fix(copilot): refactor tool approval logic and update related tests

* fix(copilot): remove local completion billing logic and update context usage handling

* fix(copilot): remove color field from indicator and workflow schemas, update related documentation

* fix(copilot): update copilot usage handling and improve test coverage for malformed completion commits

* fix(copilot): introduce workflow graph document format and update related handling in tools and tests

* fix(copilot): enhance edit_workflow tool with semantic validators and improve error handling for workflow graphs

* fix(copilot): update editWorkflowServerTool tests to reflect changes in block naming and metadata handling

* fix(copilot): enhance editWorkflowServerTool with block position preservation and validation for internal fields in graph-only edits

* fix(copilot): update inline tool call tests and logic for review controls and entity diffs; enhance workflow graph parsing with condition edge validation

* fix(copilot): improve subgraph node handling in parseVisibleWorkflowEdges; enhance error reporting for unknown edge references

* fix(copilot): remove unused color properties from entity types and update related tests; enhance workflow edge parsing logic

* fix(copilot): update edit_workflow description for clarity on block deletion; adjust error message for block type validation; modify default horizontal handle behavior in preview node

* fix(copilot): remove color property from indicators and workflows; update related logic and tests for consistency

* fix(copilot): remove color property from indicators and workflows; update related logic and tests for consistency

* feat(import-export): bump TradingGoose export envelope to v2

Update the unified export envelope version and align import/export tests and types with the new version.\n\nCo-authored-by: Codex <codex@openai.com>

* feat(copilot): clarify workflow edit topology semantics

Tighten edit_workflow guidance and errors so block ids are treated as stable identities, and preserve overlay metadata when parsing graph-only workflow Mermaid.\n\nCo-authored-by: Codex <codex@openai.com>

* fix(copilot): update workflow document formats and descriptions; adjust tests for consistency

* fix(copilot): enhance workflow validation and update document format references

* fix(import-export): update export version from 2 to 1 across various modules

* fix(export): update export version from 2 to 1 in various components

* fix(copilot): enhance workflow documentation and validation; update tests for consistency

* fix(copilot): implement billing completion usage reporting and update related tests

* fix(copilot): enhance completion usage reporting with validation for invalid reports and billing failures

* fix(import-export): update tests to ignore generated fields in transfer records and remove strict validation

* fix(copilot): refine workflow graph handling and improve Mermaid documentation clarity

* fix(copilot): improve error handling in completion usage reporting and update related tests

* fix(copilot): rename commitLocalCopilotCompletionUsageReports to mirrorLocalCopilotCompletionUsageReports and update related usages and tests

* fix(copilot): consolidate usage reservation commits

Replace the deprecated adjust path with a commit wrapper that reserves and releases Copilot usage around billing operations, and pass workspace context through the store.

Co-authored-by: Codex <codex@openai.com>

* fix(workflows): allow condition source handles

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

* docs(changelog): add June 11 2026 branch summary

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

* refactor(copilot): extract completion billing helpers

Move completion billing and mirror logic into a shared lib module used by copilot routes.\n\nCo-authored-by: Codex <codex@openai.com>

* fix(copilot): forward workspace id in context usage

Pass workspaceId through the copilot usage context flow so workspace-bounded requests keep their billing context.\n\nCo-authored-by: Codex <codex@openai.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
…142)

* feat(workflow): resolve editor trigger input from session snapshot

Co-authored-by: Codex <codex@openai.com>

* fix(workflows): preserve input trigger snapshot values

Co-authored-by: Codex <codex@openai.com>

* fix(workflow): stabilize workflow test execution

Keep test-input writes on a dedicated origin, prefer connected runnable triggers, and block run until the session is ready.\n\nCo-authored-by: Codex <codex@openai.com>

* fix(workflows): preserve queued trigger types

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): require live start block for queued webhook and schedule runs

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): remove test-input Yjs special case

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflow): block chat-only workflows from editor run

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(workflow): run selected trigger blocks

Propagate the selected workflow node into manual execution and resolve editor test runs against the selected trigger block when available.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(workflow): derive run target from awareness

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): select trigger branch for editor Run

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(workflows): preserve trigger source in queued executions

Propagate trigger metadata from editor test runs through the queue client and API so queued executions keep the correct trigger identity.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): resolve queued trigger identity from workflow state

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(workflows): simplify trigger helpers

Remove redundant trigger helper exports and inline the same logic in the existing selection helpers.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): reject chat triggers in editor runs

Prevent editor Run from selecting chat triggers and preserve the fallback selection flow for the remaining trigger branches.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(workflows): add coverage for editor trigger resolution

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): relax manual queue trigger matching

Allow manual queue runs to match non-chat start blocks while preserving exact matching for non-manual triggers.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(yjs): cover shared workflow session bootstrap loading

Add coverage for the loading window before a shared workflow session publishes a readable document, and factor repeated bootstrap fixture setup into a helper.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): use editor test trigger for client workflow execution

Co-authored-by: Codex <codex@openai.com>\nCo-authored-by: BWJ2310 <brucewj2310@gmail.com>\nCo-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(workflow): unify workflow trigger resolution

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflow): preserve trigger identity and live run input

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(workflows): rename workflow start target to trigger target

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): align trigger selection with trigger-mode blocks

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(workflows): require explicit trigger blocks for workflow runs

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): align run_workflow trigger handling

Require exact trigger block ids, remove the legacy start alias, and resolve copilot runs to manual unless the trigger is chat.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* style(workflows): reorder accessible reference imports

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): handle missing trigger blocks consistently

Disable schedules and webhooks when their trigger block is missing, tighten schedule creation validation, and keep editor trigger resolution aligned with manual editor runs.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(workflow): centralize executable workflow data

Consolidate executable block and edge filtering into a shared helper, then reuse it across workflow execution paths and tests.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): preserve resolved trigger input for copilot runs

Keep explicit copilot workflow input intact when resolving manual runs, and pass the resolved input into queued execution.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(schedules): delete orphaned schedule rows

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(resolver): clarify trigger block alias expectation

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
* feat(i18n): canonicalize locale-prefixed routing

Move locale negotiation into the proxy, resolve authenticated locale from user settings, update locale-aware navigation/tests, and remove obsolete telemetry instrumentation scaffolding.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(nav): support authenticated public navigation

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(workflow): allow editor run to select trigger variants

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflow): improve workflow summary tooltip rendering

Use viewport-aware tooltip behavior in workflow blocks and preserve full summary text in tooltip overlays.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(settings): bootstrap authenticated settings on app load

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): resolve triggers from workflow graph edges

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(settings): keep general settings loading state in sync

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(i18n): honor stored locale for authenticated locale-prefixed routes

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): ignore chat-only triggers in editor Run

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* style(tradinggoose): wrap proxy route test case

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(tradinggoose): scope locale and settings state by user

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(tradinggoose): cover authenticated locale routing fallback

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(tradinggoose): keep locale routing aligned with auth state

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(tradinggoose): apply preferred locale during bootstrap

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(oauth): normalize callback paths across auth flows

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* style(workspace): format integrations oauth helpers

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): resolve selected trigger configuration errors

Validate the selected trigger block directly during workflow run resolution so missing trigger configuration surfaces as an error instead of being skipped silently.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* perf(control-bar): memoize workflow run trigger derivation

Avoid recomputing the derived run trigger list on every control-bar render by memoizing it against the workflow graph inputs.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(environment): simplify environment store state

Remove the obsolete environment CRUD methods from the Zustand store and load the current payload directly.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): preserve callback pathname during recovery flows

Thread the current pathname through auth recovery so login, sockets, permission fetches, and environment requests return the user to the same route after reauthentication.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): redirect authed users to their preferred locale

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(socket): keep auth error handling on the latest pathname

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
…igger (#144)

* feat(global-navbar): add sidebar user menu trigger

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): settle deleted Stripe subscriptions in webhook flow

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): avoid resetting onboarding usage for entitled subscriptions

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): ignore orphaned deleted stripe subscription events

Co-authored-by: Codex <codex@openai.com>\nCo-authored-by: BWJ2310 <brucewj2310@gmail.com>\nCo-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* style(sidebar): normalize sidebar formatting

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(db): enforce unique stripe subscription ids

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(billing): centralize Stripe subscription lookup

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): sync usage limits on subscription deletion

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(db): enforce unique stripe subscription ids

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): reject missing and duplicate deleted subscriptions

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): skip deleted subscriptions without local rows

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): allow duplicate Stripe subscription rows

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): settle subscription webhooks by Stripe id

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(global-navbar): cover compact avatar trigger outside sidebar

Co-authored-by: Codex <codex@openai.com>\nCo-authored-by: BWJ2310 <brucewj2310@gmail.com>\nCo-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): sync usage limits from settled subscription

Co-authored-by: Codex <codex@openai.com>\nCo-authored-by: BWJ2310 <brucewj2310@gmail.com>\nCo-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): enforce unique Stripe subscription lookup

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(billing): use atomic upsert for enterprise subscriptions

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(subscription): use stripe subscription id for personal upgrades

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
* fix(auth): use browser origin for auth client

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(i18n): add localized not-found route

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>
…146)

* fix(auth): centralize auth cookie cleanup

Remove browser-side cookie deletion from the auth error handler, reuse a shared cookie deletion contract in the proxy, and drop the stale app initialization lifecycle from the store bootstrap.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): route login-page sign-out failures through reauth cleanup

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): redirect authenticated users from auth entry pages

Use a real session check on the login and signup pages so logged-in users reach the workspace from the page boundary.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(proxy): let auth entry routes reach their pages

Keep localized auth routes available to the page boundary and limit reauth cookie cleanup to the login route.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): persist locale through signup verification

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(urls): normalize configured app URL helpers

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(tradinggoose): resolve canonical URLs at runtime

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(email): preserve transactional text in fallback delivery

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix: handle proxy auth cleanup and preview base URL fallback

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(tradinggoose): remove preview-only base URL fallback

Make the affected route handlers dynamic and pass the shared base URL into emails so generated content no longer depends on preview-only env vars.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(tradinggoose): update workflow test setup

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): log fallback sign-out failures

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
* refactor(proxy): use Better Auth session cookies

Remove the proxy-owned cookie cleanup helper and switch the proxy to getSessionCookie directly.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): handle login reauth cleanup

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
* fix(auth): use canonical app session for socket token route

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): simplify unauthorized session handling

Remove inline auth recovery redirects from login and workspace permissions flows.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): block login form until reauth cleanup finishes

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): remove session cookie cache

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): handle failed session creation by forcing reauth cleanup

When login returns FAILED_TO_CREATE_SESSION, fall back to the reauth cleanup
path instead of showing the old inline copy.

Add coverage for the login flow and socket token stale-cookie rejection, and
remove the unused localized login copy.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* style(workflow): format edit-workflow-block test

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): remove reauth redirect flag and guard cleanup retries

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* test(copilot): stabilize workflow tool suites

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): route session errors through reauth cleanup

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): route auth provider failures through error flow

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): preserve callback through auth error flows

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): handle reauth cleanup and error callback cookies

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(auth): replace auth error cookie flow with callback route

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): unify session recovery and SSO error handling

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): route workspace permissions auth failures through recovery

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(auth): stabilize login reauth callbacks

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
* feat(workspace): centralize current-user access checks and locale auth routing

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(workspaces): server-side workspace bootstrap

Move workspace and admin entry redirects to the server, factor workspace bootstrap helpers into a shared service, and add coverage for the auth redirect flow.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): include workspace owners in access flows

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): allow same-origin callback URLs

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): scope workspace permissions to the active user

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace): derive callback origin from request headers

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): require admin access before member deletion

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(permissions): treat workspace owners as admins

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): standardize reauth callbacks and permission state checks

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): roll back failed default workflow seeding

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): align admin access with workspace ownership

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): reuse workspace access checks

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workflows): centralize workflow permission validation

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace-permissions): route missing sessions into auth recovery

Handle resolved anonymous sessions before permissions loading and keep the hook in loading state while recovery runs.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace): redirect workspace roots without bootstrapping

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(copilot): treat workspace owners as workflow admins

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace): bootstrap root workspace on the server

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): normalize login callback URLs from request headers

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): add reauth redirect handling for stale session cookies

* fix(workspaces): normalize created workspace payloads

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): clean up seeded workflow on create failure

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspaces): handle Yjs seeding failures during workspace creation

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
#152)

* refactor(workspace-permissions): thread authenticated user id through permission loading

Use the server-provided user id at the layout boundary, remove redundant nested workspace permission providers from widgets, and update the permission hook/tests to depend on explicit auth context.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): thread authenticated user id through navbar

Pass the authenticated user id from the admin and workspace layouts into GlobalNavbar so WorkspaceDialogs can reuse the server-provided identity instead of calling useSession.

Update the admin layout test to assert the propagated user id.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): use authenticated user id for workspace dialogs

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace-invite): prevent self-invites

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): propagate authenticated email through navbar

Use the authenticated user email from layouts in the global navbar and workspace invite modal so self-invite checks and role detection don't depend on workspace permission lookups.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* feat(navbar): portal header slots into targets

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): preserve auth recovery during workspace permissions fetch

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace-permissions): restore current user row in invite modal

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(workspace-permissions): simplify initial loading fallback

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): wait for client auth before loading workspaces

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): reset workspace redirect state per user access key

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): avoid refetching session-recovery permissions

Skip reloading a workspace permission record that already resolved to
SESSION_EXPIRED when the same user/workspace key remounts.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): gate auth-dependent queries until session matches user

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace): gate permissions UI on matching session user

Require the authenticated session user to match the active user before loading workspace permissions or organization data, and hide the permissions table when there are no users to display.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace): gate workspace data on client auth

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): guard workspace data on stable session state

Derive client auth readiness from the session hook and ignore stale workspace responses when user/session identity changes.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(navbar): keep the latest header owner active

Track header slot ownership so overlapping contributors do not render stale content after one unmounts.

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): scope cached billing queries by user id

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* refactor(auth): use server-authenticated workspace context

Propagate authenticated user IDs through workspace permissions, navbar, and widget consumers while removing client-session readiness gates.

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace): use workspace user identity in invite dialogs

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(auth): pass workspace user to global navbar

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(workspace-auth): require inherited workspace sessions in nested providers

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: BWJ2310 <brucewj2310@gmail.com>
* fix(auth): pass server user into workspace socket provider

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: BWJ2310 <brucewj2310@gmail.com>

Co-authored-by: BWJ2310-backup <jun.1216.wei@gmail.com>

* fix(socket): improve logging for socket authentication errors

* fix(workspace): simplify user prop handling in WorkspaceLayoutClient

* test(auth): adjust auth error handler workspace permission case
Centralize copilot mention copy and switch mention options and submenus to
stable internal ids so the mention menu can render localized labels, empty
states, and fallback names across chats, workspace entities, knowledge bases,
docs, and logs.

Localize block and workflow block names, use localized log trigger labels in
search, and normalize queries for accent-insensitive matching while reloading
mention sources when the locale changes.

Add en, es, and zh mention message keys plus focused tests for mention menu
rendering, filtering, source reloading, and keyboard mention selection flows.
@agualdron agualdron closed this Jun 22, 2026
@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR localizes the Copilot mention menu end-to-end: it introduces a new mention-copy.ts module that derives all labels, empty states, and fallback strings from the next-intl message bundle, replaces every hardcoded English string in the menu and its filter utilities, and switches the MentionOption/MentionSubmenu types from display strings to stable internal IDs. It also adds NFD accent-stripping to the normalize helper and reloads block and workflow-block mention sources when the locale changes.

  • mention-copy.ts (new): centralises all mention-menu copy behind typed accessor functions keyed on stable internal IDs; useCopilotMentionCopy surfaces the localized bundle to both the menu and the mentions hook.
  • use-user-input-mention-sources.ts: adds locale-aware loading with ref-based stale-load cancellation for both blocks and workflow_blocks; workflow_blocks is missing a locale-based cleanup that can leave isLoadingWorkflowBlocks stuck after a mid-fetch locale switch.
  • use-user-input-mentions.ts: adds a locale-change effect that calls ensureSubmenuLoaded(openSubmenuFor) when a submenu is open, ensuring items are refreshed without closing the menu.

Confidence Score: 3/5

Safe to merge for most scenarios; the workflow_blocks submenu can display a permanent loading spinner after a locale change that races an in-flight fetch.

The core localization work is well-structured. The missing useEffect([locale]) cleanup for isLoadingWorkflowBlocks means the workflow_blocks submenu can get stuck on Loading after a mid-fetch locale switch. A test assertion also appears to describe behaviour the implementation does not yet provide.

use-user-input-mention-sources.ts (missing locale-based isLoadingWorkflowBlocks reset) and use-user-input-mentions.test.tsx (suspect assertion on root-menu locale-change case)

Important Files Changed

Filename Overview
apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.ts Adds locale-aware block/workflow-block loading with ref-based stale-load cancellation; a missing useEffect([locale]) cleanup for isLoadingWorkflowBlocks can leave the loading spinner stuck after a mid-fetch locale switch.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/mention-copy.ts New module centralising all mention-menu copy; extracts labels, submenu titles, empty states, and fallback strings from next-intl messages. Logic is clean and correctly uses per-entity fallback labels.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/mention-utils.ts Replaces display-string option keys with stable internal IDs, adds NFD accent-stripping to normalize, and threads copy/monitorCopy into all filter functions.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.ts Adds locale tracking and a locale-change effect to reload the currently open submenu; correctly guards with previousLocaleRef to avoid spurious reloads on initial mount.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/components/mention-menu.tsx Replaces all hardcoded English strings with localized copy; switches string-key option comparisons to stable internal IDs. No issues found.
apps/tradinggoose/widgets/widgets/copilot/workspace-entities.ts Drops string-based mentionOption/submenuTitle fields; CopilotWorkspaceEntityMentionOption is now an alias for CopilotWorkspaceEntityKind.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.test.tsx New hook tests; the root-menu locale-change test asserts all MENTION_SUBMENUS are loaded but the implementation returns early when openSubmenuFor is null.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.test.tsx New source hook tests verifying block and workflow-block names are reloaded with updated localized labels after a locale switch.
apps/tradinggoose/widgets/widgets/copilot/components/user-input/mention-utils.test.ts Expanded with multilingual filter tests covering accent-insensitive matching, localized trigger labels, and aggregated search.

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.ts:343-357
**Stuck loading spinner when locale changes mid-fetch for `workflow_blocks`**

The `blocks` fetch has a `useEffect([locale])` that resets `isLoadingBlocks` on locale change (line 349–352). The `workflow_blocks` fetch has no equivalent cleanup — only `useEffect([workflowId])` resets `isLoadingWorkflowBlocks`. If locale changes while `ensureWorkflowBlocksLoaded` is in-flight, the `finally` block's `if (latestWorkflowBlocksKeyRef.current === loadKey)` guard fires false (key mismatch), so `setIsLoadingWorkflowBlocks(false)` is skipped. Nothing else resets it until `workflowId` changes or the user closes and reopens the submenu. The workflow_blocks submenu will remain stuck on "Loading…" indefinitely after a mid-fetch locale switch.

### Issue 2 of 2
apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.test.tsx:231-260
**Test assertion may not match the implementation**

The test expects `ensureSubmenuLoaded` to be called for every entry in `MENTION_SUBMENUS` after a locale change when the root menu is open (`openSubmenuFor === null`). However, the locale-change `useEffect` in `use-user-input-mentions.ts` returns early when `openSubmenuFor` is null (`if (previousLocale === locale || !showMentionMenu || !openSubmenuFor) return`), so only one `ensureSubmenuLoaded('workflow_blocks')` call from the preceding `handleInputChange` would have been recorded (and was cleared by `mockClear()`). If this test currently passes it is relying on behaviour not visible in the diff; if it is silently broken, it is not catching the preloading gap it was intended to cover.

Reviews (1): Last reviewed commit: "feat(copilot): localize mention labels a..." | Re-trigger Greptile

Comment on lines 343 to 357
useEffect(() => {
setWorkflowBlocks([])
workflowBlocksLoadingRef.current = false
setIsLoadingWorkflowBlocks(false)
}, [workflowId])

useEffect(() => {
setBlocksList([])
setIsLoadingBlocks(false)
}, [locale])

useEffect(() => {
void ensureWorkflowBlocksLoaded()
}, [ensureWorkflowBlocksLoaded])
}, [locale, workflowId, workflowStoreBlocks])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stuck loading spinner when locale changes mid-fetch for workflow_blocks

The blocks fetch has a useEffect([locale]) that resets isLoadingBlocks on locale change (line 349–352). The workflow_blocks fetch has no equivalent cleanup — only useEffect([workflowId]) resets isLoadingWorkflowBlocks. If locale changes while ensureWorkflowBlocksLoaded is in-flight, the finally block's if (latestWorkflowBlocksKeyRef.current === loadKey) guard fires false (key mismatch), so setIsLoadingWorkflowBlocks(false) is skipped. Nothing else resets it until workflowId changes or the user closes and reopens the submenu. The workflow_blocks submenu will remain stuck on "Loading…" indefinitely after a mid-fetch locale switch.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mention-sources.ts
Line: 343-357

Comment:
**Stuck loading spinner when locale changes mid-fetch for `workflow_blocks`**

The `blocks` fetch has a `useEffect([locale])` that resets `isLoadingBlocks` on locale change (line 349–352). The `workflow_blocks` fetch has no equivalent cleanup — only `useEffect([workflowId])` resets `isLoadingWorkflowBlocks`. If locale changes while `ensureWorkflowBlocksLoaded` is in-flight, the `finally` block's `if (latestWorkflowBlocksKeyRef.current === loadKey)` guard fires false (key mismatch), so `setIsLoadingWorkflowBlocks(false)` is skipped. Nothing else resets it until `workflowId` changes or the user closes and reopens the submenu. The workflow_blocks submenu will remain stuck on "Loading…" indefinitely after a mid-fetch locale switch.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex Fix in Claude Code Fix in Cursor

Comment on lines +231 to +260
it('reloads mention submenu sources when the locale changes with the root menu still open', async () => {
await renderHarness({
locale: 'en',
mentionSources: createMentionSources(),
messages: enMessages,
})

await act(async () => {
latestSnapshot?.handleInputChange('@blo', { end: 4, start: 4 })
})

moveCaretToEnd()
ensureSubmenuLoaded.mockClear()

await renderHarness({
locale: 'es',
mentionSources: createMentionSources(),
messages: esMessages,
})

expect(latestSnapshot?.showMentionMenu).toBe(true)
expect(latestSnapshot?.openSubmenuFor).toBeNull()
expect(ensureSubmenuLoaded.mock.calls.map((call) => call.at(0))).toEqual(MENTION_SUBMENUS)
})

it('reloads the open blocks submenu when the locale changes without closing the menu', async () => {
await renderHarness({
locale: 'en',
mentionSources: createMentionSources(),
messages: enMessages,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test assertion may not match the implementation

The test expects ensureSubmenuLoaded to be called for every entry in MENTION_SUBMENUS after a locale change when the root menu is open (openSubmenuFor === null). However, the locale-change useEffect in use-user-input-mentions.ts returns early when openSubmenuFor is null (if (previousLocale === locale || !showMentionMenu || !openSubmenuFor) return), so only one ensureSubmenuLoaded('workflow_blocks') call from the preceding handleInputChange would have been recorded (and was cleared by mockClear()). If this test currently passes it is relying on behaviour not visible in the diff; if it is silently broken, it is not catching the preloading gap it was intended to cover.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/tradinggoose/widgets/widgets/copilot/components/user-input/hooks/use-user-input-mentions.test.tsx
Line: 231-260

Comment:
**Test assertion may not match the implementation**

The test expects `ensureSubmenuLoaded` to be called for every entry in `MENTION_SUBMENUS` after a locale change when the root menu is open (`openSubmenuFor === null`). However, the locale-change `useEffect` in `use-user-input-mentions.ts` returns early when `openSubmenuFor` is null (`if (previousLocale === locale || !showMentionMenu || !openSubmenuFor) return`), so only one `ensureSubmenuLoaded('workflow_blocks')` call from the preceding `handleInputChange` would have been recorded (and was cleared by `mockClear()`). If this test currently passes it is relying on behaviour not visible in the diff; if it is silently broken, it is not catching the preloading gap it was intended to cover.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Codex Fix in Claude Code Fix in Cursor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants