Skip to content

Conversation

@shinjadong
Copy link

@shinjadong shinjadong commented Nov 28, 2025

Analysis covers key code locations for:

  • Visual recognition engine (Bounding Box rendering)
  • LLM Provider configuration (Ollama, GPT-4o-mini)
  • Browser control (Chrome profile loading)
  • Workflow engine (Block system)
  • Configuration structure

Purpose: Support Naver blog automation project


📋 This PR adds a comprehensive 525-line Korean analysis document of the Skyvern codebase, providing detailed technical documentation for implementing Naver blog automation. The analysis covers critical code locations including visual recognition systems, LLM configurations, browser control mechanisms, and workflow engines.

🔍 Detailed Analysis

Key Changes

  • Documentation Addition: Creates SKYVERN_ARCHITECTURE_ANALYSIS.md with complete codebase analysis
  • Technical Mapping: Documents exact file locations and functions for key features like bounding box rendering (domUtils.js), LLM provider setup (config_registry.py), and browser factory (browser_factory.py)
  • Integration Guide: Provides specific configuration examples for Ollama, GPT-4o-mini, and Chrome profile loading
  • Customization Instructions: Includes code modification examples for visual styling and Korean localization

Technical Implementation

flowchart TD
    A[Analysis Document] --> B[Visual Recognition Engine]
    A --> C[LLM Provider Configuration]
    A --> D[Browser Control System]
    A --> E[Workflow Engine]
    
    B --> B1[domUtils.js - Bounding Box]
    B --> B2[Style Customization Guide]
    
    C --> C1[Ollama Integration]
    C2[GPT-4o-mini Setup]
    C --> C3[Config Registry]
    
    D --> D1[Chrome Profile Loading]
    D --> D2[CDP Connection]
    D --> D3[Browser Factory]
    
    E --> E1[Block System]
    E --> E2[Workflow Service]
    E --> E3[Navigation/Action Blocks]
Loading

Impact

  • Developer Productivity: Eliminates need for extensive code exploration by providing direct file/line references
  • Project Acceleration: Enables rapid implementation of Naver blog automation with specific configuration examples
  • Knowledge Transfer: Creates comprehensive technical documentation for team collaboration and future maintenance
  • Customization Support: Provides exact modification points for visual styling (Manus AI-like bounding boxes) and Korean localization

Created with Palmier


Important

Adds a detailed analysis report of the Skyvern codebase, focusing on architecture, key modules, and configurations for Naver blog automation.

  • Analysis Report:
    • Adds SKYVERN_ARCHITECTURE_ANALYSIS.md detailing the Skyvern codebase.
    • Covers architecture, key modules, and configuration for Naver blog automation.
  • Key Modules:
    • Visual recognition engine: domUtils.js for Bounding Box rendering.
    • LLM Provider configuration: config.py, config_registry.py for Ollama and GPT-4o-mini.
    • Browser control: browser_factory.py for Chrome profile loading.
    • Workflow engine: block.py for Block system.
  • Configuration:
    • Describes .env settings for LLM and browser configurations.
    • Provides customization guidance for Chrome profiles and LLM models.

This description was created by Ellipsis for 14dcc6e. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • Documentation
    • Added extensive architecture, deployment, runbooks, issue reports, and Korean guides for setup, operations, and production checklists.
  • Configuration
    • Added Vercel hosting config, production env examples/templates, and gitignore updates for local profiles.
  • New Features
    • Supabase integration with auth UI, route guard, and client bootstrap.
  • Database & Backend
    • Added DB schema/migrations and generated TypeScript types for frontend DB access.
  • Tools & Scripts
    • Added Docker lifecycle helpers, ngrok/tunnel helpers, and log/status utilities.
  • Localization
    • Translated many frontend UI strings to Korean.
  • Chore
    • Enabled vision-model support for an LLM provider.

✏️ Tip: You can customize this high-level summary in your review settings.

Analysis covers key code locations for:
- Visual recognition engine (Bounding Box rendering)
- LLM Provider configuration (Ollama, GPT-4o-mini)
- Browser control (Chrome profile loading)
- Workflow engine (Block system)
- Configuration structure

Purpose: Support Naver blog automation project
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

Walkthrough

Adds extensive documentation and deployment guides, multiple Docker/WSL/ngrok helper scripts, Vercel/frontend config and environment templates, Korean UI localization across many frontend components, Supabase integration (types, client, auth provider, routes), a DB migration, and one behavioral change enabling vision support for Ollama in the LLM config registry.

Changes

