Skip to content

feat: Universal clipboard utility with improved copy functionality#663

Merged
tazmon95 merged 6 commits intomainfrom
feat/universal-clipboard-utility
Sep 18, 2025
Merged

feat: Universal clipboard utility with improved copy functionality#663
tazmon95 merged 6 commits intomainfrom
feat/universal-clipboard-utility

Conversation

@tazmon95
Copy link
Copy Markdown
Collaborator

@tazmon95 tazmon95 commented Sep 15, 2025

Pull Request

Summary

Implement a robust, universal clipboard utility that provides consistent copy-to-clipboard functionality across different browser contexts and security environments. This PR consolidates clipboard operations throughout the application with proper error handling and fallback mechanisms.

Changes Made

  • Add comprehensive clipboard utility (src/utils/clipboard.ts) with:

    • Modern Clipboard API with automatic fallback to document.execCommand
    • Cross-browser compatibility and security context handling
    • Detailed error reporting and debugging capabilities
    • Support for secure (HTTPS) and insecure (HTTP/localhost) contexts
  • Update components to use new clipboard utility:

    • BugReportModal: Enhanced copy functionality with error handling
    • CodeViewerModal: Improved copy-to-clipboard for code snippets
    • IDEGlobalRules: Robust clipboard operations for rule copying
    • McpConfigSection: Enhanced config and command copying
    • DocumentCard: Reliable ID copying functionality
    • KnowledgeInspector: Improved content copying
    • ButtonPlayground: Enhanced CSS style copying
  • Benefits:

    • Consistent copy behavior across all browser environments
    • Better error handling and user feedback
    • Improved accessibility and security context support
    • Enhanced debugging capabilities

Fixes #662

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Affected Services

  • Frontend (React UI)
  • Server (FastAPI backend)
  • MCP Server (Model Context Protocol)
  • Agents (PydanticAI service)
  • Database (migrations/schema)
  • Docker/Infrastructure
  • Documentation site

Testing

  • All existing tests pass
  • Added new tests for new functionality
  • Manually tested affected user flows
  • Docker builds succeed for all services

Test Evidence

# Manually tested clipboard functionality across multiple components:
# - BugReportModal: Copy button works with proper error handling
# - CodeViewerModal: Code copy functionality with fallback
# - IDEGlobalRules: Rule copying with toast notifications
# - McpConfigSection: Config and command copying
# - DocumentCard: ID copying with visual feedback
# - KnowledgeInspector: Content copying with error handling
# - ButtonPlayground: CSS style copying

Checklist

  • My code follows the service architecture patterns
  • If using an AI coding assistant, I used the CLAUDE.md rules
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass locally
  • My changes generate no new warnings
  • I have updated relevant documentation
  • I have verified no regressions in existing features

Breaking Changes

None. This is a non-breaking change that enhances existing functionality without changing any public APIs.

Additional Notes

  • The new clipboard utility provides graceful degradation across different security contexts
  • All existing clipboard functionality has been preserved while adding better error handling
  • The utility includes debugging helpers for troubleshooting clipboard issues in different environments
  • Components now provide better user feedback when clipboard operations fail

Summary by CodeRabbit

  • New Features
    • Cross-browser clipboard utility with robust fallbacks, status results, and context detection; UI shows distinct success/warning/error feedback when copying.
  • Refactor
    • Replaced in-component clipboard logic with a unified helper across multiple screens for consistent behavior and error handling.
  • Configuration
    • Frontend defaults to relative API paths (/api); absolute API URL used only when explicitly set.
  • Chores
    • Docker/front-end env adjustments and server host made configurable via env var.

- Add comprehensive clipboard utility (src/utils/clipboard.ts) with:
  - Modern Clipboard API with automatic fallback to document.execCommand
  - Cross-browser compatibility and security context handling
  - Detailed error reporting and debugging capabilities
  - Support for secure (HTTPS) and insecure (HTTP/localhost) contexts

- Update components to use new clipboard utility:
  - BugReportModal: Enhanced copy functionality with error handling
  - CodeViewerModal: Improved copy-to-clipboard for code snippets
  - IDEGlobalRules: Robust clipboard operations for rule copying
  - McpConfigSection: Enhanced config and command copying
  - DocumentCard: Reliable ID copying functionality
  - KnowledgeInspector: Improved content copying
  - ButtonPlayground: Enhanced CSS style copying

- Benefits:
  - Consistent copy behavior across all browser environments
  - Better error handling and user feedback
  - Improved accessibility and security context support
  - Enhanced debugging capabilities

Fixes #662
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 15, 2025

Walkthrough

Standardizes clipboard operations by adding a universal clipboard utility and updating multiple components to use result-based copy handling. Simplifies frontend API URL resolution to prefer relative/proxy paths and exposes API_BASE_URL/API_FULL_URL. Adds ARCHON_HOST and DOCKER_ENV to docker-compose and makes backend MCP host derive from ARCHON_HOST. No public component APIs changed.

Changes

Cohort / File(s) Summary
Clipboard utility + adoption
archon-ui-main/src/features/shared/utils/clipboard.ts, archon-ui-main/src/components/bug-report/BugReportModal.tsx, archon-ui-main/src/components/code/CodeViewerModal.tsx, archon-ui-main/src/components/settings/ButtonPlayground.tsx, archon-ui-main/src/components/settings/IDEGlobalRules.tsx, archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx, archon-ui-main/src/features/mcp/components/McpConfigSection.tsx, archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx
Adds a cross-browser, SSR-safe copyToClipboard utility with execCommand fallback plus isClipboardSupported and getSecurityContext. Replaces direct navigator.clipboard uses with async copyToClipboard calls and result-driven handling (success/error logging, toasts, copied state).
Frontend API config
archon-ui-main/src/config/api.ts
Simplifies getApiUrl to return VITE_API_URL or empty (relative). Adds getApiBasePath(), API_BASE_URL (/api) and API_FULL_URL (VITE_API_URL or empty). Removes older window/location-based URL construction.
Docker / dev infra
docker-compose.yml
Adds ARCHON_HOST=${HOST:-localhost} for archon-server and sets DOCKER_ENV=true for archon-frontend; comments out previous VITE_API_URL to prefer proxy/relative URLs.
Backend MCP host derivation
python/src/server/api_routes/mcp_api.py
MCP config endpoint now reads host from ARCHON_HOST env (default "localhost") instead of hard-coded "localhost".

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant C as UI Component
  participant CL as ClipboardUtil
  participant N as Navigator.clipboard
  participant D as document.execCommand

  U->>C: Click "Copy"
  C->>CL: copyToClipboard(text)
  alt Clipboard API available
    CL->>N: writeText(text)
    alt Success
      N-->>CL: ok
      CL-->>C: { success: true, method: 'clipboard-api' }
      C->>C: set copied / show success toast
    else Failure
      N-->>CL: error
      CL->>D: execCommand('copy') fallback
      alt Fallback success
        D-->>CL: true
        CL-->>C: { success: true, method: 'execCommand' }
        C->>C: set copied / show success toast
      else Fallback fail
        D-->>CL: false/error
        CL-->>C: { success: false, method: 'failed', error }
        C->>C: log error / show failure toast
      end
    end
  else No API available
    CL->>D: execCommand('copy')
    D-->>CL: success/failure
    CL-->>C: { success: boolean, method, error? }
    C->>C: UI feedback per result
  end
Loading
sequenceDiagram
  autonumber
  participant FE as Frontend
  participant CFG as config/api.ts
  participant S as Server (MCP API)
  participant ENV as ARCHON_HOST env

  FE->>CFG: getApiBasePath()
  alt VITE_API_URL set
    CFG-->>FE: "<VITE_API_URL>/api"
  else not set
    CFG-->>FE: "/api" (relative)
  end

  FE->>S: GET /api/mcp/config
  S->>ENV: read ARCHON_HOST (default "localhost")
  ENV-->>S: host
  S-->>FE: JSON config with host=<env or default>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • coleam00
  • Wirasm

Poem