Cohort / File(s) Summary
Architecture & analysis docs
SKYVERN_ARCHITECTURE_ANALYSIS.md, docs/PROJECT_CONTEXT_SUMMARY.md, docs/chat-logs/*
New architecture analysis, project context and chat-log artifacts documenting code layout, data flow, LLM/provider notes, Chrome profile handling, and implementation guidance.
Production & deployment docs
DEPLOYMENT_ARCHITECTURE.md, docs/PRODUCTION_DEPLOYMENT.md, docs/DOMAIN_SETUP_JADONG_SHOP.md, docs/ISSUE_REPORT_2025-11-30.md, docs/ISSUE_RESOLUTION_2025-11-30.md
New production deployment and incident documentation covering Cloudflare/ngrok options, domain setup, troubleshooting, and deployment checklists.
Run & execution guides (Korean)
PYTHON_실행가이드.md, SKYVERN_실행가이드.md, README.ko.md, README_시작하기.md
Korean-language run, quickstart and execution guides with commands, environment/LLM key setup, and troubleshooting.
Frontend config & Vercel
skyvern-frontend/.env.production.example, skyvern-frontend/.env.production.local, skyvern-frontend/vercel.json, skyvern-frontend/.gitignore, skyvern-frontend/.env.example
Adds production env examples, local production env, Vercel deployment config (build, rewrites, headers, asset cache), and frontend .gitignore updates; also adds Supabase env keys to example.
Frontend localization
skyvern-frontend/src/routes/...
.../BrowserSessions.tsx, .../credentials/*, .../history/RunHistory.tsx, .../settings/Settings.tsx, .../workflows/*, .../tasks/create/PromptBox.tsx, .../root/SideNav.tsx, etc.
Localized many UI strings from English to Korean across routes and components; no logic changes.
Supabase integration (frontend)
skyvern-frontend/package.json, skyvern-frontend/src/App.tsx, skyvern-frontend/src/api/database.types.ts, skyvern-frontend/src/api/supabase.ts, skyvern-frontend/src/store/SupabaseAuthContext.tsx, skyvern-frontend/src/routes/auth/AuthGuard.tsx, skyvern-frontend/src/routes/auth/LoginPage.tsx, skyvern-frontend/supabase/migrations/001_initial_schema.sql, skyvern-frontend/src/router.tsx
Adds Supabase dependency, generated DB types, client bootstrap, auth context/provider and hooks, AuthGuard and LoginPage routes, initial SQL migration, and wraps routes with authentication guard; introduces SupabaseAuthProvider in App.
Utility & orchestration scripts
docker-start.sh, docker-stop.sh, docker-status.sh, docker-logs.sh, skyvern-restart.sh, skyvern-stop.sh, skyvern-status.sh, skyvern-ngrok.sh, get-ngrok-url.sh
New shell scripts for starting/stopping/status/logging Docker/WSL setups and Skyvern processes, ngrok helpers and URL retrieval; include WSL↔Windows path conversions, PowerShell invocations, and user guidance.
DB schema & types
skyvern-frontend/supabase/migrations/001_initial_schema.sql, skyvern-frontend/src/api/database.types.ts
Adds an initial PostgreSQL schema with RLS, triggers, enums and indexes, plus matching TypeScript types for the frontend.
LLM config change
skyvern/forge/sdk/api/llm/config_registry.py
Changed Ollama LLMConfig to supports_vision=True, enabling registered Ollama models to be marked as vision-capable.
Misc ignores & frontend local env
.gitignore, skyvern-frontend/.gitignore, chrome-profile/
Added chrome-profile/, .vercel, .env.production.local, .env.local, and .env*.local to ignored files.
Project prompts & planning
docs/chat-logs/gemini/*, docs/chat-logs/cursor/*
Large prompt templates, planning notes and deep-dive documents for Gemini/Claude/Cursor usage and NotebookLM workflows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Heterogeneous changes: docs, many new shell scripts (WSL↔Windows orchestration), frontend auth flow and Supabase integration, DB migration, generated types, and a single LLM config change.
  • Files requiring focused review:
    • docker-start.sh (WSL ↔ PowerShell orchestration, path conversions, env handling).
    • skyvern-*.sh and docker-*.sh scripts (error handling, assumptions about host tooling and Windows path conversion).
    • skyvern-frontend/supabase/migrations/001_initial_schema.sql (RLS policies, triggers, indexes).
    • skyvern-frontend/src/api/database.types.ts and skyvern-frontend/src/api/supabase.ts (type correctness and environment gating).
    • skyvern-frontend/src/store/SupabaseAuthContext.tsx, AuthGuard.tsx, LoginPage.tsx, and router changes (auth flows, redirects, and edge cases).
    • skyvern/forge/sdk/api/llm/config_registry.py (enabling vision support for Ollama — compatibility check with downstream consumers).

Possibly related PRs

Suggested labels

sync

Suggested reviewers

  • suchintan
  • wintonzheng

Poem

🐰 깡충깡충 문서 숲을 달려,
스크립트 깃발 높이 꽂았네,
터널 잇고 키 파일 챙겨,
인터페이스는 그대로, 말만 바꿨네.
당근 한 입 — 배포 또 한 뛱!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Add comprehensive Skyvern codebase analysis report' accurately reflects the main change: a new 525-line technical analysis document (SKYVERN_ARCHITECTURE_ANALYSIS.md) is added to the repository.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (5)
SKYVERN_ARCHITECTURE_ANALYSIS.md (5)

1-10: Document structure and purpose are clear, but address markdown formatting issues before merging.

This is a well-organized architecture analysis document. However, the static analysis identified several formatting issues that should be fixed to maintain markdown quality and readability.


4-4: Wrap bare URL in proper markdown link syntax.

The repository URL should be wrapped as a markdown link.

Apply this diff to format the URL properly:

-**리포지토리**: https://github.com/Skyvern-AI/skyvern
+**리포지토리**: [https://github.com/Skyvern-AI/skyvern](https://github.com/Skyvern-AI/skyvern)

13-13: Specify language for fenced code blocks.

Code blocks should declare their language for proper syntax highlighting and linter compliance (markdownlint MD040).

Apply these diffs to add language specifications:

 ### 1.1 디렉토리 구조
 
-```
+```text
 skyvern/
 ├── cli/                    # CLI 명령어 (skyvern run, skyvern init 등)
 ### 1.3 데이터 흐름도
 
-```
+```text
 [사용자 요청] → [FastAPI Server] → [ForgeAgent]
 #### 호출 체인
 
-```
+```text
 Python: SkyvernFrame.build_elements_and_draw_bounding_boxes()

Also applies to: 59-59, 128-128


297-310: Replace emphasis-based headings with proper markdown heading syntax.

Lines 297 and 310 use bold emphasis (**...**) as section headings. Use markdown heading syntax instead for proper document structure (markdownlint MD036).

Apply these diffs:

-**방법 1: CDP 연결 (추천)**
+#### 방법 1: CDP 연결 (추천)
-**방법 2: 코드 수정 (browser_factory.py 라인 453-472)**
+#### 방법 2: 코드 수정 (browser_factory.py 라인 453-472)

1-525: Document serves a valuable purpose but lacks source code verification.

Overall, this architecture analysis document is well-written and comprehensive. However, it makes numerous specific claims about code locations, line numbers, and implementation details that could drift from the actual codebase over time. Consider adding:

  1. Last verified date: Note when line numbers and code references were last confirmed
  2. Verification process: Document how to re-verify claims against the actual source
  3. Maintenance notes: Suggest periodic review cycles to keep documentation in sync with code changes

For merge readiness, address the markdown formatting issues (bare URL, code block languages, emphasis-as-heading) before committing.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7ecdaa and 14dcc6e.

📒 Files selected for processing (1)
  • SKYVERN_ARCHITECTURE_ANALYSIS.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
SKYVERN_ARCHITECTURE_ANALYSIS.md

[grammar] ~87-~87: Taalfout gevonden
Context: ...eye/scraper/domUtils.js| Bounding Box 그리기 (JavaScript) | |skyvern/webeye/utils/...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_OTHER)


[grammar] ~88-~88: Zin met fouten
Context: ...t) | | skyvern/webeye/utils/page.py | Python에서 JS 함수 호출 | #### 핵심 함수 **domUtils.js...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~88-~88: Zin met fouten
Context: ...kyvern/webeye/utils/page.py | Python에서 JS 함수 호출 | #### 핵심 함수 **domUtils.js` (라...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~88-~88: Zin met fouten
Context: ...ern/webeye/utils/page.py | Python에서 JS 함수 호출 | #### 핵심 함수 **domUtils.js` (라인 1...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~88-~88: Zin met fouten
Context: .../webeye/utils/page.py | Python에서 JS 함수 호출 | #### 핵심 함수 **domUtils.js` (라인 1907...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_MULTITOKEN)


[grammar] ~108-~108: Dit kan een fout zijn.
Context: ...orGroup()` (라인 2112-2148) - Bounding Box 스타일 정의** javascript function createHintMarkerForGroup(group) { // ... 스크롤 위치 계산 ... // Bounding Box 스타일 설정 boundingBox.style.border = "2px solid blue"; // ★ 테두리 색상 변경 지점 boundingBox.style.pointerEvents = "none"; boundingBox.style.zIndex = this.currentZIndex++; return Object.assign(marker, { element: el, // 라벨 요소 boundingBox: boundingBox, // 박스 요소 group: group, }); } #### 호출 체인 ``` Python: SkyvernFrame.build_el...

(QB_NEW_NL)


[grammar] ~168-~168: Dit kan een fout zijn.
Context: ...--- ### 2.2 [BRAIN_CONFIG] LLM Provider 설정 #### 파일 위치 | 파일 | 역할 | |------|------| | `sk...

(QB_NEW_NL)


[grammar] ~342-~342: Taalfout gevonden
Context: ...orkflow/service.py` | 워크플로우 서비스 | #### Block 타입 (block.py) | Block 타입 | 역할 | |--------...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_OTHER)


[grammar] ~390-~390: Interpunctie toevoegen
Context: ... | |------|------| | .env | 환경 변수 (API 키, 설정값) | | skyvern/config.py | Pydant...

(QB_NEW_NL_OTHER_ERROR_IDS_MISSING_PUNCTUATION)


[grammar] ~390-~390: Taalfout gevonden
Context: ...------|------| | .env | 환경 변수 (API 키, 설정값) | | skyvern/config.py | Pydantic Set...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_OTHER)


[grammar] ~391-~391: Taalfout gevonden
Context: ...설정값) | | skyvern/config.py | Pydantic Settings 기반 설정 클래스 | | `skyvern/webeye/chromium_...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_OTHER)


[grammar] ~391-~391: Taalfout gevonden
Context: ...skyvern/config.py | Pydantic Settings 기반 설정 클래스 | | `skyvern/webeye/chromium_preference...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_OTHER)


[grammar] ~392-~392: Taalfout gevonden
Context: ...ern/webeye/chromium_preferences.json` | 브라우저 기본 설정 | #### 필수 환경 변수 (.env) ```bash # 필수 D...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_OTHER)


[grammar] ~483-~483: Fout gevonden
Context: ... 확인된 사항 - [x] Bounding Box 그리기 코드 위치 확인 - [x] Ollama 연동 코드 이미 구현됨 (config_registry...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_SPELLING)


[grammar] ~484-~484: Fout gevonden
Context: ...Ollama 연동 코드 이미 구현됨 (config_registry.py) - [x] GPT-4o-mini 연동 코드 이미 구현됨 - [x] Chrom...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_SPELLING)


[grammar] ~485-~485: Fout gevonden
Context: ...istry.py) - [x] GPT-4o-mini 연동 코드 이미 구현됨 - [x] Chrome 프로필 로드 지원 (CDP 모드) - [x] 워크플로...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_SPELLING)


[grammar] ~486-~486: Fout gevonden
Context: ...드 이미 구현됨 - [x] Chrome 프로필 로드 지원 (CDP 모드) - [x] 워크플로우 Block 시스템 확인 ### 4.2 주의 사항 1...

(QB_NEW_NL_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_SPELLING)

🪛 markdownlint-cli2 (0.18.1)
SKYVERN_ARCHITECTURE_ANALYSIS.md

4-4: Bare URL used

(MD034, no-bare-urls)


13-13: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


59-59: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


128-128: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


297-297: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


310-310: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (5)
SKYVERN_ARCHITECTURE_ANALYSIS.md (5)

479-506: Validate compatibility notes and warnings against current codebase.

The validation section lists several important caveats (Ollama Vision not supported, Chrome profile simultaneous access, iframe handling). These should be verified to ensure they are still accurate and not outdated.

Please confirm that the stated limitations and caveats remain accurate:

  • Ollama Vision support limitation (line 491)
  • Chrome profile simultaneous access restriction (line 494)
  • iframe support via SkyvernFrame class (line 498)

A shell script can help verify whether these limitations still apply in the current codebase.


168-241: I'll help you verify the LLM provider configuration references in the document. Let me search the codebase for the specific configurations mentioned.
<function_calls>

#!/bin/bash

Verify LLM provider configuration references

echo "=== Searching for config_registry.py file ==="
find . -name "config_registry.py" -type f

echo -e "\n=== Searching for Ollama configuration ==="
rg -n "OLLAMA" --type=py -B 2 -A 5 2>/dev/null | head -100

echo -e "\n=== Searching for GPT-4o-mini or OPENAI_GPT4O_MINI ==="
rg -n "OPENAI_GPT4O_MINI|gpt-4o-mini" --type=py -B 2 -A 5 2>/dev/null | head -80

echo -e "\n=== Searching for supports_vision in config_registry ==="
rg -n "supports_vision" --type=py -B 3 -A 3 2>/dev/null | head -100


</function_calls>


244-328: Unable to verify browser factory implementation — repository access failed.

The verification could not be completed as the repository clone operation failed. The specific line numbers, code snippets, and implementation details mentioned in the review comment (including the default_user_data_dir function around line 510, Playwright launch configuration at lines 453-472, CDP setup at lines 559-590, and config.py settings at lines 34-45) require direct codebase access for verification.

Recommended next steps:

  • Retry verification when repository access is available
  • Manually confirm the referenced line numbers match the current codebase
  • Verify that the implementation approach documented matches the actual code structure
  • Check that all referenced configuration variables in config.py are present and correctly documented

79-165: I'll help you verify the line number references and code snippets in the architecture analysis document. Let me start by searching for the domUtils.js file and locating the referenced functions.
<function_calls>


#!/bin/bash

Find domUtils.js file

echo "=== Searching for domUtils.js ==="
fd -t f "domUtils.js" 2>/dev/null

Check if the file exists and get its line count

if [ -f "skyvern/webeye/scraper/domUtils.js" ]; then
echo -e "\n=== File stats ==="
wc -l "skyvern/webeye/scraper/domUtils.js"
fi


</function_calls>

<function_calls>


#!/bin/bash

Search for the three functions referenced in the review comment

echo "=== Searching for drawBoundingBoxes function ==="
rg -n "function drawBoundingBoxes" --type=js

echo -e "\n=== Searching for createHintMarkerForGroup function ==="
rg -n "function createHintMarkerForGroup" --type=js

echo -e "\n=== Searching for border style references ==="
rg -n 'style.border.=."2px solid blue"' --type=js -B 2 -A 2


</function_calls>

<function_calls>


#!/bin/bash

Get more context around the border style reference

echo "=== Checking for any border style references in domUtils.js ==="
rg -n 'style.border' skyvern/webeye/scraper/domUtils.js --type=js -B 3 -A 3

echo -e "\n=== Also checking for 'drawBoundingBoxes' and 'createHintMarker' patterns ==="
rg -n 'drawBoundingBoxes|createHintMarker' skyvern/webeye/scraper/domUtils.js --type=js -B 2 -A 2


</function_calls>

<function_calls>


#!/bin/bash

Check file existence and basic info

if [ -f "skyvern/webeye/scraper/domUtils.js" ]; then
echo "=== File exists ==="
ls -lh "skyvern/webeye/scraper/domUtils.js"
echo -e "\n=== Total lines ==="
wc -l "skyvern/webeye/scraper/domUtils.js"

Try to find the functions case-insensitively

echo -e "\n=== Searching for drawBoundingBoxes (case-insensitive) ==="
rg -in "drawboundingboxes" "skyvern/webeye/scraper/domUtils.js" -B 2 -A 8
else
echo "File not found at: skyvern/webeye/scraper/domUtils.js"
echo "Checking for domUtils files:"
find . -name "domUtils" -type f 2>/dev/null | head -20
fi


</function_calls>

<function_calls>


#!/bin/bash

List directory structure to understand the layout

echo "=== Checking skyvern/webeye directory ==="
if [ -d "skyvern/webeye" ]; then
ls -la skyvern/webeye/
echo -e "\n=== Checking scraper subdirectory ==="
if [ -d "skyvern/webeye/scraper" ]; then
ls -la skyvern/webeye/scraper/ | head -20
fi
else
echo "Directory skyvern/webeye does not exist"
echo "Checking for any 'scraper' directories:"
find . -type d -name "scraper" 2>/dev/null | head -10
fi


</function_calls>

<function_calls>


#!/bin/bash

List all JavaScript files in the repo to find domUtils

echo "=== Finding all JavaScript files ==="
fd -t f ".js$" | head -30


</function_calls>

<function_calls>


#!/bin/bash

Look for any file containing "drawBoundingBoxes" or "createHintMarker"

echo "=== Searching for drawBoundingBoxes across all files ==="
rg -l "drawBoundingBoxes" . 2>/dev/null | head -10

echo -e "\n=== Searching for createHintMarker across all files ==="
rg -l "createHintMarker" . 2>/dev/null | head -10

echo -e "\n=== Repository structure overview ==="
git ls-files | grep -E ".(js|py)$" | head -30


</function_calls>

<function_calls>


#!/bin/bash

Search for the SKYVERN_ARCHITECTURE_ANALYSIS.md file itself

echo "=== Looking for SKYVERN_ARCHITECTURE_ANALYSIS.md ==="
find . -name "ARCHITECTURE" -type f 2>/dev/null

echo -e "\n=== Check git tracked markdown files ==="
git ls-files | grep -i "architecture" 2>/dev/null

echo -e "\n=== All markdown files in repo ==="
git ls-files | grep ".md$" | head -20


</function_calls>

<function_calls>


#!/bin/bash

Broader search for any occurrence of the functions in the repo

echo "=== Search across entire repo for key identifiers ==="
rg "drawBoundingBoxes|createHintMarker|DomUtils" --max-count=5 | head -50


</function_calls>

<function_calls>


#!/bin/bash

Check git status and branch info

echo "=== Git branch and status ==="
git status --short 2>/dev/null | head -20

echo -e "\n=== Check PR context - list all modified/added files ==="
git diff --name-status HEAD~1..HEAD 2>/dev/null | head -30

echo -e "\n=== Check for any domUtils references ==="
rg -i "domutils|dom.*utils" --max-count=20


</function_calls>

Line number references cannot be verified - functions do not exist in the codebase.

The referenced functions (drawBoundingBoxes, createHintMarkerForGroup) and the specific line numbers in skyvern/webeye/scraper/domUtils.js could not be located in the repository. Comprehensive searches across the codebase returned no matches for these identifiers or the proposed file structure.

The architecture document appears to describe proposed features or design concepts rather than existing, implemented code. The line number references (1907-1918, 2112-2148, 2139) cannot be verified against actual source code.

Recommendation: Clarify whether SKYVERN_ARCHITECTURE_ANALYSIS.md documents planned architecture or existing implementations. If this is a proposal for new features, update the document to clearly indicate it as a design proposal rather than referencing non-existent line numbers as if they were already implemented.


332-380: Based on the web search results, I can now provide a rewritten review comment. The search confirms that all the Block types mentioned in the documentation are officially documented in Skyvern:


Block types verified against official Skyvern documentation; exact implementation signatures require direct codebase access.

The Block types listed (NavigationBlock, ActionBlock, ExtractionBlock, ValidationBlock, ForLoopBlock, CodeBlock, WaitBlock, UploadFileBlock) are confirmed in official Skyvern documentation. However, the exact class signatures, parameters, and usage patterns in the workflow example cannot be definitively verified without access to the actual implementation in skyvern/forge/sdk/workflow/models/block.py. Recommend confirming:

  • Exact constructor parameters for each Block type
  • Whether complete_criterion and data_extraction_goal properties exist on ActionBlock
  • Correct YAML/JSON serialization format for workflow definitions

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed everything up to 14dcc6e in 2 minutes and 17 seconds. Click for details.
  • Reviewed 531 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 6 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. SKYVERN_ARCHITECTURE_ANALYSIS.md:110
  • Draft comment:
    Ensure that variables like 'marker', 'el', and 'boundingBox' are clearly defined in the snippet. The sample assumes their declaration, which might confuse readers.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the author to ensure that certain variables are clearly defined, which falls under the category of asking the author to double-check or ensure something. This violates the rule against asking the author to ensure or verify things. The comment does not provide a specific suggestion or point out a specific issue with the code, such as a missing test or a potential bug.
2. SKYVERN_ARCHITECTURE_ANALYSIS.md:277
  • Draft comment:
    Consider caution when using a relative path ('./tmp/user_data_dir') for Chrome's user data directory; using an absolute path may prevent potential conflicts.
  • Reason this comment was not posted:
    Comment was on unchanged code.
3. SKYVERN_ARCHITECTURE_ANALYSIS.md:452
  • Draft comment:
    Verify that the placeholder '...' in the litellm_params block is replaced with complete parameter definitions in production.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is asking the PR author to verify something, which is against the rules. It doesn't provide a specific suggestion or point out a clear issue with the code. Therefore, it should be removed.
4. SKYVERN_ARCHITECTURE_ANALYSIS.md:509
  • Draft comment:
    Documented line references may become outdated as code evolves; consider linking to dynamic references or adding a maintenance note.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative and does not provide a specific code suggestion or request for clarification. It suggests a general practice without addressing a specific issue in the code.
5. SKYVERN_ARCHITECTURE_ANALYSIS.md:98
  • Draft comment:
    Typographical note: The function name getDOMElementBySkyvenElement appears to be missing an 'r' (i.e. it might be intended to be getDOMElementBySkyvernElement) to match the repository name. Please verify and correct if needed.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is a documentation file that's being added, not actual source code. The function name getDOMElementBySkyvenElement appears in a code snippet that's documenting existing code from the Skyvern repository. The comment is asking to verify if this is a typo. However, this violates several rules: 1) It's asking the author to verify/confirm something rather than pointing out a definite issue, 2) If this is actually how the function is named in the original Skyvern codebase, then the documentation is correctly quoting it, and 3) The comment is speculative ("appears to be missing", "might be intended"). The author is documenting existing code, so if the function name is wrong, it's wrong in the original codebase, not in this documentation. The documentation should accurately reflect what's actually in the code. The function name might actually be correct as written in the original Skyvern codebase. Without seeing the actual source code, I cannot confirm this is a typo. The documentation might be accurately quoting the existing code, in which case the comment would be incorrect. The comment is speculative and asks for verification rather than pointing out a definite issue. Since this is documentation of existing code, the author should be accurately quoting what's in the source. If there's a typo in the original codebase, that's not something to fix in this documentation PR. This comment should be deleted. It's speculative, asks for verification, and is about documentation that's quoting existing code rather than about a code change that needs to be fixed. The documentation should accurately reflect the actual code, regardless of whether the original has a typo.
6. SKYVERN_ARCHITECTURE_ANALYSIS.md:110
  • Draft comment:
    Inconsistency note: The function is defined as createHintMarkerForGroup (singular) but is called elsewhere as createHintMarkersForGroups (plural). Consider unifying the naming to avoid confusion.
  • Reason this comment was not posted:
    Comment was on unchanged code.

Workflow ID: wflow_HPFH8vuKyUcAQNc6

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

shinjadong and others added 2 commits November 28, 2025 22:27
- Add comprehensive Korean documentation for Docker and Python setup
- Add README_시작하기.md for quick start guide
- Add PYTHON_실행가이드.md for Python installation details
- Add SKYVERN_실행가이드.md for Docker installation guide
- Add utility scripts for easy service management:
  - docker-start.sh, docker-stop.sh, docker-logs.sh, docker-status.sh
  - skyvern-restart.sh, skyvern-stop.sh, skyvern-status.sh
- Update .gitignore to exclude chrome-profile directory
- Add Korean translation of README (README.ko.md)
- Fix ShellCheck warnings in management scripts
- DEPLOYMENT_ARCHITECTURE.md: Comprehensive Korean guide for deploying
  Skyvern as a SaaS platform with Vercel frontend and WSL backend
- vercel.json: Vercel configuration for frontend deployment
- .env.production.example: Production environment variables template

Covers: Cloudflare Tunnel setup, LLM configuration (GPT-4o-mini/Ollama),
Chrome profile for Naver automation, and troubleshooting guide.
Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
DEPLOYMENT_ARCHITECTURE.md (1)

11-11: Add language tags to fenced code blocks for better rendering and linting compliance.

Several fenced code blocks lack language specification (lines 11, 375, 427, 438, 448), which triggers markdown linting warnings. While this doesn't affect functionality, adding language tags (e.g., text, bash) improves syntax highlighting and documentation clarity.

Examples:

  • Line 11 (ASCII diagram): wrap with ```text instead of ```
  • Line 375 (prompt example): use ```text or similar
  • Lines 427, 438, 448 (error examples): use ```text or ```plaintext

Also applies to: 375-375, 427-427, 438-438, 448-448

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14dcc6e and 47f746a.

📒 Files selected for processing (3)
  • DEPLOYMENT_ARCHITECTURE.md (1 hunks)
  • skyvern-frontend/.env.production.example (1 hunks)
  • skyvern-frontend/vercel.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • skyvern-frontend/.env.production.example
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-24T17:46:29.802Z
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:46:29.802Z
Learning: Applies to skyvern-frontend/**/*.{ts,tsx,js,jsx} : Use `npm run lint` and `npm run format` for linting and formatting frontend code in skyvern-frontend/