I tap my paw — copy, hop, and send,
A tiny utility saves the day again.
From proxy paths to ARCHON_HOST's call,
I nibble bugs and paste them all.
Hop on, clipboard — happiness for all. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The changeset includes unrelated infrastructure and configuration edits (docker-compose.yml environment tweaks, python/src/server/api_routes/mcp_api.py host behavior, and archon-ui-main/src/config/api.ts API URL logic) that are not part of the clipboard utility objectives in issue #662. These deployment and server/frontend config changes are out of scope for a clipboard-focused feature and increase review surface and deployment risk. As currently presented, the PR contains out-of-scope modifications that should be separated or justified. Please move the infrastructure and API/config changes into a dedicated PR or provide a clear justification, test/deployment notes, and updated linked issues in this PR if they must remain; splitting these concerns will simplify review and reduce deployment risk.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "feat: Universal clipboard utility with improved copy functionality" is a concise, single sentence that accurately summarizes the primary change (adding a universal clipboard utility and integrating it across components). It is specific, relevant to the changeset, and clear for teammates scanning history.
Linked Issues Check ✅ Passed The PR implements the core coding objectives of issue #662: it introduces a universal clipboard utility that prefers the modern Clipboard API with a document.execCommand fallback, provides feature detection and a getSecurityContext helper, and integrates the utility into CodeViewerModal and BugReportModal (and additional components) to standardize copy behavior and error handling. The primary API functions (copyToClipboard, isClipboardSupported, getSecurityContext) and integrations requested by the issue are present and error paths are handled. One minor divergence is that I did not find a separate copyTextToClipboard wrapper export referenced in the issue; if that wrapper is required, adding a small alias would close that gap.
Description Check ✅ Passed The PR description closely follows the repository template and includes a clear Summary, Changes Made, Type of Change, Affected Services, Testing notes, Test Evidence, Checklist, and Additional Notes, and it links the related issue (#662), so it is largely complete for review. I noticed a minor file-path inconsistency (the description references src/utils/clipboard.ts while the implementation appears under archon-ui-main/src/features/shared/utils/clipboard.ts) and the Test Evidence section contains manual testing notes instead of explicit commands or CI output. Overall the description provides sufficient context but would benefit from correcting the path and adding concrete test commands or CI results.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/universal-clipboard-utility

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3283de2 and b5efda2.

📒 Files selected for processing (1)
  • archon-ui-main/src/features/shared/utils/clipboard.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • archon-ui-main/src/features/shared/utils/clipboard.ts

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tazmon95 tazmon95 self-assigned this Sep 15, 2025
@tazmon95 tazmon95 added the bug label Sep 15, 2025
@tazmon95 tazmon95 requested a review from Wirasm September 15, 2025 02:12
@tazmon95 tazmon95 added this to Archon Sep 15, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (12)
archon-ui-main/src/utils/clipboard.ts (2)

17-27: Guard against SSR/non‑browser environments in copyToClipboard.

Direct navigator/document access throws during SSR. Short‑circuit early with a clear error.

 export const copyToClipboard = async (text: string): Promise<ClipboardResult> => {
+  if (typeof window === 'undefined' || typeof document === 'undefined') {
+    return { success: false, method: 'failed', error: 'Clipboard unavailable on server' };
+  }
   // Try modern clipboard API first
   if (navigator.clipboard && navigator.clipboard.writeText) {

20-26: Preserve original error for diagnostics.

Capture Clipboard API error to include in the eventual failure message if fallback also fails.

-  if (navigator.clipboard && navigator.clipboard.writeText) {
+  let apiError: unknown | undefined;
+  if (navigator.clipboard && navigator.clipboard.writeText) {
     try {
       await navigator.clipboard.writeText(text);
       return { success: true, method: 'clipboard-api' };
     } catch (error) {
-      console.warn('Clipboard API failed, trying fallback:', error);
+      apiError = error;
+      console.warn('Clipboard API failed, trying fallback:', error);
     }
   }
@@
-    return { 
+    return {
       success: false, 
       method: 'failed', 
-      error: error instanceof Error ? error.message : 'Unknown error' 
+      error:
+        (apiError instanceof Error && `API failed: ${apiError.message}`) ||
+        (error instanceof Error && error.message) ||
+        'Unknown error'
     };
archon-ui-main/src/features/mcp/components/McpConfigSection.tsx (3)

189-199: Surface copy method in toast for debugging.

Expose which path succeeded (Clipboard API vs execCommand) to aid user reports.

-    if (result.success) {
-      showToast("Configuration copied to clipboard", "success");
+    if (result.success) {
+      showToast(`Configuration copied (${result.method})`, "success");

212-222: Same enhancement for Claude command.

-    if (result.success) {
-      showToast("Command copied to clipboard", "success");
+    if (result.success) {
+      showToast(`Command copied (${result.method})`, "success");

287-291: Optionally disable Copy when unsupported.

Consider disabling the button if isClipboardSupported() is false to improve UX in restricted contexts.

archon-ui-main/src/components/code/CodeViewerModal.tsx (1)

106-115: Clean up timeout on unmount.

Store the timer id and clear it in cleanup to avoid setting state after unmount.

-  const handleCopyCode = async () => {
+  const copyTimer = React.useRef<number | null>(null);
+  const handleCopyCode = async () => {
     if (activeExample) {
       const result = await copyToClipboard(activeExample.code)
       if (result.success) {
         setCopied(true)
-        setTimeout(() => setCopied(false), 2000)
+        if (copyTimer.current) window.clearTimeout(copyTimer.current)
+        copyTimer.current = window.setTimeout(() => setCopied(false), 2000)
       } else {
         console.error('Failed to copy to clipboard:', result.error)
       }
     }
   }
+  useEffect(() => () => { if (copyTimer.current) window.clearTimeout(copyTimer.current) }, [])
archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (1)

83-91: Clear copy timer safely.

Avoid dangling timeout if component closes quickly.

-  const handleCopy = useCallback(async (text: string, id: string) => {
-    const result = await copyToClipboard(text);
-    if (result.success) {
-      setCopiedId(id);
-      setTimeout(() => setCopiedId((v) => (v === id ? null : v)), 2000);
+  const clearTimerRef = useRef<number | null>(null);
+  const handleCopy = useCallback(async (text: string, id: string) => {
+    const result = await copyToClipboard(text);
+    if (result.success) {
+      setCopiedId(id);
+      if (clearTimerRef.current) window.clearTimeout(clearTimerRef.current);
+      clearTimerRef.current = window.setTimeout(() => setCopiedId((v) => (v === id ? null : v)), 2000);
     } else {
       console.error("Failed to copy to clipboard:", result.error);
     }
   }, []);
+  useEffect(() => () => { if (clearTimerRef.current) window.clearTimeout(clearTimerRef.current); }, []);
archon-ui-main/src/components/settings/ButtonPlayground.tsx (1)

283-291: Clear copy timeout; prevent multiple overlapping timers.

-  const handleCopyToClipboard = async () => {
+  const copyTimer = React.useRef<number | null>(null);
+  const handleCopyToClipboard = async () => {
     const result = await copyToClipboard(generateCSS());
     if (result.success) {
       setCopied(true);
-      setTimeout(() => setCopied(false), 2000);
+      if (copyTimer.current) window.clearTimeout(copyTimer.current);
+      copyTimer.current = window.setTimeout(() => setCopied(false), 2000);
     } else {
       console.error('Failed to copy to clipboard:', result.error);
     }
   };
+  React.useEffect(() => () => { if (copyTimer.current) window.clearTimeout(copyTimer.current); }, []);
archon-ui-main/src/components/settings/IDEGlobalRules.tsx (1)

476-490: Surface method in toast and clean up timer.

Provide method detail for debugging and avoid stale timers on unmount.

-  const handleCopyToClipboard = async () => {
+  const copyTimer = React.useRef<number | null>(null);
+  const handleCopyToClipboard = async () => {
     const result = await copyToClipboard(currentRules);
     
     if (result.success) {
       setCopied(true);
-      showToast(`${selectedRuleType === 'claude' ? 'Claude Code' : 'Universal'} rules copied to clipboard!`, 'success');
+      showToast(`${selectedRuleType === 'claude' ? 'Claude Code' : 'Universal'} rules copied (${result.method})`, 'success');
       
       // Reset copy icon after 2 seconds
-      setTimeout(() => {
-        setCopied(false);
-      }, 2000);
+      if (copyTimer.current) window.clearTimeout(copyTimer.current);
+      copyTimer.current = window.setTimeout(() => setCopied(false), 2000);
     } else {
       console.error('Failed to copy text:', result.error);
       showToast('Failed to copy to clipboard', 'error');
     }
   };
+  React.useEffect(() => () => { if (copyTimer.current) window.clearTimeout(copyTimer.current); }, []);
archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx (1)

70-78: Log failure path for visibility; keep user feedback consistent.

Match other components by logging copy errors when copy fails.

   const handleCopyId = useCallback(
     async (e: React.MouseEvent) => {
       e.stopPropagation();
       const result = await copyToClipboard(document.id);
       if (result.success) {
         setIsCopied(true);
         setTimeout(() => setIsCopied(false), 2000);
+      } else {
+        // Keep silent UI but log for diagnostics
+        console.error("Failed to copy document id:", result.error);
       }
     },
     [document.id],
   );
archon-ui-main/src/components/bug-report/BugReportModal.tsx (2)

100-117: Differentiate copy failure with context.

When clipboard copy fails in fallback, include security context to aid user action.

-        const clipboardResult = await copyToClipboard(formattedReport);
+        const clipboardResult = await copyToClipboard(formattedReport);
 
-        if (clipboardResult.success) {
+        if (clipboardResult.success) {
           showToast(
             "Failed to create GitHub issue, but bug report was copied to clipboard. Please paste it in a new GitHub issue.",
             "warning",
             10000,
           );
         } else {
-          showToast(
-            "Failed to create GitHub issue and could not copy to clipboard. Please report manually.",
-            "error",
-            10000,
-          );
+          const ctx = (await import("../../utils/clipboard")).getSecurityContext?.() ?? "unknown";
+          showToast(`Failed to create GitHub issue and could not copy to clipboard (context: ${ctx}). Please report manually.`, "error", 10000);
         }

130-141: Inline copy action: show method for support tickets.

-    const result = await copyToClipboard(formattedReport);
-    if (result.success) {
-      showToast("Bug report copied to clipboard", "success");
+    const result = await copyToClipboard(formattedReport);
+    if (result.success) {
+      showToast(`Bug report copied (${result.method})`, "success");
     } else {
       showToast("Failed to copy to clipboard", "error");
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e2e8aa and f595884.

📒 Files selected for processing (8)
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx (4 hunks)
  • archon-ui-main/src/components/code/CodeViewerModal.tsx (2 hunks)
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx (3 hunks)
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx (2 hunks)
  • archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (2 hunks)
  • archon-ui-main/src/features/mcp/components/McpConfigSection.tsx (3 hunks)
  • archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx (2 hunks)
  • archon-ui-main/src/utils/clipboard.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
archon-ui-main/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend

archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)

Files:

  • archon-ui-main/src/utils/clipboard.ts
  • archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx
  • archon-ui-main/src/components/code/CodeViewerModal.tsx
  • archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx
  • archon-ui-main/src/features/mcp/components/McpConfigSection.tsx
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx
**/*.{py,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never return None/null to indicate failure; raise an exception with details instead

Files:

  • archon-ui-main/src/utils/clipboard.ts
  • archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx
  • archon-ui-main/src/components/code/CodeViewerModal.tsx
  • archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx
  • archon-ui-main/src/features/mcp/components/McpConfigSection.tsx
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx
archon-ui-main/src/features/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

archon-ui-main/src/features/**/*.{ts,tsx}: Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Biome formatting in features: 120-character lines, double quotes, trailing commas

archon-ui-main/src/features/**/*.{ts,tsx}: Use Biome formatting/conventions in /src/features: 120-char lines, double quotes, trailing commas
Use useSmartPolling and polling intervals (1–2s active, 5–10s background) with smart pausing on tab inactivity
Expose progress via dedicated hooks (e.g., useCrawlProgressPolling, useProjectTasks) instead of ad-hoc timers
Do not use prop drilling for data fetching/state; rely on TanStack Query caches/selectors

Files:

  • archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx
  • archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx
  • archon-ui-main/src/features/mcp/components/McpConfigSection.tsx
archon-ui-main/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Legacy UI code should adhere to standard React ESLint rules

Files:

  • archon-ui-main/src/components/code/CodeViewerModal.tsx
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx
archon-ui-main/src/components/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Legacy UI under /components should follow ESLint standard React rules

Files:

  • archon-ui-main/src/components/code/CodeViewerModal.tsx
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx
🧬 Code graph analysis (7)
archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx (1)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/components/code/CodeViewerModal.tsx (1)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (1)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/components/settings/IDEGlobalRules.tsx (1)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/components/settings/ButtonPlayground.tsx (1)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/features/mcp/components/McpConfigSection.tsx (1)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/components/bug-report/BugReportModal.tsx (2)
archon-ui-main/src/utils/clipboard.ts (1)
  • copyToClipboard (17-63)
archon-ui-main/src/services/bugReportService.ts (2)
  • BugReportData (33-42)
  • bugReportService (244-244)
🔇 Additional comments (7)
archon-ui-main/src/features/mcp/components/McpConfigSection.tsx (1)

7-7: LGTM: centralized clipboard util adoption.

archon-ui-main/src/components/code/CodeViewerModal.tsx (1)

33-33: LGTM: centralized clipboard util import.

Consistent with new utility; reduces duplication.

archon-ui-main/src/components/settings/ButtonPlayground.tsx (1)

6-6: LGTM: reuse shared util instead of inline copy logic.

archon-ui-main/src/components/settings/IDEGlobalRules.tsx (1)

6-6: LGTM: unified clipboard flow and error handling.

archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx (1)

18-18: LGTM: use shared util in card action.

archon-ui-main/src/components/bug-report/BugReportModal.tsx (2)

381-389: LGTM: handler rename avoids shadowing imported util.

New name handleCopyToClipboard prevents confusion and improves readability.


14-14: LGTM: imports new util; avoids name shadowing via handler.

Comment thread archon-ui-main/src/utils/clipboard.ts
Comment thread archon-ui-main/src/utils/clipboard.ts
…uration

Clipboard utility improvements:
- Prevent textarea element leak in clipboard fallback with proper cleanup
- Add SSR compatibility with typeof guards for navigator/document
- Use finally block to ensure cleanup in all error cases

Host configuration fixes:
- Update MCP API to use ARCHON_HOST environment variable instead of hardcoded localhost
- Add ARCHON_HOST to docker-compose environment variables
- Ensures MCP configuration shows correct hostname in different deployment environments

Addresses CodeRabbit feedback and restores missing host functionality
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
python/src/server/api_routes/mcp_api.py (2)

104-115: Normalize ARCHON_HOST to avoid client-unreachable values (e.g., 0.0.0.0).

If ARCHON_HOST is set to 0.0.0.0/:: (common in container configs), clients cannot connect. Sanitize to a reachable host for the browser.

Apply this diff:

@@
-            # Configuration for streamable-http mode with actual port
-            config = {
-                "host": os.getenv("ARCHON_HOST", "localhost"),
-                "port": mcp_port,
-                "transport": "streamable-http",
-            }
+            # Configuration for streamable-http mode with actual port
+            env_host = os.getenv("ARCHON_HOST", "").strip()
+            host = "localhost" if env_host in {"", "0.0.0.0", "::"} else env_host
+            config = {
+                "host": host,
+                "port": mcp_port,
+                "transport": "streamable-http",
+            }

Optional: prefer the incoming request’s host (x-forwarded-host or request.url.hostname) as a fallback when ARCHON_HOST is unset. I can provide a patch if you want to take that route.


97-135: Add ETag support to /api/mcp/config for cheap polling and 304s (per server guidelines).

Small win for bandwidth and client responsiveness; hash the effective config and return 304 when unchanged.

Apply this diff:

@@
-@router.get("/config")
-async def get_mcp_config():
+@router.get("/config")
+async def get_mcp_config(request, response):
@@
-            api_logger.info("MCP configuration (streamable-http mode)")
+            # Compute a stable ETag over the public config
+            import hashlib
+            etag = hashlib.sha256(
+                f"{config['host']}:{config['port']}:{config.get('model_choice','gpt-4o-mini')}".encode("utf-8")
+            ).hexdigest()[:16]
+            if request.headers.get("if-none-match") == etag:
+                from fastapi import Response
+                return Response(status_code=304)
+            response.headers["ETag"] = etag
+
+            api_logger.info("MCP configuration (streamable-http mode)")

Add imports outside this hunk:

# at top-level imports
from fastapi import APIRouter, HTTPException, Request, Response  # add Request, Response

If you prefer, I can wrap this with a small helper to avoid repetition across endpoints.

🧹 Nitpick comments (2)
docker-compose.yml (2)

31-31: Avoid ${HOST}; default ARCHON_HOST to ARCHON_PUBLIC_HOST (host.docker.internal)

ARCHON_PUBLIC_HOST is not defined in .env.example or .env — add it (e.g. ARCHON_PUBLIC_HOST=host.docker.internal).

File: docker-compose.yml (line ~31) — replace:

-      - ARCHON_HOST=${HOST:-localhost}
+      - ARCHON_HOST=${ARCHON_PUBLIC_HOST:-host.docker.internal}

163-163: Document DOCKER_ENV — consumed by the UI.

archon-ui-main/vite.config.ts:18 reads process.env.DOCKER_ENV === 'true' || existsSync('/.dockerenv'); add DOCKER_ENV to the environment-variable docs (expected value: 'true' to force Docker mode; fallback: /.dockerenv).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f595884 and f9c6d41.

📒 Files selected for processing (3)
  • archon-ui-main/src/utils/clipboard.ts (1 hunks)
  • docker-compose.yml (2 hunks)
  • python/src/server/api_routes/mcp_api.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • archon-ui-main/src/utils/clipboard.ts
🧰 Additional context used
📓 Path-based instructions (5)
python/src/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

python/src/**/*.py: Fail fast on critical conditions: service startup failures, missing configuration/env vars, database connection/auth failures, critical dependencies unavailable
Never accept or store corrupted data (e.g., zero embeddings, null foreign keys, malformed JSON); skip failed items entirely and continue processing
For batch/background operations, continue processing but log detailed per-item failures; for external APIs use retries with exponential backoff and then fail clearly
Error messages must include context, use specific exception types, preserve full stack traces (logging with exc_info=True), include relevant IDs/URLs, and never return None to indicate failure—raise instead; for batch ops report success counts and detailed failures
Backend uses Python 3.12 with a 120-character line length
Avoid introducing WebSocket support in the backend; updates are handled via HTTP polling
Adhere to Ruff lint rules (e.g., no unused imports) and provide type hints to satisfy MyPy

python/src/**/*.py: Fail fast on service startup failures (credentials, DB, service init); crash with clear errors
Treat missing configuration (env vars/invalid settings) as fatal; stop the system
Do not hide database connection failures; bubble up and surface clearly
Authentication/authorization failures must halt the operation and be visible
Never silently accept bad data; let Pydantic validation errors raise
If critical dependencies are unavailable, fail immediately
Reject invalid data that could corrupt state (e.g., zero embeddings, null FKs, malformed JSON)
Batch processing should complete remaining items but log detailed per-item failures
Background tasks (e.g., embedding generation) should finish queues while logging failures
Treat optional features as skippable: log and skip when disabled rather than crashing
External API calls: use retry with exponential backoff; on final failure, raise with clear service/context info
Never accept corrupted data during partial-failure work...

Files:

  • python/src/server/api_routes/mcp_api.py
python/src/server/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Use specific exception classes and FastAPI exception handlers to produce rich JSON error responses

python/src/server/**/*.py: Provide rich error responses in FastAPI (custom exceptions and handlers that return structured JSON with detail/type)
Implement HTTP polling support and ETag caching on endpoints to enable 304 responses

Files:

  • python/src/server/api_routes/mcp_api.py
python/src/server/{api_routes,services}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Follow Service Layer pattern: API routes delegate to services, which handle business logic and call the database layer

Files:

  • python/src/server/api_routes/mcp_api.py
**/*.{py,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never return None/null to indicate failure; raise an exception with details instead

Files:

  • python/src/server/api_routes/mcp_api.py
python/src/server/api_routes/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Place API route handlers under python/src/server/api_routes/

Files:

  • python/src/server/api_routes/mcp_api.py
🧠 Learnings (1)
📚 Learning: 2025-09-13T15:53:40.741Z
Learnt from: CR
PR: coleam00/Archon#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-13T15:53:40.741Z
Learning: Applies to .env : Optional environment variables may be set: LOGFIRE_TOKEN, LOG_LEVEL, ARCHON_SERVER_PORT, ARCHON_MCP_PORT, ARCHON_UI_PORT

Applied to files:

  • docker-compose.yml

Comment thread docker-compose.yml
- Update getApiUrl() to return empty string when VITE_API_URL is unset
- Ensures all API requests use relative paths (/api/...) in development
- Prevents bypassing Vite proxy with absolute URLs (host:port)
- Maintains existing functionality for explicit VITE_API_URL configuration
- Fix TypeScript error by using bracket notation for environment access

Addresses CodeRabbit feedback about dev setup relying on Vite proxy
Use proper type assertion to access VITE_API_URL environment variable
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
archon-ui-main/src/config/api.ts (2)

30-31: Normalize to avoid //api when VITE_API_URL ends with /.

If VITE_API_URL has a trailing slash, ${apiUrl}/api yields a double slash. Normalize first.

-  return `${apiUrl}/api`;
+  const base = apiUrl.replace(/\/+$/, '');
+  return `${base}/api`;

34-36: Avoid module-load evaluation; export a lazy getter.

API_FULL_URL = getApiUrl() executes at import time, which can be brittle in SSR/tests. Prior learning for this file recommends lazy getters over module-load constants.

-export const API_FULL_URL = getApiUrl();
+export function getApiFullUrl(): string {
+  return getApiUrl();
+}

Optionally, also prefer getApiBasePath() at call sites over API_BASE_URL to keep behavior encapsulated.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9c6d41 and af7e93a.

📒 Files selected for processing (1)
  • archon-ui-main/src/config/api.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
archon-ui-main/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend

archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)

Files:

  • archon-ui-main/src/config/api.ts
**/*.{py,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never return None/null to indicate failure; raise an exception with details instead

Files:

  • archon-ui-main/src/config/api.ts
🧠 Learnings (1)
📚 Learning: 2025-09-04T16:30:05.227Z
Learnt from: stevepresley
PR: coleam00/Archon#573
File: archon-ui-main/src/config/api.ts:15-25
Timestamp: 2025-09-04T16:30:05.227Z
Learning: Archon UI API config: Prefer lazy getters getApiFullUrl() and getWsUrl() over module-load constants to avoid SSR/test crashes. Avoid CommonJS exports patterns (Object.defineProperty(exports,…)) in ESM. Add typeof window guards with VITE_API_URL fallback inside getApiUrl()/getWebSocketUrl() when SSR safety is required.

Applied to files:

  • archon-ui-main/src/config/api.ts
🔇 Additional comments (1)
archon-ui-main/src/config/api.ts (1)

16-18: Empty-string sentinel: verify callers and prefer base-path helper.

Returning '' to signal "relative/proxy mode" is fine only if every caller builds paths via getApiBasePath() or API_BASE_URL — verify there are no direct concatenations of getApiUrl() with path strings (risk: malformed URLs or accidental leading "//"). Automated search in the sandbox failed; run these locally and fix any matches to use the base-path helper:

# search all JS/TS files (exclude node_modules)
rg -n -S '\bgetApiUrl\s*\(' -g '!**/node_modules/**' || true
rg -n -S 'getApiUrl\(\)\s*\+' -g '!**/node_modules/**' || true
rg -n -S '\$\{\s*getApiUrl\(\)\s*\}' -g '!**/node_modules/**' || true
rg -n -S 'getApiUrl\(\)\s*/' -g '!**/node_modules/**' || true
rg -n -S '\bgetApiBasePath\s*\(' -g '!**/node_modules/**' || true
rg -n -S '\bAPI_(BASE|FULL)_URL\b' -g '!**/node_modules/**' || true

Comment on lines +10 to +13
// Check if VITE_API_URL is explicitly provided (for absolute URL mode)
const viteApiUrl = (import.meta.env as any).VITE_API_URL as string | undefined;
if (viteApiUrl) {
return viteApiUrl;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Remove any-cast; use typed env and trim.

Casting import.meta.env to any breaks strict TS guarantees and violates our frontend guideline. Type it and avoid any.

Apply this diff:

-  const viteApiUrl = (import.meta.env as any).VITE_API_URL as string | undefined;
+  const viteApiUrl = import.meta.env.VITE_API_URL?.trim();

Add or update env typings (new file suggested) to keep strict mode:

// env.d.ts
interface ImportMetaEnv {
  readonly VITE_API_URL?: string;
}
interface ImportMeta {
  readonly env: ImportMetaEnv;
}
🤖 Prompt for AI Agents
In archon-ui-main/src/config/api.ts around lines 10 to 13, remove the unsafe
(import.meta.env as any) cast and use a typed env property instead; add a new
env.d.ts (placed in src/ or root) containing the suggested
ImportMetaEnv/ImportMeta interfaces so TypeScript knows VITE_API_URL is
optional, then read const viteApiUrl = import.meta.env.VITE_API_URL; and return
viteApiUrl?.trim() (or undefined if falsy) so the value is typed and
whitespace-trimmed.

@@ -0,0 +1,135 @@
/**
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Following the new architecture this file should be inside the src/features directory

src/features/shared/

Comment thread archon-ui-main/src/utils/clipboard.ts Outdated
return 'insecure';
};

/**
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is this needed if we have completely replaced the old one?

This would be dead code together with the old api

@tazmon95 tazmon95 moved this to In progress in Archon Sep 16, 2025
…ecture

- Move clipboard.ts from src/utils/ to src/features/shared/utils/
- Remove copyTextToClipboard backward compatibility function (dead code)
- Update all import statements to use new file location
- Maintain full clipboard functionality with modern API and fallbacks

Addresses:
- Review comment r2348420743: Move to new architecture location
- Review comment r2348422625: Remove unused backward compatibility function

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
archon-ui-main/src/features/shared/utils/clipboard.ts (3)

31-38: Fallback path should check for document in SSR before touching document.body.

Use a typeof guard to avoid throwing when document is undefined in SSR.

-    // Ensure document.body exists before proceeding
-    if (!document.body) {
+    // Ensure document exists and document.body is available before proceeding
+    if (typeof document === "undefined" || !document.body) {
       return {
         success: false,
         method: 'failed',
-        error: 'document.body is not available'
+        error: 'document is not available'
       };
     }

28-30: Preserve focus when using the textarea fallback to avoid stealing focus.

Capture and restore the previously focused element; this improves UX and a11y.

-  let textarea: HTMLTextAreaElement | null = null;
+  let textarea: HTMLTextAreaElement | null = null;
+  let prevActive: Element | null = null;
@@
-    document.body.appendChild(textarea);
+    prevActive = document.activeElement;
+    document.body.appendChild(textarea);
     textarea.select();
     textarea.setSelectionRange(0, text.length);
@@
-    if (textarea && document.body && document.body.contains(textarea)) {
+    if (textarea && document.body && document.body.contains(textarea)) {
       try {
         document.body.removeChild(textarea);
       } catch (cleanupError) {
         // Ignore cleanup errors - element may have already been removed
         console.warn('Failed to cleanup textarea element:', cleanupError);
       }
     }
+    // Restore prior focus if possible
+    if (prevActive && "focus" in prevActive && typeof (prevActive as any).focus === "function") {
+      try {
+        (prevActive as HTMLElement).focus();
+      } catch {
+        /* no-op */
+      }
+    }

Also applies to: 50-53, 71-80


118-125: *Recognize IPv6 localhost and .localhost in security context.

Treat ::1 and subdomains like foo.localhost as localhost for clearer diagnostics.

 export const getSecurityContext = (): string => {
   if (typeof window === 'undefined') return 'server';
   if (window.isSecureContext) return 'secure';
   if (window.location.protocol === 'https:') return 'https';
-  if (window.location.hostname === 'localhost' || 
-      window.location.hostname === '127.0.0.1') return 'localhost';
+  const host = window.location.hostname;
+  if (
+    host === 'localhost' ||
+    host === '127.0.0.1' ||
+    host === '::1' ||
+    host.endsWith('.localhost')
+  ) return 'localhost';
   return 'insecure';
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af7e93a and 3283de2.

📒 Files selected for processing (8)
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx (4 hunks)
  • archon-ui-main/src/components/code/CodeViewerModal.tsx (2 hunks)
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx (3 hunks)
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx (2 hunks)
  • archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (2 hunks)
  • archon-ui-main/src/features/mcp/components/McpConfigSection.tsx (3 hunks)
  • archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx (2 hunks)
  • archon-ui-main/src/features/shared/utils/clipboard.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • archon-ui-main/src/features/projects/documents/components/DocumentCard.tsx
  • archon-ui-main/src/features/mcp/components/McpConfigSection.tsx
  • archon-ui-main/src/components/code/CodeViewerModal.tsx
  • archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx
  • archon-ui-main/src/components/settings/ButtonPlayground.tsx
  • archon-ui-main/src/components/settings/IDEGlobalRules.tsx
  • archon-ui-main/src/components/bug-report/BugReportModal.tsx
🧰 Additional context used
📓 Path-based instructions (3)
archon-ui-main/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend

archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)

Files:

  • archon-ui-main/src/features/shared/utils/clipboard.ts
archon-ui-main/src/features/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

archon-ui-main/src/features/**/*.{ts,tsx}: Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Biome formatting in features: 120-character lines, double quotes, trailing commas

archon-ui-main/src/features/**/*.{ts,tsx}: Use Biome formatting/conventions in /src/features: 120-char lines, double quotes, trailing commas
Use useSmartPolling and polling intervals (1–2s active, 5–10s background) with smart pausing on tab inactivity
Expose progress via dedicated hooks (e.g., useCrawlProgressPolling, useProjectTasks) instead of ad-hoc timers
Do not use prop drilling for data fetching/state; rely on TanStack Query caches/selectors

Files:

  • archon-ui-main/src/features/shared/utils/clipboard.ts
**/*.{py,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Never return None/null to indicate failure; raise an exception with details instead

Files:

  • archon-ui-main/src/features/shared/utils/clipboard.ts
🔇 Additional comments (2)
archon-ui-main/src/features/shared/utils/clipboard.ts (2)

82-84: Export alias copyTextToClipboard to preserve API contract (#662)

Repo search shows only copyToClipboard is used in-repo; no occurrences of copyTextToClipboard. If this util is part of the public API or used by downstream packages, add the alias at the end of archon-ui-main/src/features/shared/utils/clipboard.ts.

 };
 
+/** Alias to match API contract from #662 */
+export const copyTextToClipboard = copyToClipboard;

1-127: Format archon-ui-main/src/features/shared/utils/clipboard.ts with Biome (double quotes + trailing commas)
Per src/features conventions, convert single quotes to double quotes and add trailing commas; run: npx @biomejs/biome format archon-ui-main/src/features/shared/utils/clipboard.ts

Comment thread archon-ui-main/src/features/shared/utils/clipboard.ts Outdated
@Wirasm Wirasm self-requested a review September 18, 2025 10:16
- Add typeof navigator !== 'undefined' guard before accessing navigator.clipboard
- Add typeof document !== 'undefined' guard before using document.execCommand fallback
- Ensure proper error handling when running in server-side environment
- Maintain existing functionality while preventing ReferenceError during SSR/prerender

Addresses CodeRabbit feedback: Navigator access needs SSR-safe guards

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@tazmon95 tazmon95 merged commit 9ffca82 into main Sep 18, 2025
8 checks passed
@github-project-automation github-project-automation Bot moved this from In progress to Done in Archon Sep 18, 2025
@Wirasm Wirasm deleted the feat/universal-clipboard-utility branch September 22, 2025 07:06
leonj1 pushed a commit to leonj1/Archon that referenced this pull request Oct 13, 2025
…oleam00#663)

* feat: Add universal clipboard utility with enhanced copy functionality

- Add comprehensive clipboard utility (src/utils/clipboard.ts) with:
  - Modern Clipboard API with automatic fallback to document.execCommand
  - Cross-browser compatibility and security context handling
  - Detailed error reporting and debugging capabilities
  - Support for secure (HTTPS) and insecure (HTTP/localhost) contexts

- Update components to use new clipboard utility:
  - BugReportModal: Enhanced copy functionality with error handling
  - CodeViewerModal: Improved copy-to-clipboard for code snippets
  - IDEGlobalRules: Robust clipboard operations for rule copying
  - McpConfigSection: Enhanced config and command copying
  - DocumentCard: Reliable ID copying functionality
  - KnowledgeInspector: Improved content copying
  - ButtonPlayground: Enhanced CSS style copying

- Benefits:
  - Consistent copy behavior across all browser environments
  - Better error handling and user feedback
  - Improved accessibility and security context support
  - Enhanced debugging capabilities

Fixes coleam00#662

* fix: Improve clipboard utility robustness and add missing host configuration

Clipboard utility improvements:
- Prevent textarea element leak in clipboard fallback with proper cleanup
- Add SSR compatibility with typeof guards for navigator/document
- Use finally block to ensure cleanup in all error cases

Host configuration fixes:
- Update MCP API to use ARCHON_HOST environment variable instead of hardcoded localhost
- Add ARCHON_HOST to docker-compose environment variables
- Ensures MCP configuration shows correct hostname in different deployment environments

Addresses CodeRabbit feedback and restores missing host functionality

* fix: Use relative URLs for Vite proxy in development

- Update getApiUrl() to return empty string when VITE_API_URL is unset
- Ensures all API requests use relative paths (/api/...) in development
- Prevents bypassing Vite proxy with absolute URLs (host:port)
- Maintains existing functionality for explicit VITE_API_URL configuration
- Fix TypeScript error by using bracket notation for environment access

Addresses CodeRabbit feedback about dev setup relying on Vite proxy

* fix: Resolve TypeScript error in API configuration

Use proper type assertion to access VITE_API_URL environment variable

* Address PR review comments: Move clipboard utility to features architecture

- Move clipboard.ts from src/utils/ to src/features/shared/utils/
- Remove copyTextToClipboard backward compatibility function (dead code)
- Update all import statements to use new file location
- Maintain full clipboard functionality with modern API and fallbacks

Addresses:
- Review comment r2348420743: Move to new architecture location
- Review comment r2348422625: Remove unused backward compatibility function

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix SSR safety issue in clipboard utility

- Add typeof navigator !== 'undefined' guard before accessing navigator.clipboard
- Add typeof document !== 'undefined' guard before using document.execCommand fallback
- Ensure proper error handling when running in server-side environment
- Maintain existing functionality while preventing ReferenceError during SSR/prerender

Addresses CodeRabbit feedback: Navigator access needs SSR-safe guards

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
coleam00 added a commit that referenced this pull request Apr 7, 2026
feat: add WISC framework context engineering for video demonstration
Tyone88 pushed a commit to Tyone88/Archon that referenced this pull request Apr 16, 2026
…eparation

feat: add WISC framework context engineering for video demonstration
joaobmonteiro pushed a commit to joaobmonteiro/Archon that referenced this pull request Apr 26, 2026
…eparation

feat: add WISC framework context engineering for video demonstration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done (In Stable)

Development

Successfully merging this pull request may close these issues.

feat: Universal clipboard utility with improved copy functionality

2 participants