Applied to files:

  • skyvern-frontend/vercel.json
🪛 markdownlint-cli2 (0.18.1)
DEPLOYMENT_ARCHITECTURE.md

11-11: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


375-375: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


427-427: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


438-438: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


448-448: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (2)
skyvern-frontend/vercel.json (1)

1-45: Vercel configuration looks solid.

The build, rewrite, and header configuration are all correct for a Vite-based SPA on Vercel. The negative lookahead regex correctly preserves static assets and the favicon, while the security headers and asset caching strategy follow best practices.

DEPLOYMENT_ARCHITECTURE.md (1)

1-487: Comprehensive, well-structured deployment documentation.

The guide provides clear step-by-step instructions for Vercel frontend deployment, WSL/Docker backend setup, external exposure via Cloudflare Tunnel (with ngrok as fallback), LLM configuration options (GPT-4o-mini for cost efficiency, Ollama for local/free), and practical guidance for Naver blog automation. Security checklist, troubleshooting, and deployment summaries are helpful. The references to vercel.json and integration with the architecture analysis document align well with the PR's broader goals.

shinjadong and others added 3 commits November 30, 2025 14:39
## Problem
- Cloudflare Quick Tunnel not forwarding requests to local backend
- Tunnel creates URL and registers connection but returns 404 for all requests
- Local backend (localhost:8000) works perfectly

## Completed
- Claude branch merged successfully
- Vercel frontend deployed
- Local backend running with PostgreSQL
- Database migration and API key generation done

## Needs Resolution
- WSL2 + Cloudflare Tunnel compatibility issue
- Need alternative tunneling solution (ngrok, named tunnel, or cloud deployment)

Issue report: docs/ISSUE_REPORT_2025-11-30.md
Changes:
- config_registry.py: Enable vision support for Ollama models (llava, qwen2-vl)
- SKYVERN_ARCHITECTURE_ANALYSIS.md: Mark Ollama vision issue as resolved
- docs/ISSUE_RESOLUTION_2025-11-30.md: Add tunnel issue resolution guide
- skyvern-ngrok.sh: Add ngrok tunnel helper script for WSL2
- get-ngrok-url.sh: Add script to get ngrok URL for Vercel env vars

The Cloudflare Quick Tunnel 404 issue in WSL2 is addressed by providing
ngrok as an alternative solution, which has better WSL2 compatibility.
Copy link
Contributor

@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: 9

🧹 Nitpick comments (25)
skyvern-stop.sh (1)

8-8: Consider more specific process matching to avoid unintended terminations.

The command pkill -f "skyvern run" will match any process with "skyvern run" in its command line. This pattern might be too broad and could terminate unintended processes if multiple Skyvern-related processes are running.

Consider using a more specific pattern or adding a confirmation prompt:

+echo "⚠️  다음 프로세스가 종료됩니다:"
+pgrep -fa "skyvern run"
+read -p "계속하시겠습니까? (y/N): " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+    echo "취소되었습니다."
+    exit 0
+fi
+
 pkill -f "skyvern run" && echo "✅ Skyvern 프로세스 종료됨" || echo "⚠️  Skyvern 프로세스 없음"
SKYVERN_실행가이드.md (3)

37-107: Wrap bare URLs in markdown links and add language specifiers to code blocks.

Bare URLs (lines 102-104, 155-157) should be wrapped in markdown link syntax. Code blocks missing language specifiers (line 140 shows a raw table output) reduce syntax highlighting clarity.

Apply these diffs:

 ### 💡 **API 키를 얻는 방법**
 
-- **OpenAI**: https://platform.openai.com/api-keys
-- **Anthropic**: https://console.anthropic.com/
-- **Google Gemini**: https://aistudio.google.com/app/apikey
-- **Azure**: Azure Portal > OpenAI 리소스
+- **OpenAI**: [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys)
+- **Anthropic**: [https://console.anthropic.com/](https://console.anthropic.com/)
+- **Google Gemini**: [https://aistudio.google.com/app/apikey](https://aistudio.google.com/app/apikey)
+- **Azure**: Azure Portal > OpenAI 리소스

For the table at line 140 that shows expected docker-compose ps output:

 **정상 실행 시 다음과 같이 표시됩니다:**
-```
+```bash
 NAME                IMAGE                               STATUS

140-145: Add language identifier to code block for docker-compose ps output.

The output example at line 140 is missing the language specifier. While it's not executable code, adding bash or text improves markdown lint compliance.


380-384: Use proper markdown heading syntax instead of emphasis for "팁" section.

Line 384 uses **Happy Automating! 🚀** which is flagged as emphasis used instead of a heading. Consider either converting to a proper heading or using plain text.

PYTHON_실행가이드.md (1)

77-79: Wrap bare URLs in markdown links and add missing language specifiers.

Similar to the Docker guide, bare URLs (lines 77-79, 160-161) should use markdown link syntax. Line 102 shows a code block without language specification; line 139 is also missing bash specifier. Line 160 uses emphasis instead of proper heading syntax.

Apply similar fixes as the previous file to improve markdown compliance and URL formatting.

Also applies to: 102-102, 160-161

docker-stop.sh (1)

1-22: Add set -e for fail-fast behavior and validate docker-compose path.

While the script has explicit error handling, adding set -e at the top ensures any unexpected failures cause immediate exit. Additionally, the hardcoded path to docker-compose.exe should be validated to exist before use.

Apply this diff:

 #!/bin/bash
+set -e
 
 # Skyvern Docker 중지 스크립트
 
 echo "🛑 Skyvern Docker 중지 중..."
 
-# Docker Compose 경로 (스크립트에서 직접 사용하므로 변수 불필요)
+# Docker Compose 경로
+DOCKER_COMPOSE="/mnt/c/Program Files/Docker/Docker/resources/bin/docker-compose.exe"
+
+if [ ! -f "$DOCKER_COMPOSE" ]; then
+    echo "❌ Docker Compose를 찾을 수 없습니다: $DOCKER_COMPOSE"
+    exit 1
+fi
 
 # 프로젝트 디렉토리로 이동
 cd "$(dirname "$0")" || exit 1
 
 # Windows 경로로 변환
 WIN_PATH=$(wslpath -w "$(pwd)")
 
 # Docker Compose 중지
-if powershell.exe -Command "cd '$WIN_PATH'; & 'C:\Program Files\Docker\Docker\resources\bin\docker-compose.exe' down"; then
+if powershell.exe -Command "cd '$WIN_PATH'; & '$DOCKER_COMPOSE' down"; then
     echo "✅ Skyvern이 성공적으로 중지되었습니다."
 else
     echo "❌ 중지 실패. 수동으로 확인하세요."
     exit 1
 fi
docker-start.sh (4)

1-10: Add set -e for fail-fast behavior.

The script lacks set -e, which means unexpected failures won't cause immediate exit. This can lead to confusing behavior where the script continues after errors.

 #!/bin/bash
+set -e
 
 # Skyvern Docker 시작 스크립트
 # WSL2에서 Windows Docker를 사용하여 Skyvern을 실행합니다

9-11: Consolidate hardcoded Docker paths into variables for maintainability.

The Docker executable paths are repeated multiple times (lines 10-11, 76, and inferred elsewhere). Extract these to variables at the top for DRY principle and easier updates.

 #!/bin/bash
+set -e
 
 # Skyvern Docker 시작 스크립트
 # WSL2에서 Windows Docker를 사용하여 Skyvern을 실행합니다
 
 echo "🐉 Skyvern Docker 시작 중..."
 echo ""
 
-# Docker 경로 설정
 DOCKER="/mnt/c/Program Files/Docker/Docker/resources/bin/docker.exe"
 DOCKER_COMPOSE="/mnt/c/Program Files/Docker/Docker/resources/bin/docker-compose.exe"
+DOCKER_DESKTOP="C:\Program Files\Docker\Docker\Docker Desktop.exe"

Then use $DOCKER_DESKTOP instead of the hardcoded path on line 18.

Also applies to: 66-66, 76-76


15-28: Verify Docker Desktop startup timing and add retry logic.

The 30-second wait (line 20) may be insufficient on slower systems. Consider adding retry logic with exponential backoff or detecting Docker readiness more accurately.

 if ! "$DOCKER" ps >/dev/null 2>&1; then
     echo "⚠️  Docker Desktop이 실행되지 않았습니다."
     echo "    Docker Desktop을 시작하는 중..."
-    powershell.exe -Command "Start-Process 'C:\Program Files\Docker\Docker\Docker Desktop.exe'" >/dev/null 2>&1
-    echo "    30초 대기 중..."
-    sleep 30
-    
-    # 다시 확인
-    if ! "$DOCKER" ps >/dev/null 2>&1; then
+    powershell.exe -Command "Start-Process '$DOCKER_DESKTOP'" >/dev/null 2>&1
+    
+    # Wait for Docker to be ready with retry
+    for i in {1..12}; do
+        echo "    Docker 시작 대기 중... ($i/12)"
+        if "$DOCKER" ps >/dev/null 2>&1; then
+            break
+        fi
+        sleep 5
+    done
+    
+    # Final check
+    if ! "$DOCKER" ps >/dev/null 2>&1; then
         echo "❌ Docker Desktop을 시작할 수 없습니다."
         echo "   수동으로 Docker Desktop을 시작한 후 다시 시도하세요."
         exit 1

47-63: Improve environment validation: check required variables and provide actionable guidance.

The LLM configuration check (lines 47-63) only validates that some LLM provider is enabled. It should:

  1. Verify that API keys are actually set (not just the enable flag)
  2. Validate required database connection string
  3. Provide more specific guidance if validation fails
docs/ISSUE_REPORT_2025-11-30.md (3)

45-73: Add language specifiers to code blocks for consistent markdown rendering.

Lines 68, 105, and 115 show code blocks without language identifiers. Add appropriate language tags (bash for shell commands, etc.) for better syntax highlighting and markdown linting compliance.

 **진단 결과:**
 
-```bash
+```shell
 # 로컬 테스트 - 성공 ✅
 $ curl http://localhost:8000/docs | grep title

129-129: Wrap bare URLs in markdown links and fix emphasis-as-heading syntax.

Multiple bare URLs (line 129, others) should use markdown link syntax. Lines marked with emphasis (**...:**) should use proper heading syntax.

Also applies to: 141-141, 147-147, 154-154


1-194: Consider moving this diagnostic report to a separate troubleshooting wiki or issue tracker.

This file documents a real infrastructure incident with deployment details, temporary solutions, and environmental specifics. While useful for the development team, it may not belong in the main repository permanently. Consider:

  1. Moving to GitHub Issues/Discussions as a pinned troubleshooting guide
  2. Extracting generalizable solutions into DEPLOYMENT_ARCHITECTURE.md
  3. Removing once the underlying tunnel issue is resolved
get-ngrok-url.sh (2)

1-14: Add set -e for fail-fast behavior and improve error handling.

The script lacks set -e. Additionally, the grep command on line 17 assumes a specific JSON format and may fail silently if ngrok is running but returns unexpected output.

 #!/bin/bash
+set -e
 # get-ngrok-url.sh - ngrok URL 확인 및 Vercel 환경변수 형식 출력
 
 # ngrok API에서 터널 정보 가져오기
 NGROK_API="http://localhost:4040/api/tunnels"
 
 # ngrok 실행 확인
-if ! curl -s "$NGROK_API" > /dev/null 2>&1; then
+if ! curl -s "$NGROK_API" >/dev/null 2>&1; then
     echo "❌ ngrok이 실행 중이 아닙니다!"

16-22: Make URL extraction more robust with explicit error checking.

The grep/sed pipeline (lines 17, 25) is fragile. If the JSON format changes or contains unexpected values, it will silently fail. Use jq if available, or add explicit validation.

 # URL 추출
-NGROK_URL=$(curl -s "$NGROK_API" | grep -oP '"public_url":"https://[^"]+' | head -1 | cut -d'"' -f4)
+NGROK_RESPONSE=$(curl -s "$NGROK_API")
+NGROK_URL=$(echo "$NGROK_RESPONSE" | grep -oP '"public_url":"https://[^"]+' | head -1 | cut -d'"' -f4)
 
 if [ -z "$NGROK_URL" ]; then
     echo "❌ ngrok URL을 가져올 수 없습니다!"
+    echo "Response: $NGROK_RESPONSE" >&2
     exit 1
 fi

Better yet, if jq is available:

+if command -v jq >/dev/null 2>&1; then
+    NGROK_URL=$(curl -s "$NGROK_API" | jq -r '.tunnels[0].public_url')
+else
+    NGROK_URL=$(echo "$NGROK_RESPONSE" | grep -oP '"public_url":"https://[^"]+' | head -1 | cut -d'"' -f4)
+fi
skyvern-ngrok.sh (2)

24-38: Break down ngrok installation command for readability.

The installation command (lines 28-32) spans multiple lines making it hard to copy/paste. Consider formatting it as a single inline command or with clearer line continuation.

     echo ""
     echo "설치 방법:"
-    echo "  curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \\"
-    echo "    sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \\"
-    echo "    echo 'deb https://ngrok-agent.s3.amazonaws.com buster main' | \\"
-    echo "    sudo tee /etc/apt/sources.list.d/ngrok.list && \\"
-    echo "    sudo apt update && sudo apt install ngrok"
+    echo "  # 1단계: GPG 키 추가"
+    echo "  curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc"
+    echo ""
+    echo "  # 2단계: 저장소 추가"
+    echo "  echo 'deb https://ngrok-agent.s3.amazonaws.com buster main' | sudo tee /etc/apt/sources.list.d/ngrok.list"
+    echo ""
+    echo "  # 3단계: 설치"
+    echo "  sudo apt update && sudo apt install ngrok"

34-36: Provide direct link to ngrok authentication token retrieval.

Line 36 references the dashboard URL for auth token, which is good, but could be more explicit about the next step (copying the token and running the auth command).

     echo ""
     echo "설치 후 인증:"
-    echo "  ngrok config add-authtoken YOUR_NGROK_AUTH_TOKEN"
+    echo "  1. https://dashboard.ngrok.com/get-started/your-authtoken 에서 토큰 복사"
+    echo "  2. ngrok config add-authtoken <YOUR_TOKEN_HERE>"
-    echo "  (https://dashboard.ngrok.com/get-started/your-authtoken 에서 토큰 확인)"
SKYVERN_ARCHITECTURE_ANALYSIS.md (2)

4-4: Wrap bare URLs in markdown links.

Lines 4 and 269-271 contain bare URLs that should be wrapped in markdown link syntax for proper rendering and linting compliance.

 **분석 기준**: 커밋 `5b530ca` (2025-11-28)
-**리포지토리**: https://github.com/Skyvern-AI/skyvern
+**리포지토리**: [https://github.com/Skyvern-AI/skyvern](https://github.com/Skyvern-AI/skyvern)

And for the resources section:

-- **공식 문서**: https://www.skyvern.com/docs/
-- **Discord 커뮤니티**: https://discord.gg/fG2XXEuQX3
-- **GitHub**: https://github.com/skyvern-ai/skyvern
+- **공식 문서**: [https://www.skyvern.com/docs/](https://www.skyvern.com/docs/)
+- **Discord 커뮤니티**: [https://discord.gg/fG2XXEuQX3](https://discord.gg/fG2XXEuQX3)
+- **GitHub**: [https://github.com/skyvern-ai/skyvern](https://github.com/skyvern-ai/skyvern)

Also applies to: 269-271


59-59: Add language specifiers to code blocks.

Multiple code blocks lack language identifiers. Lines 59, 128, 297, and 342 should have language specifications (bash, python, javascript, etc.) for consistent rendering and markdown linting.

 ### 1.3 데이터 흐름도
 
-```
+```
 [사용자 요청] → [FastAPI Server] → [ForgeAgent]

Similar fixes needed for Python code blocks (add python identifier), JavaScript blocks (add javascript), and bash blocks (add bash).

Also applies to: 128-128, 297-297, 342-342

skyvern-restart.sh (2)

8-8: Add error handling for skyvern-stop.sh dependency.

Line 8 invokes ./skyvern-stop.sh without checking if it exists or is executable, which can silently fail if the script is missing or has incorrect permissions.

- ./skyvern-stop.sh
+ if [ ! -f ./skyvern-stop.sh ]; then
+   echo "❌ Error: skyvern-stop.sh not found in $(pwd)"
+   exit 1
+ fi
+ ./skyvern-stop.sh || { echo "❌ Failed to stop existing services"; exit 1; }

Alternatively, consider using set -o pipefail near the top of the script to catch command failures more systematically.


34-40: Replace hardcoded sleep with polling for service readiness.

Lines 38-39 use a fixed 30-second sleep, which is either insufficient or wasteful. Implement a readiness check instead.

# Poll for Skyvern readiness (max 60 seconds)
echo "⏳ Waiting for Skyvern to be ready..."
for i in {1..12}; do
  if curl -s http://localhost:8000/docs >/dev/null 2>&1; then
    echo "✅ Skyvern is ready!"
    break
  fi
  [ $i -lt 12 ] && sleep 5
done
docs/ISSUE_RESOLUTION_2025-11-30.md (1)

34-62: Clarify ngrok free tier limitations.

Line 34–51 (ngrok solution) does not mention that the free tier has session timeout limits (~2 hours) and regenerates the URL on each restart. For production SaaS deployment, this limitation should be explicitly stated so developers understand the trade-off.

Consider adding:

**⚠️ 제한사항**: ngrok 무료 플랜은 세션이 2시간마다 끊어지고 URL이 재생성됩니다. 
프로덕션 배포에는 **Cloudflare Named Tunnel**이나 **유료 ngrok** 권장.
docs/chat-logs/cursor/cursor.md (2)

1-50: Chat logs contain incomplete/fragmented conversational output.

Lines 1–50 show raw conversation fragments with tool names like [5 tools called], [3 tools called] (lines 9, 13, 21, 25, etc.) without revealing what tools were actually executed. This makes the logs difficult to follow and reduces their educational value.

For public repository documentation, consider:

  • Option 1: Clean and curate these logs into proper narrative guides in docs/ (not docs/chat-logs/)
  • Option 2: If keeping as chat logs, add a README explaining the format and providing index/TOC

245-312: Duplicate content: same deployment guidance repeated.

Lines 245–312 repeat the GitHub push summary and checklist that appears elsewhere in the file (e.g., around lines 115–240). This suggests the file is raw chat output without deduplication.

For a public-facing repository, consolidate related information into a single curated section or split into separate documents by topic.

docs/chat-logs/gemini/gemini-1.md (1)

500-600: Large code snippets inline with documentation.

Lines ~500–600 contain embedded Python and JavaScript code snippets that should be:

  • Moved to /examples/ or /snippets/ directory
  • Referenced via links in documentation
  • Not duplicated if they appear elsewhere in the codebase

Example (lines 497–540): Full NotebookLM prompt replicated. Better approach:

See: `docs/prompts/notebooklm-skyvern-guide.md` for complete NotebookLM integration prompt.

echo ""

# 실시간 로그 확인
powershell.exe -Command "cd '$WIN_PATH'; & 'C:\Program Files\Docker\Docker\resources\bin\docker-compose.exe' logs -f --tail=100"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the docker-logs.sh file
find . -name "docker-logs.sh" -type f | head -20

Repository: Skyvern-AI/skyvern

Length of output: 180


🌐 Web query:

Docker Compose Windows PATH environment variable docker compose command availability

💡 Result:

Short answer

  • On Windows the recommended way to get the docker compose command is Docker Desktop (it bundles Compose v2 and exposes it as the Docker CLI subcommand docker compose). Install/enable Docker Desktop and the command will be available when Docker Desktop is running. [1][5]

If you have a standalone Compose binary (legacy docker-compose.exe)

  • That binary must be on your PATH (e.g., %ProgramFiles%\Docker or the folder where you put docker-compose-windows-x86_64.exe). If it is not in PATH the shell will not find docker-compose (or docker-compose.exe). Add the folder to the System PATH and restart your shell. [3][2]

Commands to check

  • Docker Desktop / Compose v2: docker compose version.
  • Standalone/legacy: docker-compose --version.
    If either returns “not found”, either Docker Desktop is not running/installed or the appropriate executable is not on PATH. [1][3]

Useful references

  • Docker Compose install (Docker Desktop/Compose v2): Docker docs. [1]
  • Standalone (Windows Server / legacy docker-compose.exe) and PATH notes. [3]
  • Migration/alias notes (docker compose vs docker-compose and Docker Desktop aliasing). [5]

References
[1] https://docs.docker.com/compose/install/
[2] https://docs.docker.com/reference/cli/docker/compose/
[3] https://docs.docker.com/compose/install/standalone/
[5] https://www.docker.com/blog/announcing-compose-v2-general-availability/


Use docker compose command from system PATH instead of hardcoded Docker Desktop installation path.

The hardcoded path C:\Program Files\Docker\Docker\resources\bin\docker-compose.exe is not portable—Docker Desktop installation paths vary across different versions and custom installations. Modern Docker Desktop (Compose v2) exposes docker compose as a CLI subcommand available on the system PATH when Docker Desktop is running. Use the suggested fix:

-powershell.exe -Command "cd '$WIN_PATH'; & 'C:\Program Files\Docker\Docker\resources\bin\docker-compose.exe' logs -f --tail=100"
+powershell.exe -Command "cd '$WIN_PATH'; docker compose logs -f --tail=100"

This approach is more portable and aligns with Docker's recommended practices.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
powershell.exe -Command "cd '$WIN_PATH'; & 'C:\Program Files\Docker\Docker\resources\bin\docker-compose.exe' logs -f --tail=100"
powershell.exe -Command "cd '$WIN_PATH'; docker compose logs -f --tail=100"
🤖 Prompt for AI Agents
In docker-logs.sh around line 18, the script invokes a hardcoded Docker Desktop
binary path which is not portable; replace that call with the portable system
PATH invocation using the Docker CLI subcommand (i.e., use "docker compose"
instead of the full C:\Program Files\...docker-compose.exe) so the script relies
on the user's PATH and modern Compose v2 behavior; update the powershell command
to call "docker compose logs -f --tail=100" in the same working directory and
remove the hardcoded absolute executable path.

Comment on lines +1 to +100
**shinjadong/skyvern**

최적화된 프롬프트 <system> 당신은 **오픈소스 코드베이스 분석 전문가**입니다.

* 대규모 Python 프로젝트의 아키텍처를 역공학(Reverse Engineering)하는 능력
* 코드 흐름을 추적하여 "이 기능은 어디서 시작해서 어디서 끝나는지" 매핑
* 개발자가 즉시 수정 가능한 수준의 구체적 파일/함수/라인 지목 </system>

<mission> \*\*Skyvern\*\* (https://github.com/Skyvern-AI/skyvern) 리포지토리를 분석하여, "네이버 블로그 자동화" 프로젝트에 필요한 \*\*핵심 코드 위치\*\*\*\*수정 포인트\*\*를 개발자가 즉시 활용할 수 있는 \*\*코드 지도(Code Map)\*\*로 작성하십시오. </mission> <context> <project\_goal> - 최종 목표: 네이버 블로그 자동 포스팅 (로그인 유지, 스마트에디터 제어, 이미지 업로드) - 핵심 요구사항: 1. 기존 Chrome 프로필 로드 (캡차 우회) 2. 시각적 디버깅 (Manus AI처럼 박스+번호 오버레이) 3. Local LLM(Ollama) 또는 저비용 모델(GPT-4o-mini) 연동 </project\_goal><user\_interest> 사용자는 특히 \*\*"Manus AI"\*\*처럼 화면에 **Bounding Box + Label**을 그려서 "AI가 뭘 보고 있는지" 시각화하는 기능에 큰 관심이 있습니다. 이 기능의 **정확한 구현 위치**를 반드시 찾아주십시오. </user\_interest>

<analysis\_constraints>

* 분석 기준: **최신 main 브랜치** (커밋 해시 명시 권장)
* 언어: Python 3.10+ 기준
* 추정이 아닌 **실제 파일 경로**만 제시 (존재 여부 검증 필수)
* 파일이 없거나 구조가 다르면 "확인 필요" 표기 </analysis\_constraints> </context>

<analysis\_methodology> 다음 순서로 체계적으로 분석하십시오:

<step\_1 name="전체 구조 파악">

1. 리포지토리 클론 또는 GitHub 탐색
2. 최상위 디렉토리 구조 매핑
3. `<span><span>pyproject.toml</span></span>`, `<span><span>setup.py</span></span>`, `<span><span>requirements.txt</span></span>`로 핵심 의존성 파악
4. `<span><span>README.md</span></span>`, `<span><span>docs/</span></span>` 폴더로 공식 아키텍처 문서 확인 </step\_1>

<step\_2 name="엔트리포인트 추적">

1. `<span><span>main.py</span></span>` 또는 `<span><span>__main__.py</span></span>` 찾기
2. CLI 명령어 정의 위치 (`<span><span>click</span></span>`, `<span><span>typer</span></span>`, `<span><span>argparse</span></span>` 사용 여부)
3. 서버 실행 시 호출되는 첫 함수 추적 </step\_2>

<step\_3 name="핵심 모듈 분석"> 각 타겟 기능에 대해:

1. 키워드 검색 (예: "bounding\_box", "overlay", "screenshot")
2. 클래스/함수 정의 위치 확인
3. 호출 체인(Call Chain) 역추적
4. 설정 파일과의 연결점 파악 </step\_3>

<step\_4 name="수정 포인트 도출">

1. 설정만으로 변경 가능한 것 vs 코드 수정 필요한 것 분류
2. 수정 시 영향 범위(Side Effect) 분석
3. 테스트 코드 존재 여부 확인 </step\_4> </analysis\_methodology>

<analysis\_targets> 우선순위 순으로 분석하십시오:

<target\_1 name="시각적 인식 엔진" priority="최우선" tag="MANUS\_FEATURE"> **질문**: 웹페이지에서 상호작용 가능한 요소를 탐지하고, 스크린샷 위에 **Bounding Box + 번호 라벨**을 그리는 코드는 어디에 있습니까?

**찾아야 할 것**:

* 스크린샷 캡처 함수
* 요소 탐지 로직 (DOM 기반 vs Vision 기반)
* 오버레이 렌더링 함수 (PIL, OpenCV, 또는 브라우저 inject)
* 디버깅 모드 ON/OFF 설정 위치

**예상 키워드**: `<span><span>bounding_box</span></span>`, `<span><span>overlay</span></span>`, `<span><span>annotate</span></span>`, `<span><span>highlight</span></span>`, `<span><span>draw_rect</span></span>`, `<span><span>label</span></span>` </target\_1>

<target\_2 name="LLM Provider 설정" priority="높음" tag="BRAIN\_CONFIG"> **질문**: OpenAI 대신 **Ollama** 또는 **GPT-4o-mini**로 변경하려면 어떤 파일의 어떤 값을 수정해야 합니까?

**찾아야 할 것**:

* LLM 클라이언트 추상화 인터페이스 (Provider Pattern)
* 모델명/엔드포인트 설정 위치
* API 키 환경변수 매핑
* Ollama 지원 여부 (이미 구현? 추가 필요?)

**예상 키워드**: `<span><span>llm_provider</span></span>`, `<span><span>openai</span></span>`, `<span><span>model</span></span>`, `<span><span>client</span></span>`, `<span><span>completion</span></span>` </target\_2>

<target\_3 name="브라우저 제어" priority="높음" tag="HANDS\_CONTROL"> **질문**: 클릭, 타이핑, 스크롤, 파일 업로드를 수행하는 **Playwright 래퍼 코드**는 어디에 있습니까?

**찾아야 할 것**:

* Playwright 초기화 및 브라우저 실행 코드
* **Chrome 프로필(User Data Dir) 로드 설정 위치**
* 각 액션(click, type, scroll, upload) 함수 정의
* iFrame 진입/탈출 처리 로직

**예상 키워드**: `<span><span>playwright</span></span>`, `<span><span>browser</span></span>`, `<span><span>page</span></span>`, `<span><span>click</span></span>`, `<span><span>fill</span></span>`, `<span><span>user_data_dir</span></span>`, `<span><span>launch</span></span>` </target\_3>

<target\_4 name="워크플로우 엔진" priority="중간" tag="TASK\_ENGINE"> **질문**: YAML/JSON 태스크 파일을 파싱하고 순차 실행하는 \*\*메인 루프(Orchestrator)\*\*는 어디에 있습니까?

**찾아야 할 것**:

* 태스크 파일 스키마 정의
* 파싱 로직
* 실행 루프 (while/for)
* 에러 핸들링 및 재시도 로직

**예상 키워드**: `<span><span>task</span></span>`, `<span><span>workflow</span></span>`, `<span><span>execute</span></span>`, `<span><span>step</span></span>`, `<span><span>yaml</span></span>`, `<span><span>schema</span></span>` </target\_4>

<target\_5 name="설정 파일 구조" priority="중간" tag="CONFIG\_MAP"> **질문**: 전체 시스템 설정을 제어하는 **Config 파일들**의 위치와 각 설정 항목의 역할은 무엇입니까?

**찾아야 할 것**:

* `<span><span>.env</span></span>`, `<span><span>config.yaml</span></span>`, `<span><span>settings.py</span></span>`
* 환경별(dev/prod) 설정 분리 여부
* 필수 vs 선택 설정 항목 구분 </target\_5> </analysis\_targets>

<output\_format> 다음 구조로 결과를 작성하십시오:
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Extracted chat log presents internal tool traces and intermediate errors.

Lines 1–100 contain metadata like [5 tools called], <tool_use_error>, bash command outputs with stderr. While this shows the analysis process, it's not suitable for end-user documentation without filtering and context.

For public documentation, create a curated summary (e.g., ARCHITECTURE.md, DEPLOYMENT.md) extracted from these logs, not the logs themselves.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🤖 Prompt for AI Agents
docs/chat-logs/claudecode-cloud/claudecode-cloud.md lines 1-100: the content
currently contains raw internal tool traces, errors and stderr outputs which are
not suitable for public docs — replace this block with a short curated summary
describing what the logs contained (e.g., tools invoked, high-level error
categories, and outcomes), remove any sensitive or stack-trace details, and
point readers to newly created developer-only artifacts (ARCHITECTURE.md and
DEPLOYMENT.md) for full provenance; ensure the summary mentions where full raw
logs are stored (internal log path) and include a one-line remediation/action
note (e.g., "See ARCHITECTURE.md for cleaned architecture mapping and
DEPLOYMENT.md for environment/setup steps").

Comment on lines +1 to +100
**Gemini**

**[케어온]마일스톤 진짜**

#



#

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

**고정된 채팅**

교보문고 강남점 오픈 시간 및 분실물 문의

케어온 디지털 트윈 OS 기술 설계

생존 전략: 위기를 기회로

갤럭시S25울트라 당근 썸네일 제작

노트 정리: 비즈니스 빌더를 위한 전략

환율 폭등 원인 분석 및 해결책 제시

Skyvern 마스터 가이드 연구 계획

네이버 블로그 캡차 해결 전략

Deep Agents: 자율 에이전트 구축 설명

음악 유튜브 수익화 전략 가이드

네이버 블로그 캡차 해결 전략

AI 음악 유튜브 시장 블루오션 발굴

[웹소설]리서치

# Gemini와의 대화

강남 집에 인터넷 이 맛이갔어 ... 그래서 새로 계약했는데 설치가 일주일정도 후에 된대. 그동안 내가 무조건 폰팜 구축에 집중해야하는데 어떻게해야할지모르겠어. 시흥 집에 있으면 내가 중요한 일에 집중을 못하고 강남근처에있긴해야하는데

사장님, **이건 위기가 아니라 '기회'입니다.**

오히려 잘 됐습니다. 우리가 구축하려는 **'스마트폰 팜(Phone Farm)'의 본질**이 뭡니까? **"유선 인터넷(ISP)에 의존하지 않고, 모바일 네트워크로 독립하는 것"** 아닙니까?

인터넷 설치를 기다리는 일주일은 \*\*"유선망이 끊겨도 돌아가는 무적의 시스템"\*\*을 구축할 수 있는 **최고의 '실전 훈련(Live Drill)' 기간**입니다.

시흥으로 가지 마세요. **강남 방을 '요새'로 만드십시오.** 지금 가지고 계신 장비(아이폰 3대)만으로 \*\*'자가 발전 인터넷망'\*\*을 구축하고 폰 팜 구축에 '과몰입'할 수 있는 \*\*[비상계엄 작전]\*\*을 짜드립니다.

---

### 🚨 [작전명: Broken Web] 일주일 생존 & 구축 전략

**핵심 개념**: **"아이폰 3대는 훌륭한 모뎀이다."** 사장님은 이미 인터넷 선이 3개나 더 있습니다. (아이폰 XR 2대, XS 1대)

#### 1. 네트워크 복구: "테더링 3중망 구축"

강남 방의 인터넷이 죽었으니, **아이폰을 '메인 공유기'로 승격**시킵니다.

* **1호기 (아이폰 XS)****개발용 노트북**에 USB 연결 (USB 테더링)
* *용도*: 사장님의 메인 인터넷 (검색, 챗GPT, 코딩용). 속도 가장 빠름.
* **2호기 (아이폰 XR)****강남 데스크탑**에 USB 연결 (USB 테더링)
* *용도*: Agent 2 테스트 및 서버 구동용.
* **3호기 (아이폰 XR)****예비용 / Redroid 테스트용**

> **[Tip]**: 오늘 주문한 **유전원 허브**가 내일 오면, 노트북에 아이폰 3대를 다 꽂아서 **'부하 분산(Load Balancing)'** 테스트를 미리 해볼 수 있습니다. 전화위복입니다.
---

### 📅 [일주일 로드맵] 인터넷 없이 '공장' 짓기

이 기간 동안은 \*\*'대용량 다운로드'\*\*는 피하고, \*\*'로컬 개발(Local Dev)'\*\*\*\*'하드웨어 세팅'\*\*에 집중합니다.

#### **Day 1 (오늘): "다운로드 특공대 & 로컬 세팅"**

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Chat log formatting: Mixed conversation fragments and unstructured prompts.

Lines 1–100 show raw Gemini chat output with Korean conversational text mixed with structured prompt templates. While the technical content appears sound, the file lacks:

  • Clear section headings and navigation
  • Separation between user prompts and AI responses
  • Index or table of contents

For production SaaS documentation, this should be:

  1. Split into separate files by topic (e.g., prompts/naver-captcha.md, prompts/skyvern-architecture.md)
  2. Edited for clarity and removed redundant conversational backfill
  3. Indexed in a parent docs/chat-logs/README.md
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


11-11: Multiple headings with the same content

(MD024, no-duplicate-heading)


13-13: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


15-15: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


17-17: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


19-19: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


21-21: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


23-23: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


25-25: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


27-27: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


29-29: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


31-31: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


33-33: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


35-35: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


77-77: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

Comment on lines +113 to +120
### 생성된 API 키

```
Organization ID: o_467286173652022586
API Key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
(만료: 100년 후)
```

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove or redact the JWT token example.

Line 117 contains what appears to be a real JWT token (or at minimum, a realistic example that looks extractable). API credentials and tokens should never be committed to version control, even partially.

Apply this diff to redact the token:

 ### 생성된 API 키
 

Organization ID: o_467286173652022586
-API Key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
-(만료: 100년 후)
+API Key: [REDACTED - see .env.local or admin panel]
+(만료: 100년 후)


If this is a real token that exists in the file, immediately rotate or revoke it.

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
### 생성된 API 키

🧰 Tools
🪛 Gitleaks (8.29.1)

[high] 117-117: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 markdownlint-cli2 (0.18.1)

115-115: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In docs/ISSUE_REPORT_2025-11-30.md around lines 113 to 120, remove the visible
JWT-like API key and replace it with a redacted placeholder exactly as: "API
Key: [REDACTED - see .env.local or admin panel]" (keep the Organization ID and
expiry line but update the API Key line), commit the change, and if the token in
the file is an actual active credential immediately rotate or revoke it and
update any docs to reference secure storage instead of embedding tokens.

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove user-specific hardcoded paths.

This guide contains hardcoded paths specific to a user account (/home/tlswk/projects/skyvern/), making it unsuitable as general documentation.

Replace hardcoded paths with relative or generic examples:

-nano /home/tlswk/projects/skyvern/.env
+nano .env
+# 또는
+nano ~/.skyvern/.env
-cd /home/tlswk/projects/skyvern
+cd ~/projects/skyvern
+# 또는 프로젝트 디렉토리로 이동:
+cd /path/to/skyvern
 ## 📋 유용한 명령어
 
-모든 명령어는 프로젝트 디렉토리에서 실행하세요:
-```bash
-cd /home/tlswk/projects/skyvern
-```
+모든 명령어는 Skyvern 프로젝트 디렉토리에서 실행하세요.
 ## 📁 프로젝트 구조
 

-/home/tlswk/projects/skyvern/
+~/projects/skyvern/
├── .env # 환경 설정 파일
├── .venv/ # Python 가상환경



Also applies to: 45-46, 61-61, 140-152

<details>
<summary>🤖 Prompt for AI Agents</summary>

In README_시작하기.md around line 33 (and also apply same changes at 45-46, 61, and
140-152): remove the user-specific hardcoded path /home/tlswk/projects/skyvern
and replace it with a generic instruction that commands should be run from the
Skyvern project directory (예: "모든 명령어는 Skyvern 프로젝트 디렉토리에서 실행하세요.") and use
generic path examples like ~/projects/skyvern or ${PROJECT_DIR} in listings;
update the file listings and examples to use those generic paths and ensure any
commands reference the project root rather than a specific user home.


</details>

<!-- This is an auto-generated comment by CodeRabbit -->

권장 `LLM_KEY`: `OLLAMA`
참고: Ollama는 아직 비전을 지원하지 않습니다.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update documentation to match code changes.

This line states that Ollama doesn't support vision yet, but the code change in skyvern/forge/sdk/api/llm/config_registry.py (line 1340) enables vision support for Ollama with a comment indicating it supports vision models like llava and qwen2-vl.

Either:

  1. Remove or update this note if Ollama now supports vision models, or
  2. Revert the code change if Ollama doesn't actually support vision yet

Based on learnings, update relevant documentation when making code changes.

🤖 Prompt for AI Agents
In README.ko.md around line 484, the sentence "참고: Ollama는 아직 비전을 지원하지 않습니다."
conflicts with a code change that enables Ollama vision support; either update
the note to reflect that Ollama now supports vision models (mention supported
models like llava and qwen2-vl or link to the specific config/commit) or revert
the code change in skyvern/forge/sdk/api/llm/config_registry.py if Ollama truly
does not support vision; verify upstream Ollama support first, then edit this
line to a precise, accurate statement (or remove it) so the docs match the
current code.

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix broken table of contents links.

The links in the table of contents (lines 4-8) use anchor fragments that don't match the actual heading IDs. Markdown heading anchors are auto-generated by removing special characters and converting to lowercase with hyphens.

Apply this diff to fix the anchor links:

-1. [환경 준비 완료 사항](#환경-준비-완료-사항)
-2. [LLM API 키 설정하기](#llm-api-키-설정하기)
-3. [Skyvern 실행하기](#skyvern-실행하기)
-4. [접속 및 사용법](#접속-및-사용법)
-5. [문제 해결](#문제-해결)
+1. [환경 준비 완료 사항](#-환경-준비-완료-사항)
+2. [LLM API 키 설정하기](#-llm-api-키-설정하기)
+3. [Skyvern 실행하기](#-skyvern-실행하기)
+4. [접속 및 사용법](#-접속-및-사용법)
+5. [문제 해결](#-문제-해결)

Alternatively, test the links by rendering the markdown to verify which anchors are actually generated.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

4-4: Link fragments should be valid

(MD051, link-fragments)


5-5: Link fragments should be valid

(MD051, link-fragments)


6-6: Link fragments should be valid

(MD051, link-fragments)


7-7: Link fragments should be valid

(MD051, link-fragments)


8-8: Link fragments should be valid

(MD051, link-fragments)

🤖 Prompt for AI Agents
In SKYVERN_실행가이드.md around lines 3 to 8, the table of contents anchor links do
not match the auto-generated heading IDs; update the links on lines 4–8 so each
fragment matches Markdown's heading-to-anchor rules (convert to lowercase,
remove special characters, replace spaces with hyphens), for example change the
anchor text to the exact hyphenated, lowercased form produced by your Markdown
renderer (or render the file to verify) so each ToC entry points to its
corresponding heading.

# ========================
# Authentication
# ========================
VITE_SKYVERN_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjQ5MDk0NDE3NDAsInN1YiI6Im9fNDY3Mjg2MTczNjUyMDIyNTg2In0.AQUHkS-9QtvzlGmaoURLoxzkoRX5OiEgGslnsJ0zupU
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Remove hardcoded API key from version control.

This file contains a JWT token that appears to be a real API key. Production environment files with actual secrets should never be committed to version control.

Take the following actions:

  1. Remove this file from the repository:
git rm --cached skyvern-frontend/.env.production.local
  1. Add it to .gitignore:
# Frontend
node_modules
.env.backup
.env.old
+.env.production.local
  1. Rotate the exposed API key immediately

  2. Create a template file instead (e.g., .env.production.example) with placeholder values:

VITE_SKYVERN_API_KEY=your_api_key_here
  1. Document in README how to obtain and configure the production API key
🧰 Tools
🪛 Gitleaks (8.29.1)

[high] 14-14: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🤖 Prompt for AI Agents
In skyvern-frontend/.env.production.local at line 14 there is a hardcoded JWT
API key that must be removed from version control; remove the file from the
repository history/staging (unstage and delete tracked copy), add
.env.production.local to .gitignore, rotate the exposed API key immediately with
the provider, create a template file .env.production.example containing a
placeholder key value for onboarding, and update the README with instructions on
how to obtain and configure the production API key and where to place the real
.env.production.local file locally.

f"ollama/{ollama_model_name}",
["OLLAMA_SERVER_URL", "OLLAMA_MODEL"],
supports_vision=False, # Ollama does not support vision yet
supports_vision=True, # Ollama supports vision models (llava, qwen2-vl, etc.)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Ollama vision models support llava qwen2-vl 2024 2025

💡 Result:

Short answer: Yes. Ollama's model library includes LLaVA and Qwen (Qwen2.5‑VL / Qwen2‑VL family) vision‑language models — e.g., LLaVA is listed and Qwen2.5‑VL is available (requires Ollama ≥0.7.0). [1][2]

Sources:

  • Ollama models list (shows LLaVA and Qwen2.5‑VL). [1]
  • Ollama Qwen2.5‑VL library page (readme notes required Ollama 0.7.0). [2]

🏁 Script executed:

fd "README.ko.md" --type f

Repository: Skyvern-AI/skyvern

Length of output: 180


Update README.ko.md: Ollama now supports vision models.

Ollama does support vision-language models including LLaVA and Qwen2-VL (Qwen2.5-VL requires Ollama ≥0.7.0). The code change to supports_vision=True is correct. However, line 484 in README.ko.md incorrectly states "Ollama does not yet support vision" and should be updated to reflect current capabilities.

🤖 Prompt for AI Agents
In README.ko.md around line 484, the doc currently states "Ollama does not yet
support vision"; update that sentence to reflect that Ollama now supports
vision-language models (e.g., LLaVA and Qwen2-VL) and note that Qwen2.5-VL
requires Ollama ≥0.7.0 — replace the negative statement with a brief positive
one mentioning supported models and the version requirement.

- Cloudflare Tunnel + custom domain configuration
- Vercel frontend domain setup (app.jadong.shop)
- WSL backend tunnel setup (api.jadong.shop)
- Step-by-step guide with Gabia nameserver migration
Copy link
Contributor

@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)
docs/DOMAIN_SETUP_JADONG_SHOP.md (3)

5-5: Specify language identifiers for fenced code blocks.

Per markdown linting standards, code blocks should declare their language. The ASCII diagram (line 5) should use ```text and the nameserver example (line 35) should use ```text or be converted to a list.

Apply these diffs:

-```
+```text
 ┌─────────────────────────────────────────────────────────────────┐
 │                        jadong.shop                               │
 ├─────────────────────────────────────────────────────────────────┤
-```
+```text
 # Cloudflare 네임서버 (예시 - 실제 값은 다를 수 있음)
 ns1.cloudflare.com
 ns2.cloudflare.com
-```
+```

Also applies to: 35-35


22-22: Wrap bare URL in markdown link format.

Per markdown linting (MD034), bare URLs should be formatted as links. Change line 22 from https://dash.cloudflare.com to [https://dash.cloudflare.com](https://dash.cloudflare.com).


1-204: Consider adding English translation or summary for accessibility.

This comprehensive setup guide is written entirely in Korean, which may limit discoverability and usability for developers who don't read Korean. Given this appears to be a core onboarding document referenced from other setup guides, consider adding an English version or at minimum an English summary and table of contents to support the broader development team.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1794548 and a38b458.

📒 Files selected for processing (1)
  • docs/DOMAIN_SETUP_JADONG_SHOP.md (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T17:46:44.733Z
Learning: Update relevant documentation when making code changes
🪛 markdownlint-cli2 (0.18.1)
docs/DOMAIN_SETUP_JADONG_SHOP.md

5-5: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


22-22: Bare URL used

(MD034, no-bare-urls)


35-35: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

Comment on lines +86 to +87
originRequest:
noTLSVerify: true
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Search for related configuration, certificates, or explanations in the codebase
fd -e md -e json -e yaml -e yml | xargs grep -l "noTLSVerify\|caPool\|TLS\|certificate" 2>/dev/null | head -20

Repository: Skyvern-AI/skyvern

Length of output: 180


🏁 Script executed:

# Check the specific file for context around line 86-87
cat -n docs/DOMAIN_SETUP_JADONG_SHOP.md | sed -n '75,100p'

Repository: Skyvern-AI/skyvern

Length of output: 180


🌐 Web query:

Cloudflare Tunnel noTLSVerify security best practices self-signed certificates

💡 Result:

Concise best-practices for Cloudflare Tunnel + self-signed certs (avoiding insecure noTLSVerify)

  1. Prefer validating TLS instead of disabling it

    • Use Cloudflare Origin CA or a publicly‑trusted cert on the origin and run Full (strict) / Strict modes whenever possible. This prevents active MITM attacks. [1][2]
  2. If you must accept self‑signed certs, prefer scoped trust over global disable

    • Use cloudflared’s caPool/origin CA path (trust a specific CA bundle) or set noTLSVerify per‑ingress only as a last resort — don’t set a global noTLSVerify=true unless unavoidable. Global --no-tls-verify can be problematic; per‑ingress settings are safer. [3][4]
  3. Treat noTLSVerify as temporary and compensating control

    • noTLSVerify disables certificate validation and allows any origin cert (MITM risk). Use it only for short troubleshooting windows or isolated internal apps, and document/approve its use. [2][5]
  4. Compensating controls if you must disable verification

    • Restrict the Tunnel/ingress to internal IP ranges or private networks.
    • Enforce Zero Trust access policies (Identity, device posture, IP allowlists) for the application.
    • Use Authenticated Origin Pulls or mTLS where possible to ensure Cloudflare is talking to the real origin.
    • Monitor logs/alerts, enable strict TLS timeouts, and limit network exposure (firewall, security groups). [1][3][6]
  5. Certificate lifecycle & configuration hygiene

    • Use short‑lived or rotated certificates, maintain a CA bundle for internal PKI and point cloudflared’s caPool to it.
    • Ensure originServerName / Host header match the cert SAN when using validated modes.
    • Test changes in staging before production. [3][1]

Quick references

  • cloudflared origin parameters (noTLSVerify, caPool): Cloudflare docs. [3]
  • Cloudflare guidance on Full vs Full (strict) and MITM risk: docs & blog. [2][5]
  • Tunnel troubleshooting notes on self‑signed certs and noTLSVerify use cases: Cloudflare docs. [1]
  • cloudflared behaviour/issues discussion (per‑ingress vs global flags): cloudflared GitHub. [4]

If you want, I can: (a) show exact config snippets for cloudflared (ingress example + caPool), or (b) review your current tunnel config and recommend changes.


Reconsider noTLSVerify: true in production tunnel configuration.

Disabling TLS verification between Cloudflare Tunnel and the backend service allows potential MITM attacks. Verify whether your origin service uses a valid certificate; if so, remove this setting. For self-signed certificates, use caPool to specify a trusted CA bundle instead, or address the certificate issue before production deployment.

🤖 Prompt for AI Agents
In docs/DOMAIN_SETUP_JADONG_SHOP.md around lines 86-87, the tunnel config sets
originRequest.noTLSVerify: true which disables TLS verification; remove or set
this to false in production and instead ensure the origin has a valid
certificate. If the origin uses a self-signed or internal CA, replace
noTLSVerify with an explicit caPool pointing to the trusted CA bundle (or
install a proper certificate on the origin) so the tunnel can verify TLS without
disabling security.

shinjadong and others added 2 commits November 30, 2025 18:13
- Add PRODUCTION_DEPLOYMENT.md with architecture overview
- Document Cloudflare Tunnel + Vercel setup
- Add environment variables reference
- Update .gitignore to exclude local env files

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

Co-Authored-By: Claude <[email protected]>
Changed from temporary trycloudflare.com URL to permanent domain:
- VITE_API_BASE_URL → https://api.jadong.shop/api/v1
- VITE_WSS_BASE_URL → wss://api.jadong.shop/api/v1
- VITE_ARTIFACT_API_BASE_URL → https://api.jadong.shop
Copy link
Contributor

@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: 0

♻️ Duplicate comments (1)
skyvern-frontend/.env.production.local (1)

1-22: Critical: This file contains hardcoded credentials and must not be committed to version control.

This issue was previously flagged in past review comments (line 14) but remains unresolved. The file contains a real JWT token (line 14) that enables unauthorized access to your production API. This is a security incident.

Immediate actions required:

  1. Do NOT merge this PR. Remove this file from version control immediately:

    git rm --cached skyvern-frontend/.env.production.local
  2. Rotate the exposed API key with your authentication provider (this JWT is now public in the repository).

  3. Add to .gitignore to prevent future commits:

    echo ".env.production.local" >> skyvern-frontend/.gitignore
  4. Use only .env.production.example as a template with placeholder values for team onboarding.

  5. Force-push to remove this commit from history or use BFG/git-filter-branch to purge the JWT from the repository.

See the previous review comments (line 14) for complete remediation steps. This file should be maintained locally only with actual credentials, never committed to version control.

🧹 Nitpick comments (1)
docs/PRODUCTION_DEPLOYMENT.md (1)

5-17: Specify language for fenced code block.

The ASCII art diagram is missing a language specifier. While this renders correctly, it violates markdown best practices per markdownlint-cli2.

Apply this diff to add a language specifier:

-```
+```text
 +-------------------+     +------------------------+     +------------------+
 |  app.jadong.shop  | --> |      Vercel CDN        | --> |  React Frontend  |
 |   (Frontend)      |     |   (Edge Network)       |     |                  |
 +-------------------+     +------------------------+     +------------------+
@@ ... @@
 |  api.jadong.shop  | --> |  Cloudflare Tunnel     | --> |  WSL2 Ubuntu     |
 |   (Backend API)   |     |  (skyvern-prod)        |     |  localhost:8000  |
 +-------------------+     +------------------------+     +------------------+
-```
+```
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a38b458 and 1a52f25.

📒 Files selected for processing (3)
  • docs/PRODUCTION_DEPLOYMENT.md (1 hunks)
  • skyvern-frontend/.env.production.local (1 hunks)
  • skyvern-frontend/.gitignore (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • skyvern-frontend/.gitignore
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T17:46:44.733Z
Learning: Update relevant documentation when making code changes
📚 Learning: 2025-11-24T17:46:29.802Z
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:46:29.802Z
Learning: Run backend service using `skyvern run server` or run both backend and UI using `skyvern run all`

Applied to files:

  • docs/PRODUCTION_DEPLOYMENT.md
📚 Learning: 2025-11-24T17:46:29.802Z
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:46:29.802Z
Learning: Applies to skyvern-frontend/**/*.{ts,tsx,js,jsx} : Use `npm run lint` and `npm run format` for linting and formatting frontend code in skyvern-frontend/

Applied to files:

  • docs/PRODUCTION_DEPLOYMENT.md
  • skyvern-frontend/.env.production.local
📚 Learning: 2025-11-24T17:46:44.733Z
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T17:46:44.733Z
Learning: Never commit secrets or credentials to version control

Applied to files:

  • skyvern-frontend/.env.production.local
🪛 dotenv-linter (4.0.0)
skyvern-frontend/.env.production.local

[warning] 9-9: [UnorderedKey] The VITE_ARTIFACT_API_BASE_URL key should go before the VITE_WSS_BASE_URL key

(UnorderedKey)


[warning] 20-20: [UnorderedKey] The VITE_ENABLE_LOG_ARTIFACTS key should go before the VITE_ENVIRONMENT key

(UnorderedKey)


[warning] 21-21: [UnorderedKey] The VITE_ENABLE_CODE_BLOCK key should go before the VITE_ENABLE_LOG_ARTIFACTS key

(UnorderedKey)

🪛 Gitleaks (8.29.1)
skyvern-frontend/.env.production.local

[high] 14-14: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🪛 markdownlint-cli2 (0.18.1)
docs/PRODUCTION_DEPLOYMENT.md

5-5: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

- SideNav: 네비게이션 메뉴 한글화
- Settings: 설정 페이지 전체 한글화
- Workflows: 워크플로우 페이지 및 관련 컴포넌트 한글화
  - 폴더 관리 (생성, 편집, 삭제) 다이얼로그
  - 워크플로우 액션 메뉴
  - 가져오기/내보내기 기능
- Discover: 둘러보기 페이지 한글화
  - 예제 케이스 레이블
  - 프롬프트 박스 UI
  - 고급 설정 섹션
- History: 실행 기록 페이지 한글화
  - 테이블 헤더, 검색, 툴팁
- Credentials: 인증 정보 페이지 한글화
  - 탭, 버튼, 모달 다이얼로그
  - 오류 메시지 및 알림
- BrowserSessions: 브라우저 세션 페이지 한글화
  - 테이블 헤더, 상태 메시지
  - 세션 생성 드로어
Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
skyvern-frontend/src/routes/workflows/components/FolderCard.tsx (1)

56-65: Consider translating the aria-label for consistency.

The tooltip content has been localized to Korean, but the aria-label attribute on line 59 remains "Edit folder" in English. For consistency with screen reader users, consider translating it as well.

Apply this diff if you want to maintain consistency:

                      <button
                        onClick={() => setIsEditDialogOpen(true)}
                        className="rounded p-1.5 text-slate-400 transition-colors hover:bg-slate-500/20 hover:text-slate-300"
-                       aria-label="Edit folder"
+                       aria-label="폴더 편집"
                      >
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a52f25 and 0657b7c.

📒 Files selected for processing (19)
  • skyvern-frontend/src/routes/browserSessions/BrowserSessions.tsx (8 hunks)
  • skyvern-frontend/src/routes/credentials/CredentialsList.tsx (2 hunks)
  • skyvern-frontend/src/routes/credentials/CredentialsModal.tsx (8 hunks)
  • skyvern-frontend/src/routes/credentials/CredentialsPage.tsx (5 hunks)
  • skyvern-frontend/src/routes/discover/WorkflowTemplates.tsx (1 hunks)
  • skyvern-frontend/src/routes/history/RunHistory.tsx (8 hunks)
  • skyvern-frontend/src/routes/root/SideNav.tsx (1 hunks)
  • skyvern-frontend/src/routes/runs/RunRouter.tsx (1 hunks)
  • skyvern-frontend/src/routes/settings/Settings.tsx (3 hunks)
  • skyvern-frontend/src/routes/tasks/create/PromptBox.tsx (8 hunks)
  • skyvern-frontend/src/routes/workflows/ImportWorkflowButton.tsx (3 hunks)
  • skyvern-frontend/src/routes/workflows/WorkflowActions.tsx (4 hunks)
  • skyvern-frontend/src/routes/workflows/Workflows.tsx (16 hunks)
  • skyvern-frontend/src/routes/workflows/components/CreateFolderDialog.tsx (2 hunks)
  • skyvern-frontend/src/routes/workflows/components/DeleteFolderButton.tsx (4 hunks)
  • skyvern-frontend/src/routes/workflows/components/EditFolderDialog.tsx (2 hunks)
  • skyvern-frontend/src/routes/workflows/components/FolderCard.tsx (2 hunks)
  • skyvern-frontend/src/routes/workflows/components/ViewAllFoldersDialog.tsx (3 hunks)
  • skyvern-frontend/src/routes/workflows/components/WorkflowFolderSelector.tsx (3 hunks)
✅ Files skipped from review due to trivial changes (3)
  • skyvern-frontend/src/routes/discover/WorkflowTemplates.tsx
  • skyvern-frontend/src/routes/browserSessions/BrowserSessions.tsx
  • skyvern-frontend/src/routes/workflows/components/EditFolderDialog.tsx
🧰 Additional context used
📓 Path-based instructions (2)
skyvern-frontend/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

skyvern-frontend/**/*.{ts,tsx,js,jsx}: Use npm run lint and npm run format for linting and formatting frontend code in skyvern-frontend/
Maintain line length of 120 characters for TypeScript/JavaScript code

Files:

  • skyvern-frontend/src/routes/workflows/components/DeleteFolderButton.tsx
  • skyvern-frontend/src/routes/workflows/Workflows.tsx
  • skyvern-frontend/src/routes/credentials/CredentialsPage.tsx
  • skyvern-frontend/src/routes/credentials/CredentialsList.tsx
  • skyvern-frontend/src/routes/credentials/CredentialsModal.tsx
  • skyvern-frontend/src/routes/workflows/WorkflowActions.tsx
  • skyvern-frontend/src/routes/workflows/components/WorkflowFolderSelector.tsx
  • skyvern-frontend/src/routes/tasks/create/PromptBox.tsx
  • skyvern-frontend/src/routes/workflows/components/FolderCard.tsx
  • skyvern-frontend/src/routes/workflows/components/ViewAllFoldersDialog.tsx
  • skyvern-frontend/src/routes/root/SideNav.tsx
  • skyvern-frontend/src/routes/runs/RunRouter.tsx
  • skyvern-frontend/src/routes/settings/Settings.tsx
  • skyvern-frontend/src/routes/workflows/components/CreateFolderDialog.tsx
  • skyvern-frontend/src/routes/history/RunHistory.tsx
  • skyvern-frontend/src/routes/workflows/ImportWorkflowButton.tsx
**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use async/await patterns for asynchronous operations

Files:

  • skyvern-frontend/src/routes/workflows/components/DeleteFolderButton.tsx
  • skyvern-frontend/src/routes/workflows/Workflows.tsx
  • skyvern-frontend/src/routes/credentials/CredentialsPage.tsx
  • skyvern-frontend/src/routes/credentials/CredentialsList.tsx
  • skyvern-frontend/src/routes/credentials/CredentialsModal.tsx
  • skyvern-frontend/src/routes/workflows/WorkflowActions.tsx
  • skyvern-frontend/src/routes/workflows/components/WorkflowFolderSelector.tsx
  • skyvern-frontend/src/routes/tasks/create/PromptBox.tsx
  • skyvern-frontend/src/routes/workflows/components/FolderCard.tsx
  • skyvern-frontend/src/routes/workflows/components/ViewAllFoldersDialog.tsx
  • skyvern-frontend/src/routes/root/SideNav.tsx
  • skyvern-frontend/src/routes/runs/RunRouter.tsx
  • skyvern-frontend/src/routes/settings/Settings.tsx
  • skyvern-frontend/src/routes/workflows/components/CreateFolderDialog.tsx
  • skyvern-frontend/src/routes/history/RunHistory.tsx
  • skyvern-frontend/src/routes/workflows/ImportWorkflowButton.tsx
🧬 Code graph analysis (2)
skyvern-frontend/src/routes/root/SideNav.tsx (2)
skyvern-frontend/src/components/icons/CompassIcon.tsx (1)
  • CompassIcon (33-33)
skyvern-frontend/src/components/NavLinkGroup.tsx (1)
  • NavLinkGroup (95-95)
skyvern-frontend/src/routes/history/RunHistory.tsx (1)
skyvern-frontend/src/components/Tip.tsx (1)
  • Tip (31-31)
🔇 Additional comments (26)
skyvern-frontend/src/routes/root/SideNav.tsx (1)

23-61: Korean localization looks good!

The navigation labels have been properly translated to Korean with appropriate terminology. The translations are consistent and grammatically correct.

skyvern-frontend/src/routes/workflows/components/FolderCard.tsx (1)

73-75: Korean workflow count format is correct.

The localized format "워크플로우 {count}개" properly follows Korean grammar patterns for counting items.

skyvern-frontend/src/routes/workflows/Workflows.tsx (4)

62-72: Default workflow title properly localized.

The default workflow title has been updated to "새 워크플로우" (New Workflow) in Korean, maintaining consistency with the UI localization.


272-292: Page header and narrative cards translated effectively.

The main heading and all three narrative card descriptions have been properly localized to Korean, maintaining the clarity and intent of the original English text.


343-361: Empty state messaging is clear and informative.

The empty folder state messaging has been well-translated to Korean, providing clear guidance to users about creating and organizing folders.


615-620: Tooltip logic preserved with Korean text.

The conditional tooltip text for parameter visibility correctly uses Korean translations while maintaining the same logic flow (show/hide/no parameters).

skyvern-frontend/src/routes/runs/RunRouter.tsx (1)

87-90: Loading message properly localized.

The loading indicator text has been correctly translated to Korean "작업 정보를 불러오는 중..." which naturally conveys the loading state.

skyvern-frontend/src/routes/workflows/components/DeleteFolderButton.tsx (2)

66-75: Dialog localization is comprehensive and clear.

All dialog text including tooltip, title, and description has been properly translated to Korean. The messaging clearly communicates the delete action to users.

Note: The aria-label on line 60 remains "Delete folder" in English. Consider translating it to "폴더 삭제" for consistency with screen readers.


82-97: Radio group options clearly differentiate deletion modes.

The Korean translations for the two deletion options clearly distinguish between deleting just the folder vs. deleting both the folder and its workflows, which is important for preventing data loss.

skyvern-frontend/src/routes/workflows/ImportWorkflowButton.tsx (3)

73-84: Success and error toasts properly localized.

The toast notifications for YAML/JSON import have been translated to Korean with appropriate success and error messaging. The error message correctly uses the getErrorMessage helper to provide detailed feedback.


107-118: PDF import messaging includes dynamic filename.

The Korean toast messages properly incorporate the dynamic filename using string interpolation (${file.name}), maintaining the informative nature of the notifications.


157-159: Tooltip provides clear import guidance.

The tooltip text clearly communicates that users can import workflows from YAML, JSON, or PDF files in Korean.

skyvern-frontend/src/routes/workflows/WorkflowActions.tsx (2)

110-154: Menu items clearly translated.

The dropdown menu items have been properly localized to Korean:

  • "워크플로우 복제" (Clone Workflow)
  • "내보내기..." (Export as...)
  • "워크플로우 삭제" (Delete Workflow)

The translations are clear and consistent with common UI terminology.


158-166: Delete confirmation dialog uses proper Korean sentence structure.

The dialog description correctly embeds the workflow title within the Korean sentence structure using {workflow.title}, producing natural-sounding text like "워크플로우 [Title]이(가) 삭제됩니다."

skyvern-frontend/src/routes/settings/Settings.tsx (4)

31-61: Settings card and form labels properly localized.

The Settings card title, description, form labels (Environment, Organization), and select placeholders have all been appropriately translated to Korean, maintaining clear user guidance.


65-70: API key section clearly labeled.

The API key card title and the fallback message for missing keys have been properly localized to Korean.


74-89: 1Password integration guidance maintained in Korean.

The 1Password integration card has been localized while preserving the important link to the service account documentation. The Korean text provides clear context for users.


92-99: Azure integration section properly translated.

The Azure integration card title and description are appropriately localized to Korean.

skyvern-frontend/src/routes/history/RunHistory.tsx (1)

150-150: LGTM! Korean localization applied correctly.

All UI strings have been consistently localized to Korean without any changes to component logic or behavior. The translations cover all user-facing text including headers, placeholders, table headers, tooltips, and empty states.

Also applies to: 161-161, 174-178, 194-194, 230-230, 296-297, 328-328, 431-431

skyvern-frontend/src/routes/tasks/create/PromptBox.tsx (1)

56-111: LGTM! Comprehensive Korean localization applied.

All user-facing strings have been translated to Korean, including:

  • Example case labels
  • Main prompt heading and placeholder
  • Toast notifications (success and error messages)
  • Skyvern version descriptions
  • Advanced settings header

The localization is thorough and no functional logic has been altered.

Also applies to: 208-209, 227-228, 243-243, 258-258, 290-291, 300-301, 369-369

skyvern-frontend/src/routes/workflows/components/WorkflowFolderSelector.tsx (1)

79-79: LGTM! Folder selector UI localized to Korean.

All UI strings in the WorkflowFolderSelector component have been translated to Korean, maintaining consistent localization with the rest of the workflows UI.

Also applies to: 83-83, 109-109, 132-132

skyvern-frontend/src/routes/credentials/CredentialsList.tsx (1)

12-13: LGTM! Empty state messages localized.

All credential empty-state messages have been translated to Korean, providing a consistent experience across the credentials feature.

Also applies to: 47-47

skyvern-frontend/src/routes/credentials/CredentialsModal.tsx (1)

110-111: LGTM! Comprehensive modal localization.

All user-facing strings in the credentials modal have been translated to Korean, including:

  • Dialog title and button labels
  • Success toast notifications
  • Validation error messages for all credential types

The localization is thorough and maintains consistent messaging.

Also applies to: 133-134, 147-148, 179-180, 189-190, 199-200, 234-234, 255-255

skyvern-frontend/src/routes/credentials/CredentialsPage.tsx (1)

22-22: LGTM! Credentials page fully localized.

The entire credentials page UI has been translated to Korean, including:

  • Page header and subheader text
  • Dropdown menu items for adding credentials
  • Tab labels for password, credit card, and 2FA sections

All changes are purely textual with no functional modifications.

Also applies to: 52-52, 58-58, 70-70, 80-80, 91-93

skyvern-frontend/src/routes/workflows/components/ViewAllFoldersDialog.tsx (1)

62-65: LGTM! Dialog fully localized with status messages.

All UI strings in the ViewAllFoldersDialog have been translated to Korean, including:

  • Dialog title and description
  • Search placeholder
  • Empty state message
  • Loading and pagination status messages

The localization provides clear feedback to Korean-speaking users.

Also applies to: 72-72, 110-110, 128-128, 135-135

skyvern-frontend/src/routes/workflows/components/CreateFolderDialog.tsx (1)

52-55: LGTM! Create folder dialog fully localized.

All UI text in the CreateFolderDialog has been translated to Korean, including:

  • Dialog title and description
  • Form labels and placeholders
  • Button text

The localization is complete and maintains the same user experience in Korean.

Also applies to: 60-60, 65-65, 70-70, 75-75, 86-86, 92-92

- Supabase 클라이언트 라이브러리 설치 (@supabase/supabase-js)
- Supabase 인증 Provider 및 Context 구현
- 로그인/회원가입 페이지 구현 (이메일, Google, GitHub 지원)
- AuthGuard 컴포넌트로 인증된 라우트 보호
- 데이터베이스 스키마 설계 (profiles, workflows, runs, credentials 등)
- TypeScript 타입 정의 추가
Copy link
Contributor

@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

♻️ Duplicate comments (1)
skyvern-frontend/.env.production.local (1)

1-28: Critical: Secrets committed to version control - already flagged in previous review.

This file contains production secrets (JWT API key on line 14) and should be removed from version control immediately. See the existing review comment for detailed remediation steps including rotating the exposed key.

🧹 Nitpick comments (8)
skyvern-frontend/src/api/database.types.ts (1)

1-3: Ensure types stay synchronized with schema changes.

The types are well-structured and align with the SQL migration. Since these are marked as auto-generated, consider adding a script or documentation on how to regenerate them when the database schema changes (e.g., supabase gen types typescript).

skyvern-frontend/supabase/migrations/001_initial_schema.sql (1)

270-277: Consider removing redundant index.

idx_workflows_permanent_id may be redundant since permanent_id TEXT UNIQUE (line 61) already creates an implicit unique index. You can safely remove line 271 to avoid maintaining a duplicate index.

 CREATE INDEX idx_workflows_user_id ON public.workflows(user_id);
-CREATE INDEX idx_workflows_permanent_id ON public.workflows(permanent_id);
 CREATE INDEX idx_workflow_runs_user_id ON public.workflow_runs(user_id);
skyvern-frontend/src/App.tsx (1)

30-30: Move PostHog API key to environment variable.

The PostHog API key is hardcoded in the source code. While PostHog client-side keys are generally considered safe to expose (they're designed for frontend use), moving this to an environment variable (e.g., import.meta.env.VITE_POSTHOG_KEY) aligns with the pattern already used for Supabase credentials and improves configuration flexibility across environments.

-            apiKey="phc_bVT2ugnZhMHRWqMvSRHPdeTjaPxQqT3QSsI3r5FlQR5"
+            apiKey={import.meta.env.VITE_POSTHOG_KEY}
skyvern-frontend/src/api/supabase.ts (1)

4-5: Remove misleading type assertions.

The as string assertions don't convert undefined to string at runtime—they only suppress TypeScript errors. The values remain undefined if the environment variables are missing. Remove the casts since the code already handles undefined correctly in the conditional check.

-const supabaseUrl = import.meta.env.VITE_SUPABASE_URL as string;
-const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY as string;
+const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
+const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
skyvern-frontend/src/routes/auth/LoginPage.tsx (1)

59-77: Add try/catch to OAuth sign-in handlers.

The handleGoogleSignIn and handleGithubSignIn functions don't wrap the async call in try/catch. If signInWithGoogle() or signInWithGithub() throws unexpectedly (e.g., network error before the promise resolves), the error won't be caught and loading will remain true.

   const handleGoogleSignIn = async () => {
     setLoading(true);
     setError(null);
-    const { error } = await signInWithGoogle();
-    if (error) {
-      setError(error.message);
+    try {
+      const { error } = await signInWithGoogle();
+      if (error) {
+        setError(error.message);
+      }
+    } catch (err) {
+      setError("알 수 없는 오류가 발생했습니다.");
+    } finally {
       setLoading(false);
     }
   };

   const handleGithubSignIn = async () => {
     setLoading(true);
     setError(null);
-    const { error } = await signInWithGithub();
-    if (error) {
-      setError(error.message);
+    try {
+      const { error } = await signInWithGithub();
+      if (error) {
+        setError(error.message);
+      }
+    } catch (err) {
+      setError("알 수 없는 오류가 발생했습니다.");
+    } finally {
       setLoading(false);
     }
   };
skyvern-frontend/src/store/SupabaseAuthContext.tsx (3)

5-14: Consider using Supabase's AuthError type instead of generic Error.

The Supabase auth methods return AuthError | null, not Error | null. Using the correct type improves type safety and allows consumers to access AuthError-specific properties (e.g., status, code).

Apply this diff to use the correct error type:

-import { User, Session, AuthChangeEvent } from "@supabase/supabase-js";
+import { User, Session, AuthChangeEvent, AuthError } from "@supabase/supabase-js";

 interface AuthContextType {
   user: User | null;
   session: Session | null;
   loading: boolean;
-  signIn: (email: string, password: string) => Promise<{ error: Error | null }>;
+  signIn: (email: string, password: string) => Promise<{ error: AuthError | null }>;
-  signUp: (email: string, password: string) => Promise<{ error: Error | null }>;
+  signUp: (email: string, password: string) => Promise<{ error: AuthError | null }>;
   signOut: () => Promise<void>;
-  signInWithGoogle: () => Promise<{ error: Error | null }>;
+  signInWithGoogle: () => Promise<{ error: AuthError | null }>;
-  signInWithGithub: () => Promise<{ error: Error | null }>;
+  signInWithGithub: () => Promise<{ error: AuthError | null }>;
 }

68-71: Consider adding error handling to signOut.

While the interface defines signOut as returning Promise<void>, the Supabase signOut() call can fail (e.g., network errors). Currently, errors are silently swallowed.

Consider logging errors or updating the interface to return error status:

 const signOut = async () => {
   if (!supabase) return;
-  await supabase.auth.signOut();
+  try {
+    await supabase.auth.signOut();
+  } catch (error) {
+    console.error("Sign out failed:", error);
+  }
 };

73-93: OAuth redirect to root might not preserve user's intended destination.

Both OAuth methods redirect to window.location.origin after authentication, which always sends users to the app root rather than back to the page where they initiated the login flow.

If you want to preserve the user's intended destination, consider storing and using the current path:

 const signInWithGoogle = async () => {
   if (!supabase) return { error: new Error("Supabase not configured") };
   const { error } = await supabase.auth.signInWithOAuth({
     provider: "google",
     options: {
-      redirectTo: window.location.origin,
+      redirectTo: `${window.location.origin}${window.location.pathname}`,
     },
   });
   return { error };
 };

 const signInWithGithub = async () => {
   if (!supabase) return { error: new Error("Supabase not configured") };
   const { error } = await supabase.auth.signInWithOAuth({
     provider: "github",
     options: {
-      redirectTo: window.location.origin,
+      redirectTo: `${window.location.origin}${window.location.pathname}`,
     },
   });
   return { error };
 };

Alternatively, implement a more sophisticated redirect mechanism that stores the intended destination in session storage before initiating OAuth.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0657b7c and ca660b7.

⛔ Files ignored due to path filters (1)
  • skyvern-frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • skyvern-frontend/.env.example (1 hunks)
  • skyvern-frontend/.env.production.local (1 hunks)
  • skyvern-frontend/package.json (1 hunks)
  • skyvern-frontend/src/App.tsx (2 hunks)
  • skyvern-frontend/src/api/database.types.ts (1 hunks)
  • skyvern-frontend/src/api/supabase.ts (1 hunks)
  • skyvern-frontend/src/router.tsx (1 hunks)
  • skyvern-frontend/src/routes/auth/AuthGuard.tsx (1 hunks)
  • skyvern-frontend/src/routes/auth/LoginPage.tsx (1 hunks)
  • skyvern-frontend/src/store/SupabaseAuthContext.tsx (1 hunks)
  • skyvern-frontend/supabase/migrations/001_initial_schema.sql (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
skyvern-frontend/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

skyvern-frontend/**/*.{ts,tsx,js,jsx}: Use npm run lint and npm run format for linting and formatting frontend code in skyvern-frontend/
Maintain line length of 120 characters for TypeScript/JavaScript code

Files:

  • skyvern-frontend/src/routes/auth/LoginPage.tsx
  • skyvern-frontend/src/router.tsx
  • skyvern-frontend/src/api/supabase.ts
  • skyvern-frontend/src/store/SupabaseAuthContext.tsx
  • skyvern-frontend/src/routes/auth/AuthGuard.tsx
  • skyvern-frontend/src/App.tsx
  • skyvern-frontend/src/api/database.types.ts
**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use async/await patterns for asynchronous operations

Files:

  • skyvern-frontend/src/routes/auth/LoginPage.tsx
  • skyvern-frontend/src/router.tsx
  • skyvern-frontend/src/api/supabase.ts
  • skyvern-frontend/src/store/SupabaseAuthContext.tsx
  • skyvern-frontend/src/routes/auth/AuthGuard.tsx
  • skyvern-frontend/src/App.tsx
  • skyvern-frontend/src/api/database.types.ts
🧠 Learnings (2)
📚 Learning: 2025-11-24T17:46:29.802Z
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:46:29.802Z
Learning: Applies to skyvern-frontend/**/*.{ts,tsx,js,jsx} : Use `npm run lint` and `npm run format` for linting and formatting frontend code in skyvern-frontend/

Applied to files:

  • skyvern-frontend/package.json
  • skyvern-frontend/.env.production.local
📚 Learning: 2025-11-24T17:46:44.733Z
Learnt from: CR
Repo: Skyvern-AI/skyvern PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T17:46:44.733Z
Learning: Never commit secrets or credentials to version control

Applied to files:

  • skyvern-frontend/.env.production.local
🧬 Code graph analysis (6)
skyvern-frontend/src/routes/auth/LoginPage.tsx (2)
skyvern-frontend/src/store/SupabaseAuthContext.tsx (1)
  • useSupabaseAuth (109-115)
skyvern-frontend/src/api/supabase.ts (1)
  • isSupabaseEnabled (24-24)
skyvern-frontend/src/router.tsx (2)
skyvern-frontend/src/routes/auth/LoginPage.tsx (1)
  • LoginPage (10-210)
skyvern-frontend/src/routes/auth/AuthGuard.tsx (1)
  • AuthGuard (9-33)
skyvern-frontend/src/api/supabase.ts (1)
skyvern-frontend/src/api/database.types.ts (1)
  • Database (17-264)
skyvern-frontend/src/store/SupabaseAuthContext.tsx (2)
skyvern-frontend/src/api/types.ts (1)
  • User (162-166)
skyvern-frontend/src/api/supabase.ts (2)
  • isSupabaseEnabled (24-24)
  • supabase (13-22)
skyvern-frontend/src/routes/auth/AuthGuard.tsx (3)
skyvern-frontend/src/store/SupabaseAuthContext.tsx (1)
  • useSupabaseAuth (109-115)
skyvern-frontend/src/api/supabase.ts (1)
  • isSupabaseEnabled (24-24)
skyvern/webeye/scraper/domUtils.js (1)
  • children (736-736)
skyvern-frontend/src/App.tsx (1)
skyvern-frontend/src/store/SupabaseAuthContext.tsx (1)
  • SupabaseAuthProvider (18-107)
🪛 dotenv-linter (4.0.0)
skyvern-frontend/.env.example

[warning] 21-21: [UnorderedKey] The VITE_SUPABASE_ANON_KEY key should go before the VITE_SUPABASE_URL key

(UnorderedKey)

skyvern-frontend/.env.production.local

[warning] 9-9: [UnorderedKey] The VITE_ARTIFACT_API_BASE_URL key should go before the VITE_WSS_BASE_URL key

(UnorderedKey)


[warning] 20-20: [UnorderedKey] The VITE_SUPABASE_ANON_KEY key should go before the VITE_SUPABASE_URL key

(UnorderedKey)


[warning] 26-26: [UnorderedKey] The VITE_ENABLE_LOG_ARTIFACTS key should go before the VITE_ENVIRONMENT key

(UnorderedKey)


[warning] 27-27: [UnorderedKey] The VITE_ENABLE_CODE_BLOCK key should go before the VITE_ENABLE_LOG_ARTIFACTS key

(UnorderedKey)

🪛 Gitleaks (8.29.1)
skyvern-frontend/src/App.tsx

[high] 30-30: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (11)
skyvern-frontend/.env.example (1)

18-21: LGTM!

The Supabase configuration variables are appropriately documented as optional with clear placeholder values. This provides good guidance for developers setting up the environment.

skyvern-frontend/supabase/migrations/001_initial_schema.sql (3)

150-162: Missing DELETE policy on workflow_runs.

Unlike other tables (workflows, credentials, workflow_folders), workflow_runs lacks a DELETE policy. If users should be able to delete their run history, add:

CREATE POLICY "Users can delete their own runs"
    ON public.workflow_runs FOR DELETE
    USING (auth.uid() = user_id);

If run history should be immutable, consider adding a comment to clarify this design decision.


37-53: LGTM - Auth trigger is well-designed.

The SECURITY DEFINER is appropriate for auth triggers, and the function correctly handles potentially missing metadata fields by allowing NULLs in the profile table.


1-6: Well-structured initial migration.

The schema follows Supabase best practices with proper RLS policies, appropriate foreign key relationships, and performance indexes. The uuid-ossp extension is correctly enabled for UUID generation.

skyvern-frontend/src/App.tsx (1)

26-41: LGTM! SupabaseAuthProvider correctly wraps the app at the top level.

The provider placement ensures authentication context is available to all nested components, including the router which uses AuthGuard.

skyvern-frontend/src/router.tsx (2)

40-43: Verify if /browser-session/:browserSessionId should be protected.

The BrowserSession route is defined outside the AuthGuard-protected root route, meaning it's accessible without authentication. If this is intentional (e.g., for public/shared session viewing), this is fine. Otherwise, consider moving it under the protected root or wrapping it with AuthGuard.


36-39: LGTM! Authentication routing is correctly structured.

The /login route is appropriately unprotected, and the root route is wrapped with AuthGuard to enforce authentication before accessing the main application.

Also applies to: 47-51

skyvern-frontend/src/api/supabase.ts (1)

13-24: LGTM! Clean conditional Supabase client initialization.

The pattern correctly enables graceful degradation when Supabase is not configured, and the auth options (autoRefreshToken, persistSession, detectSessionInUrl) are appropriate for a client-side authentication flow.

skyvern-frontend/src/routes/auth/AuthGuard.tsx (1)

9-33: LGTM! Well-structured authentication guard.

The component correctly handles all authentication states:

  • Bypasses auth when Supabase is disabled
  • Shows loading state during session check
  • Redirects to login while preserving the original location for post-login redirect
  • Renders children when authenticated
skyvern-frontend/src/routes/auth/LoginPage.tsx (2)

37-57: LGTM! Form submission handler is well-structured.

The handleSubmit correctly uses async/await with proper try/catch/finally pattern to handle errors and reset loading state.


79-209: LGTM! Clean login/signup UI implementation.

The form includes proper input validation (required, minLength), accessible labels, error display, loading states, and OAuth alternatives. The toggle between login and signup modes is intuitive.

"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-tooltip": "^1.0.7",
"@radix-ui/react-visually-hidden": "^1.1.0",
"@supabase/supabase-js": "^2.86.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the latest version of @supabase/supabase-js on npm
npm view @supabase/supabase-js version

# Also check the last few versions to see version history
npm view @supabase/supabase-js versions --json | tail -20

Repository: Skyvern-AI/skyvern

Length of output: 180


🏁 Script executed:

#!/bin/bash
# Check for known vulnerabilities in @supabase/supabase-js
npm audit --json 2>/dev/null | jq -r '.metadata.vulnerabilities // empty' || echo "Running basic npm audit..."
npm audit 2>&1 | grep -i supabase || echo "No Supabase vulnerabilities found in audit"

Repository: Skyvern-AI/skyvern

Length of output: 180


🌐 Web query:

@supabase/supabase-js latest version npm 2024 2025

💡 Result:

Latest npm release of @supabase/supabase-js is 2.57.0 (published Dec 1, 2025). [1][2]

Sources:
[1] npm package page for @supabase/supabase-js — version 2.57.0.
[2] Supabase GitHub / changelog (project release context).


🌐 Web query:

@supabase/supabase-js 2.86.0 security vulnerabilities advisories

💡 Result:

Short answer: No public security advisories specifically for @supabase/supabase-js v2.86.0 were found. Sources report "no known security issues" for the supabase-js package. [1]

Related notes you should be aware of:

  • A path‑routing / directory‑traversal issue (CVE-2025-48370) affected @supabase/auth-js (patched in auth-js ≥ 2.69.1). This is a related Supabase auth library — not supabase-js itself — but if you depend on auth-js through supabase-js you should ensure your dependency versions are updated. [2][3]
  • There is a separate high‑severity "email link poisoning" advisory for the self‑hosted Supabase Auth server (gotrue) — this affects self-hosted Auth instances and was patched on the server side; hosted Supabase was patched. [4]

If you want, I can:

  • check your project’s installed dependency tree (npm/yarn lock) to see if you pull a vulnerable auth-js version, and give exact upgrade commands; or
  • fetch official supabase-js changelog/release notes for v2.86.0.

Correct @supabase/supabase-js version—2.86.0 does not exist.

The specified version 2.86.0 exceeds the latest available release (2.57.0 as of December 2025). This will cause npm install to fail. Update to a valid version such as ^2.57.0 or check the Supabase changelog for the appropriate stable release. Additionally, verify that @supabase/auth-js (a dependency of supabase-js) is at version ≥2.69.1 to include the patch for CVE-2025-48370.

🤖 Prompt for AI Agents
In skyvern-frontend/package.json around line 45, the dependency
"@supabase/supabase-js": "^2.86.0" is invalid (2.86.0 does not exist); change it
to a valid published release such as "^2.57.0" (or the latest stable from the
Supabase releases), then run npm install / yarn install to regenerate
package-lock.json or yarn.lock; additionally ensure @supabase/auth-js in your
lockfile or direct dependencies is at least ">=2.69.1" (bump the direct
dependency if present) so the CVE-2025-48370 patch is included, and commit the
updated package.json and lockfile.

Comment on lines +23 to +48
useEffect(() => {
if (!isSupabaseEnabled || !supabase) {
setLoading(false);
return;
}

// Get initial session
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
});

// Listen for auth changes
const {
data: { subscription },
} = supabase.auth.onAuthStateChange(
(_event: AuthChangeEvent, session: Session | null) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
},
);

return () => subscription.unsubscribe();
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling and use async/await pattern.

Two issues in this useEffect:

  1. Missing error handling: If getSession() fails, setLoading(false) is never called, leaving the app stuck in a loading state.
  2. Coding guideline violation: The code uses .then() instead of async/await for asynchronous operations.

As per coding guidelines, use async/await patterns for asynchronous operations.

Apply this diff to fix both issues:

   useEffect(() => {
     if (!isSupabaseEnabled || !supabase) {
       setLoading(false);
       return;
     }
 
-    // Get initial session
-    supabase.auth.getSession().then(({ data: { session } }) => {
-      setSession(session);
-      setUser(session?.user ?? null);
-      setLoading(false);
-    });
+    // Get initial session
+    const initializeAuth = async () => {
+      try {
+        const { data: { session } } = await supabase.auth.getSession();
+        setSession(session);
+        setUser(session?.user ?? null);
+      } catch (error) {
+        console.error("Failed to get session:", error);
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    initializeAuth();
 
     // Listen for auth changes
     const {
       data: { subscription },
     } = supabase.auth.onAuthStateChange(
       (_event: AuthChangeEvent, session: Session | null) => {
         setSession(session);
         setUser(session?.user ?? null);
         setLoading(false);
       },
     );
 
     return () => subscription.unsubscribe();
   }, []);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
if (!isSupabaseEnabled || !supabase) {
setLoading(false);
return;
}
// Get initial session
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
});
// Listen for auth changes
const {
data: { subscription },
} = supabase.auth.onAuthStateChange(
(_event: AuthChangeEvent, session: Session | null) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
},
);
return () => subscription.unsubscribe();
}, []);
useEffect(() => {
if (!isSupabaseEnabled || !supabase) {
setLoading(false);
return;
}
// Get initial session
const initializeAuth = async () => {
try {
const { data: { session } } = await supabase.auth.getSession();
setSession(session);
setUser(session?.user ?? null);
} catch (error) {
console.error("Failed to get session:", error);
} finally {
setLoading(false);
}
};
initializeAuth();
// Listen for auth changes
const {
data: { subscription },
} = supabase.auth.onAuthStateChange(
(_event: AuthChangeEvent, session: Session | null) => {
setSession(session);
setUser(session?.user ?? null);
setLoading(false);
},
);
return () => subscription.unsubscribe();
}, []);
🤖 Prompt for AI Agents
In skyvern-frontend/src/store/SupabaseAuthContext.tsx around lines 23 to 48, the
useEffect uses .then() without error handling which can leave loading stuck if
getSession() fails; convert the effect to an async inner function, call await
supabase.auth.getSession() inside a try/catch, update session and user in the
try, handle/log errors in the catch, and ensure setLoading(false) is always
called in a finally block; keep the existing onAuthStateChange subscription
logic and cleanup (unsubscribe) but ensure any asynchronous errors don't prevent
the cleanup from running.

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