diff --git a/BLOG_AGENT.md b/BLOG_AGENT.md deleted file mode 100644 index fadddbd5..00000000 --- a/BLOG_AGENT.md +++ /dev/null @@ -1,107 +0,0 @@ -You are a RcloneView technical blog writing expert working inside a VS Code environment. -You can analyze the following folders in the workspace: - -/blog -/howto -/docs -/tutorials - -You can also refer to related topics on the internet to write SEO-optimized content. - -Your role is to write SEO-friendly blog posts based on RcloneView and rclone. -We will always follow the 3-step workflow below. - -Please refer to blog\template.md and use the necessary images. Since there are many image files in the /static path, search through all subdirectories and use the required ones. - -===================================================== -STEP 1 – Topic & Purpose Proposal (SEO-focused) -===================================================== - -1. Analyze the documents in /blog, /howto, /docs, /tutorials in the workspace, - combine topic ideas related to RcloneView or rclone from the internet, - and propose new blog topics that do not overlap with existing ones. - -2. Output each proposed topic in the following format: - [EN Title] – An English SEO title that includes “RcloneView” - [Korean Summary] – A 2–3 sentence summary in Korean describing what the article will cover - [Purpose] – A 1–2 sentence explanation in English describing the goal of the article - [Target Keywords] – 5–10 English keywords for SEO - -3. Avoid topics that duplicate existing /blog articles. - -4. After proposing the topics, automatically proceed to the next step. - -===================================================== -STEP 2 – Outline & Structure Creation -===================================================== - -Based on the selected topic, automatically perform the following tasks. - -1. Clearly restate the selected: - [Topic] - [Purpose] - -2. Also include the following: - [Audience] - Beginner cloud-storage users - Engineers - Corporate IT administrators - -[Tone & Style] -Friendly and simple explanations -Technical blog style -Marketing-friendly tone -Mimic the style of existing /blog documents in the workspace - -3. Create a detailed article outline: - Briefly describe what will be covered in each section - Appropriately reflect RcloneView’s real features - (multi-cloud, compare, sync, mount, scheduler, etc.) - Analyze topic-related articles on the internet - -4. When creating the structure, refer to the writing style and format used in existing local documents (/blog, /howto, /tutorials). - -5. Organize the output in the following format: - -[Topic] -[Purpose] -[Audience] -[Tone & Style] -[Outline] - -Once the outline is complete, automatically proceed to STEP 3. - -===================================================== -STEP 3 – Final Blog Post Generation (Docusaurus + SEO) -===================================================== - -Automatically generate the final article according to the following criteria. -All content must be written in English. - -[Topic] -Use the Topic selected in STEP 1/2. - -[Purpose] -Use the Purpose defined in STEP 1/2. - -[Audience] -Beginner cloud users -General users -Engineers -Corporate IT administrators - -[Tone & Style] -Friendly and simple explanations -Technical blog -Marketing-friendly tone -Blog page style: follow the style of existing /blog documents - -[Notes & Rules for Using References When Writing] -Analyze existing documents and reuse reference documents or image links used in previous posts as much as possible. -If they cannot be found in the main document, analyze /blog, /howto, /tutorials, /docs/tutorial-basics, /docs/tutorial-extras and create links to relevant content. -If no related content exists, insert a placeholder comment so that Docusaurus build does not fail even if the referenced file or link is not present. -Analyze topic-related articles on the internet. - -[Output Format – Final Deliverable] - -Create a .md file under the /blog path with today’s date. diff --git a/BLOG_AGENT_Usage_Guide.md b/BLOG_AGENT_Usage_Guide.md deleted file mode 100644 index 5fdf47a6..00000000 --- a/BLOG_AGENT_Usage_Guide.md +++ /dev/null @@ -1,72 +0,0 @@ -Codex Blog Generation Command Guide / Codex 블로그 생성 명령어 가이드 - -이 문서는 VS Code Codex(챗GPT 기반 코드 어시스턴트)를 사용하여 RcloneView 블로그 글을 자동 생성하는 방법을 설명합니다. 동시에 영어와 한국어로 작성되어 있습니다. -This document explains how to use VS Code Codex (ChatGPT Code Companion) to automatically generate RcloneView blog posts, written in both Korean and English. - -🧩 Overview / 개요 - -Codex는 BLOG_AGENT.md의 규칙을 읽고, RcloneView용 SEO 최적화 블로그 글을 자동으로 생성할 수 있습니다. -Codex can read rules from BLOG_AGENT.md and automatically create SEO‑optimized blog articles for RcloneView. -Codex는 다음을 지원합니다: / Codex can do: - -- 자동 주제 선택 / automatic topic selection -- 직접 입력한 주제 기반 생성 / topic-based generation (when you provide one) -- Docusaurus 스타일의 완성된 Markdown 파일 생성 / generates complete Markdown in Docusaurus format - -🧩 Basic Command / 기본 명령어 - -아래 명령어를 Codex에 입력하면 자동으로 블로그 글을 생성합니다. -Use this command to have Codex generate a blog post automatically: - -Please read BLOG_AGENT.md in this repo. -Follow its instructions to generate a new RcloneView blog post now. -Use "tayson" as the author for this article. - -🧩 Command With a Custom Topic / 주제를 직접 지정하는 명령어 - -주제를 직접 입력하면 STEP 1(주제 제안)을 생략하고 바로 아웃라인 생성으로 넘어갑니다. -If you provide a topic, Codex skips STEP 1 and begins with STEP 2. - -Please read BLOG_AGENT.md in this repo. -Follow its instructions to generate a new RcloneView blog post now. -Use "tayson" as the author for this article. -Use this topic: - -Example / 예시 -Use this topic: RcloneView mount performance optimization for S3 and R2. - -🧩 When No Topic Is Provided / 주제를 비워두면 - -아무 주제도 입력하지 않으면 Codex가 자동으로 주제를 생성합니다. -If you do NOT provide a topic, Codex will: - -- analyze /blog, /howto, /tutorials -- avoid duplicates -- propose 3–5 SEO-friendly topics -- choose one automatically -- continue through STEP 2 → STEP 3 - -사용 예 / Example: -Please read BLOG_AGENT.md in this repo. -Follow its instructions to generate a new RcloneView blog post now. -Use "tayson" as the author for this article. -Topic: - -🧩 Output Result / 출력 결과 - -Codex는 최종적으로 아래 형식의 마크다운을 출력합니다: -Codex creates the final Markdown file with: - -- Docusaurus frontmatter -- SEO title & tags -- internal links reused from workspace -- placeholder comments if links are missing - -저장은 수동으로 /blog 폴더에 넣으면 됩니다: Save the final output manually under: -/blog/YYYY-MM-DD-.md - -🧩 Tips / 사용 팁 - -BLOG_AGENT.md를 최신 규칙으로 유지하세요. / Keep BLOG_AGENT.md updated. -Codex가 워크스페이스 파일을 읽을 수 있어야 합니다. / Ensure Codex can read workspace files. -주제를 직접 입력하면 원하는 방향으로 더 빠르게 만들 수 있습니다. / Providing a topic produces faster targeted results. diff --git a/BLOG_ARCHIVE_CATEGORIES.md b/BLOG_ARCHIVE_CATEGORIES.md deleted file mode 100644 index 7d79b7f2..00000000 --- a/BLOG_ARCHIVE_CATEGORIES.md +++ /dev/null @@ -1,78 +0,0 @@ -# Blog Archive 카테고리 분류 규칙 - -`/blog/archive` (All Posts) 페이지가 620여 개 글을 카테고리로 묶을 때 쓰는 규칙. -구현: `src/theme/BlogArchivePage/categories.js` (이 문서와 반드시 동기 유지). - -> 배경: blog 사이드바(`blogSidebarCount: 'ALL'`)가 모든 글 페이지에 620개 링크 -> (~120KB)를 인라인해 9로케일 빌드가 3.1GB까지 커졌다. 사이드바를 제거하고 -> (`blogSidebarCount: 0`) 전체 목록을 아카이브 페이지 1장으로 옮겼다. -> 아카이브는 카테고리/연도 뷰 토글 + 제목 필터를 제공한다. - -## 분류 알고리즘 — 2단 판정 - -글 한 편의 대표 카테고리는 다음 순서로 정해진다. **첫 매치가 승리.** - -### 1단: 슬러그 동사 프리픽스 (실측 620편 중 ~66% 판정) - -슬러그가 글의 실제 주제를 가장 정확히 반영하므로 태그보다 먼저 검사한다. - -| 우선순위 | 슬러그 패턴 | 카테고리 | -|---|---|---| -| 1 | `fix-` `troubleshoot-` `repair-` `recover-` `resolve-`, `-error(s)-` | Troubleshooting | -| 2 | `compare-` `comparison-`, `-vs-`, `-comparison` (끝) | Comparisons | -| 3 | `migrate-` `move-` `transfer-` `copy-`, `…-to-…rcloneview` (끝) | Migration & Transfer | -| 4 | `sync-` `synchronize-` | Sync | -| 5 | `backup-` `back-up-`, `-backup-` | Backup & Recovery | -| 6 | `manage-` `connect-` `setup-` `set-up-` `use-` `access-` `mount-` | Provider Guides | - -### 2단: 태그 폴백 (~33% 판정) - -슬러그로 판정되지 않으면 태그를 아래 우선순위로 검사한다. - -**⚠️ Use Cases 를 작업 태그(migration/backup/sync)보다 먼저 검사해야 한다.** -산업/유즈케이스 글은 거의 항상 작업 태그도 달고 있어서, 순서를 바꾸면 -Backup 이 34%까지 부풀며 다른 카테고리를 흡수한다 (실측으로 확인된 함정). - -| 우선순위 | 태그 | 카테고리 | -|---|---|---| -| 1 | troubleshooting, data-loss, data-recovery, ransomware | Troubleshooting | -| 2 | comparison, compare, storage-comparison, pricing | Comparisons | -| 3 | industry, business, enterprise, education, healthcare, hipaa, photography, media, dam, video-production, nonprofit, university, cad, accounting, finance, cctv, ai, plex, data-pipeline, huggingface, remote-work, architecture, engineering, compliance | Use Cases & Industries | -| 4 | migration, cloud-migration, cloud-to-cloud, cloud-file-transfer, copy, move | Migration & Transfer | -| 5 | backup, cloud-backup, hard-drive-backup, disaster-recovery, archive, digital-preservation | Backup & Recovery | -| 6 | sync, cloud-sync, offline-sync, google-drive-sync, onedrive-sync, cloud-storage-synchronization | Sync | -| 7 | feature, automation, mount, job-management, encryption, security, performance, filters, vfs, monitoring, cli, crypt, rclone-crypt, dashboard, job-history, history, duplicates, folder-comparison, cleanup, organization, cost-optimization, optimization, drag-and-drop, installation, api, docker, workspace | Features & Automation | -| 8 | (프로바이더 태그 ~70종 — categories.js 의 `PROVIDER_TAGS`) | Provider Guides | -| 9 | (그 외 전부 — 폴백) | Platforms & Tips | - -## 실측 분포 (2026-07-14, 619편 기준) - -| 카테고리 | 글 수 | 비중 | -|---|---|---| -| Migration & Transfer | 157 | 25% | -| Backup & Recovery | 105 | 17% | -| Troubleshooting | 78 | 13% | -| Use Cases & Industries | 73 | 12% | -| Provider Guides | 62 | 10% | -| Sync | 55 | 9% | -| Comparisons | 41 | 7% | -| Features & Automation | 41 | 7% | -| Platforms & Tips (폴백) | 7 | 1% | - -## 유지보수 - -- **새 태그를 추가하면**: 어느 카테고리에 속할지 판단해 `categories.js` 의 - 해당 세트에 넣는다. 안 넣으면 그 태그만 가진 글은 Platforms & Tips 로 떨어진다. -- **새 프로바이더 지원 시**: `PROVIDER_TAGS` 에 태그 추가. -- **카테고리 라벨 번역**: `i18n//code.json` 의 `blog.archive.category.*` - (8개 로케일 모두). -- **분포 재검증**: 카테고리가 한쪽으로 쏠리면 (한 카테고리 >35% 또는 주요 - 카테고리 <3%) 규칙을 재조정한다. 검증 스크립트는 이 문서의 규칙을 - Python 으로 옮겨 돌리면 된다 (frontmatter tags + slug 파싱). - -## 관련 파일 - -- `src/theme/BlogArchivePage/index.js` — 아카이브 페이지 (뷰 토글 + 필터) -- `src/theme/BlogArchivePage/categories.js` — 분류 규칙 구현 (이 문서의 소스) -- `src/components/CustomNavbar.js` — "All Posts" 네비 항목 -- `docusaurus.config.js` — `blogSidebarCount: 0` diff --git a/BLOG_FACTCHECK_GUIDELINE.md b/BLOG_FACTCHECK_GUIDELINE.md deleted file mode 100644 index 606699e8..00000000 --- a/BLOG_FACTCHECK_GUIDELINE.md +++ /dev/null @@ -1,499 +0,0 @@ -# RcloneView Blog Fact-Check Guideline - -> **Purpose:** Post-generation validation guideline to verify expressions, numbers, and terminology in auto-generated RcloneView blog posts. -> **Companion:** For feature details, refer to `RCLONEVIEW_FEATURE_SPEC.md`. This document focuses on **validation rules only**. -> **Sources:** Verified against `rcloneview-support/howto`, `rcloneview-support/docs` documentation + full `rclone-navigator` source code analysis. -> **Last Updated:** 2026-06-23 -> **Guideline Version:** 1.2 - ---- - -## How to Use (2-Document System) - -| Step | Document | Role | -|------|----------|------| -| 1 (Before writing) | `RCLONEVIEW_FEATURE_SPEC.md` | Reference feature spec to write with accurate information | -| 2 (After writing) | **This document** | Validate expressions, numbers, terminology, and prohibited claims | - ---- - -## Verification Principles - -> **Absence from this document does not mean something is wrong.** - -1. **Feature existence:** This document is reference only. `RCLONEVIEW_FEATURE_SPEC.md`, source code, and official documentation are authoritative sources. -2. **Expressions/tone/terminology:** This document is the authoritative source. Follow these rules. -3. **Numbers/defaults:** Only cite verified numbers listed in this document. For other values, verify directly from source. -4. **Cloud providers:** New providers are added with rclone updates. A provider not listed here is still valid if rclone supports it. -5. **Preventing false negatives:** When a blog mentions a feature not in this document, do not immediately flag it as incorrect. Re-verify against the Feature Spec or source code first. - ---- - -## Table of Contents - -1. [Validation Rules](#1-validation-rules) -2. [Terminology & Naming](#2-terminology--naming) -3. [License & Pricing Facts](#3-license--pricing-facts) -4. [Verified Numbers & Defaults](#4-verified-numbers--defaults) -5. [URLs & Contact](#5-urls--contact) -6. [Unverified / Do Not Claim](#6-unverified--do-not-claim) -7. [Fact-Check Checklist](#7-fact-check-checklist) -8. [Safe Descriptions](#8-safe-descriptions) - ---- - -## 1. Validation Rules - -Rules that MUST be followed when auto-generating blog posts. - -### 1.1 Absolute Prohibitions - -| Rule | Reason | -|------|--------| -| Do not state specific prices (dollars/currency) | Prices change frequently. Direct to "see pricing page" instead | -| Do not cite exact cloud provider counts like "100+" | Count varies with rclone updates. Use "90+" or "dozens of" | -| No superlatives: "fastest", "only", "first" | Unverifiable comparative claims | -| Do not describe future features as confirmed | Includes unimplemented features like "Proxy settings (coming soon)" | -| Do not make specific security/encryption strength claims | "AES-256" etc. are rclone crypt implementations, not RcloneView features | -| Comparisons with other products are allowed ONLY in comparison posts, sourced from `COMPETITORS_SPEC.md` | See Section 9. Outside that scope, no product comparisons (legal + unverifiable risk) | -| Do not describe rclone features as RcloneView-exclusive | RcloneView is a GUI frontend for rclone | -| Do not fabricate installation commands or package names | Only use methods from Feature Spec Section 18. See Section 1.5 below | -| Do not feature or mention any storage service absent from Feature Spec Section 10 | rclone has no backend for it — the post would be false. Caused a real forum complaint (TeraBox, 2026-08). See Section 1.7 below | -| Do not describe RcloneView as headless/CLI/server tool | It is a GUI-only app requiring a display server. See Section 1.6 below | -| Do not claim availability on unofficial package managers | AUR, Snap Store, Flathub, Homebrew — none are official channels | -| Do not cite specific performance numbers | Transfer speed, throughput etc. are environment-dependent and unverifiable | - -### 1.2 Expression Guide - -| Context | Correct | Incorrect | -|---------|---------|-----------| -| Cloud provider count | "Supports 90+ cloud storage services" | "Supports 100 cloud services" | -| rclone relationship | "GUI client built on rclone" | "A tool that replaces rclone" | -| Bidirectional sync | "Bidirectional sync (Beta)" | "Perfect bidirectional sync" | -| Encryption | "Encryption support via rclone Crypt" | "Military-grade encryption" | -| Free features | "Basic features available with FREE license" | "All features available for free" | -| Platform | "Supports Windows, macOS, and Linux" | "Supports all operating systems" | -| Mount | "Mount as a virtual drive" | "Works exactly like a local drive" | - -### 1.3 Number/Value Citation Rules - -- Use only values directly confirmed from documentation or code -- Express variable numbers (cloud count, versions) as ranges -- Show defaults in parenthetical format: "(default: X)" -- Never cite performance numbers (transfer speed, etc.) — they are environment-dependent - -### 1.4 Screenshot/Image Reference Rules - -- Screenshots in documentation may differ from the current version -- Do not describe version-specific screenshots as "current appearance" -- Describe UI by function, not by button placement - -### 1.5 Installation & Distribution Claim Rules - -These rules prevent the most common and damaging type of AI hallucination: fabricated installation methods that lead users to dead ends. - -**Only these installation methods are valid:** - -| Platform | Valid Method | Command/Action | -|----------|------------|----------------| -| Windows | Download .exe from rcloneview.com | Run `setup_rclone_view-{version}.exe` | -| macOS | Download .dmg from rcloneview.com | Open `RcloneView-{version}.dmg` | -| Linux | Download .AppImage from rcloneview.com | `chmod +x RcloneView-*.AppImage && ./RcloneView-*.AppImage` | -| Linux | Download .deb from rcloneview.com | `sudo dpkg -i rclone_view-*-linux-{arch}.deb` | -| Linux | Download .rpm from rcloneview.com | `sudo rpm -i rclone_view-*-linux-{arch}.rpm` | - -**These installation methods are FABRICATED — never use them:** - -| Fabricated Method | Why It's Wrong | -|-------------------|---------------| -| `yay -S rcloneview` | No AUR package exists | -| `pacman -S rcloneview` | Not in official Arch repos | -| `snap install rcloneview` | Not published to Snap Store | -| `flatpak install rcloneview` | Not published to Flathub | -| `brew install rcloneview` | No Homebrew formula exists | -| `apt install rcloneview` | No APT repository exists — use .deb direct download | -| `dnf install rcloneview` | No DNF repository exists — use .rpm direct download | -| `pip install rcloneview` | Not a Python package | -| `npm install rcloneview` | Not a Node.js package | -| `docker run rcloneview` | No Docker image exists | - -**Architecture-specific rules:** -- Linux x86_64 and aarch64 (ARM64) builds both exist -- Windows is x86-64 ONLY (no ARM64 Windows build) -- macOS is Universal (Intel + Apple Silicon in one .dmg) -- No 32-bit builds exist for any platform - -### 1.6 Platform & Headless Operation Rules - -RcloneView is a **GUI desktop application**. Every blog post MUST respect these constraints: - -| Rule | Details | -|------|---------| -| GUI is mandatory | RcloneView requires a display server (X11 or Wayland on Linux, native GUI on Windows/macOS) | -| Cannot run headless | No CLI-only mode, no headless mode, no server mode | -| Cannot be a systemd service | RcloneView itself cannot run as `/etc/systemd/system/rcloneview.service`. The documented systemd service is for `rclone rcd` (the rclone daemon), NOT RcloneView | -| Technology stack is Flutter | NOT Qt, NOT Electron, NOT GTK. It uses Flutter/Dart with GTK+3 as a Linux dependency | -| Remote desktop is an option | VNC, RDP, or X11 forwarding can provide a display for remote machines, but this must be stated explicitly | - -**Platform-specific blog post requirements:** - -| Post Topic | MUST Include | MUST NOT Claim | -|------------|-------------|----------------| -| Raspberry Pi / ARM SBC | Desktop environment + display server required; recommend rclone CLI for headless | Headless setup as primary use case | -| Arch Linux | Direct download from rcloneview.com (.AppImage or manual) | AUR package, Qt5 dependencies | -| Any Linux distro | GTK+3 and X11/Wayland requirement | Package manager installation (unless it's dpkg/rpm with downloaded file) | -| Server / NAS | Use Connection Manager to connect to remote rclone; don't install RcloneView on server | RcloneView as server software | -| Docker | Not applicable — use rclone CLI in Docker | Docker image for RcloneView | - -### 1.7 Supported Storage Service Validation (Provider Whitelist) - -**Background (real incident):** In August 2026 a forum user reported that our blog claimed RcloneView supports TeraBox. rclone has NO TeraBox backend — the post described a completely fabricated "select TeraBox from the provider list + OAuth" flow. Similar fabricated posts existed for Hubic (backend removed from rclone; service shut down) and Icedrive (WebDAV-only, and Icedrive is sunsetting WebDAV as of April 2026). All were removed. - -**The whitelist:** `RCLONEVIEW_FEATURE_SPEC.md` Section 10 (10.1–10.5) plus the virtual remotes in Section 11. This is the ONLY list of storage services a post may feature. - -| Rule | Details | -|------|---------| -| Featured provider MUST be in Feature Spec Section 10 | "Featured" = appears in the title, slug, tags, keywords, or is the subject of setup instructions | -| Popularity is NOT support | TeraBox, Baidu Netdisk, MediaFire, Degoo, Sync.com, Tresorit, Internxt, Filen, Icedrive have huge search volume — and NO rclone backend. Never write about them | -| Gateway access (WebDAV/FTP/SFTP/S3-compatible) needs official proof | A post may describe reaching a service via a generic protocol ONLY if the service officially documents that endpoint today (not historically). Cite the condition (e.g., "requires paid plan"). If unsure, do not publish | -| Dead or dying services are banned as featured topics | A service that shut down or deprecated its API/protocol (Hubic, Uptobox seizure, Icedrive WebDAV sunset) must not get a how-to post, even if a backend still exists in rclone | -| Do not name unsupported services even in passing | Free-tier tables, union-remote examples, and "Related Guides" links must only reference whitelisted services | -| Machine gate | `node scripts/check-provider-support.mjs` scans every blog post (all 9 locales) against a blacklist of known-unsupported services and FAILS the build on any hit. Run it before publishing; extend its blacklist when a new unsupported service becomes popular | - ---- - -## 2. Terminology & Naming - -### 2.1 Product & Brand Names - -| Correct | Incorrect | -|---------|-----------| -| RcloneView | Rclone View, rcloneview, RCloneView, Rclone-View | -| rclone | Rclone (mid-sentence), RCLONE | -| Rclone (sentence start only) | rClone | -| PLUS License | Plus license, plus License | -| FREE License | Free license | -| Lifetime License | lifetime license | - -### 2.2 Feature Names - -| Feature | Correct Name | Notes | -|---------|-------------|-------| -| File browser panels | File Explorer | Left/right panes | -| Folder comparison | Folder Compare | Compare button | -| Job management | Job Manager | Job Manager button | -| Mount management | Mount Manager | Remote tab | -| Connection management | Connect Manager / Connection Manager | Settings tab | -| Remote management | Remote Manager | Remote tab | -| Built-in rclone | Embedded Rclone | External: External Rclone | -| Virtual remotes | Virtual Remotes | Alias, Crypt, Cache, etc. | -| System tray | System Tray | Tray icon | -| Simulation mode | Dry Run | Sync simulation | -| Batch jobs | Batch Operations | Beta feature | - -### 2.3 Cloud Service Names - -| Correct | Incorrect | -|---------|-----------| -| Google Drive | Google drive, GDrive | -| OneDrive | One Drive, Onedrive | -| Dropbox | Drop Box, DropBox | -| Backblaze B2 | BackBlaze, Backblaze b2 | -| Cloudflare R2 | CloudFlare, cloudflare R2 | -| Amazon S3 | Amazon s3 (AWS S3 is acceptable informally) | -| pCloud | PCloud, Pcloud | -| Yandex Disk | Yandex disk, YandexDisk | -| Mega | MEGA (official is MEGA, but rclone uses Mega) | -| Proton Drive | ProtonDrive, proton drive | -| Azure File Storage | Azure file storage | -| Zoho WorkDrive | Zoho Workdrive | -| Citrix ShareFile | Citrix Sharefile | -| HiDrive | Hi Drive, Hidrive | -| iCloud Drive | icloud Drive, ICloud | - ---- - -## 3. License & Pricing Facts - -> For detailed feature comparison, see `RCLONEVIEW_FEATURE_SPEC.md` Section 16. - -### 3.1 Verified License Structure - -| Fact | Value | Source | -|------|-------|--------| -| License types | FREE, PLUS, Lifetime | Docs + Code | -| FREE requires no license key | Confirmed | Docs | -| PLUS requires license key | Confirmed | Docs + Code | -| Activation path | Help > Activate License | Docs | -| Discount coupons are one-time per email | Confirmed | Docs | - -### 3.2 License-Related Claim Prohibitions - -- Specific prices for RcloneView itself (frequently change) -- Subjective evaluations like "free is enough" -- Specific trial period duration (may change) - -> **Exception:** Comparison posts MAY state a competitor's price/tier structure when it is sourced -> from `COMPETITORS_SPEC.md` and date-stamped ("as of {Month Year}"). This is competitor pricing, -> not RcloneView pricing. See Section 9. - ---- - -## 4. Verified Numbers & Defaults - -Verified values that may be cited in blog posts. - -| Item | Value | Source | -|------|-------|--------| -| Embedded Rclone default address | http://127.0.0.1:5582 | Docs + Code | -| External Rclone default port | 5572 | Docs + Code | -| Multi-thread transfers default | 4 | Docs | -| Equality checkers default | 8 | Docs | -| Sync retry default | 3 times | Docs | -| Supported UI languages | 9 | Code (arb files) | -| Explorer panel count | 1-4 | Code | -| macOS recommended file handles | 524288 | Docs | -| Cache mode default | writes | Docs | -| Minimum rclone version | v1.69.1 | Docs | -| SMTP default port | 587 | Code | -| Supported cloud count | 90+ | Code analysis | - -### 4.1 Number Citation Cautions - -- **Variable:** Cloud provider count, rclone version, app version -- **Environment-dependent:** Transfer speed, mount performance, cache efficiency -- **Never cite:** Specific prices, discount rates, trial periods - ---- - -## 5. URLs & Contact - -### 5.1 Official URLs (Verified) - -| Purpose | URL | -|---------|-----| -| Official website | https://rcloneview.com | -| Download | https://rcloneview.com/src/download.html | -| Pricing & License | https://rcloneview.com/src/pricing.html | -| Rclone official | https://rclone.org | -| Update feed | https://rcloneview.com/appcast/ | -| macOS builds | https://downloads.bdrive.com/rclone_view/builds/ | - -### 5.2 Support Channels (Verified) - -| Channel | Contact | -|---------|---------| -| Email | rcloneview@bdrive.com | -| Forum | https://forum.rcloneview.com | - -### 5.3 Reference Documentation (Verified) - -| Document | URL | -|----------|-----| -| Rclone filtering | https://rclone.org/filtering/ | -| Rclone bisync | https://rclone.org/bisync/ | -| Rclone overview | https://rclone.org/overview/ | -| AWS S3 docs | https://docs.aws.amazon.com/general/latest/gr/s3.html | - -### 5.4 URL Citation Rules - -- Only URLs from the above lists may be included in blog posts -- Third-party service URLs (AWS Console, Cloudflare Dashboard, etc.) only in tutorial context -- Broken link warning: Verify link validity before publishing - ---- - -## 6. Unverified / Do Not Claim - -Items confirmed in only one source (docs or code), or insufficiently verified. **Do not state definitively in blog posts.** - -### 6.1 Code-Only (Not Documented) — Possibly Internal/Unreleased - -| Item | Status | Reason | -|------|--------|--------| -| Email Notifications | Code only | Not in docs, may be PLUS feature | -| Telegram Bot | Code only | Not in docs | -| Slack Integration | Code only | Not in docs | -| Discord Integration | Code only | Not in docs | -| Web Server Access | Code only | Not in docs | -| Application Lock | Code only | Not in docs | -| Batch Operations | Code only | Beta status, insufficient documentation | -| Thumbnail View | Code only | Image preview grid | -| Get Public Link | Code only | Provider-specific support unclear | -| iCloud Photos | Code only | Separate package, insufficient docs | -| Analytics/Telemetry | Code only | Not appropriate for public disclosure | - -### 6.2 Unimplemented / Coming Soon - -| Item | Status | -|------|--------| -| Proxy settings | Marked "coming soon" in docs | - -### 6.3 Version-Dependent Facts - -| Item | Caution | -|------|---------| -| App version number | Docs: 0.6.301~1.1.517 / Code: 1.4.1+1 — verify latest before publishing | -| rclone version | v1.69.1~v1.70.1 mentioned — verify latest | -| iCloud Drive support | Requires rclone v1.69+ — must state version requirement | - -### 6.4 Subjective/Exaggeration Risk Expressions - -When these expressions appear in generated blog posts, automatically remove or replace: - -| Risky Expression | Replacement | -|-----------------|-------------| -| "perfect" | "comprehensive" or remove | -| "fastest" | Remove (no performance comparisons) | -| "only" / "unique" | "one of few" or remove | -| "revolutionary" / "innovative" | Remove | -| "unlimited" | "numerous" or cite specific numbers | -| "safe" / "highly secure" | "leverages rclone's encryption capabilities" | -| "easy" / "simple" | "GUI-based" | -| "all clouds" | "90+ cloud storage services" | -| "real-time" | "live transfer monitoring" | -| "automatically" | Describe the specific behavior | - ---- - -## 7. Fact-Check Checklist - -Final verification checklist before blog publication: - -**Provider Support (Section 1.7 — caused a real forum complaint):** -- [ ] Is the featured storage service listed in `RCLONEVIEW_FEATURE_SPEC.md` Section 10 (or a Section 11 virtual remote)? -- [ ] Are there ZERO mentions of unsupported services (TeraBox, Baidu Netdisk, MediaFire, Degoo, Sync.com, Tresorit, Internxt, Filen, Icedrive, Hubic, ...)? A post featuring one is REMOVE, not FIX -- [ ] If the post uses WebDAV/FTP/S3-gateway access, is that endpoint officially documented by the service today, with conditions stated? -- [ ] Does `node scripts/check-provider-support.mjs` pass? - -**Terminology & Expression:** -- [ ] Is the product name exactly "RcloneView"? -- [ ] Are rclone features clearly distinguished from RcloneView features? -- [ ] Is the FREE/PLUS license distinction accurate? -- [ ] Are there no specific prices mentioned? -- [ ] Are there no superlatives (fastest, only, first)? -- [ ] Are cloud service names spelled correctly? -- [ ] Are all cited URLs from the verified list? -- [ ] Are there no performance claims (speed, efficiency)? -- [ ] Are there no direct product comparisons? -- [ ] Is bidirectional sync marked as "Beta"? -- [ ] Are all cited numbers verified values? (See Section 4) - -**Features & Status:** -- [ ] Are unimplemented (Coming Soon) features not described as confirmed? -- [ ] Are code-only features (Section 6.1) not described as official features? -- [ ] Is platform support stated as "Windows, macOS, Linux"? -- [ ] Is the technology stack described as Flutter/Dart (NOT Qt, NOT Electron)? - -**Installation & Distribution (CRITICAL — most common failure point):** -- [ ] Are ALL installation commands valid per Section 1.5? -- [ ] Are there NO fabricated package manager commands (yay, snap, flatpak, brew, apt repo, dnf repo)? -- [ ] Does every install instruction start with "Download from rcloneview.com"? -- [ ] Are architecture references correct (x86_64, aarch64 for Linux; x86-64 only for Windows; Universal for macOS)? - -**Platform & Headless (CRITICAL — caused real user complaints):** -- [ ] Is it clear that RcloneView is a GUI application requiring a display? -- [ ] Are there NO claims of headless/CLI/server operation? -- [ ] Is the systemd service clearly identified as `rclone rcd`, NOT RcloneView? -- [ ] For Raspberry Pi/ARM posts: Is desktop environment requirement stated? -- [ ] For Arch Linux posts: Is installation via direct download (NOT AUR)? -- [ ] For server/NAS posts: Is it clear to install rclone (not RcloneView) on the server? - -**Format & Frontmatter:** -- [ ] All 3 imports present? (`CloudSupportGrid`, `cloudIcons`, `RvCta`) -- [ ] `` immediately after the intro paragraph? -- [ ] `` immediately after ``? -- [ ] `` as the very last line? -- [ ] 3–5 images using HTML `` with `class="img-large img-center"`? -- [ ] Image paths from the approved list only? (See Generator Prompt Rule 3) -- [ ] No empty lines between frontmatter fields? -- [ ] `title` and `description` in double quotes? -- [ ] `slug` does NOT include the date prefix? -- [ ] `authors` key is one of the valid values: `jay`, `steve`, `tayson`, `kai`, `morgan`, `casey`, `robin`, `alex`? -- [ ] author order check (DATE-DERIVED, Generator Rule 18 — no state file): - ROTATION = [jay, steve, tayson, kai, morgan, casey, robin, alex] (index = position) - 1. Recompute the expected positions from today's date: - EPOCH_DAY=$(( $(date +%s) / 86400 )) - P1=$(( (EPOCH_DAY * 2) % 8 )) - P2=$(( (EPOCH_DAY * 2 + 1) % 8 )) - 2. Post 1 author MUST be ROTATION[P1]; Post 2 author MUST be ROTATION[P2]. - (If only 1 post survived, it must be ROTATION[P1].) - 3. Mismatch → FIX the `authors:` field to the correct key. - 4. There is NO `blog/.rotation-state` file — if one appears in the diff, - remove it from the commit. Do not read or update any rotation state. - ---- - -## 8. Safe Descriptions - -Pre-verified phrases that can be safely used in blog posts: - -**Product Introduction:** -> RcloneView is a GUI client built on rclone that lets you manage 90+ cloud storage services from a single interface on Windows, macOS, and Linux. - -**Core Value:** -> It provides a graphical interface for file browsing, synchronization, folder comparison, and virtual drive mounting — everything you need for cloud storage management. - -**Free Usage:** -> Basic file management, sync, mount, and folder comparison features are available with the FREE license. Advanced features like scheduled sync and multi-window support require a PLUS license. - -**rclone Relationship:** -> RcloneView is not the official rclone GUI — it is an independent GUI frontend that communicates via the rclone RC API. It ships with an embedded rclone binary and can also connect to external rclone instances. - -**Mount Description:** -> Mount cloud storage as a local drive and access it directly from your file explorer. On Windows, assign a drive letter; on macOS and Linux, specify a mount point. - -**Sync Description:** -> Use one-way sync to mirror source content to a destination, or bidirectional sync (Beta) to merge changes from both sides. 1:N sync lets you synchronize one source to multiple destinations simultaneously. - ---- - -## 9. Competitor Comparison Validation - -> **Scope:** Applies ONLY to comparison posts (Generator Category 5), "best {competitor} -> alternatives" listicles, and one-line soft differentiators. Facts come exclusively from -> `COMPETITORS_SPEC.md`. If a competitor claim is not in that file, FLAG it (FIX or REMOVE). - -### 9.1 Allowed in comparison posts - -- A factual, date-stamped comparison table or paragraph drawn from `COMPETITORS_SPEC.md`. -- Stating a competitor's verified limitation as fact (e.g., "RaiDrive does not offer a sync - feature", "RaiDrive has no macOS app", "the free tier shows ads") — when the row exists in - `COMPETITORS_SPEC.md`. -- Naming the competitor in the title/slug (e.g., `rcloneview-vs-raidrive`). -- A "neutral" factual word like **"one of the few"** is acceptable; the banned superlatives - below are NOT (even in comparison posts). - -### 9.2 Still prohibited (even in comparison posts) - -| Prohibited | Why | -|------------|-----| -| Superlatives: "only", "fastest", "first", "best", "perfect" as a claim about RcloneView | Unverifiable; Section 6.4 still applies | -| Disparagement: "RaiDrive is bad/broken/a scam/overpriced" | Legal risk; reads as untrustworthy | -| Any competitor fact NOT in `COMPETITORS_SPEC.md` | Hallucination risk | -| Undated pricing/tier claims | Competitor pricing changes — must say "as of {Month Year}" | -| Comparing RcloneView to **NetDrive** | NetDrive is a Bdrive sister product — never target it | -| Framing **rclone** as a rival | rclone is the engine RcloneView is built on | -| Claiming an rclone capability as RcloneView-exclusive vs a competitor | Section 1.1 still applies | - -### 9.3 Comparison post checklist (in addition to Section 7) - -- [ ] Every competitor fact traces to a row in `COMPETITORS_SPEC.md`? -- [ ] All competitor pricing/tier claims date-stamped "as of {Month Year}"? -- [ ] At least one genuine competitor STRENGTH acknowledged (balanced tone)? -- [ ] No banned superlatives about RcloneView (Section 9.2)? -- [ ] No disparaging language about the competitor? -- [ ] Post does NOT compare against NetDrive or frame rclone as a rival? -- [ ] Title/slug uses the competitor name correctly spelled (RaiDrive, CloudMounter, Mountain Duck, ExpanDrive)? - -### 9.4 Safe comparison phrasings (pre-verified) - -> As of June 2026, RaiDrive focuses on mounting cloud storage as a network drive on Windows and -> does not include a sync feature. RcloneView adds one-way sync and folder compare on top of -> mounting, and runs on macOS and Linux as well as Windows. - -> RaiDrive's free Standard tier keeps Amazon S3, Azure, and Backblaze B2 read-only and shows ads. -> With RcloneView, read/write access to those services is available on the FREE license. - -> Both tools mount cloud storage well. The practical difference is scope: RcloneView also syncs, -> compares folders, and supports 90+ providers across Windows, macOS, and Linux. diff --git a/BLOG_FACTCHECK_GUIDELINE_ko.md b/BLOG_FACTCHECK_GUIDELINE_ko.md deleted file mode 100644 index 2e6a88b4..00000000 --- a/BLOG_FACTCHECK_GUIDELINE_ko.md +++ /dev/null @@ -1,421 +0,0 @@ -# RcloneView Blog Fact-Check Guideline - -> **Purpose:** RcloneView 블로그 자동 생성 후, 표현/수치/명칭을 검증하는 가이드라인. -> **Companion:** 기능 상세는 `RCLONEVIEW_FEATURE_SPEC.md`를 참조. 이 문서는 **검증 규칙**에 집중한다. -> **Sources:** `rcloneview-support/howto`, `rcloneview-support/docs` 문서 + `rclone-navigator` 소스코드 전체 분석 기반. -> **Last Updated:** 2026-04-13 -> **Guideline Version:** 1.1 - ---- - -## 사용 방법 (2-문서 체계) - -| 순서 | 문서 | 역할 | -|------|------|------| -| 1 (글 작성 전) | `RCLONEVIEW_FEATURE_SPEC.md` | 기능 명세 참고 → 정확한 정보로 글 작성 | -| 2 (글 작성 후) | **이 문서** | 표현/수치/명칭/금지 항목 검증 | - ---- - -## 검증 원칙 (Verification Principles) - -> **이 문서에 없다고 틀린 것이 아니다.** - -1. **기능 존재 여부:** 이 문서는 참고만. `RCLONEVIEW_FEATURE_SPEC.md`, 소스코드, 공식 문서가 권위 소스이다. -2. **표현/톤/명칭:** 이 문서가 권위 소스이다. 여기 규칙을 따른다. -3. **수치/기본값:** 이 문서에 명시된 검증 수치만 인용. 그 외 수치는 소스에서 직접 확인. -4. **클라우드 제공자:** rclone 업데이트로 수시 추가됨. 이 문서 목록에 없는 제공자라도 rclone이 지원하면 유효. -5. **false negative 방지:** 블로그에서 언급한 기능이 이 문서에 없을 때, 즉시 "틀림"으로 판정하지 말고 Feature Spec 또는 소스코드에서 재확인. - ---- - -## Table of Contents - -1. [Validation Rules (블로그 생성 규칙)](#1-validation-rules) -2. [Terminology & Naming (정확한 용어)](#2-terminology--naming) -3. [License & Pricing Facts (라이선스 사실)](#3-license--pricing-facts) -4. [Verified Numbers & Defaults (검증된 수치)](#4-verified-numbers--defaults) -5. [URLs & Contact (검증된 링크)](#5-urls--contact) -6. [Unverified / Do Not Claim (주장 금지 항목)](#6-unverified--do-not-claim) -7. [Fact-Check Checklist](#7-fact-check-checklist) -8. [Safe Descriptions (사전 검증 문구)](#8-safe-descriptions) - ---- - -## 1. Validation Rules - -블로그 자동 생성 시 반드시 준수해야 할 규칙. - -### 1.1 절대 금지 사항 - -| Rule | Reason | -|------|--------| -| 구체적 가격(달러/원)을 명시하지 않는다 | 가격은 수시로 변경됨. "pricing page 참조"로 유도 | -| 지원 클라우드 개수를 "100+"처럼 정확하게 표기하지 않는다 | rclone 업데이트마다 변동. "90개 이상" 또는 "수십 개" 사용 | -| "가장 빠른", "유일한", "최초의" 등 최상급 표현 금지 | 검증 불가능한 비교 주장 | -| 미래 기능을 확정적으로 서술하지 않는다 | "Proxy 설정 (coming soon)" 같은 미구현 기능 포함 | -| 보안/암호화 강도를 구체적으로 주장하지 않는다 | "AES-256" 등은 rclone crypt의 구현이며, RcloneView 자체 기능이 아님 | -| 다른 제품과의 직접 비교 금지 | 법적 리스크 및 검증 불가 | -| rclone 자체 기능을 RcloneView 고유 기능처럼 서술하지 않는다 | RcloneView는 rclone의 GUI 프론트엔드 | -| 설치 명령이나 패키지 이름을 날조하지 않는다 | Feature Spec Section 18의 방법만 사용. 아래 1.5 참조 | -| Feature Spec Section 10에 없는 스토리지 서비스를 다루거나 언급하지 않는다 | rclone에 해당 백엔드가 없어 글 자체가 거짓이 됨. 실제 포럼 컴플레인 발생(TeraBox, 2026-08). 아래 1.7 참조 | -| RcloneView를 헤드리스/CLI/서버 도구로 설명하지 않는다 | 디스플레이 서버 필수 GUI 앱. 아래 1.6 참조 | -| 비공식 패키지 매니저 배포를 주장하지 않는다 | AUR, Snap Store, Flathub, Homebrew — 모두 비공식 | -| 구체적 성능 수치를 인용하지 않는다 | 전송 속도 등은 환경 의존적이며 검증 불가 | - -### 1.2 표현 가이드 - -| 상황 | 올바른 표현 | 잘못된 표현 | -|------|------------|------------| -| 클라우드 제공자 수 | "90개 이상의 클라우드 스토리지 지원" | "100개 클라우드 지원" | -| rclone 관계 | "rclone 기반 GUI 클라이언트" | "rclone을 대체하는 도구" | -| 양방향 동기화 | "양방향 동기화 (Beta)" | "완벽한 양방향 동기화" | -| 암호화 | "rclone Crypt를 통한 암호화 지원" | "군사급 암호화 제공" | -| 무료 기능 | "무료 라이선스로 기본 기능 사용 가능" | "무료로 모든 기능 사용 가능" | -| 플랫폼 | "Windows, macOS, Linux 지원" | "모든 운영체제 지원" | -| 마운트 | "가상 드라이브로 마운트" | "로컬 드라이브처럼 완벽히 작동" | - -### 1.3 숫자/수치 인용 규칙 - -- 문서 또는 코드에서 직접 확인된 수치만 사용 -- 변동 가능한 수치(클라우드 수, 버전 등)는 범위로 표현 -- 기본값은 "(기본값: X)" 형태로 괄호 안에 표기 -- 성능 수치(전송 속도 등)는 절대 명시하지 않음 (환경 의존적) - -### 1.4 스크린샷/이미지 참조 규칙 - -- 문서에 포함된 스크린샷의 UI가 현재 버전과 다를 수 있음 -- 버전 특정 스크린샷을 "현재 모습"으로 서술하지 않음 -- UI 설명 시 기능 중심으로 서술 (버튼 위치보다 기능 설명) - -### 1.5 설치 및 배포 관련 규칙 - -AI 할루시네이션 중 가장 위험한 유형: 존재하지 않는 설치 방법을 안내하여 사용자가 막다른 골목에 빠지는 것을 방지. - -**유효한 설치 방법:** - -| 플랫폼 | 유효한 방법 | 명령/행동 | -|--------|-----------|----------| -| Windows | rcloneview.com에서 .exe 다운로드 | `setup_rclone_view-{version}.exe` 실행 | -| macOS | rcloneview.com에서 .dmg 다운로드 | `RcloneView-{version}.dmg` 열기 | -| Linux | rcloneview.com에서 .AppImage 다운로드 | `chmod +x RcloneView-*.AppImage && ./RcloneView-*.AppImage` | -| Linux | rcloneview.com에서 .deb 다운로드 | `sudo dpkg -i rclone_view-*-linux-{arch}.deb` | -| Linux | rcloneview.com에서 .rpm 다운로드 | `sudo rpm -i rclone_view-*-linux-{arch}.rpm` | - -**날조된 설치 방법 — 절대 사용 금지:** - -| 날조된 방법 | 잘못된 이유 | -|------------|-----------| -| `yay -S rcloneview` | AUR 패키지 없음 | -| `pacman -S rcloneview` | 공식 Arch 저장소에 없음 | -| `snap install rcloneview` | Snap Store 미게시 | -| `flatpak install rcloneview` | Flathub 미게시 | -| `brew install rcloneview` | Homebrew formula 없음 | -| `apt install rcloneview` | APT 저장소 없음 — .deb 직접 다운로드 | -| `dnf install rcloneview` | DNF 저장소 없음 — .rpm 직접 다운로드 | -| `pip install rcloneview` | Python 패키지 아님 | -| `npm install rcloneview` | Node.js 패키지 아님 | -| `docker run rcloneview` | Docker 이미지 없음 | - -**아키텍처 관련 규칙:** -- Linux x86_64 및 aarch64 (ARM64) 빌드 모두 존재 -- Windows는 x86-64 전용 (ARM64 Windows 빌드 없음) -- macOS는 Universal (Intel + Apple Silicon 하나의 .dmg) -- 모든 플랫폼에서 32비트 빌드 없음 - -### 1.6 플랫폼 및 헤드리스 운영 규칙 - -RcloneView는 **GUI 데스크톱 애플리케이션**이다. 모든 블로그 글은 이 제약을 준수해야 한다: - -| 규칙 | 상세 | -|------|------| -| GUI 필수 | Linux에서 X11 또는 Wayland, Windows/macOS에서 네이티브 GUI 필요 | -| 헤드리스 실행 불가 | CLI 전용 모드, 헤드리스 모드, 서버 모드 없음 | -| systemd 서비스 불가 | RcloneView 자체를 `/etc/systemd/system/rcloneview.service`로 실행 불가. 문서의 systemd 서비스는 `rclone rcd`(rclone 데몬)용 | -| 기술 스택은 Flutter | Qt 아님, Electron 아님, GTK 아님. GTK+3은 Linux 의존성으로 사용 | -| 원격 데스크톱은 가능 | VNC, RDP, X11 포워딩으로 원격 머신에 GUI 표시 가능하나, 명시적으로 안내 필요 | - -**플랫폼별 블로그 필수 요구사항:** - -| 글 주제 | 반드시 포함 | 절대 주장 금지 | -|---------|-----------|--------------| -| Raspberry Pi / ARM SBC | 데스크톱 환경 + 디스플레이 서버 필수; 헤드리스는 rclone CLI 권장 | 헤드리스 설정이 주요 사용 사례 | -| Arch Linux | rcloneview.com 직접 다운로드 (.AppImage 또는 수동) | AUR 패키지, Qt5 의존성 | -| 모든 Linux 배포판 | GTK+3 및 X11/Wayland 요구사항 | 패키지 매니저 설치 (dpkg/rpm + 다운로드 파일 제외) | -| 서버 / NAS | Connection Manager로 원격 rclone에 연결; 서버에 RcloneView 설치하지 않기 | RcloneView가 서버 소프트웨어 | -| Docker | 해당 없음 — Docker에서는 rclone CLI 사용 | RcloneView용 Docker 이미지 | - -### 1.7 지원 스토리지 검증 (프로바이더 화이트리스트) - -**배경 (실사고):** 2026년 8월, 블로그가 TeraBox 지원을 주장한다는 포럼 제보가 있었다. rclone에는 TeraBox 백엔드가 없으며, 해당 글은 "프로바이더 목록에서 TeraBox 선택 + OAuth"라는 완전히 날조된 절차를 담고 있었다. Hubic(rclone 백엔드 제거 + 서비스 종료), Icedrive(WebDAV 전용 접근이었으나 2026년 4월부터 WebDAV 단계적 폐지)도 같은 유형의 글이 있어 전부 삭제됐다. - -**화이트리스트:** `RCLONEVIEW_FEATURE_SPEC.md` Section 10 (10.1~10.5) + Section 11 가상 리모트. 블로그가 다룰 수 있는 스토리지 서비스는 이 목록이 전부다. - -| 규칙 | 상세 | -|------|------| -| 글의 대상 프로바이더는 반드시 Feature Spec Section 10에 있어야 한다 | "대상" = 제목·슬러그·태그·키워드에 등장하거나 설정 절차의 주제인 경우 | -| 인기 ≠ 지원 | TeraBox, Baidu Netdisk, MediaFire, Degoo, Sync.com, Tresorit, Internxt, Filen, Icedrive는 검색량이 많지만 rclone 백엔드가 없다. 절대 다루지 않는다 | -| 게이트웨이 접근(WebDAV/FTP/SFTP/S3 호환)은 공식 근거 필수 | 해당 서비스가 그 엔드포인트를 현재(과거가 아니라) 공식 문서로 제공할 때만 서술 가능. 조건(예: 유료 플랜 필요)을 명시. 불확실하면 게시하지 않는다 | -| 종료됐거나 종료 중인 서비스는 금지 | 서비스가 폐쇄됐거나 API/프로토콜을 폐지 중이면(Hubic, Uptobox 압수, Icedrive WebDAV 폐지) rclone 백엔드가 남아 있어도 how-to 글을 쓰지 않는다 | -| 미지원 서비스는 지나가는 언급도 금지 | 무료 용량 표, union 리모트 예시, Related Guides 링크에도 화이트리스트 서비스만 사용 | -| 기계적 게이트 | `node scripts/check-provider-support.mjs`가 블로그 전체(9개 로케일)를 미지원 서비스 블랙리스트와 대조해 걸리면 빌드를 실패시킨다. 게시 전 반드시 실행하고, 새 미지원 서비스가 유행하면 블랙리스트를 확장한다 | - ---- - -## 2. Terminology & Naming - -### 2.1 제품명 및 브랜드 - -| 정확한 표기 | 잘못된 표기 | -|------------|------------| -| RcloneView | Rclone View, rcloneview, RCloneView, Rclone-View | -| rclone | Rclone (문장 중간), RCLONE | -| Rclone (문장 시작만) | rClone | -| PLUS License | Plus license, plus 라이선스 | -| FREE License | Free license, 무료 라이선스 (비공식 OK) | -| Lifetime License | 평생 라이선스 (비공식 OK) | - -### 2.2 기능명 정확한 표기 - -| 기능 | 정확한 명칭 | 비고 | -|------|------------|------| -| 파일 탐색기 | File Explorer | 좌/우 패널 | -| 폴더 비교 | Folder Compare | Compare 버튼 | -| 작업 관리자 | Job Manager | Job Manager 버튼 | -| 마운트 관리자 | Mount Manager | Remote 탭 | -| 연결 관리자 | Connect Manager / Connection Manager | Settings 탭 | -| 리모트 관리자 | Remote Manager | Remote 탭 | -| 내장 Rclone | Embedded Rclone | 외부: External Rclone | -| 가상 리모트 | Virtual Remotes | Alias, Crypt, Cache 등 | -| 시스템 트레이 | System Tray | 트레이 아이콘 | -| 드라이 런 | Dry Run | 동기화 시뮬레이션 | -| 배치 작업 | Batch Operations | Beta 기능 | - -### 2.3 클라우드 서비스 정확한 표기 - -| 정확한 표기 | 잘못된 표기 | -|------------|------------| -| Google Drive | Google drive, GDrive | -| OneDrive | One Drive, Onedrive | -| Dropbox | Drop Box, DropBox | -| Backblaze B2 | BackBlaze, Backblaze b2 | -| Cloudflare R2 | CloudFlare, cloudflare R2 | -| Amazon S3 | Amazon s3, AWS S3 (비공식 OK) | -| pCloud | PCloud, Pcloud | -| Yandex Disk | Yandex disk, YandexDisk | -| Mega | MEGA (공식은 MEGA이나 rclone에서는 Mega) | -| Proton Drive | ProtonDrive, proton drive | -| Azure File Storage | Azure file storage | -| Zoho WorkDrive | Zoho Workdrive | -| Citrix ShareFile | Citrix Sharefile | -| HiDrive | Hi Drive, Hidrive | -| iCloud Drive | icloud Drive, ICloud | - ---- - -## 3. License & Pricing Facts - -> 기능 상세 비교는 `RCLONEVIEW_FEATURE_SPEC.md` Section 16 참조. - -### 3.1 검증된 라이선스 구조 - -| 항목 | 사실 | 출처 | -|------|------|------| -| 라이선스 종류 | FREE, PLUS, Lifetime | 문서+코드 | -| FREE는 라이선스 키 불필요 | 맞음 | 문서 | -| PLUS는 라이선스 키 필요 | 맞음 | 문서+코드 | -| 활성화 경로 | Help > Activate License | 문서 | -| 할인 쿠폰은 이메일당 1회 | 맞음 | 문서 | - -### 3.2 라이선스 관련 주장 금지 - -- 구체적 가격 (수시 변동) -- 경쟁사 대비 가격 비교 -- "무료로 충분하다" 류의 주관적 평가 -- Trial 기간의 구체적 일수 (변동 가능) - ---- - -## 4. Verified Numbers & Defaults - -블로그에서 인용 가능한, 검증된 구체적 수치. - -| 항목 | 값 | 출처 | -|------|-----|------| -| Embedded Rclone 기본 주소 | http://127.0.0.1:5582 | 문서+코드 | -| External Rclone 기본 포트 | 5572 | 문서+코드 | -| 멀티스레드 전송 기본값 | 4 | 문서 | -| 동등성 검사기 기본값 | 8 | 문서 | -| 동기화 재시도 기본값 | 3회 | 문서 | -| 지원 UI 언어 수 | 9개 | 코드 (arb 파일) | -| 탐색기 패널 수 | 1~4개 | 코드 | -| macOS 권장 파일 핸들 | 524288 | 문서 | -| 캐시 모드 기본값 | writes | 문서 | -| 최소 rclone 버전 | v1.69.1 | 문서 | -| SMTP 기본 포트 | 587 | 코드 | -| 지원 클라우드 수 | 90개 이상 | 코드 분석 | - -### 4.1 수치 인용 시 주의 - -- **변동 가능:** 클라우드 제공자 수, rclone 버전, 앱 버전 -- **환경 의존적:** 전송 속도, 마운트 성능, 캐시 효율 -- **절대 인용 금지:** 구체적 가격, 할인율, Trial 기간 - ---- - -## 5. URLs & Contact - -### 5.1 공식 URL (검증됨) - -| 용도 | URL | -|------|-----| -| 공식 웹사이트 | https://rcloneview.com | -| 다운로드 | https://rcloneview.com/src/download.html | -| 가격 & 라이선스 | https://rcloneview.com/src/pricing.html | -| Rclone 공식 | https://rclone.org | -| 업데이트 피드 | https://rcloneview.com/appcast/ | -| macOS 빌드 | https://downloads.bdrive.com/rclone_view/builds/ | - -### 5.2 지원 채널 (검증됨) - -| 채널 | 연락처 | -|------|--------| -| 이메일 | rcloneview@bdrive.com | -| 포럼 | https://forum.rcloneview.com | - -### 5.3 참고 문서 (검증됨) - -| 문서 | URL | -|------|-----| -| Rclone 필터링 | https://rclone.org/filtering/ | -| Rclone Bisync | https://rclone.org/bisync/ | -| Rclone 개요 | https://rclone.org/overview/ | -| AWS S3 문서 | https://docs.aws.amazon.com/general/latest/gr/s3.html | - -### 5.4 URL 인용 규칙 - -- 위 목록의 URL만 블로그에 포함 가능 -- 서드파티 서비스 URL(AWS Console, Cloudflare Dashboard 등)은 튜토리얼 문맥에서만 사용 -- 깨진 링크 주의: 게시 전 링크 유효성 확인 필수 - ---- - -## 6. Unverified / Do Not Claim - -문서 또는 코드 한쪽에서만 확인되었거나, 검증이 불충분한 항목. **블로그에서 확정적으로 서술하지 말 것.** - -### 6.1 코드에만 존재 (문서화 안 됨) — 내부/미출시 가능성 - -| 항목 | 상태 | 이유 | -|------|------|------| -| Email Notifications | 💻 코드만 | 문서에 미기재, PLUS 기능일 수 있음 | -| Telegram Bot | 💻 코드만 | 문서에 미기재 | -| Slack Integration | 💻 코드만 | 문서에 미기재 | -| Discord Integration | 💻 코드만 | 문서에 미기재 | -| Web Server Access | 💻 코드만 | 문서에 미기재 | -| Application Lock | 💻 코드만 | 문서에 미기재 | -| Batch Operations | 💻 코드만 | Beta 상태, 문서 미비 | -| Thumbnail View | 💻 코드만 | 이미지 미리보기 그리드 | -| Get Public Link | 💻 코드만 | 제공자별 지원 여부 불명확 | -| iCloud Photos | 💻 코드만 | 별도 패키지, 문서 미비 | -| Analytics/Telemetry | 💻 코드만 | 사용자에게 공개할 내용 아님 | - -### 6.2 미구현 / Coming Soon - -| 항목 | 상태 | -|------|------| -| Proxy 설정 | 문서에 "coming soon" 명시 | - -### 6.3 버전 의존적 사실 - -| 항목 | 주의사항 | -|------|----------| -| 앱 버전 번호 | 문서: 0.6.301~1.1.517 / 코드: 1.4.1+1 — 게시 시 최신 확인 | -| rclone 버전 | v1.69.1~v1.70.1 언급 — 최신 확인 필요 | -| iCloud Drive 지원 | rclone v1.69+ 필요 — rclone 버전 조건 명시 | - -### 6.4 주관적/과장 위험 표현 목록 - -블로그 생성 시 아래 표현이 나타나면 자동으로 제거하거나 수정: - -| 위험 표현 | 대체 표현 | -|-----------|----------| -| "완벽한" | "포괄적인" 또는 삭제 | -| "가장 빠른" | 삭제 (성능 비교 금지) | -| "유일한" | "몇 안 되는" 또는 삭제 | -| "혁신적인" | 삭제 | -| "무제한" | "다수의" 또는 구체적 수치 | -| "안전한/보안이 뛰어난" | "rclone의 암호화 기능 활용" | -| "쉬운/간단한" | "GUI 기반의" | -| "모든 클라우드" | "90개 이상의 클라우드 스토리지" | -| "실시간" | "진행 중인 작업 모니터링" | -| "자동으로" | 구체적 동작 설명 | - ---- - -## 7. Fact-Check Checklist - -블로그 게시 전 최종 검증 체크리스트: - -**지원 스토리지 (Section 1.7 — 실제 포럼 컴플레인 발생):** -- [ ] 글의 대상 스토리지가 `RCLONEVIEW_FEATURE_SPEC.md` Section 10(또는 Section 11 가상 리모트)에 있는가? -- [ ] 미지원 서비스(TeraBox, Baidu Netdisk, MediaFire, Degoo, Sync.com, Tresorit, Internxt, Filen, Icedrive, Hubic 등) 언급이 0건인가? 미지원 서비스를 다루는 글은 FIX가 아니라 REMOVE -- [ ] WebDAV/FTP/S3 게이트웨이 접근을 서술했다면, 그 엔드포인트가 현재 공식 문서에 있고 조건을 명시했는가? -- [ ] `node scripts/check-provider-support.mjs`가 통과하는가? - -**용어 및 표현:** -- [ ] 제품명이 "RcloneView"로 정확히 표기되었는가? -- [ ] rclone과 RcloneView의 기능이 구분되어 서술되었는가? -- [ ] FREE/PLUS 라이선스 구분이 정확한가? -- [ ] 구체적 가격이 포함되어 있지 않은가? -- [ ] 최상급 표현(가장, 유일, 최초)이 없는가? -- [ ] 클라우드 서비스 이름이 정확히 표기되었는가? -- [ ] 인용된 URL이 검증된 목록에 있는가? -- [ ] 성능 관련 주장(속도, 효율)이 없는가? -- [ ] 다른 제품과의 비교가 없는가? -- [ ] 양방향 동기화에 "Beta" 표시가 되어있는가? -- [ ] 수치가 검증된 값인가? (Section 4 참조) - -**기능 및 상태:** -- [ ] 미구현(Coming Soon) 기능이 확정적으로 서술되지 않았는가? -- [ ] 코드에만 존재하는 기능(Section 6.1)이 공식 기능처럼 서술되지 않았는가? -- [ ] 플랫폼 지원이 "Windows, macOS, Linux"로 정확한가? -- [ ] 기술 스택이 Flutter/Dart로 설명되었는가? (Qt, Electron 아님) - -**설치 및 배포 (핵심 — 가장 빈번한 오류 지점):** -- [ ] 모든 설치 명령이 Section 1.5 기준 유효한가? -- [ ] 날조된 패키지 매니저 명령(yay, snap, flatpak, brew, apt repo, dnf repo)이 없는가? -- [ ] 모든 설치 안내가 "rcloneview.com에서 다운로드"로 시작하는가? -- [ ] 아키텍처 표기가 정확한가? (Linux: x86_64/aarch64, Windows: x86-64 전용, macOS: Universal) - -**플랫폼 및 헤드리스 (핵심 — 실제 사용자 불만 발생):** -- [ ] RcloneView가 디스플레이 필수 GUI 앱임이 명확한가? -- [ ] 헤드리스/CLI/서버 운영 주장이 없는가? -- [ ] systemd 서비스가 `rclone rcd`용임이 명확한가? (RcloneView 자체 아님) -- [ ] Raspberry Pi/ARM 글: 데스크톱 환경 필수 요건이 명시되었는가? -- [ ] Arch Linux 글: 설치가 직접 다운로드(AUR 아님)로 안내되었는가? -- [ ] 서버/NAS 글: 서버에 rclone(RcloneView 아님)을 설치하라고 안내되었는가? - ---- - -## 8. Safe Descriptions (사전 검증 문구) - -블로그에서 안전하게 사용할 수 있는 사전 검증된 문구: - -**제품 소개:** -> RcloneView는 rclone 기반의 GUI 클라이언트로, Windows, macOS, Linux에서 90개 이상의 클라우드 스토리지를 하나의 인터페이스로 관리할 수 있습니다. - -**핵심 가치:** -> 파일 탐색, 동기화, 폴더 비교, 가상 드라이브 마운트 등 클라우드 스토리지 관리에 필요한 기능을 GUI로 제공합니다. - -**무료 사용:** -> 기본 파일 관리, 동기화, 마운트, 폴더 비교 기능은 FREE 라이선스로 사용할 수 있습니다. 스케줄 동기화, 다중 창 등 고급 기능은 PLUS 라이선스가 필요합니다. - -**rclone 관계:** -> RcloneView는 rclone의 공식 GUI가 아닌, rclone RC API를 활용하는 독립적인 GUI 프론트엔드입니다. 내장된 rclone 바이너리를 포함하며, 외부 rclone 인스턴스에도 연결할 수 있습니다. - -**마운트 설명:** -> 클라우드 스토리지를 로컬 드라이브처럼 마운트하여 파일 탐색기에서 직접 접근할 수 있습니다. Windows에서는 드라이브 문자 할당, macOS/Linux에서는 마운트 포인트 지정이 가능합니다. - -**동기화 설명:** -> 단방향 동기화로 소스의 내용을 대상에 반영하거나, 양방향 동기화(Beta)로 양쪽 변경사항을 병합할 수 있습니다. 1:N 동기화로 하나의 소스를 여러 대상에 동기화할 수도 있습니다. diff --git a/BLOG_FACTCHECK_PROMPT.md b/BLOG_FACTCHECK_PROMPT.md deleted file mode 100644 index 2cb323fb..00000000 --- a/BLOG_FACTCHECK_PROMPT.md +++ /dev/null @@ -1,393 +0,0 @@ -# Blog Fact-Checker — Prompt Reference - -> **Routine:** Blog Fact-Checker — Cloud Routine -> **Trigger:** API (Generator 완료 시 자동 호출) -> **Model:** Opus 4.8 -> **Repositories:** bdrive/rcloneview-support -> **Last Updated:** 2026-10-08 (STEP 5 — 빌드 실행·대기 절차 고정) - ---- - -## Cloud Environment 설정 - -``` -Environment name: blog-automation (Generator와 공유 가능) -Network: unrestricted - -Setup script: - cd rcloneview-support && npm ci -``` - ---- - -## Prompt - -``` -You are an independent fact-checker for RcloneView blog posts. You have NOT seen how these posts were written. Your job is to validate every post against strict guidelines, then build and push the verified source. - -This routine is triggered via API by the Generator routine. -The trigger text contains the Generator's branch name (e.g., "Branch: blog/auto/2026-05-06"). - -═══════════════════════════════════════════════════════════════════ -STEP 0: CHECKOUT GENERATOR BRANCH -═══════════════════════════════════════════════════════════════════ - -This routine starts from a fresh clone of rcloneview-support (main branch). -You need to switch to the branch that the Generator created. - -1. Extract the branch name from the trigger text (e.g., "blog/auto/2026-05-06") -2. Fetch and checkout that branch: - - cd rcloneview-support - git fetch origin - BRANCH="blog/auto/$(date +%Y-%m-%d)" - git checkout "${BRANCH}" || git checkout "origin/${BRANCH}" - -If the branch does not exist, output "Generator branch not found: ${BRANCH}" and stop. - -3. Verify the generator's posts exist: - - DATE=$(date +%Y-%m-%d) - ls blog/${DATE}-*.md - -If no files match today's date, output "No posts found for today on branch ${BRANCH}" and stop. - -═══════════════════════════════════════════════════════════════════ -STEP 1: READ VALIDATION RULES -═══════════════════════════════════════════════════════════════════ - -Read the file BLOG_FACTCHECK_GUIDELINE.md in the repository root completely. This contains all validation rules, including Section 9 (Competitor Comparison Validation). - -If any post is a comparison post or "alternatives" listicle, or names a competitor anywhere, ALSO read COMPETITORS_SPEC.md in the repository root. It is the ONLY authoritative source for competitor facts. Any competitor claim not traceable to a row in that file is a violation (FIX or REMOVE). - -Also read the file RCLONEVIEW_FEATURE_SPEC.md for ground truth about the product. Read it in TWO PARTS if needed: -1. First: Read with offset 0 (beginning of file) -2. Then: Read with offset 500 (rest of file, including critical Sections 18 and 19) - -You MUST read BOTH parts. Sections 18 (Distribution) and 19 (Limitations) are at the END and are CRITICAL for validating installation and platform claims. - -═══════════════════════════════════════════════════════════════════ -STEP 2: FIND TODAY'S POSTS -═══════════════════════════════════════════════════════════════════ - -List all files in the blog/ directory matching today's date pattern. -These are the posts to validate. If no files found for today, output "No posts found for today" and stop. - -═══════════════════════════════════════════════════════════════════ -STEP 3: VALIDATE EVERY POST -═══════════════════════════════════════════════════════════════════ - -Read each post and check against the FULL checklist in Guideline Section 7. - -For EACH post, verify these critical items: - -PROVIDER SUPPORT (Guideline Section 1.7 — caused a real forum complaint): -- [ ] Featured storage service listed in RCLONEVIEW_FEATURE_SPEC.md Section 10 - (or Section 11 virtual remote)? If NOT → REMOVE the post (not FIX). -- [ ] Zero mentions of unsupported services anywhere (TeraBox, Baidu Netdisk, - MediaFire, Degoo, Sync.com, Tresorit, Internxt, Filen, Icedrive, Hubic)? - Passing mentions in tables/examples/links must be FIXed out. -- [ ] WebDAV/FTP/S3-gateway access claims backed by the service's CURRENT - official docs, with conditions stated (e.g., "requires paid plan")? -- [ ] Run `node scripts/check-provider-support.mjs` — it must exit 0. It scans - all 9 locales; any hit is a build blocker. - -INSTALLATION & DISTRIBUTION (most common AI hallucination): -- [ ] Every install instruction matches Guideline Section 1.5 valid methods? -- [ ] No fabricated commands? (yay, pacman, snap, flatpak, brew, apt repo, dnf repo, pip, npm, docker) -- [ ] All installs start with "Download from rcloneview.com"? -- [ ] Architecture correct? (Linux=x86_64/aarch64, Windows=x86-64 only, macOS=Universal) - -PLATFORM & HEADLESS (caused real user complaints): -- [ ] Clear that RcloneView is a GUI app requiring a display? -- [ ] No claims of headless/CLI/server operation? -- [ ] systemd service identified as "rclone rcd", NOT RcloneView? -- [ ] Raspberry Pi/ARM posts state desktop environment required? -- [ ] Arch Linux posts do NOT reference AUR? -- [ ] Server/NAS posts clarify: install rclone on server, not RcloneView? - -COMPETITOR COMPARISON (only if the post names a competitor — Guideline Section 9): -- [ ] Every competitor fact traces to a row in COMPETITORS_SPEC.md? (else FIX/REMOVE) -- [ ] All competitor pricing/tier claims date-stamped "as of {Month Year}"? -- [ ] At least one genuine competitor strength acknowledged (balanced tone)? -- [ ] No disparagement of the competitor, and no banned superlatives about RcloneView? -- [ ] Post does NOT compare against NetDrive (sister product) and does NOT frame rclone as a rival? -- [ ] Competitor name spelled correctly? (RaiDrive, CloudMounter, Mountain Duck, ExpanDrive) - -TERMINOLOGY & EXPRESSION: -- [ ] Product name exactly "RcloneView"? -- [ ] Cloud service names spelled correctly? (per Guideline Section 2.3) -- [ ] No superlatives? (fastest, only, first, perfect, revolutionary) -- [ ] No specific prices mentioned? -- [ ] No performance numbers? (transfer speed, throughput) -- [ ] Bidirectional sync marked as "Beta"? -- [ ] Provider count uses "90+" (not 70+, 77, 100+)? -- [ ] rclone features not described as RcloneView-exclusive? -- [ ] Technology described as Flutter/Dart (NOT Qt, NOT Electron)? -- [ ] All tags exist in tags.yml? -- [ ] URLs only from verified list in Guideline Section 5? - -FORMAT: -- [ ] All 3 imports present? (CloudSupportGrid, cloudIcons, RvCta) -- [ ] RvCta immediately after intro paragraph? -- [ ] immediately after RvCta? -- [ ] as the very last line? -- [ ] 3-5 images using HTML with class="img-large img-center"? -- [ ] Image paths from approved list only? (See BLOG_GENERATOR_PROMPT.md Rule 3) -- [ ] No empty lines between frontmatter fields? -- [ ] Title and description in double quotes? -- [ ] Slug does NOT include date prefix? -- [ ] authors: valid key — one of "jay", "steve", "tayson", "kai", "morgan", "casey", "robin", "alex" (indented with 2 spaces)? - -For each post: -- PASS: No issues found — keep as-is -- FIX: Issue found but fixable — edit the file to fix, then save -- REMOVE: Fundamentally flawed premise (e.g., headless Raspberry Pi as primary use case, AUR installation guide) — delete the file entirely - -═══════════════════════════════════════════════════════════════════ -STEP 4: OUTPUT VALIDATION REPORT -═══════════════════════════════════════════════════════════════════ - -After validating all posts, output a report in this exact format: - -VALIDATION REPORT -======================== -Date: {today's date} -Total: {N} -Passed: {N} -Fixed: {N} -Removed: {N} - -| # | File | Status | Details | -|---|------|--------|---------| -| 1 | {filename} | PASS | - | -| 2 | {filename} | FIXED | {what was changed} | -| 3 | {filename} | REMOVED | {reason} | - -═══════════════════════════════════════════════════════════════════ -STEP 4.5: DUPLICATE SLUG CHECK (CRITICAL — runs BEFORE build) -═══════════════════════════════════════════════════════════════════ - -Blog filenames follow `YYYY-MM-DD-{slug}.md`. The {slug} portion determines the published URL. Two files with different dates but the SAME slug will produce a "Duplicate routes found" warning during build and cause the same URL to collide. - -Procedure: -1. List ALL files in blog/ directory -2. For each filename, strip the `YYYY-MM-DD-` prefix to extract the raw slug -3. Identify any slugs that appear in MORE than one file -4. For each duplicate group: KEEP the file with the EARLIEST date (older post has established SEO / backlinks), DELETE all newer files sharing that slug - -Example: - 2026-03-22-rcloneview-arch-linux-cloud-sync.md ← keep (older) - 2026-04-13-rcloneview-arch-linux-cloud-sync.md ← DELETE - -After deletion, verify no duplicate slugs remain before proceeding to build. - -═══════════════════════════════════════════════════════════════════ -STEP 4.7: TRANSLATE SURVIVING POSTS INTO 8 LOCALES (inline) -═══════════════════════════════════════════════════════════════════ - -The site is served in 9 languages. Every post that survived validation -(PASS or FIX — NOT REMOVE, NOT deleted as a duplicate) must be translated into -all 8 non-English locales, or it would appear untranslated on /support/ko/, -/support/ja/, etc. while the rest of the blog is localized. - -Do the translation INLINE with your own Read/Write tools. Do NOT use the -Workflow tool and do NOT spawn subagents (the Workflow tool is gated behind an -interactive approval prompt that a scheduled/unattended routine cannot pass — -Read/Write/Bash run without prompts, so translate each file yourself). - -1. Survivor list — today's-date files STILL present in blog/ after STEP 3 - (REMOVE) and STEP 4.5 (duplicate deletion): - - ls blog/${DATE}-*.md - - If the list is empty, skip to STEP 5. - -2. For EACH surviving post AND EACH of the 8 locales - (ko, ja, zh-Hans, zh-Hant, de, es, fr, id): - - Read the English source: blog/{filename} - - Translate it per the RULES below - - Write the result to: i18n/{locale}/docusaurus-plugin-content-blog/{filename} - (same filename; create the file — it does not exist yet) - - That is 8 files per surviving post. Work through them post-by-post, - locale-by-locale until all exist. - - TRANSLATION RULES — output must stay a valid, buildable Docusaurus post: - a. The written file contains ONLY the translated Markdown. No commentary. - b. Frontmatter (between the first pair of --- lines): translate ONLY the - values of "title", "description", and the human-readable strings in - "keywords". Keep every other key/value BYTE-IDENTICAL: slug, date, - authors, tags, image. Keep YAML quoting valid. - c. NEVER translate or alter: code blocks and inline code, URLs and link - targets, image paths, product names (RcloneView, rclone, NetDrive…), - cloud provider names, CLI commands/flags, HTML tags. - d. MDX import lines: rewrite paths '../src/...' → '@site/src/...' - (e.g. import RvCta from '@site/src/components/RvCta';). i18n files sit - deeper, so the relative '../src' path breaks — the alias is required. - Keep everything else in the import identical. - e. Preserve Markdown structure EXACTLY: heading hierarchy, lists, tables, - admonitions (:::tip etc.), the marker, and the SAME - number of code blocks. - f. Translate link TEXT (incl. "Related Guides" item titles) but never the - link URL. Internal links (/howto/…, /blog/…) unchanged. - g. Terminology — use consistently per locale: - | en | ko | ja | zh-Hans | zh-Hant | de | es | fr | id | - |---|---|---|---|---|---|---|---|---| - | remote | 리모트 | リモート | 远程 | 遠端 | Remote | remoto | distant | remote | - | mount | 마운트 | マウント | 挂载 | 掛載 | einbinden(mount) | montar | monter | mount | - | sync | 동기화 | 同期 | 同步 | 同步 | Synchronisation | sincronización | synchronisation | sinkronisasi | - | backup | 백업 | バックアップ | 备份 | 備份 | Backup | copia de seguridad | sauvegarde | pencadangan | - | transfer | 전송 | 転送 | 传输 | 傳輸 | Übertragung | transferencia | transfert | transfer | - | cloud storage | 클라우드 스토리지 | クラウドストレージ | 云存储 | 雲端儲存 | Cloud-Speicher | almacenamiento en la nube | stockage cloud | penyimpanan cloud | - (Chinese: zh-Hans = Simplified, zh-Hant = Traditional.) - Do NOT add or remove content; natural technical tone for native readers. - -3. Validate the translations (I18N_RUNBOOK_ko.md 2장 ③, steps 1-3): - - .venv/bin/python scripts/validate_i18n.py # "문제 0건" - node scripts/mdx_check.mjs # "실패 0" - - (If .venv is missing: python3 -m venv .venv && .venv/bin/pip install pyyaml) - Open and fix any file the validator flags, then re-validate. Do NOT proceed - to build until both pass — the full 9-locale build in STEP 5 is the final gate. - -(For LOCAL, human-run retroactive translation of many old posts, the parallel -Sonnet batch scripts/blog-i18n-batch.workflow.js is still available via the -Workflow tool — but a routine must use the inline method above.) - -═══════════════════════════════════════════════════════════════════ -STEP 5: BUILD (9 locales) -═══════════════════════════════════════════════════════════════════ - -Build with the npm script — do NOT use `yarn build --out-dir …`. The -`--out-dir` form silently skips the postbuild prune (prune-locale-static.mjs -hardcodes the build/ path), leaving dead per-locale static copies that bloat -the output and can blow past Cloudflare Pages' file-count limit. `npm run build` -runs the full chain in order: - - prebuild: scripts/check-image-refs.mjs — FAILS the build if any post (incl. - the new translations) references an image/video not in static/ (catches - invented filenames) - - docusaurus build → build/ (all 9 locales, includes the STEP 4.7 translations) - - postbuild: scripts/prune-locale-static.mjs — removes dead per-locale static - copies (keeps the output near ~858MB / ~33k files instead of ballooning) - -HOW TO RUN IT — the full 9-locale build takes about 32 minutes in this -sandbox, longer than any single Bash call may run. Follow this procedure -EXACTLY; do not improvise. - - a. Launch the build DETACHED from the tool's task tracking so no tool time - limit can kill it. Do NOT use the Bash tool's `run_in_background` option - and do NOT use the Monitor tool for the build — a background task is - killed when its timeout (max 10 min) expires; that is how the 2026-10-08 - run lost its build with only en/ko finished. - - cd /home/user/rcloneview-support - rm -f /tmp/build.log - setsid nohup bash -c 'npm run build; echo "build exit=$?"' \ - > /tmp/build.log 2>&1 < /dev/null & - sleep 5; tail -3 /tmp/build.log # prebuild checks must be starting - - b. Wait in the FOREGROUND, at most 9 minutes per Bash call (the foreground - limit is 10 min). Each call blocks until the exit line appears or 9 - minutes pass. Exit code 124 just means "9 minutes elapsed, still - building" — run the same call again. Expect 4–5 rounds. - Do NOT end your turn while the build is running. If the stop hook asks - you to commit, keep waiting — do not commit or push yet. - - timeout 540 bash -c 'until grep -q "^build exit=" /tmp/build.log; do sleep 20; done' - grep -E '^build exit=|Generated static files|Duplicate routes|\[ERROR\]' /tmp/build.log | tail -12 - - Repeat (b) until `build exit=` is present. If 8 rounds (~72 min) pass - without it, report "build did not finish" and stop — do not push. - - c. Judge the result ONLY from the log, never from a pipe's exit code: - - grep -q '^build exit=0' /tmp/build.log && echo BUILD_OK # must print BUILD_OK - grep -c 'Duplicate routes' /tmp/build.log # must be 0 - -Watch the output and act on these: -- prebuild "✘ static/ 에 없는 자산 참조 …" — a post references a missing asset. - Fix the reference (or add the file), then rebuild from (a). Do NOT proceed. -- "[WARNING] Duplicate routes found!" — STEP 4.5 missed a duplicate slug. - Re-run STEP 4.5, then rebuild from (a). -- "[ERROR]" or `build exit=` other than 0 — report the error and stop. Do not push. - -Only proceed once `build exit=0` is in the log with no duplicate-route warnings. - -빌드가 통과하면 여기서 끝이다. www 반영은 자동이다 — -STEP 6 에서 support 브랜치를 push 하고 그 PR 이 main 에 머지되면, -.github/workflows/deploy-www.yml 이 같은 빌드를 다시 돌려 -rcloneview_www/support/ 를 교체하는 PR 을 자동으로 만든다. -이 단계의 빌드는 머지 전에 깨진 콘텐츠를 걸러내기 위한 검증이다. - -═══════════════════════════════════════════════════════════════════ -STEP 6: PUSH VERIFIED SOURCE -═══════════════════════════════════════════════════════════════════ - -After successful build, commit and push the verified source. -Replace {DATE} with today's date in YYYY-MM-DD format. - -6. Push rcloneview-support (validated English source + 8-locale translations): - - cd ../rcloneview-support - git checkout -b blog/verified/${DATE} - git add blog/${DATE}-*.md # English source (fixed) - git add i18n/*/docusaurus-plugin-content-blog/${DATE}-*.md # STEP 4.7 translations (8 locales) - git commit -m "blog: verified posts + 8-locale translations for ${DATE}" - git push -u origin blog/verified/${DATE} - -NOTE: This creates a NEW branch (blog/verified/) separate from the Generator's -branch (blog/auto/). The verified branch contains the fact-checked English -versions AND their STEP 4.7 translations — support is the source of truth for -i18n, so the translations must live here (not only in the www build output). -Every surviving post has 8 translation files (one per locale); REMOVE'd and -deduped posts have none, so the ${DATE} glob stages exactly the survivors. - -NOTE on author rotation: authors are DATE-DERIVED (Generator Rule 18) and need -no state. There is NO `blog/.rotation-state` file — do not stage or commit one. -A REMOVE never shifts other days' authors, since each day's authors come from -its own date. Just verify the surviving posts use the date-correct authors -(Guideline Section 7 author order check) and FIX the `authors:` field if not. - -═══════════════════════════════════════════════════════════════════ -STEP 6.5: CREATE PULL REQUEST -═══════════════════════════════════════════════════════════════════ - -After the branch is pushed, create the PR using the GitHub MCP tool -(mcp__github__create_pull_request). - -PR — rcloneview-support (fact-checked source + translations): - owner: bdrive - repo: rcloneview-support - head: blog/verified/{DATE} - base: main - title: "blog: verified posts + translations for {DATE}" - body: - ## Summary - - Fact-checked auto-generated blog posts for {DATE} - - {N passed} passed, {N fixed} fixed, {N removed} removed - - {N surviving} posts translated into 8 locales (STEP 4.7) - - ## Validation Results - {paste the validation table from Step 4} - - ## Changes - {bullet list of each fix/removal with brief reason} - -═══════════════════════════════════════════════════════════════════ -STEP 7: SUMMARY -═══════════════════════════════════════════════════════════════════ - -Output final summary: -- Source branch checked out: blog/auto/{DATE} -- Validation results (from Step 4) -- Build status (success/fail) -- Branches pushed: - - rcloneview-support: blog/verified/{DATE} (fact-checked source) -- PRs created: - - rcloneview-support: {PR URL} -- Action needed: "Merge the support PR to main — www 반영은 Actions 가 자동으로 처리한다" - -Now execute all steps. Start by checking out the Generator branch. -``` diff --git a/BLOG_GENERATOR_PROMPT.md b/BLOG_GENERATOR_PROMPT.md deleted file mode 100644 index ee8e6b45..00000000 --- a/BLOG_GENERATOR_PROMPT.md +++ /dev/null @@ -1,425 +0,0 @@ -# Blog Generator — Prompt Reference - -> **Routine:** Blog Generator — Cloud Routine -> **Trigger:** Schedule (Daily 09:00 AM KST) -> **Model:** Opus 4.8 -> **Repository:** bdrive/rcloneview-support -> **Last Updated:** 2026-06-23 - ---- - -## Cloud Environment 설정 - -``` -Environment name: blog-automation -Network: unrestricted - -Environment variables: - FACTCHECKER_ENDPOINT=https://api.anthropic.com/v1/claude_code/routines/trig_XXXXX/fire - FACTCHECKER_TOKEN=rtn_XXXXXXXXXXXXX - -Setup script: - cd rcloneview-support && yarn install --frozen-lockfile -``` - ---- - -## Prompt - -``` -You are a professional SEO blog writer for RcloneView (https://rcloneview.com), a multi-cloud file management GUI built on top of rclone. Your task is to generate exactly 2 unique, high-quality blog posts for today's date. - -═══════════════════════════════════════════════════════════════════ -STEP 0: VERIFY ENVIRONMENT -═══════════════════════════════════════════════════════════════════ - -This routine runs from a fresh clone of rcloneview-support (main branch). -Verify the repository is ready: - - pwd - ls RCLONEVIEW_FEATURE_SPEC.md COMPETITORS_SPEC.md BLOG_FACTCHECK_GUIDELINE.md blog/tags.yml - -If any of these files are missing, report the issue and stop. - -═══════════════════════════════════════════════════════════════════ -STEP 1: READ PRODUCT KNOWLEDGE (FEATURE SPEC) -═══════════════════════════════════════════════════════════════════ - -Read the file RCLONEVIEW_FEATURE_SPEC.md in the repository root. This is your ONLY authoritative source for: -- Product features and capabilities -- Supported cloud providers (90+) -- Installation methods and download formats -- Platform support and system requirements -- Technology stack (Flutter/Dart, NOT Qt, NOT Electron) -- License structure (FREE vs PLUS) -- Limitations (GUI-only, no headless, no AUR, etc.) - -CRITICAL: Read the ENTIRE file. If it exceeds the single-read token limit, read it in TWO PARTS: -1. First: Read with offset 0 (beginning of file) -2. Then: Read with offset 500 (rest of file, including critical Sections 18 and 19) - -You MUST read BOTH parts. Sections 18 (Distribution) and 19 (Limitations) are at the END of the file and are the MOST IMPORTANT sections for preventing factual errors. - -Do NOT invent features, installation methods, or capabilities not in this file. -Pay special attention to Sections 18 (Distribution) and 19 (Limitations). - -PROVIDER WHITELIST (HARD RULE — a violation here caused a real forum complaint): -Section 10 (10.1-10.5) of the Feature Spec is the COMPLETE list of storage -services you may write about (plus Section 11 virtual remotes). If a service is -not there — TeraBox, Baidu Netdisk, MediaFire, Degoo, Sync.com, Tresorit, -Internxt, Filen, Icedrive, Hubic — you MUST NOT write about it, mention it in -free-tier tables or examples, or link to it, no matter how strong its search -volume is. Popularity is not support: rclone has no backend for these services, -so any how-to would be fabricated. If you are ever unsure whether a service is -supported, pick a different topic from the whitelist instead. - -═══════════════════════════════════════════════════════════════════ -STEP 1.5: READ COMPETITOR KNOWLEDGE (ONLY IF WRITING A COMPARISON POST) -═══════════════════════════════════════════════════════════════════ - -If (and only if) one of today's posts is a Category 5 COMPARISON post or an -"alternatives" listicle, read COMPETITORS_SPEC.md in the repository root. It is -your ONLY authoritative source for competitor facts (pricing tiers, platform -support, mount-vs-sync, free-tier limits). - -CRITICAL rules from that file: -- Use competitor facts ONLY from COMPETITORS_SPEC.md. Never invent them. -- Date-stamp every competitor pricing/tier claim: "as of {Month Year}". -- NEVER compare against NetDrive (it is a Bdrive sister product, not a competitor). -- NEVER frame rclone as a rival (it is the engine RcloneView is built on). -- Honest tone only: acknowledge one genuine competitor strength; no disparagement; - banned superlatives (only/fastest/first/best/perfect) STILL apply. - -═══════════════════════════════════════════════════════════════════ -STEP 2: READ EXISTING FILES TO AVOID TOPIC DUPLICATION -═══════════════════════════════════════════════════════════════════ - -CRITICAL: Filenames follow the pattern `YYYY-MM-DD-{slug}.md`. The {slug} portion is what determines the published URL. Two files with different dates but the same slug (e.g., `2026-04-09-manage-box-cloud-sync-backup-rcloneview.md` and `2026-04-13-manage-box-cloud-sync-backup-rcloneview.md`) will both try to publish at the SAME URL, causing duplicate route errors and build failures. - -Procedure: -1. List ALL files in the blog/ directory (not just recent ones) -2. For EACH existing filename, strip the `YYYY-MM-DD-` prefix to extract the raw slug -3. Build a "used slugs" set from these extracted slugs -4. When generating new posts, your chosen slug MUST NOT already exist in this set — regardless of when that existing post was published - -You MUST NOT create any post whose slug matches an existing post's slug. This includes: -- Same remote/provider already covered as a standalone post -- Same migration pair (e.g., "migrate-X-to-Y" already exists) -- Same comparison pair (e.g., "rcloneview-vs-X" already exists) -- Same troubleshooting topic (e.g., "fix-slow-cloud-transfers" already exists) -- Same industry vertical (e.g., "cloud-storage-law-firms" already exists) -- Same platform (e.g., "rcloneview-arch-linux" already exists) -- Same feature deep-dive (e.g., "vfs-cache-mount-performance" already exists) - -Before writing each post, verify its slug is NOT in the used-slugs set. If it matches, pick a different topic or differentiate the slug meaningfully (e.g., add a qualifier that reflects different content, not just a date). - -═══════════════════════════════════════════════════════════════════ -STEP 3: READ tags.yml FOR VALID TAGS -═══════════════════════════════════════════════════════════════════ - -Read the tags file at blog/tags.yml to get the list of valid tags. -Every tag used in your posts MUST exist in this file. Use the EXACT key (left side before the colon). Common tags include: RcloneView, cloud-storage, cloud-sync, backup, guide, comparison, troubleshooting, tips, feature, industry, platform, migration, mount, performance, encryption, automation, linux, windows, macos, and provider-specific tags like google-drive, onedrive, dropbox, amazon-s3, azure, wasabi, backblaze-b2, etc. - -═══════════════════════════════════════════════════════════════════ -STEP 4: PICK 2 TOPICS (7-CATEGORY STRATEGY, rotate over days) -═══════════════════════════════════════════════════════════════════ - -Use today's date in YYYY-MM-DD format for all file naming. - -Distribute today's 2 posts across these 7 categories. Rotate categories -over days; prioritize categories 1–3 (bread and butter). Avoid hitting -the same category two days in a row when feasible. - -1. REMOTES (highest weight): Managing specific cloud storage providers with RcloneView - - Format: "Manage {Provider} Storage — Sync and Backup Files with RcloneView" - - Slug: manage-{provider}-cloud-sync-backup-rcloneview - - Tags: RcloneView, {provider-tag}, cloud-storage, cloud-sync, backup - - {Provider} MUST be listed in Feature Spec Section 10 (PROVIDER WHITELIST rule - in STEP 1). Verify before writing; if it is not there, choose another provider. - -2. CROSS-PROVIDER TRANSFERS: Migration/sync between two specific providers - - Format: "Migrate {Source} to {Destination} — Transfer Files with RcloneView" OR "Sync {Source} to {Destination} — Cloud Backup with RcloneView" - - Slug: migrate-{source}-to-{dest}-rcloneview OR sync-{source}-to-{dest}-rcloneview - - Tags: RcloneView, {source-tag}, {dest-tag}, cloud-to-cloud, migration OR sync - - BOTH {Source} and {Destination} MUST be listed in Feature Spec Section 10 - (PROVIDER WHITELIST rule in STEP 1). - -3. PAIN POINTS / TROUBLESHOOTING: Common cloud storage problems and solutions - - Format: "Fix {Problem} — {Solution} with RcloneView" OR "{Problem} — How to Resolve with RcloneView" - - Slug: fix-{problem-slug}-rcloneview - - Tags: RcloneView, troubleshooting, tips, {relevant-tags} - -4. INDUSTRY VERTICALS: Cloud storage solutions for specific industries - - Format: "Cloud Storage for {Industry} — {Benefit} with RcloneView" - - Slug: cloud-storage-{industry}-rcloneview - - Tags: RcloneView, cloud-storage, industry, backup, guide - -5. COMPARISON: RcloneView vs competitor tools (FREQUENCY-LIMITED — see note below) - - Requires reading COMPETITORS_SPEC.md (STEP 1.5). Facts from that file ONLY. - - Valid competitors: RaiDrive, CloudMounter, Mountain Duck, ExpanDrive, Air Explorer. - NEVER NetDrive (sister product). NEVER rclone (the engine). - - Two sub-formats: - a) Head-to-head: "RcloneView vs {Competitor} — Mount and Sync Cloud Storage Compared" - Slug: rcloneview-vs-{competitor} - b) Alternatives listicle (best for capturing "{competitor} alternative" searches): - "Best {Competitor} Alternatives — Cross-Platform Cloud Mount and Sync with RcloneView" - Slug: best-{competitor}-alternatives-rcloneview - - Tags: RcloneView, comparison, cloud-storage - - MUST: date-stamp competitor pricing/tiers ("as of {Month Year}"); acknowledge one genuine - competitor strength; honest tone, no disparagement, no banned superlatives about RcloneView. - - Lead with our verified wins (COMPETITORS_SPEC.md Section 1): cross-platform, free mount + - free sync, free S3/Azure/B2 write, 90+ providers, no ads. - - FREQUENCY RULE: Generate a COMPARISON post AT MOST about once per week, never two days in a - row. There are only ~5 valid competitors — churning thin comparison posts hurts SEO. Prefer - REFRESHING an existing comparison post's facts over creating a near-duplicate. On most days, - pick from categories 1–4, 6, 7 instead. Comparison reach is carried mainly by Layer B below. - -6. PLATFORM: Running RcloneView on specific OS/hardware - - Format: "RcloneView on {Platform} — Cloud Storage Sync and Backup" - - Slug: rcloneview-{platform}-cloud-sync - - Tags: RcloneView, {platform-tag}, cloud-sync, installation - -7. FEATURE DEEP-DIVE: Detailed guide on a specific RcloneView feature - - Format: "{Feature} — {Benefit Description} in RcloneView" - - Slug: {feature-slug}-rcloneview - - Tags: RcloneView, feature, {relevant-tags} - -═══════════════════════════════════════════════════════════════════ -STEP 5: WRITE EACH POST WITH EXACT FORMAT -═══════════════════════════════════════════════════════════════════ - -Each post MUST follow this EXACT structure. Do NOT deviate: - ---- -slug: {slug-without-date} -title: "{Title with — Em Dash Separator}" -authors: - - {author} -description: "{SEO description 120-160 chars, include RcloneView and primary keyword}" -keywords: - - {keyword 1} - - {keyword 2} - - {keyword 3} - - {keyword 4} - - {keyword 5} - - {keyword 6} - - {keyword 7} - - {keyword 8} - - {keyword 9 (optional)} - - {keyword 10 (optional)} -tags: - - RcloneView - - {tag2} - - {tag3} - - {tag4} - - {tag5 (optional)} ---- - -import CloudSupportGrid from '../src/components/CloudSupportGrid'; -import cloudIcons from '../src/contexts/cloudIcons'; -import RvCta from '../src/components/RvCta'; - -# {Same Title as frontmatter title, without quotes} - -> {One-sentence hook/summary that captures the post's value proposition} - -{Introductory paragraph: 2-4 sentences explaining the problem or context. Mention RcloneView as the solution. Be specific and practical, not generic.} - - - - - -## {Section 1 Title — Descriptive, Not Generic} - -{2-3 paragraphs of substantive content. Be specific about RcloneView features, workflows, or benefits. Include technical details where relevant.} - -{descriptive alt text} - -{Optional additional paragraph after image} - -## {Section 2 Title} - -{2-3 paragraphs of content} - -{descriptive alt text} - -## {Section 3 Title} - -{2-3 paragraphs of content} - -{descriptive alt text} - -## {Optional Section 4 — if content warrants it} - -{Content} - -{descriptive alt text} - -## Getting Started - -1. **Download RcloneView** from [rcloneview.com](https://rcloneview.com/src/download.html). -2. {Step 2 specific to this post's topic} -3. {Step 3 specific to this post's topic} -4. {Step 4 specific to this post's topic} - -{Closing motivational sentence about the topic's benefit.} - ---- - -**Related Guides:** - -- [{Related Post Title 1}](https://rcloneview.com/support/blog/{related-slug-1}) -- [{Related Post Title 2}](https://rcloneview.com/support/blog/{related-slug-2}) -- [{Related Post Title 3}](https://rcloneview.com/support/blog/{related-slug-3}) - - - -═══════════════════════════════════════════════════════════════════ -CRITICAL FORMAT RULES (DO NOT VIOLATE) -═══════════════════════════════════════════════════════════════════ - -1. FILE NAMING: {DATE}-{slug}.md — Example: 2026-04-14-manage-box-cloud-sync-backup-rcloneview.md -2. IMAGES: ALWAYS use HTML tags, NEVER Markdown ![](). Images MUST use class="img-large img-center" -3. IMAGE PATHS: Only use these exact paths (rotate through them): - - /support/images/en/blog/new-remote.png - - /support/images/en/blog/cloud-to-cloud-transfer-default.png - - /support/images/en/tutorials/wasabi-drag-and-drop.png - - /support/images/en/howto/rcloneview-basic/compare-display-select.png - - /support/images/en/howto/rcloneview-basic/job-run-click.png - - /support/images/en/tutorials/wasabi-real-time-monitoring-transferring.png - - /support/images/en/howto/rcloneview-advanced/create-job-schedule.png - - /support/images/en/howto/rcloneview-basic/job-history.png - - /support/images/en/howto/rcloneview-basic/mount-from-remote-explorer.png - - /support/images/en/howto/rcloneview-basic/mount-from-mount-manager.png - - /support/images/en/blog/synology-nas-autodection-and-connection.png -4. IMPORTS: Always include all three imports EXACTLY as shown (no @site/ prefix) -5. RvCta: Always include immediately after the intro paragraph -6. TRUNCATE: Always include after RvCta -7. TAGS: Every tag MUST exist in tags.yml. Always include "RcloneView" as the first tag -8. WORD COUNT: Each post should be 400-600 words (excluding frontmatter and code) -9. EM DASH: Use — (em dash) in titles, not - (hyphen) for separators -10. RELATED GUIDES: Link to 3 existing blog posts that are topically related. Use actual slugs from existing posts -11. CLOSING: Always end with as the very last line -12. KEYWORDS: 8-10 SEO-optimized keywords per post, mix of short-tail and long-tail -13. NO EMPTY LINES between frontmatter fields -14. DESCRIPTION: Must be in double quotes in frontmatter -15. TITLE: Must be in double quotes in frontmatter -16. EACH POST: Must have 3-5 images distributed throughout the content sections -17. SLUG: Must NOT include the date prefix — only the topic slug -18. AUTHORS: Assign authors using a DATE-DERIVED deterministic formula. - Do NOT read or write any state file. Do NOT "remember" who went last. - Do NOT pick names yourself. Compute the positions with the shell, then - map positions → names. This removes all drift and all model discretion. - - ROTATION ORDER (fixed array, index = position): - 0: jay 1: steve 2: tayson 3: kai - 4: morgan 5: casey 6: robin 7: alex - - STEP A — Compute today's two positions with the shell (run verbatim): - - EPOCH_DAY=$(( $(date +%s) / 86400 )) - P1=$(( (EPOCH_DAY * 2) % 8 )) # Post 1 position - P2=$(( (EPOCH_DAY * 2 + 1) % 8 )) # Post 2 position - echo "Post1 position=$P1 Post2 position=$P2" - - STEP B — Map positions → author keys using the ROTATION ORDER above: - Post 1 author = ROTATION[P1] - Post 2 author = ROTATION[P2] - - You MUST use the P1/P2 values printed by the shell. Do not substitute - your own choice. If you only publish 1 post today (e.g. the other was a - duplicate), use the Post 1 author (position P1). - - Why date-derived: the author depends ONLY on the calendar date, so it is - perfectly even (each author exactly twice per 8 days), self-correcting, - and immune to skipped/missing days — a skipped day never shifts later - days, because each day's authors come from its own date, not a counter. - There is NO state file to read, update, or commit. - - All 8 keys are defined in blog/authors.yml: - jay, steve, tayson, kai, morgan, casey, robin, alex - Format in frontmatter — exactly one key (indented with 2 spaces): - authors: - - - - EXAMPLE: - Shell prints "Post1 position=4 Post2 position=5" - → Post 1 author = morgan, Post 2 author = casey - (Next day's date yields positions 6 and 7 → robin, alex; the day after - → 0 and 1 → jay, steve; fully deterministic from the date alone.) - -═══════════════════════════════════════════════════════════════════ -STEP 6: WRITE FILES AND PUSH -═══════════════════════════════════════════════════════════════════ - -Write each file to: blog/{DATE}-{slug}.md - -After writing all 2 files, commit and push to a branch: - - DATE=$(date +%Y-%m-%d) - git checkout -b blog/auto/${DATE} - git add blog/${DATE}-*.md - git commit -m "blog: auto-generate posts for ${DATE}" - git push -u origin blog/auto/${DATE} - -IMPORTANT — BRANCH OVERRIDE: The target branch for blog posts is ALWAYS -`blog/auto/${DATE}`, regardless of any session-level instruction that -specifies a different development branch (e.g. `claude/xxx`). Session branch -instructions apply to general development tasks only. For this routine, the -`blog/auto/${DATE}` branch takes unconditional priority. Do NOT push to the -session branch. - -NOTE: There is NO `blog/.rotation-state` file anymore. Author assignment is -date-derived (Rule 18) and needs no state — do not create, stage, or commit -any rotation-state file. - -Output a numbered list of all created files with their full paths. - -═══════════════════════════════════════════════════════════════════ -STEP 7: TRIGGER FACT-CHECKER -═══════════════════════════════════════════════════════════════════ - -After successfully pushing the branch, trigger the Fact-checker routine: - - DATE=$(date +%Y-%m-%d) - curl -s -X POST "${FACTCHECKER_ENDPOINT}" \ - -H "Authorization: Bearer ${FACTCHECKER_TOKEN}" \ - -H "anthropic-beta: experimental-cc-routine-2026-04-01" \ - -H "anthropic-version: 2023-06-01" \ - -H "Content-Type: application/json" \ - -d "{\"text\": \"Branch: blog/auto/${DATE}\"}" - -If the curl call succeeds (HTTP 200/201), output: - "Fact-checker triggered successfully for branch blog/auto/${DATE}" - -If it fails, output the error and the branch name so it can be triggered manually. - -═══════════════════════════════════════════════════════════════════ -CONTENT QUALITY GUIDELINES -═══════════════════════════════════════════════════════════════════ - -- Write as if you are an expert cloud infrastructure consultant -- Be specific: mention actual provider features and API behaviors from RCLONEVIEW_FEATURE_SPEC.md -- Include practical scenarios (e.g., "a photography studio with 2TB of RAW files") -- Avoid generic filler like "In today's digital world" or "Cloud storage is important" -- Each section should provide actionable information, not just describe features -- Use active voice and direct language -- Vary sentence structure and paragraph length for readability -- Related Guides should link to REAL existing posts (check filenames from Step 2) -- NEVER mention specific pricing of any cloud provider or RcloneView itself -- NEVER fabricate installation commands — only use methods from RCLONEVIEW_FEATURE_SPEC.md Section 18 - -LAYER B — SOFT DIFFERENTIATION (applies to EVERY post, not just comparisons): -- Where it fits naturally, weave in ONE factual differentiator sentence that highlights a genuine - RcloneView strength WITHOUT naming any competitor. This is how comparison value is delivered - daily without dedicated comparison posts. Examples (rotate, adapt to the topic): - • "Unlike mount-only tools, RcloneView also syncs and compares folders — on the FREE license." - • "RcloneView mounts AND syncs 90+ providers from one window, on Windows, macOS, and Linux." - • "Connect S3, Azure, or Backblaze B2 with full read/write on the FREE license." -- Keep it to ONE such sentence per post, placed where it reads naturally (often the intro or the - Getting Started lead-in). Do NOT name competitors in Layer B. Do NOT use superlatives. It must - be a plain fact verifiable from RCLONEVIEW_FEATURE_SPEC.md. - -Now execute all steps. Generate and write 2 blog posts. -``` diff --git a/COMPETITORS_SPEC.md b/COMPETITORS_SPEC.md deleted file mode 100644 index 33954458..00000000 --- a/COMPETITORS_SPEC.md +++ /dev/null @@ -1,181 +0,0 @@ -# RcloneView Competitor Specification - -> **Purpose:** The SINGLE authoritative source of facts for any RcloneView blog post that -> compares RcloneView to another product (Category 5 — COMPARISON, "alternatives" listicles, -> and the soft one-line differentiators woven into everyday posts). -> **Companion:** Product facts live in `RCLONEVIEW_FEATURE_SPEC.md`. Validation tone/rules live -> in `BLOG_FACTCHECK_GUIDELINE.md` (Section 9). This file holds COMPETITOR facts only. -> **Last Verified:** 2026-06-23 -> **Verification cadence:** Re-verify all pricing/feature rows EVERY QUARTER. Pricing changes -> frequently — every competitor claim in a post MUST be phrased "as of {Month Year}". - ---- - -## 0. Golden Rules for Comparison Content (read first) - -1. **Facts only from this file.** If a competitor fact is not in this document, do NOT state it. - Re-verify on the competitor's official site and add it here first. -2. **Honest, not disparaging.** State what we genuinely win on. Never insult a competitor, never - call them "bad", never claim they are "broken". Let the factual table do the persuading. -3. **No superlatives** — the existing ban on "fastest / only / first / perfect" STILL APPLIES, - even in comparison posts. "RcloneView syncs for free; RaiDrive does not sync" is a fact. - "RcloneView is the only tool that syncs" is a banned superlative (and false). -4. **Always date-stamp.** Pricing and tier structures change. Use "As of {Month Year}, …". -5. **Acknowledge a competitor strength** in every head-to-head post (builds trust + reads as - balanced to both readers and Google's helpful-content system). -6. **NetDrive is OFF-LIMITS.** NetDrive (netdrive.net) is a Bdrive sister product, NOT a - competitor. Never position against it. Never write "RcloneView vs NetDrive". -7. **rclone is the engine, not a competitor.** RcloneView is a GUI built on rclone. Never frame - rclone as a rival; frame RcloneView as "the GUI that makes rclone approachable." - ---- - -## 1. RcloneView — Our Positioning Facts (the "win" column) - -All verified against `RCLONEVIEW_FEATURE_SPEC.md`. These are the differentiators safe to lead with: - -| Strength | Fact | -|----------|------| -| Cross-platform | Windows, macOS, AND Linux (native builds for each) | -| Free mount | Mounting cloud storage as a local/virtual drive works on the FREE license | -| Free sync | One-way sync and folder compare work on the FREE license | -| Provider breadth | 90+ cloud providers (via rclone engine), including S3/Azure/B2/Wasabi with write access | -| No ads | The FREE license shows no advertisements | -| Open engine | Built on rclone (mature, open-source, widely audited transfer engine) | -| Multi-panel | 1–4 Explorer panels; multiple accounts of the same provider can be open at once | -| What is PLUS-only | Scheduled sync, multi-window, batch operations (Beta) — everything else is FREE | - -**One-line soft differentiators (Layer B — for everyday posts, NO competitor name):** -- "Unlike mount-only tools, RcloneView also syncs — on the FREE license, across Windows, macOS, and Linux." -- "RcloneView mounts AND syncs 90+ providers from one window — no per-service upgrade ladder." -- "Connect S3, Azure, or Backblaze B2 with full read/write on the FREE license." - ---- - -## 2. RaiDrive (primary target — high search volume) - -> Official: https://www.raidrive.com · Pricing: https://www.raidrive.com/pricing -> Vendor: OpenBoxLab Inc. · Pricing page confirmed verbatim 2026-06-23. - -| Attribute | Fact (as of June 2026) | Source | -|-----------|------------------------|--------| -| Core function | **Mount only** — maps cloud/NAS as a network drive. **No sync feature.** | raidrive.com | -| Platform | **Windows-focused; no macOS app.** ("Connect without Windows sign-in" feature confirms Windows orientation.) | pricing page, cloudmounter.net compare | -| Free tier ("Standard") | Has **advertisements**; limited to **8 drives**; Forum support only | raidrive.com/pricing | -| Free tier write access | Writable: Google Drive, OneDrive, Dropbox, **Naver MYBOX**, WebDAV, SFTP, FTP. **Everything else read-only** (incl. MEGA, pCloud, Box, SharePoint, AWS S3, Azure, Backblaze B2, Cloudflare R2, Wasabi, MinIO, Storj, etc.) | raidrive.com/pricing | -| Pricing model | **5-tier ladder** (Standard / Starter / Individual / Team / Essential). Write access unlocks in **three groups**, each at a higher tier | raidrive.com/pricing | -| Group 1 — consumer write | Google Drive/OneDrive/Dropbox/MEGA/pCloud/Yandex etc. writable from **Starter (≈ $1.84/mo)** | raidrive.com/pricing | -| Group 2 — business write | Google Workspace, OneDrive Business, SharePoint, Box etc. writable from **Individual (≈ $2.84/mo)**. At Individual, object storage is STILL read-only | raidrive.com/pricing | -| Group 3 — object storage write | **AWS S3, Azure, Backblaze B2, Cloudflare R2, Wasabi, MinIO, Storj etc. require Team (≈ $4.84/mo)** — or a paid **add-on** on the Essential tier | raidrive.com/pricing | -| Essential tier ($2.17/mo) | Cheaper, but business + object-storage write are **paid add-ons** (Writable Addon), and Local Disk / File Lock are add-ons too | raidrive.com/pricing | -| Local Disk / File Lock | Local Disk mount = Individual+; File Lock = Team+ (add-ons on Essential) | raidrive.com/pricing | -| Displayed prices | "**Per month on a 3-year commitment**" — month-to-month is higher; auto-charged after 14-day trial | raidrive.com/pricing | -| Multiple accounts | **Cannot open multiple accounts of the same provider simultaneously** | cloudmounter.net compare | -| CLI / automation | **No command-line control** | cloudmounter.net compare | -| Genuine strength (acknowledge) | Strong media streaming from cloud without downloading first; broad provider catalog | cloudwards / PCWorld | - -**RcloneView vs RaiDrive — honest angle:** -> RaiDrive is a capable Windows mount tool with a broad provider catalog. RcloneView differs in -> three concrete ways. First, it runs on macOS and Linux as well as Windows. Second, it adds -> folder sync and compare on top of mounting — RaiDrive mounts only. Third, where RaiDrive unlocks -> write access in stages (consumer services at Starter, business services at Individual, and -> object storage like Amazon S3, Azure, and Backblaze B2 only at the Team tier — all as of June -> 2026), RcloneView provides read/write to those services on its FREE license. If you only mount -> consumer drives on Windows, RaiDrive's free tier works; if you also sync, write to S3/Azure/B2, -> or use a Mac, RcloneView covers more without climbing a tier ladder. - ---- - -## 3. CloudMounter (secondary target) - -> Official: https://cloudmounter.net - -| Attribute | Fact (as of June 2026) | Source | -|-----------|------------------------|--------| -| Core function | **Mount only** (cloud/FTP/WebDAV as local drive). No dedicated sync/scheduler. | cloudmounter.net | -| Platform | macOS and Windows (Mac free version is notably better) | cloudwards | -| Pricing | Personal ≈ **$29.99/yr per 1 Mac**; Team ≈ **$99.99** (5 devices); lifetime available | Capterra / cloudwards | -| Free version | Yes, limited | cloudwards | -| Strength (acknowledge) | Strong client-side AES-256 encryption; clean Mac UX | cloudwards | - -**Angle:** RcloneView adds true sync + compare and free S3/Azure/B2 write, across all three OSes. - ---- - -## 4. Mountain Duck (secondary target) - -> Official: https://mountainduck.io - -| Attribute | Fact (as of June 2026) | Source | -|-----------|------------------------|--------| -| Core function | **Mount only** (Cyberduck's mounting sibling) | mountainduck.io | -| Platform | macOS and Windows | mountainduck.io | -| Pricing | Paid one-time license per major version (verify exact figure before citing); 30% switch discount | mountainduck.io | -| Strength (acknowledge) | Mature, lightweight, deep protocol support via Cyberduck lineage | mountainduck.io | - -**Angle:** RcloneView adds sync + compare + scheduling and is free to mount; Mountain Duck is mount-only and paid. - ---- - -## 5. ExpanDrive (secondary target — note: now free for personal) - -> Official: https://www.expandrive.com - -| Attribute | Fact (as of June 2026) | Source | -|-----------|------------------------|--------| -| Core function | Mount + some sync flexibility | cloudwards | -| Pricing | **Personal now free**; Server edition ≈ $99 | cloudwards | -| Platform | macOS, Windows, Linux | cloudwards | -| Strength (acknowledge) | Free personal tier; fast multi-threaded engine | cloudwards | - -**Angle (careful — ExpanDrive personal is also free):** Lead on provider breadth (90+ via rclone), -folder compare, and the open rclone engine rather than on price here. - ---- - -## 6. Air Explorer / Air Live Drive (tertiary) - -> Official: https://www.airexplorer.net · https://www.airlivedrive.com - -| Attribute | Fact (as of June 2026) | Source | -|-----------|------------------------|--------| -| Air Explorer | File-transfer manager across clouds; freemium (Pro paid) | airexplorer.net | -| Air Live Drive | Mount clouds as drives; freemium | airlivedrive.com | -| Platform | Windows-centric (Air Explorer has macOS) | vendor sites | - -**Angle:** RcloneView unifies mount + sync + compare in one app on all three OSes with 90+ providers. - ---- - -## 7. odrive (tertiary) - -| Attribute | Fact (as of June 2026) | -|-----------|------------------------| -| Core function | Sync/"infinite sync" placeholder model; consumer-oriented | -| Pricing | Freemium; Premium subscription for advanced sync | -| Note | Different model (placeholder sync); compare cautiously, lead on RcloneView's GUI + rclone breadth | - ---- - -## 8. DO-NOT-TARGET list - -| Name | Why excluded | -|------|--------------| -| **NetDrive** | Bdrive sister product — never position against it | -| **rclone (CLI)** | The engine RcloneView is built on — frame as "we add a GUI", not as a rival | - ---- - -## 9. High-intent target keywords (for slugs/titles) - -These capture users already shopping for a competitor — the highest-converting traffic: - -- `rcloneview-vs-raidrive` — "RcloneView vs RaiDrive — Mount and Sync Cloud Storage Compared" -- `best-raidrive-alternatives-rcloneview` — listicle capturing "RaiDrive alternative" searches -- `rcloneview-vs-cloudmounter` -- `rcloneview-vs-mountain-duck` -- `raidrive-no-sync-use-rcloneview` (pain-point framing, no head-to-head) -- `mount-and-sync-cloud-free-rcloneview` (soft, no competitor name) - -> Listicle "best {competitor} alternatives" pages typically absorb the most competitor-brand -> search volume and should be refreshed (not duplicated) each quarter. diff --git a/I18N_OVERVIEW_ko.md b/I18N_OVERVIEW_ko.md deleted file mode 100644 index 105fadd2..00000000 --- a/I18N_OVERVIEW_ko.md +++ /dev/null @@ -1,123 +0,0 @@ -# RcloneView Support 다국어화(i18n) — 개요와 배포 구조 변경 제안 - -> 팀 공유용 문서. 무엇을 하고 있고, 어떤 문제를 만났고, 왜 배포 구조를 바꿔야 하는지 설명한다. -> 작업 절차·명령어 등 실무 상세는 [I18N_RUNBOOK_ko.md](./I18N_RUNBOOK_ko.md) 참고. -> 작성: 2026-07-09, 기준 브랜치: `feature/i18n` - ---- - -## 1. 무엇을 하는가 - -support 사이트(블로그 620개 + howto/tutorials 문서)를 **RcloneView Desktop과 동일한 9개 언어**로 제공한다. - -| 로케일 | 언어 | | 로케일 | 언어 | -|---|---|---|---|---| -| `en` | 영어 (원문) | | `de` | 독일어 | -| `ko` | 한국어 | | `es` | 스페인어 | -| `ja` | 일본어 | | `fr` | 프랑스어 | -| `zh-Hans` | 중국어 간체 | | `id` | 인도네시아어 | -| `zh-Hant` | 중국어 번체 | | | | - -- URL: `/support/`(영어), `/support/ko/...`, `/support/ja/...` 형태. hreflang 자동 생성으로 SEO 처리. -- 번역은 Claude(Sonnet) 파이프라인으로 생성하고, 4단계 자동 검증 후 커밋. -- **진행 현황(2026-07-09): 620개 중 360개 완료 (58%)**, 검증·전체 빌드 통과 상태. - -## 2. Docusaurus i18n의 동작 방식 — 그리고 만난 문제 - -Docusaurus의 다국어는 **"언어 하나 = 사이트 하나"** 방식이다: - -- 번역본은 언어별 **파일 복사본**으로 관리 (`i18n/ko/...`, `i18n/ja/...`) -- 빌드하면 **언어마다 사이트 전체를 다시 생성** — 이미지·JS까지 각 언어 폴더에 복사됨 - -이 구조라서 다음이 발생한다 (실측): - -| | 영어만 (현재 운영) | 9개 언어 빌드 | -|---|---|---| -| 산출물 용량 | 337MB | **3.1GB** (이미지가 9벌 복제, 2GB 이상이 중복) | -| 파일 수 | 약 4,000개 | **36,126개** | -| 빌드 시간 | 1~2분 | **약 14분** (풀 빌드 9회) | - -### 왜 이게 "배포" 문제인가 - -지금 배포는 **빌드 산출물을 www 저장소의 `support/` 폴더에 커밋**하고, main 머지 시 Cloudflare가 www를 통째로 반영하는 방식이다. 9개 언어가 되면: - -1. **Cloudflare Pages는 배포당 20,000파일 제한** — 36,000파일을 커밋해 머지하는 순간 배포가 실패한다. 즉 현재 방식으로는 다국어 빌드를 반영할 방법이 없다. -2. www 저장소가 지금도 1.5GB(대부분 support 산출물 이력)인데, 매일 블로그 봇 커밋마다 9개 언어의 sitemap/RSS/페이지네이션이 전부 바뀌어 이력이 계속 불어난다. -3. PR에 빌드 산출물 수천 파일이 섞여 diff 리뷰가 사실상 불가능하다. - -## 3. 검토한 대안: Astro로 갈아타면? (NetDrive 블로그처럼) - -bdweb의 NetDrive 블로그(Astro 5)를 심층 분석했다. 결론: **부분적으로만 해결되고, 지금 갈아타는 건 손해.** - -| 문제 | Astro로 옮기면 | -|---|---| -| 산출물 ×9 (이미지 복제) | ✅ 구조적으로 해결 — 단일 빌드, 이미지 한 벌 공유 (추산 ~600MB / ~8,000파일) | -| 원문-번역 동기화 | ❌ 동일 — Astro도 언어별 파일 복사본. 번역 파이프라인이 해결할 문제 | -| i18n 편의 기능 | ❌ 전부 수제작 — 미번역 글 영어 fallback, hreflang, 언어별 RSS/sitemap, 태그, 문서 사이드바를 직접 구현해야 함 (Docusaurus는 기본 제공, 이미 구축 완료) | - -참고 사실: -- NetDrive 블로그는 **영어 단독**(97개 글)이다. i18n은 헤더/푸터 라벨 en/ko 토글뿐 — "Astro 다국어 사례"가 아니어서 가져다 쓸 코드가 없다. -- 우리 콘텐츠 3,500여 파일에는 Docusaurus 전용 문법(`:::tip`, ``, `@site/src` React import)이 박혀 있어 이관 시 전량 변환이 필요하다. -- 기존 URL 620개×9를 깨지 않고 옮겨야 하는 SEO 리스크도 있다. - -**판단**: 산출물 크기 하나를 해결하려고 나머지 전부를 다시 만들 가치가 없다. 산출물 문제는 아래처럼 배포 변경만으로 해결된다. (단, 신규 사이트를 오늘 처음 만든다면 Astro도 합리적 선택지다.) - -## 4. 제안하는 구조: 빌드 산출물을 git 밖으로 - -> **[결정 2026-07-18] 이 장의 제안은 철회됨.** 계정이 Pages **Pro 플랜(파일 -> 10만 개 한도)**으로 확인됐고 (아래 도식의 "20k 제한"은 Free 플랜 기준), -> 빌드도 846MB/약 33k 파일로 감축돼 한도 내이므로 **기존 방식(산출물을 www에 -> 커밋)을 유지**하기로 했다. 구현했던 R2 킷은 저장소에서 제거(git 히스토리에 -> 보존). 아래 내용은 검토 기록으로 남긴다. - -**"support 산출물을 www 저장소에 커밋"을 중단**하고, CI가 빌드해서 R2 오브젝트 스토리지에 올리고, Worker가 서빙한다. NetDrive 블로그가 이미 같은 패턴(GitHub Actions 빌드 → nginx 서버 rsync, `bdweb/.github/workflows/blog-deploy.yml`)으로 운영 중이라 팀에 검증된 방식이다. - -``` -[변경 전] -글 작성 → 빌드 → 산출물을 www에 커밋 → PR → 머지 → Cloudflare 반영 - (3.1GB/36k 파일이 git에 들어감 → Pages 20k 제한에 걸려 불가) - -[변경 후] -글 작성(소스 md 9개) → support 저장소에 PR → 리뷰·머지 - ↓ (GitHub Actions 자동) - 빌드(14분) → rclone sync로 R2 업로드 - ↓ -방문자 rcloneview.com/support/* ←— Cloudflare Worker가 R2에서 서빙 -방문자 rcloneview.com/(나머지) ←— www 기존 방식 그대로 (변화 없음) -``` - -### 구성 요소와 역할 - -| 구성 요소 | 역할 | 비고 | -|---|---|---| -| GitHub Actions | main 머지 감지 → 빌드 → R2 업로드. PR 시점엔 빌드 검사만 | bdweb blog-deploy.yml과 동일 패턴 | -| R2 버킷 | 빌드 산출물 저장소 (3.1GB, 파일 수 제한 없음) | `rclone sync`로 증분 업로드 | -| Cloudflare Worker | `/support/*` 요청을 R2에서 꺼내 서빙 (~50줄) | 나머지 경로는 기존 www로 통과 | -| www 저장소 | `support/` 폴더 제거, 홈페이지 전용으로 회귀 | 배포 방식 변화 없음 | - -### 팀원 입장에서 바뀌는 것 / 안 바뀌는 것 - -- **안 바뀜**: PR 확인 → 머지 흐름, 사이트 URL, 방문자 화면 전부 그대로. -- **좋아짐**: PR이 마크다운 소스만 담게 되어 리뷰 가능해짐 (글 1개 = 원문 1 + 번역 8 = 9파일). PR에 빌드 통과 ✅/❌가 미리 표시됨. -- **비용**: R2 무료 구간(저장 10GB, egress 무제한 무료) 안. Worker는 무료 플랜 10만 요청/일, 초과 시 월 $5. 사실상 0~$5/월. - -### 사람이 한 번만 해야 하는 초기 설정 - -1. Cloudflare 대시보드에서 R2 버킷 생성 + API 토큰 발급 -2. GitHub support 저장소 Settings → Secrets에 토큰 등록 (`R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_ENDPOINT`) -3. Worker 배포 승인 (`wrangler deploy` 시 Cloudflare 인증) - -이후는 전부 자동. - -## 5. 남은 작업 (2026-07-09 기준) - -1. 소급 번역 완료 — 260개 남음 (세션 윈도우 3회분) -2. 신규 글 봇에 번역 단계 통합 — 글 1개 발행 시 8개 번역 동시 생성 -3. 배포 전환 — 위 4장 구조 구축 (R2/Worker/Actions), www에서 support 제거 -4. 배포 시 언어별 sitemap을 Google Search Console/Bing에 등록 -5. (별건) 홈페이지 rcloneview_www 자체의 다국어화 — 정적 HTML이라 별도 설계 필요, Astro가 후보 - -### SEO 참고 - -- hreflang이 언어별 페이지 관계를 선언하므로 중복 콘텐츠 문제는 없다. -- 유일한 리스크는 **부분 번역 상태의 장기화** — 미번역 글은 로케일 URL에 영어가 그대로 노출(fallback)되므로, 소급 번역을 빨리 끝내는 것이 좋다. diff --git a/I18N_RUNBOOK_ko.md b/I18N_RUNBOOK_ko.md deleted file mode 100644 index 9b7cc21c..00000000 --- a/I18N_RUNBOOK_ko.md +++ /dev/null @@ -1,149 +0,0 @@ -# i18n 작업 런북 — 번역 배치 실행·검증·재개 절차 - -> 실무용 문서. 새 Claude 세션(또는 사람)이 이 문서만 보고 번역 배치를 이어서 돌릴 수 있도록 모든 절차·규칙·함정을 기록한다. -> 배경·구조 설명은 [I18N_OVERVIEW_ko.md](./I18N_OVERVIEW_ko.md) 참고. -> 로컬에서 결과물을 확인하려면 [LOCAL_TESTING_ko.md](./LOCAL_TESTING_ko.md) 를 따를 것 (일반적인 npm run serve/start 로는 404 가 난다). -> 최종 갱신: 2026-07-09 - ---- - -## 1. 현재 상태 - -- 브랜치: `feature/i18n` (origin 미푸시, 푸시/PR 시점은 사장님 결정 대기) -- 진행: **블로그 625편 + docs 80편 완역** (× 8로케일 = 5,592파일 + 사이드바 라벨), 전체 빌드 통과. support 사이트 콘텐츠 번역 100% 완료 -- 커밋 이력: - -| 커밋 | 내용 | -|---|---| -| `1a13371` | i18n 설정 + UI 문자열 + tags.yml 번역 (8로케일) | -| `36a90f0` | 원문 콘텐츠 정규화 (링크 88파일, 태그 37파일) | -| `f3db344` | 번역 파이프라인 스크립트 + 파일럿 | -| `965609c` | 배치 1: 98포스트 (784파일) | -| `aadfa87` | 배치 2: 80포스트 (640파일) | -| `1681ee9` | 배치 3: 100포스트 (800파일) | -| `617cb00` | 배치 4: 80포스트 (640파일) | -| `a709567` | 배치 5: 80포스트 (640파일) — 결함 0, zh-Hans 자동교정 2건 | -| `1a286e1` | 배치 6: 80포스트 (640파일) — 결함 0, de 수동교정 2건 (표 헤더·링크 텍스트) | -| `1341c68` | 배치 7(블로그 최종): 99포스트 (792파일) — 아티팩트 자동교정 규칙 추가(), YAML 3건, 원문 버그 6종 수리 | -| `00adb15` | docs 배치: 80문서 (640파일) + howto 사이드바 라벨 8로케일 — scripts/docs-i18n-batch.workflow.js 신설, 검증기 docs 확장 | -| (HEAD) | 배치 8: main 머지로 유입된 봇 신규 글 6편 (48파일) — ja 링크 텍스트 1건 교정 | - -- 번역 방식: **API 키/Batch API 사용 안 함** (사장님 명시 거부). Claude Code 구독 세션 안에서 Sonnet 서브에이전트로 번역. 세션 사용량 윈도우에 맞춰 배치당 80~100포스트. -- 실측 비용/시간: 배치당(640~800 에이전트) 약 40~70분, Sonnet 토큰 약 1,400만 (번역 1건당 22~25k). -- 결함률: 배치 3~4 기준 ~0.3%, 전부 검증 단계에서 자동 교정됨. - -## 2. 번역 배치 실행 절차 (Claude Code 세션) - -### ① 미번역 목록 계산 (파일 존재 여부 기준) - -```python -from pathlib import Path -posts = sorted([p.name for p in Path('blog').glob('*.md') if p.name != 'template.md'], reverse=True) -done = {p.name for p in Path('i18n/ko/docusaurus-plugin-content-blog').glob('*.md')} -batch = [p for p in posts if p not in done][:80] # 배치 크기 80~100 -``` - -- 기준 로케일은 ko (모든 배치가 8로케일 동시 생성이므로 ko 존재 = 완료로 간주 가능). -- `template.md`는 번역 대상 아님. - -### ② Workflow 실행 - -Claude Code의 Workflow 도구로 `scripts/blog-i18n-batch.workflow.js`를 실행한다: - -- `scriptPath`: 이 저장소의 `scripts/blog-i18n-batch.workflow.js` -- `args`: `{"posts": [①에서 계산한 파일명 배열]}` — **JSON 값으로 전달** (문자열로 감싸면 스크립트가 방어적으로 파싱하긴 함) -- 동작: 포스트 × 8로케일 쌍마다 Sonnet 에이전트(`model: 'sonnet'`, `effort: 'low'`)가 원문을 Read → 번역 → `i18n/{locale}/docusaurus-plugin-content-blog/{파일명}`에 직접 Write. 동시 실행 ~10개. -- 스크립트 안의 프롬프트(STRICT RULES 8개)와 용어집이 번역 품질의 핵심 — **수정 시 신중히**. - -### ③ 검증 (4단계, 순서대로) - -```bash -# 1+2단계: 구조 검사 + YAML + 아티팩트 자동 교정 ( 제거, de 인용부호) -.venv/bin/python scripts/validate_i18n.py # "문제 0건" 확인 - -# 3단계: MDX 컴파일 검사 -node scripts/mdx_check.mjs # "실패 0" 확인 - -# 4단계: 9로케일 전체 빌드 — 최종 관문 -rm -rf build && npm run build > build.log 2>&1; echo "exit=$?" -# ⚠ 반드시 $?를 직접 확인. `npm run build | tail`처럼 파이프 걸면 tail의 exit 0에 가려짐 -``` - -- `.venv`가 없으면: `python3 -m venv .venv && .venv/bin/pip install pyyaml` -- 문제 발견 시: validate_i18n.py 출력의 해당 파일을 열어 수동 교정 후 재검증. 반복 패턴이면 validate_i18n.py에 자동 교정 규칙 추가. - -### ④ 커밋 (사장님 사전 승인: "빌드 통과하면 커밋") - -```bash -git add i18n -git commit -m "i18n: translate N more blog posts into all 8 locales (batch X)" -``` - -푸시는 지시 없이 하지 않는다. - -## 3. 번역 규칙 (에이전트 프롬프트의 STRICT RULES 요약) - -1. 산출 파일에는 번역된 마크다운만 (해설·주석 금지) -2. frontmatter: `title`, `description`(및 `keywords`의 자연어)만 번역. **slug/date/authors/tags/image는 바이트 단위 동일** -3. 코드블록·인라인코드·URL·이미지 경로·제품명(RcloneView, rclone...)·클라우드 서비스명·CLI 명령은 절대 번역 금지 -4. MDX import: `'../src/...'` → `'@site/src/...'`로 변환 (i18n 폴더 깊이에서 상대경로가 깨짐) -5. 마크다운 구조 보존: 제목 계층, 표, `:::tip` admonition, `` 마커, 코드블록 개수 동일 -6. 링크 텍스트는 번역, 링크 URL은 불변 -7. 용어집 준수 (Desktop ARB와 통일): - -| en | ko | ja | zh-Hans | zh-Hant | de | es | fr | id | -|---|---|---|---|---|---|---|---|---| -| remote | 리모트 | リモート | 远程 | 遠端 | Remote | remoto | distant | remote | -| mount | 마운트 | マウント | 挂载 | 掛載 | einbinden(mount) | montar | monter | mount | -| sync | 동기화 | 同期 | 同步 | 同步 | Synchronisation | sincronización | synchronisation | sinkronisasi | -| backup | 백업 | バックアップ | 备份 | 備份 | Backup | copia de seguridad | sauvegarde | pencadangan | -| transfer | 전송 | 転送 | 传输 | 傳輸 | Übertragung | transferencia | transfert | transfer | -| cloud storage | 클라우드 스토리지 | クラウドストレージ | 云存储 | 雲端儲存 | Cloud-Speicher | almacenamiento en la nube | stockage cloud | penyimpanan cloud | - -## 4. 알려진 함정과 해결 (이미 밟은 지뢰들) - -| 증상 | 원인 | 해결 (적용 완료) | -|---|---|---| -| 로케일 빌드에서 `/support/ko/support/...` 이중 경로 | 원문 링크에 baseUrl(`](/support/`) 포함 | 원문 88파일을 `](/`로 정규화. **신규 글은 처음부터 `/howto/...` 형태로** | -| 번역 빌드에서 상대 `.md` 링크 깨짐 | Docusaurus 3.7 i18n 버그 | howto/tutorials 41개 링크를 절대 사이트 경로로 변환 | -| MDX import 해석 실패 | i18n 폴더 깊이에서 `../src/` 불능 | `@site/src/` 별칭으로 변환 (프롬프트 규칙 4) | -| 번역 파일 끝 `` 잔류 | 에이전트 Write 실수 | validate_i18n.py가 자동 제거 | -| de 로케일 YAML 파싱 실패 | `„...“` 닫는 따옴표를 `"`로 써서 YAML 문자열 조기 종료 | validate_i18n.py가 정규식으로 자동 교정 | -| 빌드 실패를 통과로 오판 | `npm run build \| tail`의 exit code는 tail 것 | `$?` 직접 확인 | -| ``가 MDX 컴파일 실패 | 순수 MDX에선 HTML 주석 불가 (Docusaurus는 전처리함) | mdx_check.mjs가 컴파일 전에 주석 제거 | -| 빌드 시 undefined tag 경고 | 원문이 tags.yml에 없는 태그 사용 | 37포스트 재매핑 (S3→s3 등). **신규 글은 tags.yml에 정의된 소문자 태그만** | -| 태그 라벨이 영어로만 표시 | 태그도 로케일별 번역 필요 | `i18n/{loc}/docusaurus-plugin-content-blog/tags.yml` 생성 (라벨만 번역, key/permalink는 영어 유지) | -| 라이브에 깨진 이미지 노출 | template.md 카탈로그에 실재하지 않는 파일명 36개가 실려 있었고 봇이 그중에서 골라 씀 | 가짜 항목 제거 + `scripts/check-image-refs.mjs`가 prebuild로 전 콘텐츠의 자산 참조 실재 여부 검사 (누락 시 빌드 실패) | -| 태그 페이지 제목 중복(ko "게시물개의 게시물", ja "件件") / id는 항상 단수 표시 | `{nPosts}`가 이미 단위 포함 문자열인데 템플릿이 단위를 또 붙임; id는 복수형 카테고리가 1개뿐이라 2형 메시지의 첫 형(단수)만 선택됨 | code.json 교정. **규칙: `\|` 분절 수는 로케일의 `Intl.PluralRules` 카테고리 수와 일치**(ko/ja/zh/id=1형, de=2형, es/fr=3형), `{nPosts}`·`{nDocsTagged}` 뒤에 단위 반복 금지 | - -## 5. 신규 글 작성 봇에 반영할 규칙 (작업 #5) - -1. 태그는 `blog/tags.yml`에 정의된 소문자 키만 사용 -2. 내부 링크는 baseUrl 없이 `/howto/...`, `/blog/...` 형태 -3. MDX import는 `@site/src/...` 별칭 사용 -4. 글 발행 시 8로케일 번역을 같은 PR에 포함 — **구현됨**: Fact-checker STEP 4.7 이 검증 통과 글을 **인라인(자기 Read/Write)** 으로 번역하고 2장 ③ 검증을 돈다. ⚠️ **루틴은 Workflow 도구/서브에이전트를 못 쓴다** — 무인 루틴에서 Workflow 도구가 승인 프롬프트에 걸려 멈추기 때문(2026-07-21 실측). `scripts/blog-i18n-batch.workflow.js`(병렬 Sonnet)는 **로컬 소급 번역 전용**으로만 유지. STEP 5 빌드는 `npm run build`(prebuild 이미지검사 + postbuild 프룬)로 검증만 한다 — www 반영은 `.github/workflows/deploy-www.yml` 이 main 머지 후 자동으로 처리한다(2026-07-28). STEP 6-B 는 영어 원문 + `i18n/*/docusaurus-plugin-content-blog/${DATE}-*.md`(8로케일 번역)을 verified 브랜치에 함께 커밋 — support 가 번역 원본이므로 소스에 남긴다. **3단계 계획 전부 완료.** -5. 이미지·비디오는 static/에 실재하는 파일만 참조 (template.md 카탈로그는 2026-07-18 실측 정리됨). 발행 전 `npm run check:images`로 확인 — 없는 파일명을 지어내면 빌드가 실패한다 - -## 6. 배포 (작업 #6 — 종결: 기존 Pages 방식 유지) - -> **2026-07-18 결정**: Cloudflare 계정이 **Pages Pro 플랜(파일 10만 개 한도)**으로 -> 확인됐다 (R2 전환은 Free 플랜의 2만 개 한도를 전제로 세운 계획이었음). -> 빌드도 846MB / 약 33,000 파일로 감축돼(→ `docs/journals/2026-07-16-build-size-reduction_ko.md`) -> 한도 내이므로, **기존 방식(빌드 산출물을 www 저장소 `support/`에 커밋 → -> Pages 배포)을 그대로 유지**한다. -> 당시 구현했던 R2 킷(`.github/workflows/deploy.yml`, `workers/support-router/`, -> `DEPLOYMENT_R2_ko.md`)은 저장소에서 제거됨 — 필요해지면 git 히스토리에서 복원. - -유효하게 남은 후속 작업: - -1. **[사람]** 언어별 sitemap을 Search Console/Bing Webmaster에 등록 - -## 7. 참고 파일 - -| 파일 | 용도 | -|---|---| -| `scripts/blog-i18n-batch.workflow.js` | 번역 배치 오케스트레이션 (Claude Code Workflow용) | -| `scripts/validate_i18n.py` | 검증 1+2단계 + 아티팩트 자동 교정 | -| `scripts/mdx_check.mjs` | 검증 3단계 (MDX 컴파일) | -| `scripts/translate_blog.py` | (미사용 보관) Batch API 파이프라인. API 키 방식이라 사용 안 함. 용어집·변환 규칙의 원본 | -| `bdweb/.github/workflows/blog-deploy.yml` | 배포 CI 참고 패턴 (NetDrive 블로그, 검증된 실물) | diff --git a/LOCAL_TESTING_ko.md b/LOCAL_TESTING_ko.md deleted file mode 100644 index 3e5256ad..00000000 --- a/LOCAL_TESTING_ko.md +++ /dev/null @@ -1,83 +0,0 @@ -# 로컬 테스트 가이드 — 이대로 안 하면 "페이지를 찾을 수 없습니다"가 뜹니다 - -> 이 브랜치(feature/i18n)를 클론 받아 테스트하는 사람을 위한 문서. -> **Docusaurus 의 일반적인 실행 방법(`npm run serve`, `npm run start`)으로는 -> 이 사이트를 온전히 볼 수 없다.** 이유와 올바른 방법을 설명한다. - ---- - -## TL;DR — 올바른 실행법 (복사해서 실행) - -```bash -# 터미널 1 — support 사이트 (이 저장소) -cd rcloneview-support -npm ci -npm run build # 9로케일 전체 빌드 (~15분, 최초 1회) -node scripts/preview-server.mjs # → :3001 - -# 터미널 2 — www 사이트 (rcloneview_www 저장소, feature/i18n 브랜치) -cd rcloneview_www -node scripts/i18n/www-preview.mjs # → :3002 -``` - -**브라우저 진입점: http://localhost:3002/** ← 여기서 시작하면 -www ↔ support 를 오가며 9개 언어 전부, 실서비스와 동일하게 탐색된다. - ---- - -## 하지 말아야 할 실행법과 그 이유 - -### ❌ `npm run serve` — 점(.) 포함 경로가 전부 404 - -Docusaurus 의 `serve`(내부적으로 serve-handler)는 URL 에 점이 있으면 -파일 확장자로 오인한다. `/support/release-notes/v1.4` 의 ".4" 를 확장자로 -보고 디렉터리의 index.html 을 찾지 않아 **파일이 존재하는데도 404** 를 낸다. -→ 대신 `node scripts/preview-server.mjs` 를 쓸 것 (동일 역할 + 결함 없음 + -실서비스 Worker 와 같은 라우팅 규칙). - -### ❌ `npm run start` (dev 서버) — 영어 외 전부 404 - -Docusaurus dev 서버는 **한 번에 한 로케일만** 띄울 수 있다 (공식 제약: -"각 로케일은 독립된 SPA"). 기본은 영어라서 언어 선택기로 한국어를 고르면 -404 가 뜬다. 코드 수정(HMR)이 필요할 때만 쓰고, 특정 언어를 보려면: - -```bash -npm run start -- --locale ko # 한국어만 뜨는 dev 서버 (다른 언어는 404) -``` - -### ❌ 한쪽 사이트만 띄우기 — 네비 절반이 404 - -네비바의 **Plus / 다운로드**는 www 사이트(rcloneview_www) 페이지이고, -www 쪽 네비의 **지원 / 릴리스 노트 / 블로그**는 이 저장소 페이지다. -실서비스에선 같은 도메인이라 자연스럽게 이어지지만, 로컬에선 저장소가 -분리돼 있어 **양쪽 프리뷰(:3001 + :3002)를 함께 띄워야** 끊기지 않는다 -(두 서버가 서로 프록시/포워딩하도록 구성돼 있음). - ---- - -## 이건 404 가 떠도 정상입니다 - -| 경로 | 이유 | -|------|------| -| www 의 EULA·개인정보처리방침의 번역판 | 법적 문서는 의도적으로 영문만 제공 (열린 결정) | -| 캠페인 페이지(`ad-*.html`, blackFriday 등)의 로케일 URL | 단명 페이지라 번역 대상에서 제외 | -| dev 서버(:3000)에서 영어 외 로케일 | 위 "npm run start" 항목 참조 | - -## 테스트 체크리스트 (전부 통과해야 정상) - -http://localhost:3002/ 에서 시작: - -- [ ] 푸터 하단 오른쪽 언어 선택기로 **한국어** 전환 → `/ko/index.html` -- [ ] 네비: Plus → 한국어 가격 / 다운로드 → 한국어 다운로드 -- [ ] 네비: 지원 → `/support/ko/` (한국어 support 홈, 카드 3종 한국어) -- [ ] 네비: 릴리스 노트 → 한국어 v1.4 (`/support/ko/release-notes/v1.4`) ← 점 경로! -- [ ] 네비: 블로그 → 한국어 블로그 → All posts(아카이브) 카테고리/연도 뷰 + 필터 -- [ ] 언어 선택기로 日本語 등 다른 언어 전환 — 위 여정 반복 시 언어 유지 -- [ ] 아무 글이나 열어 본문 번역 + 하단 prev/next + "전체 글 보기" 확인 - -## 문제가 있으면 - -- 화면이 예전 것 같다 → 강력 새로고침 (Cmd+Shift+R). 프리뷰 서버는 - no-store 를 보내지만, 과거 방문분이 캐시돼 있을 수 있다. -- `/support/*` 가 502 → 터미널 1(support 프리뷰)이 꺼진 것. 다시 실행. -- 빌드가 오래 걸린다 → 정상 (9로케일 ~15분). 완료 후엔 서버만 켜면 된다. diff --git a/RCLONEVIEW_FEATURE_SPEC.md b/RCLONEVIEW_FEATURE_SPEC.md deleted file mode 100644 index b01fc387..00000000 --- a/RCLONEVIEW_FEATURE_SPEC.md +++ /dev/null @@ -1,1092 +0,0 @@ -# RcloneView Feature Specification - -> **Purpose:** Official feature specification for writing RcloneView blog posts. All content verified against source code (`rclone-navigator`) + official documentation (`rcloneview-support/howto`, `docs`). -> **Last Updated:** 2026-04-13 -> **App Version:** 1.4.1+1 -> **Framework:** Flutter (Dart 3.2.6+) - ---- - -## Table of Contents - -1. [Product Overview](#1-product-overview) -2. [File Explorer](#2-file-explorer) -3. [File Operations](#3-file-operations) -4. [Sync & Job Management](#4-sync--job-management) -5. [Folder Compare](#5-folder-compare) -6. [Mount & Virtual Drive](#6-mount--virtual-drive) -7. [Rclone Terminal](#7-rclone-terminal) -8. [Remote Management](#8-remote-management) -9. [Connection Management](#9-connection-management) -10. [Supported Cloud Providers](#10-supported-cloud-providers) -11. [Virtual Remotes](#11-virtual-remotes) -12. [Settings & Preferences](#12-settings--preferences) -13. [Notification & Remote Control](#13-notification--remote-control) -14. [Multi-Window & System Tray](#14-multi-window--system-tray) -15. [Platform Support](#15-platform-support) -16. [License Structure](#16-license-structure) -17. [Batch Operations (Beta)](#17-batch-operations-beta) - ---- - -## 1. Product Overview - -### 1.1 What is RcloneView - -RcloneView is a cross-platform GUI client built on rclone. It runs on Windows, macOS, and Linux, managing 90+ cloud storage services from a single interface. - -**Architecture:** -- RcloneView communicates with rclone via the rclone RC (Remote Control) API -- Ships with an Embedded Rclone binary — no separate installation required -- Can also connect to external rclone instances (local, remote server, Docker) -- It is an independent GUI frontend that leverages rclone, not a replacement for rclone - -**Embedded Rclone:** -- Default API address: `http://127.0.0.1:5582` (localhost loopback) -- Minimum supported rclone version: v1.69.1+ -- Option to auto-terminate rclone on app exit -- In-app rclone Self Update capability - -### 1.2 Main UI Layout - -The RcloneView main screen consists of 4 areas: - -**1) Menu Bar (top)** -- **Home tab:** Sync, Compare, Job Manager, New Window buttons -- **Remote tab:** New Remote, Remote Manager, Mount Manager, Job Manager buttons -- **Settings tab:** Connect Manager, General, Layout, View count -- **Help tab:** Check for Updates, Feedback, Homepage, Register License Key - -**2) Explorer Panels (center)** -- 1 to 4 panels displayed simultaneously (horizontal/vertical split) -- Each panel: Tab Bar + Breadcrumb Path Bar + Folder Tree + File List -- Panel toolbar: Create Alias (favorite), Mount folder, Edit remote settings, Refresh - -**3) Info View (bottom tabs)** -- **Transferring tab:** Monitor active jobs (progress, speed, file count) -- **Terminal tab:** Built-in rclone CLI terminal -- **Log tab:** Timestamped log entries -- **Features tab:** Upcoming features preview - -**4) Footer (bottom bar)** -- App version info -- License info (FREE License / PLUS License) -- Rclone connection info (version, server address, OS) - ---- - -## 2. File Explorer - -### 2.1 Explorer Components - -Each Explorer panel is a file manager for browsing cloud or local storage. - -**Tab Bar:** -- Displays the currently connected remote -- Switch between remotes via tabs - -**Breadcrumb Path Bar:** -- Shows folder path hierarchically -- Auto-complete suggestions -- Right-click menu: Cut, Copy, Paste, Copy Full Path (with Remote), Select All -- Copy Full Path: Copies in `mygoogledrive:Meet recordings` format for direct rclone CLI use - -**Folder Tree:** -- Collapsible left-side folder tree navigator -- Expand/collapse folders to browse hierarchy - -**File List:** -- Columns: Name, Type, Modified date, Size -- Thumbnail view support (image file preview grid) -- Footer summary: Total files/folders count and total file size - -### 2.2 View Modes - -| View Mode | Description | -|-----------|-------------| -| List View | Detailed file information (name, size, date, type) | -| Tree View | Folder hierarchy navigation | -| Thumbnail View | Image file preview grid | - -### 2.3 Layout Settings - -- **Horizontal split:** Panels arranged side by side -- **Vertical split:** Panels stacked top to bottom -- **Panel count:** 1 to 4 panels simultaneously -- Changed via Settings tab > Layout / View count - ---- - -## 3. File Operations - -### 3.1 Basic File Operations - -All operations are performed via right-click context menu or keyboard shortcuts. - -| Operation | Method | Shortcut | Description | -|-----------|--------|----------|-------------| -| Copy | Right-click > Copy | Ctrl+C / Cmd+C | Copy files/folders | -| Cut | Right-click > Cut | Ctrl+X / Cmd+X | Cut files/folders (move) | -| Paste | Right-click > Paste | Ctrl+V / Cmd+V | Paste copied/cut items | -| Delete | Right-click > Delete | - | Delete files/folders (with confirmation dialog) | -| Rename | Right-click > Rename | - | Rename files/folders (inline editing) | -| New Folder | Right-click > New Folder | - | Create new folder at current location | -| Download | Right-click > Download | - | Cloud to local download | -| Upload | Right-click > Upload | - | Local to cloud upload | -| Reload | Right-click > Reload | F5 / Cmd+R | Refresh folder contents | -| Get Size | Right-click > Get Size | - | Calculate total size of selected items | -| Get Public Link | Right-click > Get Public Link | - | Generate shareable public link (provider-specific) | -| Open in Explorer | Right-click > Open in Explorer | - | Open in native file manager | - -### 3.2 Multi-Selection - -| Method | Behavior | -|--------|----------| -| Ctrl + Click | Toggle individual file selection | -| Shift + Click | Select range (all files between first and last click) | - -### 3.3 Drag & Drop - -| Scenario | Behavior | -|----------|----------| -| Within same remote | **Move** | -| Between different remotes | **Copy** | -| Windows Explorer to RcloneView | **Upload** (to cloud) | - -- Drag and drop confirmation popup can be toggled in Settings - ---- - -## 4. Sync & Job Management - -### 4.1 Sync Configuration (4 Steps) - -Sync jobs are configured via a 4-step wizard: - -**Step 1: Configure Storage** -- Select source remote + folder -- Select destination remote + folder -- Enter job name (allowed characters: a-z, A-Z, 0-9, -, _) -- 1:N sync: Add multiple destinations -- Sync direction: - - **One-way** "Modifying destination only" — modifies destination only (stable, official) - - **Bidirectional** "Bidirection" — merges changes from both sides (Beta, experimental) -- Create empty directories option - -**Step 2: Advanced Settings** -- **Number of file transfers:** Concurrent file transfer count -- **Number of multi-thread transfers:** Default 4, set 0 to disable -- **Number of equality checkers:** Default 8, recommend 4 or less for slow backends -- **Enable checksum:** Compare files by hash + size -- **Retry entire sync if fails:** Default 3, set 1 to disable retry - -**Step 3: Filtering Settings** -- **Max file size:** In MB (exclude files exceeding this) -- **Max file age:** Units: y (year), d (day), h (hour), m (minute), s (second) -- **Max folder depth:** Limit folder hierarchy levels -- **Predefined filters:** Music, Video, Image, Document, Google Docs, Box Docs -- **Custom filters:** File type, folder, path exclusion rules - - Examples: `.iso` (exclude extension), `/.git/*` (exclude root .git files), `.git/` (exclude all .git folders) - -**Step 4: Scheduling — PLUS License Only** -- Crontab-style scheduling -- Fields: Minute (0-59), Hour (0-23), Day of Week (0-6), Day of Month (1-31), Month (1-12) -- Supported formats: empty (every), lists (1,3,5), ranges (0-2), steps (6-12/3) -- Simulate schedule: Preview next execution times - -### 4.2 Dry Run (Simulation) - -Simulates sync without making actual changes: -- Shows list of files to be copied -- Shows list of files to be deleted -- Preview detailed operation list -- Recommended before actual sync to prevent mistakes - -### 4.3 Job Manager - -Central management interface for creating, editing, executing, and monitoring jobs. - -**Job Management:** -- Add Job: Create new job -- Edit Job: Modify existing job -- Duplicate: Clone a job -- Delete: Remove job -- Export: Save job settings as `rclone_jobs_~.json` file -- Import: Load jobs from JSON file - -**Job Types:** -- Sync: Source to destination synchronization -- Copy: Copy files/folders -- Move: Move files/folders -- Delete: Remove files/folders -- Download: Cloud to local -- Upload: Local to cloud - -**Execution Modes:** -- One-time: Execute immediately (not saved) -- Add: Create and save job -- Edit: Modify existing job - -### 4.4 Job History - -Detailed tracking of each job's execution history. - -**History Fields:** -| Field | Description | -|-------|-------------| -| Execution Type | Manual or Scheduled | -| Start Time | Execution start time | -| Time Spent | Duration | -| Status | Completed / Errored / Canceled | -| Total Size | Total transferred size | -| Speed | Transfer speed | -| Files | Number of files transferred | -| Job Type | Sync/Copy/Move/Delete/Download/Upload | - -**History Filters:** -- From ~ To (date range) -- Today, Yesterday, Last week, Last month -- Delete all - -### 4.5 1:N Synchronization - -Synchronize one source to multiple destinations simultaneously. -- Add multiple destination folders in Step 1 -- Same source content is mirrored to each destination -- Available with FREE license - -### 4.6 Transfer Monitoring - -Monitor active jobs in the Transferring tab of the bottom Info View: -- Progress percentage display -- Transfer speed -- File count and size transferred -- Cancel running jobs - -Bottom tab filters: Show/hide by Download, Upload, Sync job types - ---- - -## 5. Folder Compare - -### 5.1 Overview - -Visually compare two folders (local/cloud) side by side, showing differences. - -Launched via the **Compare** button in the Home tab. - -### 5.2 Comparison Result Filters - -| Filter | Description | -|--------|-------------| -| Show left-only files | Files existing only on the left | -| Show right-only files | Files existing only on the right | -| Show same files | Identical files on both sides | -| Show different files | Files with different sizes | -| Show errored files | Error/conflict files | - -### 5.3 Comparison View Actions - -**Navigation:** -- Navigate to upper folder -- Navigate to lower folder - -**File Operations:** -- Copy right: Copy files from left to right -- Copy left: Copy files from right to left -- Delete: Delete selected files - -**Size Change Discovery:** -- Find folders by file count change -- Find folders by size change -- Find folder with largest change -- Find folder with next large change -- Find folder with smallest change -- Find folder with next smaller change - -**Copy Behavior:** -- Copies only when file doesn't exist on target side OR has different size -- After copying, files are marked as "equal" in comparison view - -### 5.4 Folder Compare with Filter — PLUS License Only - -Restrict comparison targets with custom filter rules: -- Filter by folder name and file type -- Examples: `.iso` (exclude), `/.git/*` (root .git files), `/.git/` (root .git folder), `.git/` (all .git folders) - ---- - -## 6. Mount & Virtual Drive - -### 6.1 Overview - -Mount cloud storage as a local drive and access it directly from your file explorer. - -### 6.2 Mount Methods - -**Method 1: From Remote Explorer** -1. Select the remote folder to mount in the explorer -2. Click the Mount icon in the panel toolbar -3. Configure mount settings -4. Click "Save and mount" or "Save" - -**Method 2: From Mount Manager** -1. Click Mount Manager button in Remote tab -2. Click New mount -3. Select remote and subdirectory -4. Configure options -5. Click Save or Save and mount - -### 6.3 Mount Configuration Options - -| Setting | Default/Options | Description | -|---------|----------------|-------------| -| Target | Auto / manual drive letter | Windows: Drive letter assignment | -| Mount to local path | - | Custom mount location (macOS/Linux) | -| Auto mount | Off | Auto-mount on startup (PLUS) | -| Volume name | - | Displayed volume name | -| Mount type | cmount (Windows) / nfsmount (Linux/macOS) | Mount method | -| Network drive | Off | Show as network drive (Windows) | -| Read only | Off | Read-only mode | -| Allow other | Off | Allow other users to access (Linux) | -| Cache mode | off / minimal / **writes** (default) / full | VFS cache mode | -| Cache max size | -1 (unlimited) | Maximum cache size (bytes) | -| Cache max age | - | Cache data validity period (nanoseconds) | -| Dir cache time | - | Directory cache validity period (nanoseconds) | - -### 6.4 Mount Manager - -Management by mount status: - -| Status | Available Actions | -|--------|-------------------| -| Mounted | Unmount, Open (open in file explorer) | -| Unmounted | Mount, Edit, Delete | - -**Constraints:** -- Edit/Delete disabled while mounted -- Open disabled while unmounted - -### 6.5 Mount Management from System Tray - -- Right-click RcloneView tray icon -- View mounted drives in Mount menu -- Toggle mount/unmount -- Start new mount - ---- - -## 7. Rclone Terminal - -### 7.1 Overview - -Built-in terminal in RcloneView for executing rclone CLI commands directly. Located in the Terminal tab of the bottom Info View. - -### 7.2 Features - -- Full terminal emulation based on xterm.dart -- PTY (pseudo-terminal) support -- Rclone command auto-complete: type `rclone` + space for command suggestions -- Shell environment: Windows CMD/PowerShell, Linux bash, macOS zsh - -**Common Commands:** -| Command | Description | -|---------|-------------| -| `rclone listremotes` | List configured remotes | -| `rclone about "remote:"` | Get remote storage usage | -| `rclone config create ` | Create remote via CLI | - -### 7.3 View Management - -- **Expand:** Full-screen terminal -- **Shrink:** Return to default layout - -### 7.4 Output Handling - -- Text selection supported -- Right-click menu: Copy, Paste, Copy All - ---- - -## 8. Remote Management - -### 8.1 Remote Setup Methods - -Adding cloud storage connections (remotes) in RcloneView varies by provider. - -**OAuth-Based (Browser Login):** -Browser opens for account authentication, then auto-connects. No separate API key needed. -- Google Drive, Dropbox, Google Photos, OneDrive, Box, pCloud, Yandex Disk, premiumize.me, put.io, HiDrive - -**Credential Entry:** -Directly enter Access Key, Token, or account credentials. -- Amazon S3 (Access Key ID + Secret Access Key + Region) -- Cloudflare R2 (API Token + Account ID + Endpoint) -- Mega (Email + Password) -- Backblaze B2 (Application Key ID + Application Key) -- Proton Drive (Email + Password, optional 2FA) -- Gofile (Access Token) -- Azure File Storage (Account Name + Shared Key + Share Name) -- iCloud Drive (requires rclone v1.69+) -- SFTP (Host + SSH authentication) - -**Additional Configuration Required:** - -| Provider | Additional Setting | -|----------|-------------------| -| Zoho WorkDrive | Region selection | -| Google Cloud Storage | Project Number | -| Citrix ShareFile | Root Folder ID | -| Google Drive Shared with Me | `shared_with_me = true` | -| Box for Business | `box_sub_type = enterprise` | -| Dropbox for Business | `dropbox_business = true` | -| Google Drive Computers | `root_folder_id = computer ID` | - -### 8.2 Remote Manager - -Access via Remote tab > Remote Manager button. -- Display all registered remotes -- Edit/delete per remote -- View remote configuration - ---- - -## 9. Connection Management - -### 9.1 Connection Types - -**Embedded Rclone (Built-in):** -- Included by default, no separate installation needed -- Address: `http://127.0.0.1:5582` -- Shares lifecycle with app (option to terminate on app exit) -- Displays rclone version, supports Self Update - -**External Rclone:** -- Connect to a separately running rclone instance -- Runs on: local machine, remote server, Docker container -- Default port: 5572 -- Launch command: `rclone rcd --rc-user= --rc-pass= --rc-addr=127.0.0.1:5572` - -### 9.2 Adding External Connection - -Settings tab > Connect Manager > New Connection: -1. Enter Display Name -2. Enter Remote Address (`http://:5572`) -3. Enter Username / Password -4. Option to disable SSL certificate verification (for self-signed certificates) -5. Test Connection to verify -6. Save - -### 9.3 AWS EC2 Integration - -Scenario: Run external rclone on AWS EC2 for remote connection. - -**Recommended Setup:** -- AMI: Ubuntu Server 22.04 LTS or 20.04 LTS -- Instance: t2.micro (Free Tier eligible) -- Storage: Minimum 8 GB -- Security Group: SSH (port 22, IP-restricted) + Custom TCP (port 5572) - -**Installation:** -```bash -curl https://rclone.org/install.sh | sudo bash -rclone version -``` - -**Daemon Launch:** -```bash -rclone rcd --rc-user=admin --rc-pass=admin --rc-addr=0.0.0.0:5572 -``` - -**systemd Service:** -- File path: `/etc/systemd/system/rclone-rcd.service` -- Run user: Ubuntu -- Key flags: `--rc-user`, `--rc-pass`, `--rc-addr`, `--rc-web-gui` (optional), `--log-file`, `--log-level` - -**Health Check:** -```bash -curl -X POST -u admin:admin "http://:5572/rc/noop" -``` - ---- - -## 10. Supported Cloud Providers - -### 10.1 OAuth Direct Login - -| Provider | Auth Method | -|----------|------------| -| Google Drive | OAuth (browser) | -| Dropbox | OAuth (browser) | -| Google Photos | OAuth (browser) | -| Microsoft OneDrive | OAuth (browser) | -| Box | OAuth (browser) | -| pCloud | OAuth (browser) | -| Yandex Disk | OAuth (browser) | -| premiumize.me | OAuth (browser) | -| put.io | OAuth (browser) | -| HiDrive | OAuth (browser) | - -### 10.2 Personal/Business Cloud - -| Provider | Notes | -|----------|-------| -| Google Drive Shared with Me | Requires shared_with_me setting | -| Google Drive Computers | Requires root_folder_id setting | -| Dropbox for Business | Requires dropbox_business setting | -| Box for Business | box_sub_type = enterprise | -| Mega | Email + Password | -| Proton Drive | Requires rclone v1.69+ | -| Backblaze B2 | Application Key ID + Key | -| Gofile | Access Token | -| iCloud Drive | Requires rclone v1.69+ | -| iCloud Photos | Separate package (code-verified) | -| Zoho WorkDrive | Requires Region selection | -| Citrix ShareFile | Requires Root Folder ID | -| Google Cloud Storage | Requires Project Number | -| Azure File Storage | Account + Key + Share Name | -| Koofr | - | -| Jottacloud | - | -| Mail.ru Cloud | - | -| Seafile | - | -| Storj | - | -| OpenDrive | - | -| PikPak | - | -| SugarSync | - | -| Files.com | - | -| Enterprise File Fabric | - | -| Cloudinary | - | -| Internet Archive | - | -| ImageKit | - | -| Linkbox | - | -| Pixeldrain | - | -| Uptobox | - | -| Uloz.to | - | - -### 10.3 S3-Compatible Providers - -Services accessed via rclone's S3 protocol. Requires Access Key + Secret Key + Endpoint. - -| Provider | | Provider | | Provider | -|----------|---|----------|---|----------| -| Amazon S3 | | Cloudflare R2 | | Wasabi | -| IDrive e2 | | MinIO | | DigitalOcean Spaces | -| Linode Object Storage | | Google Cloud Storage (S3) | | IBM COS | -| Tencent COS | | Alibaba OSS | | Huawei OBS | -| IONOS | | Ceph | | StackPath | -| Synology C2 | | Seagate Lyve | | Arvan Cloud | -| Scaleway | | Selectel | | Storj S3 | -| Outscale | | Magalu | | Leviia | -| Liara | | RackCorp | | SeaweedFS | -| Dreamhost | | Petabox | | China Mobile | -| Qiniu | | Netease | | Hetzner | -| OVHcloud | | Cubbit DS3 | | Rclone S3 | - -> **Note:** S3-compatible providers may be added or changed with rclone version updates. Prefer "numerous S3-compatible services" over citing specific counts. - -### 10.4 Protocol-Based Storage - -| Protocol | Description | -|----------|-------------| -| SFTP | SSH File Transfer Protocol (port 22) | -| FTP | File Transfer Protocol | -| WebDAV | Web Distributed Authoring and Versioning | -| SMB/CIFS | Server Message Block (network file sharing) | -| HTTP | Read-only HTTP access | -| HDFS | Hadoop Distributed File System | - -### 10.5 Local Storage - -| Type | Description | -|------|-------------| -| Local disk | Windows/Mac/Linux internal disks | -| External drives | SSD, USB, etc. | -| Synology NAS | Auto-detection support (toggle in Settings) | - ---- - -## 11. Virtual Remotes - -Wrappers that add functionality to existing remotes using rclone's virtual remote system. - -| Remote | Purpose | Example Use Case | -|--------|---------|-----------------| -| **Alias** | Shortcut to a specific cloud folder | Assign a short name to a deeply nested path | -| **Crypt** | Encrypt file names, contents, folder names | Store sensitive data encrypted in the cloud | -| **Memory** | RAM-based temporary storage | Testing and temporary operations | -| **Cache** | Accelerate slow remotes via caching | Includes Plex media server integration | -| **Chunker** | Split large files into chunks | Store large files on providers with size limits | -| **Combine** | Merge multiple folders as subfolders | Multiple clouds as one virtual tree | -| **Union** | Merge multiple folders into one view | Unified view across multiple storages | -| **Hasher** | Add hashing for integrity checks | Add checksums to remotes that don't support them | -| **Compress** | Compress files before upload | Save storage capacity | - ---- - -## 12. Settings & Preferences - -### 12.1 General - -| Setting | Description | -|---------|-------------| -| Language | UI language selection (9 languages) | -| Launch at login | Auto-start on system login | -| Start minimized | Launch into system tray | -| Quit on close | Close button behavior (quit vs. background) | -| Auto-detect Synology NAS | Auto-detect NAS on local network | -| Show local cloud folders | Display local cloud folders | -| Check for updates | Automatic update checking | -| Restore Default Settings | Reset all settings | - -### 12.2 Interfaces & Notifications - -| Setting | Description | -|---------|-------------| -| Dark mode | Light / Dark / System theme | -| Theme color | Accent color selection | -| Confirm drag and drop | Confirmation popup for drag operations | -| Show Job Types | Transfer log filter (Download/Upload/Sync) | -| Show job state log | Show detailed log after transfers | -| Show comparison completed | Folder comparison completion notification | -| Show confirmation before deleting files in compare | Delete confirmation in compare view | -| Show sync completion notification | Sync completion notification | -| Show network error dialog | Network error alert | - -### 12.3 Embedded Rclone - -| Setting | Description | -|---------|-------------| -| Stop rclone on App Exit | Terminate rclone process on app close | -| Local Rclone location | rclone binary path (embedded or custom) | -| Local Rclone config location | rclone.conf file path | -| Default download folder | Default download destination | -| Default upload folder | Default upload source | -| Global Rclone Flags | Additional rclone flags (e.g., `--no-check-certificate`) | -| Config Password | Password for encrypted rclone config | -| Enable rclone Logging | Activate file-based logging | -| Log folder | Log file storage directory | -| Log file name | Default log filename | -| Log level | DEBUG / INFO / NOTICE / ERROR | - -### 12.4 Supported UI Languages - -| Language | Notes | -|----------|-------| -| English | Default | -| Korean | - | -| French | - | -| German | - | -| Chinese Simplified | - | -| Chinese Traditional | - | -| Japanese | - | -| Spanish | - | -| Indonesian | - | - -Includes Noto Sans fonts (KR, SC, TC, JP variants) for CJK character support. - ---- - -## 13. Notification & Remote Control - -> **Note:** Features in this section are confirmed in source code but not yet documented in official docs. Presumed to be PLUS license features. - -### 13.1 Email Notifications - -Email alerts on job completion. -- Direct SMTP server configuration (host, port 587, authentication) -- RcloneView Relay service option -- Multiple recipient support -- Job size threshold (MB/GB units, notify only for jobs exceeding threshold) - -### 13.2 Telegram Bot - -- Telegram Bot Token + Chat ID configuration -- Job status notifications - -### 13.3 Slack Integration - -- App Token + Bot Token configuration -- User ID specification -- Job status notifications - -### 13.4 Discord Integration - -- Bot Token + User/Application ID configuration -- DM-based job status notifications - -### 13.5 Application Lock - -- Password-protect app access -- Password stored in encrypted secure storage - ---- - -## 14. Multi-Window & System Tray - -### 14.1 Multi-Window — PLUS License Only - -- Create new window via Home tab > New Window button -- Each window maintains independent state -- Inter-window communication via IPC -- Window position/size auto-saved - -### 14.2 System Tray - -Available with all license types. - -**Tray Menu:** -- View list of mounted drives -- Toggle mount/unmount -- Start new mount -- Open/close app - -**Background Behavior:** -- Minimizes to system tray (depending on settings) -- Jobs continue running in background -- Notification popup on job completion - ---- - -## 15. Platform Support - -### 15.1 Windows - -| Feature | Description | -|---------|-------------| -| Mount type | cmount (default) | -| Drive letter | Auto or manual assignment | -| Network drive | Option to show as network drive | -| System tray | Tray icon and context menu | -| Startup | Launch at login support | -| Desktop notifications | Job completion alerts | - -### 15.2 macOS - -| Feature | Description | -|---------|-------------| -| Mount type | nfsmount (default) | -| Mount point | Custom path specification | -| File access permissions | Privacy & Security > Files & Folders or Full Disk Access | -| File handle limit | Default 256-1024, recommended 524288 | -| Supported versions | Ventura, Sonoma, Sequoia confirmed | -| Dock integration | Window management via Dock icon click | - -**macOS File Handle Configuration:** -- Create LaunchDaemon plist: `/Library/LaunchDaemons/limit.maxfiles.plist` -- Set both soft/hard limits to 524288 -- Reboot required - -**macOS Known Issues:** -- Desktop/Documents/Downloads folders may appear empty — grant Privacy & Security permissions -- External SSD not accessible — browse `/Volumes`, create Alias remote as workaround - -### 15.3 Linux - -| Feature | Description | -|---------|-------------| -| Mount type | nfsmount | -| GUI compatibility | GTK/Wayland | -| System integration | D-Bus, AppIndicator | -| Service | systemd user service | -| Allow other | Option to allow other users to access mounts | - -### 15.4 Network Ports - -| Port | Purpose | -|------|---------| -| 5582 | Embedded Rclone API (default) | -| 5572 | External Rclone API (default) | -| 22 | SFTP | -| 80/443 | HTTP/HTTPS (WebDAV, OAuth) | -| 587 | SMTP (email notifications) | - ---- - -## 16. License Structure - -### 16.1 License Types - -| Type | Description | -|------|-------------| -| FREE | Basic features, no license key required | -| PLUS (Subscription) | Subscription-based, time-limited | -| Lifetime | One-time purchase, permanent use | - -### 16.2 License Activation - -- Path: Help > Activate License -- Enter email address + license key -- Discount coupons: One-time use per email address - -### 16.3 FREE vs PLUS Feature Comparison - -| Feature | FREE | PLUS | -|---------|:----:|:----:| -| Mount/Unmount | O | O | -| File Explorer (browse/copy/delete) | O | O | -| Folder Compare (basic) | O | O | -| Sync & Job Management | O | O | -| 1:N Synchronization | O | O | -| Job History & Logs | O | O | -| System Tray | O | O | -| Rclone Terminal | O | O | -| Dry Run | O | O | -| Export/Import Jobs | O | O | -| Folder Compare with Filter | X | O | -| Schedule-Based Sync | X | O | -| Auto Start Schedule on Startup | X | O | -| Auto Mount on Startup | X | O | -| Multi-Window | X | O | - ---- - -## 17. Batch Operations (Beta) - -> **Status:** Beta feature. Confirmed in source code but stability is not fully verified. - -### 17.1 Overview - -Automation feature that chains multiple operations for sequential execution. - -### 17.2 Supported Step Types - -| Step | Description | -|------|-------------| -| mkdir | Create folder | -| copyFolder | Copy folder (uses sync) | -| copyFile | Copy single file | -| sync | Synchronize folders | -| check | Verify/compare folders | -| move | Move files/folders | -| rename | Rename files | -| delete | Filter-based deletion | -| deleteFile | Delete single file | -| purge | Remove directory | -| rmdirs | Remove empty directories | -| filelist | Generate file listing | -| sleep | Pause execution | - -### 17.3 Batch Features - -- Variable piping between steps -- Dry-run preview -- Step-by-step progress tracking -- Execution monitoring - ---- - -## 18. Distribution & Installation - -### 18.1 Official Download Formats - -All downloads available at https://rcloneview.com/src/download.html - -| Platform | Format | Architectures | File Name Pattern | -|----------|--------|--------------|-------------------| -| Windows | .exe (Inno Setup installer) | x86-64 only | `setup_rclone_view-{version}.exe` | -| macOS | .dmg (Disk Image) | Universal (x86-64 + ARM64 Apple Silicon) | `RcloneView-{version}.dmg` | -| Linux | .AppImage | x86_64, aarch64 (ARM64) | `RcloneView-{version}-{arch}.AppImage` | -| Linux | .deb (Debian/Ubuntu) | x86_64, aarch64 (ARM64) | `rclone_view-{version}-linux-{arch}.deb` | -| Linux | .rpm (Fedora/RHEL) | x86_64, aarch64 (ARM64) | `rclone_view-{version}-linux-{arch}.rpm` | - -### 18.2 Official Distribution Channels - -| Channel | Status | Notes | -|---------|--------|-------| -| rcloneview.com download page | **Official** | Only official distribution channel | -| macOS auto-updater (Sparkle) | **Official** | In-app update via appcast feed | - -### 18.3 NOT Official Distribution Channels - -These channels do **NOT** have official RcloneView packages. Blog posts MUST NOT instruct users to install from these sources: - -| Channel | Status | Notes | -|---------|--------|-------| -| AUR (Arch User Repository) | **NOT available** | No official AUR package exists | -| Snap Store | **NOT available** | Config exists in source but not actively published | -| Flathub / Flatpak | **NOT available** | Config exists in source but not actively published | -| Homebrew (macOS) | **NOT available** | No formula/cask exists | -| APT repository | **NOT available** | No PPA or apt repo — use .deb direct download | -| RPM repository (dnf/yum) | **NOT available** | No repo — use .rpm direct download | -| pip / npm / any package manager | **NOT available** | Not applicable | -| Any third-party mirror | **Unofficial** | Not endorsed or maintained | - -### 18.4 System Requirements - -**All platforms — GUI is REQUIRED:** -- RcloneView is a **GUI desktop application** built with Flutter -- It **cannot run headless** (without a display server) -- It **cannot run as a systemd/Windows service** by itself -- For headless/server scenarios, use rclone CLI directly (`rclone rcd`) - -**Windows:** -- Architecture: x86-64 only (no ARM64 Windows build) -- Requires VC++ 2015-2022 Redistributable -- Minimum: Windows Vista or later - -**macOS:** -- Architecture: Universal binary (Intel x86-64 + Apple Silicon ARM64) -- Minimum: macOS 12.7 (Monterey) -- Notarized and code-signed - -**Linux:** -- Architecture: x86_64 and aarch64 (ARM64) -- Desktop environment required: X11 or Wayland display server -- Required dependency: GTK+ 3.0 -- Required dependency: libayatana-appindicator3-1 or libappindicator3-1 (system tray) -- Tested base: Ubuntu 22.04 LTS (Jammy) -- FUSE required for mount functionality (fuse3 recommended) - -### 18.5 Linux ARM64 Notes (Raspberry Pi, etc.) - -ARM64 builds (.deb, .rpm, .AppImage) are provided for Linux. However: - -- **A graphical desktop environment IS REQUIRED** — RcloneView cannot run on a headless system -- For Raspberry Pi or similar ARM64 SBCs, a desktop environment (e.g., Raspberry Pi Desktop with X11/Wayland) must be installed and running -- Alternatively, remote desktop (VNC/RDP) or X11 forwarding can be used to display the GUI on another machine -- For truly headless operation (no display at all), use rclone CLI directly — RcloneView adds no value without a screen -- Performance on ARM64 SBCs varies significantly — do not cite specific speed numbers - -### 18.6 Technology Stack - -| Component | Technology | Notes | -|-----------|-----------|-------| -| GUI Framework | **Flutter** (Dart 3.2.6+) | NOT Qt, NOT Electron, NOT GTK app | -| Terminal | xterm.dart | Built-in terminal emulation | -| State management | Riverpod | flutter_riverpod | -| Database | SQLite (sqflite_common_ffi) | Local storage | -| Secure storage | flutter_secure_storage | Credentials | -| Build system | CMake (Linux/Windows), Xcode (macOS) | Platform-specific | -| Linux packaging | flutter_distributor, appimage-builder | .deb, .rpm, .AppImage | -| Windows packaging | Inno Setup | .exe installer | -| macOS packaging | appdmg | .dmg with notarization | - ---- - -## 19. Limitations & Negative Facts - -This section explicitly states what RcloneView **does NOT** support, **cannot** do, or **does NOT** provide. Blog posts MUST NOT claim or imply otherwise. - -### 19.1 RcloneView is NOT... - -| Claim | Reality | -|-------|---------| -| A headless/CLI tool | It is a GUI-only application. For CLI, use rclone directly | -| A replacement for rclone | It is a frontend that depends on rclone | -| The official rclone GUI | It is an independent third-party GUI for rclone | -| A web application | It is a native desktop app (no browser-based interface for end users) | -| A mobile app | No iOS or Android builds are distributed | -| A Qt application | It is built with Flutter/Dart | -| An Electron application | It is built with Flutter/Dart | -| A cloud service | It runs entirely on the user's local machine | -| Available on package managers | Only distributed via direct download from rcloneview.com | - -### 19.2 RcloneView CANNOT... - -| Claim | Reality | -|-------|---------| -| Run without a display server | Requires X11 or Wayland on Linux, GUI on all platforms | -| Run as a background daemon/service | The app itself cannot be a systemd service. (rclone rcd CAN, but that's rclone, not RcloneView) | -| Run on 32-bit systems | Only 64-bit (x86-64, ARM64) builds exist | -| Run on Windows ARM | No Windows ARM64 build provided | -| Sync without rclone | Depends entirely on rclone for all storage operations | -| Work offline | Requires network access to reach cloud storage | -| Auto-update on Linux | Auto-update only available on macOS (Sparkle). Linux/Windows users must download manually | - -### 19.3 RcloneView DOES NOT provide... - -| Claim | Reality | -|-------|---------| -| AUR package | Not published to Arch User Repository | -| Snap package | Snapcraft config exists but not published to Snap Store | -| Flatpak package | Flatpak manifest exists but not published to Flathub | -| Homebrew formula/cask | Not available via Homebrew | -| APT/YUM/DNF repository | No package repository — .deb and .rpm are direct downloads | -| Docker image | Not containerized | -| iOS/Android app | Mobile builds not distributed | -| 32-bit builds | No x86 (32-bit) or armv7 builds | - -### 19.4 Blog-Specific Platform Warnings - -When writing blog posts about RcloneView on specific platforms, these facts MUST be included: - -**Raspberry Pi / ARM64 SBC posts:** -- MUST state that a desktop environment with display server is required -- MUST NOT describe headless setup as a primary use case -- MUST mention VNC/X11 forwarding as alternative if running remotely -- SHOULD recommend rclone CLI for truly headless scenarios - -**Arch Linux posts:** -- MUST NOT reference `yay -S rcloneview` or any AUR installation -- MUST use direct .AppImage, .rpm, or manual binary installation from rcloneview.com -- MUST NOT claim Qt5 dependencies — RcloneView uses Flutter/GTK+3 - -**Any Linux distro posts:** -- MUST state GTK+3 and display server (X11/Wayland) requirement -- MUST NOT describe RcloneView as a systemd service -- The systemd service documented in official docs is for `rclone rcd`, NOT for RcloneView itself - -**Server/NAS posts:** -- MUST clarify that RcloneView is a GUI tool, not a server application -- For server use: connect to external rclone via Connection Manager, don't install RcloneView on the server - ---- - -## Appendix: Credential Guides - -### AWS S3 -- AWS Management Console: `https://aws.amazon.com/console` -- Generate Access Key in IAM Console -- Required: Access Key ID, Secret Access Key, Region code (e.g., ap-northeast-2) - -### Cloudflare R2 -- Dashboard: `https://dash.cloudflare.com` -- Create R2 Bucket, then generate API Token -- Requires Admin Read & Write permissions -- Endpoint: `https://.r2.cloudflarestorage.com` - -### Backblaze B2 -- Key management: `https://secure.backblaze.com/b2_buckets.htm` -- Required: Application Key ID, Application Key - -### Proton Drive -- Login: `https://drive.proton.me/` -- Required: Email, Password, optional 2FA -- 2FA setup: `https://proton.me/support/two-factor-authentication` - -### Gofile -- Token: `https://gofile.io/myprofile` -- Found in Account API Token field - -### Azure File Storage -- Azure Portal > Storage Account > Access keys -- Required: Storage Account Name, Shared Key, Share Name - -### Mega -- Login: `https://mega.nz/login` -- Required: Email, Password - ---- - -## Appendix: Troubleshooting Reference - -### macOS: Desktop/Documents/Downloads Folders Appear Empty -- **Cause:** macOS Catalina+ privacy permissions not granted -- **Fix 1:** Grant permissions in System Settings > Privacy & Security > Files & Folders -- **Fix 2:** Add RcloneView to Full Disk Access -- **Required:** Restart RcloneView after permission changes - -### macOS: Too Many Open Files Error -- **Cause:** macOS file descriptor default limit (256-1024) -- **Fix:** Create `/Library/LaunchDaemons/limit.maxfiles.plist`, set soft/hard to 524288 -- **Required:** Reboot - -### macOS: External SSD Not Accessible -- **Fix:** Browse `/Volumes` to find SSD, then create an Alias remote - -### Log Collection -1. Settings > Embedded Rclone > Enable rclone Logging checkbox -2. Log level: DEBUG (most verbose) -3. Click Restart Embedded Rclone -4. Reproduce the issue -5. Send log file to rcloneview@bdrive.com diff --git a/RCLONEVIEW_FEATURE_SPEC_ko.md b/RCLONEVIEW_FEATURE_SPEC_ko.md deleted file mode 100644 index df158292..00000000 --- a/RCLONEVIEW_FEATURE_SPEC_ko.md +++ /dev/null @@ -1,1092 +0,0 @@ -# RcloneView Feature Specification - -> **Purpose:** RcloneView 블로그 작성 시 참고하는 공식 기능 명세서. 모든 내용은 소스코드(`rclone-navigator`) + 공식 문서(`rcloneview-support/howto`, `docs`)에서 검증됨. -> **Last Updated:** 2026-04-13 -> **App Version:** 1.4.1+1 -> **Framework:** Flutter (Dart 3.2.6+) - ---- - -## Table of Contents - -1. [Product Overview](#1-product-overview) -2. [File Explorer](#2-file-explorer) -3. [File Operations](#3-file-operations) -4. [Sync & Job Management](#4-sync--job-management) -5. [Folder Compare](#5-folder-compare) -6. [Mount & Virtual Drive](#6-mount--virtual-drive) -7. [Rclone Terminal](#7-rclone-terminal) -8. [Remote Management](#8-remote-management) -9. [Connection Management](#9-connection-management) -10. [Supported Cloud Providers](#10-supported-cloud-providers) -11. [Virtual Remotes](#11-virtual-remotes) -12. [Settings & Preferences](#12-settings--preferences) -13. [Notification & Remote Control](#13-notification--remote-control) -14. [Multi-Window & System Tray](#14-multi-window--system-tray) -15. [Platform Support](#15-platform-support) -16. [License Structure](#16-license-structure) -17. [Batch Operations (Beta)](#17-batch-operations-beta) - ---- - -## 1. Product Overview - -### 1.1 What is RcloneView - -RcloneView는 rclone 기반의 크로스 플랫폼 GUI 클라이언트이다. Windows, macOS, Linux에서 동작하며, 90개 이상의 클라우드 스토리지를 하나의 인터페이스로 관리한다. - -**핵심 구조:** -- RcloneView는 rclone RC(Remote Control) API를 통해 rclone과 통신한다 -- 내장된 Embedded Rclone 바이너리를 포함하며, 별도 설치 없이 바로 사용 가능하다 -- 외부 rclone 인스턴스(로컬/원격 서버/Docker)에도 연결할 수 있다 -- rclone 자체 기능이 아닌, rclone을 활용하는 독립적 GUI 프론트엔드이다 - -**Embedded Rclone:** -- 기본 API 주소: `http://127.0.0.1:5582` (localhost loopback) -- 지원 rclone 최소 버전: v1.69.1 이상 -- 앱 종료 시 자동 종료 옵션 지원 -- 앱 내에서 rclone 자체 업데이트(Self Update) 가능 - -### 1.2 Main UI Layout - -RcloneView의 메인 화면은 4개 영역으로 구성된다: - -**1) Menu Bar (상단 메뉴)** -- **Home 탭:** Sync, Compare, Job Manager, New Window 버튼 -- **Remote 탭:** New Remote, Remote Manager, Mount Manager, Job Manager 버튼 -- **Settings 탭:** Connect Manager, General, Layout, View count -- **Help 탭:** Check for Updates, Feedback, Homepage, Register License Key - -**2) Explorer Panels (중앙)** -- 1~4개 패널 동시 표시 가능 (수평/수직 분할) -- 각 패널: Tab Bar + Breadcrumb Path Bar + Folder Tree + File List -- 패널 툴바: Alias(즐겨찾기) 생성, 폴더 마운트, 리모트 설정 편집, 새로고침 - -**3) Info View (하단 탭)** -- **Transferring 탭:** 진행 중인 작업 모니터링 (진행률, 속도, 파일 수) -- **Terminal 탭:** 내장 rclone CLI 터미널 -- **Log 탭:** 타임스탬프 포함 로그 엔트리 -- **Features 탭:** 예정 기능 미리보기 - -**4) Footer (최하단)** -- 앱 버전 정보 -- 라이선스 정보 (FREE License / PLUS License) -- rclone 연결 정보 (버전, 서버 주소, OS) - ---- - -## 2. File Explorer - -### 2.1 탐색기 구성 - -각 Explorer 패널은 클라우드 또는 로컬 스토리지를 탐색하는 파일 관리자이다. - -**Tab Bar:** -- 현재 연결된 리모트 표시 -- 탭 전환으로 여러 리모트 간 이동 - -**Breadcrumb Path Bar:** -- 현재 폴더 경로를 계층적으로 표시 -- 자동 완성 제안 기능 -- 우클릭 메뉴: Cut, Copy, Paste, Copy Full Path (with Remote), Select All -- Copy Full Path: `mygoogledrive:Meet recordings` 형태로 rclone 명령에 바로 사용 가능 - -**Folder Tree:** -- 좌측 접이식 폴더 트리 네비게이터 -- 폴더 확장/축소로 계층 탐색 - -**File List:** -- 이름, 타입, 수정일, 크기 컬럼 표시 -- 썸네일 뷰 지원 (이미지 파일 미리보기 그리드) -- 하단 요약: 전체 파일/폴더 수 및 총 파일 크기 - -### 2.2 뷰 모드 - -| 뷰 모드 | 설명 | -|---------|------| -| List View | 파일 상세 정보 (이름, 크기, 날짜, 타입) 목록 | -| Tree View | 폴더 계층 구조 탐색 | -| Thumbnail View | 이미지 파일 미리보기 그리드 | - -### 2.3 레이아웃 설정 - -- **수평 분할:** 패널을 좌우로 배치 -- **수직 분할:** 패널을 상하로 배치 -- **패널 수:** 1개 ~ 4개 동시 표시 가능 -- Settings 탭의 Layout / View count에서 변경 - ---- - -## 3. File Operations - -### 3.1 기본 파일 작업 - -모든 작업은 우클릭 컨텍스트 메뉴 또는 키보드 단축키로 수행한다. - -| 작업 | 방법 | 단축키 | 설명 | -|------|------|--------|------| -| Copy | 우클릭 > Copy | Ctrl+C / Cmd+C | 파일/폴더 복사 | -| Cut | 우클릭 > Cut | Ctrl+X / Cmd+X | 파일/폴더 잘라내기 (이동) | -| Paste | 우클릭 > Paste | Ctrl+V / Cmd+V | 복사/잘라낸 항목 붙여넣기 | -| Delete | 우클릭 > Delete | - | 파일/폴더 삭제 (확인 다이얼로그) | -| Rename | 우클릭 > Rename | - | 파일/폴더 이름 변경 (인라인 편집) | -| New Folder | 우클릭 > New Folder | - | 현재 위치에 새 폴더 생성 | -| Download | 우클릭 > Download | - | 클라우드 → 로컬 다운로드 | -| Upload | 우클릭 > Upload | - | 로컬 → 클라우드 업로드 | -| Reload | 우클릭 > Reload | F5 / Cmd+R | 폴더 내용 새로고침 | -| Get Size | 우클릭 > Get Size | - | 선택한 항목의 총 크기 계산 | -| Get Public Link | 우클릭 > Get Public Link | - | 공유 가능한 퍼블릭 링크 생성 (제공자별 지원) | -| Open in Explorer | 우클릭 > Open in Explorer | - | 네이티브 파일 관리자에서 열기 | - -### 3.2 다중 선택 - -| 방법 | 동작 | -|------|------| -| Ctrl + Click | 개별 파일 선택/해제 | -| Shift + Click | 범위 선택 (첫 번째~마지막 클릭 사이 모든 파일) | - -### 3.3 드래그 앤 드롭 - -| 상황 | 동작 | -|------|------| -| 같은 리모트 내 | **이동** (Move) | -| 다른 리모트 간 | **복사** (Copy) | -| Windows 탐색기 → RcloneView | **업로드** (Upload to cloud) | - -- 드래그 앤 드롭 시 확인 팝업 표시 가능 (Settings에서 on/off) - ---- - -## 4. Sync & Job Management - -### 4.1 동기화 설정 (4단계) - -동기화 작업은 4단계 마법사로 설정한다: - -**Step 1: Configure Storage (스토리지 설정)** -- 소스 리모트 + 폴더 선택 -- 대상 리모트 + 폴더 선택 -- 작업 이름 입력 (허용 문자: a-z, A-Z, 0-9, -, _) -- 1:N 동기화: 여러 대상 추가 가능 -- 동기화 방향: - - **단방향** "Modifying destination only" — 대상만 수정 (공식, 안정) - - **양방향** "Bidirection" — 양쪽 변경 병합 (Beta, 실험적) -- Create empty directories 옵션 - -**Step 2: Advanced Settings (고급 설정)** -- **병렬 전송 수** (Number of file transfers): 동시에 전송하는 파일 수 -- **멀티스레드 전송** (Number of multi-thread transfers): 기본값 4, 0으로 비활성화 -- **동등성 검사기 수** (Number of equality checkers): 기본값 8, 느린 백엔드는 4 이하 권장 -- **체크섬 비교** (Enable checksum): 해시+크기로 파일 동일 여부 판별 -- **실패 시 재시도** (Retry entire sync if fails): 기본값 3, 1로 설정하면 재시도 없음 - -**Step 3: Filtering Settings (필터 설정)** -- **최대 파일 크기:** MB 단위 (초과 파일 제외) -- **최대 파일 연령:** y(년), d(일), h(시), m(분), s(초) 단위 -- **최대 폴더 깊이:** 폴더 계층 수준 제한 -- **사전 정의 필터:** Music, Video, Image, Document, Google Docs, Box Docs -- **커스텀 필터:** 파일 타입, 폴더, 경로 제외 규칙 직접 작성 - - 예: `.iso` (해당 확장자 제외), `/.git/*` (루트의 .git 파일 제외), `.git/` (모든 .git 폴더 제외) - -**Step 4: Scheduling (스케줄링) — PLUS License 전용** -- Crontab 방식 스케줄링 -- 설정 필드: Minute(0-59), Hour(0-23), Day of Week(0-6), Day of Month(1-31), Month(1-12) -- 지원 포맷: 비움(매번), 리스트(1,3,5), 범위(0-2), 스텝(6-12/3) -- Simulate schedule: 다음 실행 시각 미리보기 - -### 4.2 Dry Run (시뮬레이션) - -실제 변경 없이 동기화를 시뮬레이션하는 기능: -- 복사될 파일 목록 표시 -- 삭제될 파일 목록 표시 -- 상세 작업 목록 미리 확인 -- 실수 방지를 위해 실제 동기화 전 권장 - -### 4.3 Job Manager (작업 관리자) - -작업의 생성, 편집, 실행, 모니터링을 담당하는 중앙 관리 인터페이스. - -**작업 관리:** -- Add Job: 새 작업 생성 -- Edit Job: 기존 작업 수정 -- Duplicate: 작업 복제 -- Delete: 작업 삭제 -- Export: 작업 설정을 `rclone_jobs_~.json` 파일로 내보내기 -- Import: JSON 파일에서 작업 가져오기 - -**작업 유형:** -- Sync: 소스 → 대상 동기화 -- Copy: 파일/폴더 복사 -- Move: 파일/폴더 이동 -- Delete: 파일/폴더 삭제 -- Download: 클라우드 → 로컬 -- Upload: 로컬 → 클라우드 - -**실행 모드:** -- One-time: 즉시 실행 (저장 없음) -- Add: 작업 생성 후 저장 -- Edit: 기존 작업 수정 - -### 4.4 Job History (실행 이력) - -각 작업의 실행 기록을 상세히 추적한다. - -**이력 필드:** -| 필드 | 설명 | -|------|------| -| Execution Type | Manual (수동) 또는 Scheduled (스케줄) | -| Start Time | 실행 시작 시각 | -| Time Spent | 소요 시간 | -| Status | Completed (성공) / Errored (오류) / Canceled (취소) | -| Total Size | 전송된 총 크기 | -| Speed | 전송 속도 | -| Files | 전송된 파일 수 | -| Job Type | Sync/Copy/Move/Delete/Download/Upload | - -**이력 필터:** -- From ~ To (날짜 범위) -- Today, Yesterday, Last week, Last month -- Delete all (전체 삭제) - -### 4.5 1:N Synchronization - -하나의 소스를 여러 대상에 동시 동기화하는 기능. -- Step 1에서 여러 대상 폴더를 추가 -- 각 대상에 동일한 소스 내용이 반영됨 -- FREE 라이선스에서 사용 가능 - -### 4.6 Transfer Monitoring - -하단 Info View의 Transferring 탭에서 진행 중인 작업을 실시간 모니터링: -- 진행률 표시 (퍼센트) -- 전송 속도 -- 전송된 파일 수/크기 -- 작업 취소 가능 - -하단 탭 필터: Download, Upload, Sync 작업별 표시/숨김 가능 - ---- - -## 5. Folder Compare - -### 5.1 개요 - -두 폴더(로컬/클라우드)를 나란히 비교하여 차이점을 시각적으로 보여주는 기능. - -Home 탭의 **Compare** 버튼으로 실행. - -### 5.2 비교 결과 필터 - -| 필터 | 설명 | -|------|------| -| Show left-only files | 왼쪽에만 있는 파일 | -| Show right-only files | 오른쪽에만 있는 파일 | -| Show same files | 양쪽 동일한 파일 | -| Show different files | 크기가 다른 파일 | -| Show errored files | 오류/충돌 파일 | - -### 5.3 비교 뷰 작업 - -**네비게이션:** -- Navigate to upper folder (상위 폴더) -- Navigate to lower folder (하위 폴더) - -**파일 작업:** -- Copy → : 왼쪽 → 오른쪽 복사 -- ← Copy : 오른쪽 → 왼쪽 복사 -- Delete : 선택한 파일 삭제 - -**크기 변화 탐색:** -- Find folders by file count change (파일 수 변화로 폴더 찾기) -- Find folders by size change (크기 변화로 폴더 찾기) -- Find folder with largest change (가장 큰 변화) -- Find folder with next large change (다음으로 큰 변화) -- Find folder with smallest change (가장 작은 변화) -- Find folder with next smaller change (다음으로 작은 변화) - -**복사 동작:** -- 대상에 파일이 없거나 크기가 다를 때만 복사 -- 복사 후 해당 파일은 비교 뷰에서 "equal"로 표시 - -### 5.4 Folder Compare with Filter — PLUS License 전용 - -커스텀 필터 규칙으로 비교 대상을 제한: -- 폴더명, 파일 타입별 필터 -- 예: `.iso` (제외), `/.git/*` (루트 .git 파일), `/.git/` (루트 .git 폴더), `.git/` (모든 .git 폴더) - ---- - -## 6. Mount & Virtual Drive - -### 6.1 개요 - -클라우드 스토리지를 로컬 드라이브처럼 마운트하여 파일 탐색기에서 직접 접근하는 기능. - -### 6.2 마운트 방법 - -**방법 1: Remote Explorer에서** -1. 탐색기에서 마운트할 리모트 폴더 선택 -2. 패널 툴바의 Mount 아이콘 클릭 -3. 마운트 설정 구성 -4. "Save and mount" 또는 "Save" 클릭 - -**방법 2: Mount Manager에서** -1. Remote 탭 > Mount Manager 버튼 클릭 -2. New mount 클릭 -3. 리모트 및 하위 디렉토리 선택 -4. 옵션 구성 -5. Save 또는 Save and mount 클릭 - -### 6.3 마운트 설정 옵션 - -| 설정 | 기본값/옵션 | 설명 | -|------|------------|------| -| Target | Auto / 수동 드라이브 문자 | Windows: 드라이브 문자 할당 | -| Mount to local path | - | 커스텀 마운트 위치 (macOS/Linux) | -| Auto mount | Off | 시작 시 자동 마운트 (PLUS) | -| Volume name | - | 마운트된 볼륨 표시 이름 | -| Mount type | cmount (Windows) / nfsmount (Linux/macOS) | 마운트 방식 | -| Network drive | Off | 네트워크 드라이브로 표시 (Windows) | -| Read only | Off | 읽기 전용 모드 | -| Allow other | Off | 다른 사용자 접근 허용 (Linux) | -| Cache mode | off / minimal / **writes** (기본) / full | VFS 캐시 모드 | -| Cache max size | -1 (무제한) | 최대 캐시 크기 (bytes) | -| Cache max age | - | 캐시 데이터 유효 기간 (nanoseconds) | -| Dir cache time | - | 디렉토리 캐시 유효 기간 (nanoseconds) | - -### 6.4 Mount Manager - -마운트 상태별 관리: - -| 상태 | 가능한 작업 | -|------|------------| -| Mounted (마운트됨) | Unmount, Open (파일 탐색기에서 열기) | -| Unmounted (해제됨) | Mount, Edit, Delete | - -**제약사항:** -- Mounted 상태에서는 Edit/Delete 불가 -- Unmounted 상태에서는 Open 불가 - -### 6.5 System Tray에서 마운트 관리 - -- RcloneView 트레이 아이콘 우클릭 -- Mount 메뉴에서 마운트된 드라이브 확인 -- 마운트/언마운트 전환 -- 새 마운트 시작 - ---- - -## 7. Rclone Terminal - -### 7.1 개요 - -RcloneView 내장 터미널로, rclone CLI 명령을 직접 실행할 수 있다. 하단 Info View의 Terminal 탭에 위치. - -### 7.2 기능 - -- xterm.dart 기반 풀 터미널 에뮬레이션 -- PTY(pseudo-terminal) 지원 -- rclone 명령 자동완성: `rclone` + 스페이스 입력 시 명령어 제안 -- 셸 환경: Windows CMD/PowerShell, Linux bash, macOS zsh - -**자주 사용하는 명령:** -| 명령 | 설명 | -|------|------| -| `rclone listremotes` | 설정된 리모트 목록 | -| `rclone about "remote:"` | 리모트 스토리지 사용량 | -| `rclone config create ` | CLI로 리모트 생성 | - -### 7.3 뷰 관리 - -- **Expand:** 터미널 전체 화면 -- **Shrink:** 기본 레이아웃 복귀 - -### 7.4 출력 처리 - -- 텍스트 선택 가능 -- 우클릭 메뉴: Copy, Paste, Copy All - ---- - -## 8. Remote Management - -### 8.1 리모트 추가 방식 - -RcloneView에서 클라우드 스토리지 연결(리모트)을 추가하는 방법은 제공자에 따라 다르다. - -**OAuth 기반 (브라우저 로그인):** -브라우저가 열리고 계정 인증 후 자동 연결. 별도 API 키 불필요. -- Google Drive, Dropbox, Google Photos, OneDrive, Box, pCloud, Yandex Disk, premiumize.me, put.io, HiDrive - -**인증 정보 입력:** -Access Key, Token, 또는 계정 정보를 직접 입력. -- Amazon S3 (Access Key ID + Secret Access Key + Region) -- Cloudflare R2 (API Token + Account ID + Endpoint) -- Mega (Email + Password) -- Backblaze B2 (Application Key ID + Application Key) -- Proton Drive (Email + Password, 선택적 2FA) -- Gofile (Access Token) -- Azure File Storage (Account Name + Shared Key + Share Name) -- iCloud Drive (rclone v1.69+ 필요) -- SFTP (Host + SSH 인증) - -**추가 설정 필요:** - -| 제공자 | 추가 설정 | -|--------|----------| -| Zoho WorkDrive | Region 선택 | -| Google Cloud Storage | Project Number | -| Citrix ShareFile | Root Folder ID | -| Google Drive Shared with Me | `shared_with_me = true` | -| Box for Business | `box_sub_type = enterprise` | -| Dropbox for Business | `dropbox_business = true` | -| Google Drive Computers | `root_folder_id = computer ID` | - -### 8.2 Remote Manager - -Remote 탭 > Remote Manager 버튼으로 접근. -- 등록된 모든 리모트 목록 표시 -- 리모트별 편집/삭제 -- 리모트 설정 확인 - ---- - -## 9. Connection Management - -### 9.1 연결 유형 - -**Embedded Rclone (내장):** -- 기본 제공, 별도 설치 불필요 -- 주소: `http://127.0.0.1:5582` -- 앱과 라이프사이클 공유 (앱 종료 시 함께 종료 옵션) -- rclone 버전 표시, Self Update 지원 - -**External Rclone (외부):** -- 사용자가 별도 실행한 rclone 인스턴스에 연결 -- 실행 위치: 로컬 머신, 원격 서버, Docker 컨테이너 -- 기본 포트: 5572 -- 실행 명령: `rclone rcd --rc-user= --rc-pass= --rc-addr=127.0.0.1:5572` - -### 9.2 외부 연결 추가 - -Settings 탭 > Connect Manager > New Connection: -1. Display Name 입력 -2. Remote Address 입력 (`http://:5572`) -3. Username / Password 입력 -4. SSL 인증서 검증 비활성화 옵션 (자체 서명 인증서용) -5. Test Connection으로 연결 확인 -6. Save - -### 9.3 AWS EC2 연동 - -외부 rclone을 AWS EC2에서 실행하여 원격 연결하는 시나리오: - -**권장 구성:** -- AMI: Ubuntu Server 22.04 LTS 또는 20.04 LTS -- 인스턴스: t2.micro (Free Tier 가능) -- 스토리지: 최소 8 GB -- 보안 그룹: SSH(포트 22, IP 제한) + Custom TCP(포트 5572) - -**설치:** -```bash -curl https://rclone.org/install.sh | sudo bash -rclone version -``` - -**데몬 실행:** -```bash -rclone rcd --rc-user=admin --rc-pass=admin --rc-addr=0.0.0.0:5572 -``` - -**systemd 서비스:** -- 파일 경로: `/etc/systemd/system/rclone-rcd.service` -- 실행 사용자: Ubuntu -- 주요 플래그: `--rc-user`, `--rc-pass`, `--rc-addr`, `--rc-web-gui` (선택), `--log-file`, `--log-level` - -**헬스체크:** -```bash -curl -X POST -u admin:admin "http://:5572/rc/noop" -``` - ---- - -## 10. Supported Cloud Providers - -### 10.1 OAuth 직접 로그인 - -| 제공자 | 인증 방식 | -|--------|----------| -| Google Drive | OAuth (브라우저) | -| Dropbox | OAuth (브라우저) | -| Google Photos | OAuth (브라우저) | -| Microsoft OneDrive | OAuth (브라우저) | -| Box | OAuth (브라우저) | -| pCloud | OAuth (브라우저) | -| Yandex Disk | OAuth (브라우저) | -| premiumize.me | OAuth (브라우저) | -| put.io | OAuth (브라우저) | -| HiDrive | OAuth (브라우저) | - -### 10.2 개인/비즈니스 클라우드 - -| 제공자 | 비고 | -|--------|------| -| Google Drive Shared with Me | shared_with_me 설정 필요 | -| Google Drive Computers | root_folder_id 설정 필요 | -| Dropbox for Business | dropbox_business 설정 필요 | -| Box for Business | box_sub_type = enterprise | -| Mega | Email + Password | -| Proton Drive | rclone v1.69+ 필요 | -| Backblaze B2 | Application Key ID + Key | -| Gofile | Access Token | -| iCloud Drive | rclone v1.69+ 필요 | -| iCloud Photos | 별도 패키지 (코드 확인) | -| Zoho WorkDrive | Region 선택 필요 | -| Citrix ShareFile | Root Folder ID 필요 | -| Google Cloud Storage | Project Number 필요 | -| Azure File Storage | Account + Key + Share Name | -| Koofr | - | -| Jottacloud | - | -| Mail.ru Cloud | - | -| Seafile | - | -| Storj | - | -| OpenDrive | - | -| PikPak | - | -| SugarSync | - | -| Files.com | - | -| Enterprise File Fabric | - | -| Cloudinary | - | -| Internet Archive | - | -| ImageKit | - | -| Linkbox | - | -| Pixeldrain | - | -| Uptobox | - | -| Uloz.to | - | - -### 10.3 S3 호환 제공자 - -rclone의 S3 프로토콜을 통해 접속하는 서비스들. Access Key + Secret Key + Endpoint 설정 필요. - -| 제공자 | | 제공자 | | 제공자 | -|--------|---|--------|---|--------| -| Amazon S3 | | Cloudflare R2 | | Wasabi | -| IDrive e2 | | MinIO | | DigitalOcean Spaces | -| Linode Object Storage | | Google Cloud Storage (S3) | | IBM COS | -| Tencent COS | | Alibaba OSS | | Huawei OBS | -| IONOS | | Ceph | | StackPath | -| Synology C2 | | Seagate Lyve | | Arvan Cloud | -| Scaleway | | Selectel | | Storj S3 | -| Outscale | | Magalu | | Leviia | -| Liara | | RackCorp | | SeaweedFS | -| Dreamhost | | Petabox | | China Mobile | -| Qiniu | | Netease | | Hetzner | -| OVHcloud | | Cubbit DS3 | | Rclone S3 | - -> **참고:** S3 호환 제공자는 rclone 버전에 따라 추가/변경될 수 있다. 구체적 개수보다 "다수의 S3 호환 서비스"로 표현 권장. - -### 10.4 프로토콜 기반 스토리지 - -| 프로토콜 | 설명 | -|---------|------| -| SFTP | SSH File Transfer Protocol (포트 22) | -| FTP | File Transfer Protocol | -| WebDAV | Web Distributed Authoring and Versioning | -| SMB/CIFS | Server Message Block (네트워크 파일 공유) | -| HTTP | 읽기 전용 HTTP 접근 | -| HDFS | Hadoop Distributed File System | - -### 10.5 로컬 스토리지 - -| 타입 | 설명 | -|------|------| -| 로컬 디스크 | Windows/Mac/Linux 내장 디스크 | -| 외장 드라이브 | SSD, USB 등 | -| Synology NAS | 자동 탐지 기능 지원 (Settings에서 on/off) | - ---- - -## 11. Virtual Remotes - -rclone의 가상 리모트를 활용하여 기존 리모트에 추가 기능을 부여하는 래퍼. - -| 리모트 | 용도 | 사용 예시 | -|--------|------|----------| -| **Alias** | 특정 클라우드 폴더의 바로가기 | 자주 쓰는 깊은 경로에 단축 이름 부여 | -| **Crypt** | 파일명, 내용, 폴더명 암호화 | 민감한 데이터를 암호화하여 클라우드 저장 | -| **Memory** | RAM 기반 임시 저장소 | 테스트/임시 작업용 | -| **Cache** | 느린 리모트 캐싱 가속 | Plex 미디어 서버 통합 포함 | -| **Chunker** | 대용량 파일 청크 분할 | 파일 크기 제한이 있는 제공자에 대용량 파일 저장 | -| **Combine** | 여러 폴더를 서브폴더로 병합 | 여러 클라우드를 하나의 가상 트리로 | -| **Union** | 여러 폴더를 하나로 통합 | 여러 스토리지를 단일 뷰로 합침 | -| **Hasher** | 무결성 검사용 해싱 추가 | 해시를 지원하지 않는 리모트에 체크섬 추가 | -| **Compress** | 업로드 전 파일 압축 | 스토리지 용량 절약 | - ---- - -## 12. Settings & Preferences - -### 12.1 General (일반) - -| 설정 | 설명 | -|------|------| -| Language | UI 언어 선택 (9개 언어) | -| Launch at login | 시스템 로그인 시 자동 시작 | -| Start minimized | 시스템 트레이로 최소화 시작 | -| Quit on close | 닫기 버튼 동작 (종료 vs 백그라운드) | -| Auto-detect Synology NAS | 로컬 네트워크 NAS 자동 탐지 | -| Show local cloud folders | 로컬 클라우드 폴더 표시 | -| Check for updates | 자동 업데이트 확인 | -| Restore Default Settings | 모든 설정 초기화 | - -### 12.2 Interfaces & Notifications (인터페이스) - -| 설정 | 설명 | -|------|------| -| Dark mode | Light / Dark / System 테마 | -| Theme color | 액센트 색상 선택 | -| Confirm drag and drop | 드래그 작업 확인 팝업 | -| Show Job Types | Transfer 로그 필터 (Download/Upload/Sync) | -| Show job state log | 전송 완료 후 상세 로그 표시 | -| Show comparison completed | 폴더 비교 완료 알림 | -| Show confirmation before deleting files in compare | 비교 뷰 삭제 확인 | -| Show sync completion notification | 동기화 완료 알림 | -| Show network error dialog | 네트워크 오류 경고 | - -### 12.3 Embedded Rclone (내장 Rclone 설정) - -| 설정 | 설명 | -|------|------| -| Stop rclone on App Exit | 앱 종료 시 rclone 프로세스 종료 | -| Local Rclone location | rclone 바이너리 경로 (내장 또는 커스텀) | -| Local Rclone config location | rclone.conf 파일 경로 | -| Default download folder | 다운로드 기본 경로 | -| Default upload folder | 업로드 기본 경로 | -| Global Rclone Flags | 추가 rclone 플래그 (예: `--no-check-certificate`) | -| Config Password | 암호화된 rclone 설정 비밀번호 | -| Enable rclone Logging | 파일 기반 로깅 활성화 | -| Log folder | 로그 파일 저장 경로 | -| Log file name | 기본 로그 파일명 | -| Log level | DEBUG / INFO / NOTICE / ERROR | - -### 12.4 Supported UI Languages (지원 언어) - -| 언어 | 비고 | -|------|------| -| English | 기본 | -| Korean (한국어) | - | -| French (Français) | - | -| German (Deutsch) | - | -| Chinese Simplified (简体中文) | - | -| Chinese Traditional (繁體中文) | - | -| Japanese (日本語) | - | -| Spanish (Español) | - | -| Indonesian (Bahasa Indonesia) | - | - -Noto Sans 폰트(KR, SC, TC, JP 변형) 포함으로 CJK 문자 지원. - ---- - -## 13. Notification & Remote Control - -> **참고:** 이 섹션의 기능들은 소스코드에서 확인되었으나, 공식 문서에는 미기재 상태. PLUS 라이선스 기능으로 추정됨. - -### 13.1 Email Notifications - -작업 완료 시 이메일 알림 전송. -- SMTP 서버 직접 설정 (호스트, 포트 587, 인증) -- RcloneView Relay 서비스 사용 옵션 -- 수신자 여러 명 설정 가능 -- 작업 크기 임계값 설정 (MB/GB 단위, 초과 시에만 알림) - -### 13.2 Telegram Bot - -- Telegram Bot Token + Chat ID 설정 -- 작업 상태 알림 전송 - -### 13.3 Slack Integration - -- App Token + Bot Token 설정 -- User ID 지정 -- 작업 상태 알림 전송 - -### 13.4 Discord Integration - -- Bot Token + User/Application ID 설정 -- DM으로 작업 상태 알림 전송 - -### 13.5 Application Lock - -- 비밀번호로 앱 접근 잠금 -- 보안 저장소에 비밀번호 암호화 저장 - ---- - -## 14. Multi-Window & System Tray - -### 14.1 Multi-Window — PLUS License 전용 - -- Home 탭 > New Window 버튼으로 새 창 생성 -- 각 창은 독립적 상태 유지 -- IPC를 통한 창 간 통신 -- 창 위치/크기 자동 저장 - -### 14.2 System Tray - -모든 라이선스에서 사용 가능. - -**트레이 메뉴:** -- 마운트된 드라이브 목록 확인 -- 마운트/언마운트 전환 -- 새 마운트 시작 -- 앱 열기/닫기 - -**백그라운드 동작:** -- 최소화 시 시스템 트레이로 이동 (설정에 따라) -- 백그라운드에서 작업 계속 실행 -- 작업 완료 시 알림 팝업 - ---- - -## 15. Platform Support - -### 15.1 Windows - -| 기능 | 설명 | -|------|------| -| 마운트 방식 | cmount (기본) | -| 드라이브 문자 | 자동 또는 수동 할당 | -| 네트워크 드라이브 | 네트워크 드라이브로 표시 옵션 | -| 시스템 트레이 | 트레이 아이콘 및 컨텍스트 메뉴 | -| 시작 프로그램 | Launch at login 지원 | -| 데스크톱 알림 | 작업 완료 알림 | - -### 15.2 macOS - -| 기능 | 설명 | -|------|------| -| 마운트 방식 | nfsmount (기본) | -| 마운트 포인트 | 커스텀 경로 지정 | -| 파일 접근 권한 | Privacy & Security > Files & Folders 또는 Full Disk Access | -| 파일 핸들 제한 | 기본 256~1024, 524288 권장 | -| 지원 버전 | Ventura, Sonoma, Sequoia 확인됨 | -| Dock 통합 | Dock 아이콘 클릭으로 창 관리 | - -**macOS 파일 핸들 설정:** -- LaunchDaemon plist 생성: `/Library/LaunchDaemons/limit.maxfiles.plist` -- soft/hard limit 모두 524288로 설정 -- 재부팅 필요 - -**macOS 알려진 이슈:** -- Desktop/Documents/Downloads 폴더 비어있을 수 있음 → Privacy & Security 권한 부여 -- 외장 SSD 접근 불가 → `/Volumes`에서 탐색, Alias 리모트로 우회 - -### 15.3 Linux - -| 기능 | 설명 | -|------|------| -| 마운트 방식 | nfsmount | -| GUI 호환 | GTK/Wayland | -| 시스템 통합 | D-Bus, AppIndicator | -| 서비스 | systemd user service | -| Allow other | 다른 사용자 마운트 접근 허용 옵션 | - -### 15.4 Network Ports - -| 포트 | 용도 | -|------|------| -| 5582 | Embedded Rclone API (기본) | -| 5572 | External Rclone API (기본) | -| 22 | SFTP | -| 80/443 | HTTP/HTTPS (WebDAV, OAuth) | -| 587 | SMTP (이메일 알림) | - ---- - -## 16. License Structure - -### 16.1 라이선스 종류 - -| 타입 | 설명 | -|------|------| -| FREE | 기본 기능, 라이선스 키 불필요 | -| PLUS (Subscription) | 구독형, 기간제 | -| Lifetime | 일회 결제, 영구 사용 | - -### 16.2 라이선스 활성화 - -- 경로: Help > Activate License -- 이메일 주소 + 라이선스 키 입력 -- 할인 쿠폰: 이메일당 1회 사용 - -### 16.3 FREE vs PLUS 기능 비교 - -| 기능 | FREE | PLUS | -|------|:----:|:----:| -| 마운트/언마운트 | O | O | -| 파일 탐색기 (탐색/복사/삭제) | O | O | -| 폴더 비교 (기본) | O | O | -| 동기화 & 작업 관리 | O | O | -| 1:N 동기화 | O | O | -| 작업 이력 & 로그 | O | O | -| 시스템 트레이 | O | O | -| Rclone 터미널 | O | O | -| Dry Run | O | O | -| Export/Import Jobs | O | O | -| 폴더 비교 + 필터 | X | O | -| 스케줄 기반 동기화 | X | O | -| 시작 시 스케줄 자동 실행 | X | O | -| 시작 시 자동 마운트 | X | O | -| 다중 창 | X | O | - ---- - -## 17. Batch Operations (Beta) - -> **상태:** Beta 기능. 소스코드에서 확인되었으나, 안정성이 완전히 검증되지 않음. - -### 17.1 개요 - -여러 작업을 체인으로 연결하여 순차 실행하는 자동화 기능. - -### 17.2 지원 단계 유형 - -| 단계 | 설명 | -|------|------| -| mkdir | 폴더 생성 | -| copyFolder | 폴더 복사 (sync 사용) | -| copyFile | 단일 파일 복사 | -| sync | 폴더 동기화 | -| check | 폴더 검증/비교 | -| move | 파일/폴더 이동 | -| rename | 파일 이름 변경 | -| delete | 필터 기반 삭제 | -| deleteFile | 단일 파일 삭제 | -| purge | 디렉토리 제거 | -| rmdirs | 빈 디렉토리 제거 | -| filelist | 파일 목록 생성 | -| sleep | 실행 일시 중지 | - -### 17.3 배치 기능 - -- 단계 간 변수 전달 (Variable piping) -- Dry-run 미리보기 -- 단계별 진행 추적 -- 실행 모니터링 - ---- - -## 18. 배포 및 설치 (Distribution & Installation) - -### 18.1 공식 다운로드 형식 - -모든 다운로드: https://rcloneview.com/src/download.html - -| 플랫폼 | 형식 | 아키텍처 | 파일명 패턴 | -|--------|------|---------|------------| -| Windows | .exe (Inno Setup 설치 프로그램) | x86-64 전용 | `setup_rclone_view-{version}.exe` | -| macOS | .dmg (디스크 이미지) | Universal (x86-64 + ARM64 Apple Silicon) | `RcloneView-{version}.dmg` | -| Linux | .AppImage | x86_64, aarch64 (ARM64) | `RcloneView-{version}-{arch}.AppImage` | -| Linux | .deb (Debian/Ubuntu) | x86_64, aarch64 (ARM64) | `rclone_view-{version}-linux-{arch}.deb` | -| Linux | .rpm (Fedora/RHEL) | x86_64, aarch64 (ARM64) | `rclone_view-{version}-linux-{arch}.rpm` | - -### 18.2 공식 배포 채널 - -| 채널 | 상태 | 비고 | -|------|------|------| -| rcloneview.com 다운로드 페이지 | **공식** | 유일한 공식 배포 채널 | -| macOS 자동 업데이트 (Sparkle) | **공식** | 앱 내 appcast 피드 | - -### 18.3 비공식 / 미지원 배포 채널 - -아래 채널에는 공식 RcloneView 패키지가 **없다**. 블로그에서 이 채널을 통한 설치를 안내해서는 안 된다: - -| 채널 | 상태 | 비고 | -|------|------|------| -| AUR (Arch User Repository) | **미제공** | 공식 AUR 패키지 없음 | -| Snap Store | **미제공** | 소스에 설정 존재하나 미게시 | -| Flathub / Flatpak | **미제공** | 소스에 매니페스트 존재하나 미게시 | -| Homebrew (macOS) | **미제공** | formula/cask 없음 | -| APT 저장소 | **미제공** | PPA나 apt repo 없음 — .deb 직접 다운로드 | -| RPM 저장소 (dnf/yum) | **미제공** | repo 없음 — .rpm 직접 다운로드 | -| pip / npm / 기타 패키지 매니저 | **미제공** | 해당 없음 | -| 서드파티 미러 | **비공식** | 보증/관리하지 않음 | - -### 18.4 시스템 요구사항 - -**모든 플랫폼 — GUI 필수:** -- RcloneView는 Flutter 기반 **GUI 데스크톱 애플리케이션**이다 -- **헤드리스(디스플레이 서버 없이) 실행 불가** -- **systemd/Windows 서비스로 자체 실행 불가** -- 헤드리스/서버 환경에서는 rclone CLI를 직접 사용할 것 (`rclone rcd`) - -**Windows:** -- 아키텍처: x86-64 전용 (ARM64 Windows 빌드 없음) -- VC++ 2015-2022 Redistributable 필요 -- 최소: Windows Vista 이상 - -**macOS:** -- 아키텍처: Universal 바이너리 (Intel x86-64 + Apple Silicon ARM64) -- 최소: macOS 12.7 (Monterey) -- 공증(Notarization) 및 코드 서명 완료 - -**Linux:** -- 아키텍처: x86_64 및 aarch64 (ARM64) -- 데스크톱 환경 필수: X11 또는 Wayland 디스플레이 서버 -- 필수 의존성: GTK+ 3.0 -- 필수 의존성: libayatana-appindicator3-1 또는 libappindicator3-1 (시스템 트레이) -- 테스트 기반: Ubuntu 22.04 LTS (Jammy) -- 마운트 기능에 FUSE 필요 (fuse3 권장) - -### 18.5 Linux ARM64 참고사항 (Raspberry Pi 등) - -ARM64 빌드(.deb, .rpm, .AppImage)가 Linux용으로 제공된다. 단: - -- **그래픽 데스크톱 환경이 반드시 필요** — 헤드리스 시스템에서 실행 불가 -- Raspberry Pi 등 ARM64 SBC에서는 데스크톱 환경(예: Raspberry Pi Desktop with X11/Wayland)이 설치 및 실행 중이어야 함 -- 원격 데스크톱(VNC/RDP) 또는 X11 포워딩으로 다른 머신에 GUI 표시 가능 -- 디스플레이 없이 완전 헤드리스로 운영하려면 rclone CLI 직접 사용 — 화면 없이 RcloneView는 무의미 -- ARM64 SBC에서의 성능은 크게 달라짐 — 구체적 속도 수치 인용 금지 - -### 18.6 기술 스택 - -| 구성 요소 | 기술 | 비고 | -|-----------|------|------| -| GUI 프레임워크 | **Flutter** (Dart 3.2.6+) | Qt 아님, Electron 아님, GTK 앱 아님 | -| 터미널 | xterm.dart | 내장 터미널 에뮬레이션 | -| 상태 관리 | Riverpod | flutter_riverpod | -| 데이터베이스 | SQLite (sqflite_common_ffi) | 로컬 저장소 | -| 보안 저장소 | flutter_secure_storage | 인증 정보 | -| 빌드 시스템 | CMake (Linux/Windows), Xcode (macOS) | 플랫폼별 | -| Linux 패키징 | flutter_distributor, appimage-builder | .deb, .rpm, .AppImage | -| Windows 패키징 | Inno Setup | .exe 설치 프로그램 | -| macOS 패키징 | appdmg | .dmg + 공증 | - ---- - -## 19. 제한사항 및 부정 사실 (Limitations & Negative Facts) - -RcloneView가 **지원하지 않는 것**, **할 수 없는 것**, **제공하지 않는 것**을 명시. 블로그에서 이와 반대되는 주장을 해서는 안 된다. - -### 19.1 RcloneView는 ~이/가 아니다 - -| 주장 | 실제 | -|------|------| -| 헤드리스/CLI 도구 | GUI 전용 애플리케이션. CLI는 rclone을 직접 사용 | -| rclone 대체품 | rclone에 의존하는 프론트엔드 | -| rclone 공식 GUI | rclone과 독립적인 서드파티 GUI | -| 웹 애플리케이션 | 네이티브 데스크톱 앱 (최종 사용자용 브라우저 인터페이스 없음) | -| 모바일 앱 | iOS/Android 빌드 배포 안 함 | -| Qt 애플리케이션 | Flutter/Dart 기반 | -| Electron 애플리케이션 | Flutter/Dart 기반 | -| 클라우드 서비스 | 사용자의 로컬 머신에서만 실행 | -| 패키지 매니저로 설치 가능 | rcloneview.com 직접 다운로드만 공식 지원 | - -### 19.2 RcloneView는 ~할 수 없다 - -| 주장 | 실제 | -|------|------| -| 디스플레이 서버 없이 실행 | Linux에서 X11 또는 Wayland 필수, 모든 플랫폼에서 GUI 필수 | -| 백그라운드 데몬/서비스로 실행 | 앱 자체를 systemd 서비스로 등록 불가. (rclone rcd는 가능하지만 그건 rclone이지 RcloneView가 아님) | -| 32비트 시스템에서 실행 | 64비트(x86-64, ARM64) 빌드만 존재 | -| Windows ARM에서 실행 | Windows ARM64 빌드 미제공 | -| rclone 없이 동기화 | 모든 스토리지 작업은 rclone에 전적으로 의존 | -| 오프라인 작업 | 클라우드 스토리지 접근에 네트워크 필수 | -| Linux 자동 업데이트 | 자동 업데이트는 macOS(Sparkle)만 가능. Linux/Windows는 수동 다운로드 | - -### 19.3 RcloneView가 제공하지 않는 것 - -| 주장 | 실제 | -|------|------| -| AUR 패키지 | Arch User Repository에 미게시 | -| Snap 패키지 | Snapcraft 설정 존재하나 Snap Store 미게시 | -| Flatpak 패키지 | Flatpak 매니페스트 존재하나 Flathub 미게시 | -| Homebrew formula/cask | Homebrew에서 사용 불가 | -| APT/YUM/DNF 저장소 | 패키지 저장소 없음 — .deb/.rpm은 직접 다운로드 | -| Docker 이미지 | 컨테이너화되지 않음 | -| iOS/Android 앱 | 모바일 빌드 미배포 | -| 32비트 빌드 | x86 (32비트) 또는 armv7 빌드 없음 | - -### 19.4 블로그 플랫폼별 필수 주의사항 - -특정 플랫폼에 대한 블로그 작성 시 반드시 포함해야 할 내용: - -**Raspberry Pi / ARM64 SBC 관련 글:** -- 데스크톱 환경 + 디스플레이 서버 필수임을 반드시 명시 -- 헤드리스 설정을 주요 사용 사례로 설명하면 안 됨 -- 원격 실행 시 VNC/X11 포워딩을 대안으로 언급 -- 완전 헤드리스 시나리오에는 rclone CLI 권장 - -**Arch Linux 관련 글:** -- `yay -S rcloneview` 등 AUR 설치 안내 절대 금지 -- rcloneview.com에서 .AppImage 또는 수동 바이너리 설치 안내 -- Qt5 의존성 언급 금지 — Flutter/GTK+3 기반 - -**모든 Linux 배포판 글:** -- GTK+3 및 디스플레이 서버(X11/Wayland) 요구사항 명시 -- RcloneView를 systemd 서비스로 설명 금지 -- 공식 문서의 systemd 서비스는 `rclone rcd`용이며 RcloneView 자체가 아님 - -**서버/NAS 관련 글:** -- RcloneView는 GUI 도구이며 서버 애플리케이션이 아님을 명확히 -- 서버 활용: 서버에 RcloneView를 설치하지 말고, Connection Manager로 원격 rclone에 연결 - ---- - -## Appendix: Credential Guides - -### AWS S3 -- AWS Management Console: `https://aws.amazon.com/console` -- IAM Console에서 Access Key 생성 -- 필요 정보: Access Key ID, Secret Access Key, Region 코드 (예: ap-northeast-2) - -### Cloudflare R2 -- Dashboard: `https://dash.cloudflare.com` -- R2 Bucket 생성 후 API Token 발급 -- Admin Read & Write 권한 필요 -- Endpoint: `https://.r2.cloudflarestorage.com` - -### Backblaze B2 -- 키 관리: `https://secure.backblaze.com/b2_buckets.htm` -- 필요 정보: Application Key ID, Application Key - -### Proton Drive -- 로그인: `https://drive.proton.me/` -- 필요 정보: Email, Password, 선택적 2FA -- 2FA 설정: `https://proton.me/support/two-factor-authentication` - -### Gofile -- Token 확인: `https://gofile.io/myprofile` -- Account API Token 필드에서 확인 - -### Azure File Storage -- Azure Portal > Storage Account > Access keys -- 필요 정보: Storage Account Name, Shared Key, Share Name - -### Mega -- 로그인: `https://mega.nz/login` -- 필요 정보: Email, Password - ---- - -## Appendix: Troubleshooting Reference - -### macOS: Desktop/Documents/Downloads 폴더가 비어있음 -- **원인:** macOS Catalina+ Privacy 권한 미부여 -- **해결 1:** System Settings > Privacy & Security > Files & Folders에서 권한 부여 -- **해결 2:** Full Disk Access에 RcloneView 추가 -- **필수:** 권한 변경 후 RcloneView 재시작 - -### macOS: Too many open files 오류 -- **원인:** macOS 파일 디스크립터 기본 제한 (256~1024) -- **해결:** `/Library/LaunchDaemons/limit.maxfiles.plist` 생성, soft/hard 524288 설정 -- **필수:** 재부팅 필요 - -### macOS: 외장 SSD 접근 불가 -- **해결:** `/Volumes`에서 SSD 탐색 후 Alias 리모트 생성 - -### 로그 수집 방법 -1. Settings > Embedded Rclone > Enable rclone Logging 체크 -2. Log level: DEBUG (가장 상세) -3. Restart Embedded Rclone 클릭 -4. 문제 재현 -5. 로그 파일을 rcloneview@bdrive.com으로 전송 diff --git a/README.md b/README.md index 0c6c2c27..03960388 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,7 @@ $ GIT_USER= yarn deploy ``` If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. + +## 운영 문서 + +블로그 자동화·운영 문서(프롬프트·가이드라인·스펙)는 비공개 리포 `bdrive/rcloneview-blog-automation` 에 있다. diff --git a/SCHEDULE_FACTCHECKER_PROMPT.md b/SCHEDULE_FACTCHECKER_PROMPT.md deleted file mode 100644 index 06d540e6..00000000 --- a/SCHEDULE_FACTCHECKER_PROMPT.md +++ /dev/null @@ -1,183 +0,0 @@ -# Blog Fact-Checker — Scheduled Task Prompt - -> **Schedule:** Daily 10:00 AM (Generator 완료 후 1시간 뒤) -> **Model:** Opus 4.7 -> **Folder:** C:\workspace\bdrive\source\rcloneview-support -> **Role:** 생성된 블로그 독립 검증 + 빌드 + 소스 푸시 - ---- - -## Prompt - -``` -You are an independent fact-checker for RcloneView blog posts. You have NOT seen how these posts were written. Your job is to validate every post against strict guidelines, then build and push the verified source. - -═══════════════════════════════════════════════════════════════════ -STEP 0: SYNC WITH MAIN BRANCH -═══════════════════════════════════════════════════════════════════ - -Before reading any files or running any commands, ensure the local repository is up-to-date with main: - -In rcloneview-support: - git checkout main - git pull origin main - -If there are local uncommitted changes that prevent checkout or pull, report the issue and stop. Do NOT force-overwrite local changes. - -This ensures you work with the latest Fact-Check Guideline, Feature Spec, and blog posts. - -═══════════════════════════════════════════════════════════════════ -STEP 1: READ VALIDATION RULES -═══════════════════════════════════════════════════════════════════ - -Read the file BLOG_FACTCHECK_GUIDELINE.md in the repository root completely. This contains all validation rules. - -Also read the file RCLONEVIEW_FEATURE_SPEC.md for ground truth about the product. Read it in TWO PARTS if needed: -1. First: Read with offset 0 (beginning of file) -2. Then: Read with offset 500 (rest of file, including critical Sections 18 and 19) - -You MUST read BOTH parts. Sections 18 (Distribution) and 19 (Limitations) are at the END and are CRITICAL for validating installation and platform claims. - -═══════════════════════════════════════════════════════════════════ -STEP 2: FIND TODAY'S POSTS -═══════════════════════════════════════════════════════════════════ - -List all files in the blog/ directory matching today's date pattern. -These are the posts to validate. If no files found for today, output "No posts found for today" and stop. - -═══════════════════════════════════════════════════════════════════ -STEP 3: VALIDATE EVERY POST -═══════════════════════════════════════════════════════════════════ - -Read each post and check against the FULL checklist in Guideline Section 7. - -For EACH post, verify these critical items: - -INSTALLATION & DISTRIBUTION (most common AI hallucination): -- [ ] Every install instruction matches Guideline Section 1.5 valid methods? -- [ ] No fabricated commands? (yay, pacman, snap, flatpak, brew, apt repo, dnf repo, pip, npm, docker) -- [ ] All installs start with "Download from rcloneview.com"? -- [ ] Architecture correct? (Linux=x86_64/aarch64, Windows=x86-64 only, macOS=Universal) - -PLATFORM & HEADLESS (caused real user complaints): -- [ ] Clear that RcloneView is a GUI app requiring a display? -- [ ] No claims of headless/CLI/server operation? -- [ ] systemd service identified as "rclone rcd", NOT RcloneView? -- [ ] Raspberry Pi/ARM posts state desktop environment required? -- [ ] Arch Linux posts do NOT reference AUR? -- [ ] Server/NAS posts clarify: install rclone on server, not RcloneView? - -TERMINOLOGY & EXPRESSION: -- [ ] Product name exactly "RcloneView"? -- [ ] Cloud service names spelled correctly? (per Guideline Section 2.3) -- [ ] No superlatives? (fastest, only, first, perfect, revolutionary) -- [ ] No specific prices mentioned? -- [ ] No performance numbers? (transfer speed, throughput) -- [ ] Bidirectional sync marked as "Beta"? -- [ ] Provider count uses "90+" (not 70+, 77, 100+)? -- [ ] rclone features not described as RcloneView-exclusive? -- [ ] Technology described as Flutter/Dart (NOT Qt, NOT Electron)? -- [ ] All tags exist in tags.yml? -- [ ] URLs only from verified list in Guideline Section 5? - -FORMAT: -- [ ] All 3 imports present? (CloudSupportGrid, cloudIcons, RvCta) -- [ ] RvCta immediately after intro paragraph? -- [ ] immediately after RvCta? -- [ ] as the very last line? -- [ ] 3-5 images using HTML with class="img-large img-center"? -- [ ] Image paths from approved list only? -- [ ] No empty lines between frontmatter fields? -- [ ] Title and description in double quotes? -- [ ] Slug does NOT include date prefix? -- [ ] authors: exactly " - tayson"? - -For each post: -- PASS: No issues found — keep as-is -- FIX: Issue found but fixable — edit the file to fix, then save -- REMOVE: Fundamentally flawed premise (e.g., headless Raspberry Pi as primary use case, AUR installation guide) — delete the file entirely - -═══════════════════════════════════════════════════════════════════ -STEP 4: OUTPUT VALIDATION REPORT -═══════════════════════════════════════════════════════════════════ - -After validating all posts, output a report in this exact format: - -VALIDATION REPORT -======================== -Date: {today's date} -Total: {N} -Passed: {N} -Fixed: {N} -Removed: {N} - -| # | File | Status | Details | -|---|------|--------|---------| -| 1 | {filename} | PASS | - | -| 2 | {filename} | FIXED | {what was changed} | -| 3 | {filename} | REMOVED | {reason} | - -═══════════════════════════════════════════════════════════════════ -STEP 4.5: DUPLICATE SLUG CHECK (CRITICAL — runs BEFORE build) -═══════════════════════════════════════════════════════════════════ - -Blog filenames follow `YYYY-MM-DD-{slug}.md`. The {slug} portion determines the published URL. Two files with different dates but the SAME slug will produce a "Duplicate routes found" warning during build and cause the same URL to collide. - -Procedure: -1. List ALL files in blog/ directory -2. For each filename, strip the `YYYY-MM-DD-` prefix to extract the raw slug -3. Identify any slugs that appear in MORE than one file -4. For each duplicate group: KEEP the file with the EARLIEST date (older post has established SEO / backlinks), DELETE all newer files sharing that slug - -Example: - 2026-03-22-rcloneview-arch-linux-cloud-sync.md ← keep (older) - 2026-04-13-rcloneview-arch-linux-cloud-sync.md ← DELETE - -After deletion, verify no duplicate slugs remain before proceeding to build. - -═══════════════════════════════════════════════════════════════════ -STEP 5: BUILD -═══════════════════════════════════════════════════════════════════ - -Run these commands in the rcloneview-support directory: - - npm ci - npm run build - -Watch the build output carefully. Docusaurus build may show WARNINGS (not errors) that still need action: - -- "[WARNING] Duplicate routes found!" — This means Step 4.5 missed something. Stop, re-run Step 4.5 to find and remove the remaining duplicates, then rebuild. -- "[ERROR]" or non-zero exit code — Report the error and stop. Do not push. - -Only proceed to Step 6 if the build completes with NO duplicate route warnings. - -═══════════════════════════════════════════════════════════════════ -STEP 6: PUSH SOURCE -═══════════════════════════════════════════════════════════════════ - -After successful build, push the source: - -6. Commit and push rcloneview-support (source .md files): - cd ../rcloneview-support - git checkout main - git pull origin main - git checkout -b blog/auto/{DATE} - git add blog/{DATE}-*.md - git commit -m "blog: auto-generate posts for {DATE}" - git push -u origin blog/auto/{DATE} - -Replace {DATE} with today's date in YYYY-MM-DD format. - -═══════════════════════════════════════════════════════════════════ -STEP 7: SUMMARY -═══════════════════════════════════════════════════════════════════ - -Output final summary: -- Validation results (from Step 4) -- Build status (success/fail) -- Branches pushed: - - rcloneview-support: blog/auto/{DATE} -- Action needed: "Merge the support branch to main via GitHub PR — www 반영은 Actions 가 자동으로 처리한다" - -Now execute all steps. Start by reading BLOG_FACTCHECK_GUIDELINE.md. -``` diff --git a/SCHEDULE_GENERATOR_PROMPT.md b/SCHEDULE_GENERATOR_PROMPT.md deleted file mode 100644 index e03cca2f..00000000 --- a/SCHEDULE_GENERATOR_PROMPT.md +++ /dev/null @@ -1,273 +0,0 @@ -# Blog Generator — Scheduled Task Prompt - -> **Schedule:** Daily 09:00 AM -> **Model:** Opus 4.7 -> **Folder:** C:\workspace\bdrive\source\rcloneview-support -> **Role:** Feature Spec 기반으로 블로그 2개 생성 - ---- - -## Prompt - -``` -You are a professional SEO blog writer for RcloneView (https://rcloneview.com), a multi-cloud file management GUI built on top of rclone. Your task is to generate exactly 2 unique, high-quality blog posts for today's date. - -═══════════════════════════════════════════════════════════════════ -STEP 0: SYNC WITH MAIN BRANCH -═══════════════════════════════════════════════════════════════════ - -Before reading any files, ensure the local repository is up-to-date with main: - - git checkout main - git pull origin main - -If there are local uncommitted changes that prevent checkout or pull, report the issue and stop. Do NOT force-overwrite local changes. - -This ensures you work with the latest Feature Spec, Fact-Check Guideline, tags.yml, and existing blog list. - -═══════════════════════════════════════════════════════════════════ -STEP 1: READ PRODUCT KNOWLEDGE (FEATURE SPEC) -═══════════════════════════════════════════════════════════════════ - -Read the file RCLONEVIEW_FEATURE_SPEC.md in the repository root. This is your ONLY authoritative source for: -- Product features and capabilities -- Supported cloud providers (90+) -- Installation methods and download formats -- Platform support and system requirements -- Technology stack (Flutter/Dart, NOT Qt, NOT Electron) -- License structure (FREE vs PLUS) -- Limitations (GUI-only, no headless, no AUR, etc.) - -CRITICAL: Read the ENTIRE file. If it exceeds the single-read token limit, read it in TWO PARTS: -1. First: Read with offset 0 (beginning of file) -2. Then: Read with offset 500 (rest of file, including critical Sections 18 and 19) - -You MUST read BOTH parts. Sections 18 (Distribution) and 19 (Limitations) are at the END of the file and are the MOST IMPORTANT sections for preventing factual errors. - -Do NOT invent features, installation methods, or capabilities not in this file. -Pay special attention to Sections 18 (Distribution) and 19 (Limitations). - -═══════════════════════════════════════════════════════════════════ -STEP 2: READ EXISTING FILES TO AVOID TOPIC DUPLICATION -═══════════════════════════════════════════════════════════════════ - -CRITICAL: Filenames follow the pattern `YYYY-MM-DD-{slug}.md`. The {slug} portion is what determines the published URL. Two files with different dates but the same slug (e.g., `2026-04-09-manage-box-cloud-sync-backup-rcloneview.md` and `2026-04-13-manage-box-cloud-sync-backup-rcloneview.md`) will both try to publish at the SAME URL, causing duplicate route errors and build failures. - -Procedure: -1. List ALL files in the blog/ directory (not just recent ones) -2. For EACH existing filename, strip the `YYYY-MM-DD-` prefix to extract the raw slug -3. Build a "used slugs" set from these extracted slugs -4. When generating new posts, your chosen slug MUST NOT already exist in this set — regardless of when that existing post was published - -You MUST NOT create any post whose slug matches an existing post's slug. This includes: -- Same remote/provider already covered as a standalone post -- Same migration pair (e.g., "migrate-X-to-Y" already exists) -- Same comparison pair (e.g., "rcloneview-vs-X" already exists) -- Same troubleshooting topic (e.g., "fix-slow-cloud-transfers" already exists) -- Same industry vertical (e.g., "cloud-storage-law-firms" already exists) -- Same platform (e.g., "rcloneview-arch-linux" already exists) -- Same feature deep-dive (e.g., "vfs-cache-mount-performance" already exists) - -Before writing each post, verify its slug is NOT in the used-slugs set. If it matches, pick a different topic or differentiate the slug meaningfully (e.g., add a qualifier that reflects different content, not just a date). - -═══════════════════════════════════════════════════════════════════ -STEP 3: READ tags.yml FOR VALID TAGS -═══════════════════════════════════════════════════════════════════ - -Read the tags file at blog/tags.yml to get the list of valid tags. -Every tag used in your posts MUST exist in this file. Use the EXACT key (left side before the colon). Common tags include: RcloneView, cloud-storage, cloud-sync, backup, guide, comparison, troubleshooting, tips, feature, industry, platform, migration, mount, performance, encryption, automation, linux, windows, macos, and provider-specific tags like google-drive, onedrive, dropbox, amazon-s3, azure, wasabi, backblaze-b2, etc. - -═══════════════════════════════════════════════════════════════════ -STEP 4: PICK 2 TOPICS (7-CATEGORY STRATEGY, rotate over days) -═══════════════════════════════════════════════════════════════════ - -Use today's date in YYYY-MM-DD format for all file naming. - -Distribute today's 2 posts across these 7 categories. Rotate categories -over days; prioritize categories 1–3 (bread and butter). Avoid hitting -the same category two days in a row when feasible. - -1. REMOTES (highest weight): Managing specific cloud storage providers with RcloneView - - Format: "Manage {Provider} Storage — Sync and Backup Files with RcloneView" - - Slug: manage-{provider}-cloud-sync-backup-rcloneview - - Tags: RcloneView, {provider-tag}, cloud-storage, cloud-sync, backup - -2. CROSS-PROVIDER TRANSFERS: Migration/sync between two specific providers - - Format: "Migrate {Source} to {Destination} — Transfer Files with RcloneView" OR "Sync {Source} to {Destination} — Cloud Backup with RcloneView" - - Slug: migrate-{source}-to-{dest}-rcloneview OR sync-{source}-to-{dest}-rcloneview - - Tags: RcloneView, {source-tag}, {dest-tag}, cloud-to-cloud, migration OR sync - -3. PAIN POINTS / TROUBLESHOOTING: Common cloud storage problems and solutions - - Format: "Fix {Problem} — {Solution} with RcloneView" OR "{Problem} — How to Resolve with RcloneView" - - Slug: fix-{problem-slug}-rcloneview - - Tags: RcloneView, troubleshooting, tips, {relevant-tags} - -4. INDUSTRY VERTICALS: Cloud storage solutions for specific industries - - Format: "Cloud Storage for {Industry} — {Benefit} with RcloneView" - - Slug: cloud-storage-{industry}-rcloneview - - Tags: RcloneView, cloud-storage, industry, backup, guide - -5. COMPARISON: RcloneView vs competitor tools - - Format: "RcloneView vs {Competitor} — Cloud File Transfer Tool Comparison" - - Slug: rcloneview-vs-{competitor}-comparison - - Tags: RcloneView, comparison, cloud-storage - -6. PLATFORM: Running RcloneView on specific OS/hardware - - Format: "RcloneView on {Platform} — Cloud Storage Sync and Backup" - - Slug: rcloneview-{platform}-cloud-sync - - Tags: RcloneView, {platform-tag}, cloud-sync, installation - -7. FEATURE DEEP-DIVE: Detailed guide on a specific RcloneView feature - - Format: "{Feature} — {Benefit Description} in RcloneView" - - Slug: {feature-slug}-rcloneview - - Tags: RcloneView, feature, {relevant-tags} - -═══════════════════════════════════════════════════════════════════ -STEP 5: WRITE EACH POST WITH EXACT FORMAT -═══════════════════════════════════════════════════════════════════ - -Each post MUST follow this EXACT structure. Do NOT deviate: - ---- -slug: {slug-without-date} -title: "{Title with — Em Dash Separator}" -authors: - - tayson -description: "{SEO description 120-160 chars, include RcloneView and primary keyword}" -keywords: - - {keyword 1} - - {keyword 2} - - {keyword 3} - - {keyword 4} - - {keyword 5} - - {keyword 6} - - {keyword 7} - - {keyword 8} - - {keyword 9 (optional)} - - {keyword 10 (optional)} -tags: - - RcloneView - - {tag2} - - {tag3} - - {tag4} - - {tag5 (optional)} ---- - -import CloudSupportGrid from '../src/components/CloudSupportGrid'; -import cloudIcons from '../src/contexts/cloudIcons'; -import RvCta from '../src/components/RvCta'; - -# {Same Title as frontmatter title, without quotes} - -> {One-sentence hook/summary that captures the post's value proposition} - -{Introductory paragraph: 2-4 sentences explaining the problem or context. Mention RcloneView as the solution. Be specific and practical, not generic.} - - - - - -## {Section 1 Title — Descriptive, Not Generic} - -{2-3 paragraphs of substantive content. Be specific about RcloneView features, workflows, or benefits. Include technical details where relevant.} - -{descriptive alt text} - -{Optional additional paragraph after image} - -## {Section 2 Title} - -{2-3 paragraphs of content} - -{descriptive alt text} - -## {Section 3 Title} - -{2-3 paragraphs of content} - -{descriptive alt text} - -## {Optional Section 4 — if content warrants it} - -{Content} - -{descriptive alt text} - -## Getting Started - -1. **Download RcloneView** from [rcloneview.com](https://rcloneview.com/src/download.html). -2. {Step 2 specific to this post's topic} -3. {Step 3 specific to this post's topic} -4. {Step 4 specific to this post's topic} - -{Closing motivational sentence about the topic's benefit.} - ---- - -**Related Guides:** - -- [{Related Post Title 1}](https://rcloneview.com/support/blog/{related-slug-1}) -- [{Related Post Title 2}](https://rcloneview.com/support/blog/{related-slug-2}) -- [{Related Post Title 3}](https://rcloneview.com/support/blog/{related-slug-3}) - - - -═══════════════════════════════════════════════════════════════════ -CRITICAL FORMAT RULES (DO NOT VIOLATE) -═══════════════════════════════════════════════════════════════════ - -1. FILE NAMING: {DATE}-{slug}.md — Example: 2026-04-14-manage-box-cloud-sync-backup-rcloneview.md -2. IMAGES: ALWAYS use HTML tags, NEVER Markdown ![](). Images MUST use class="img-large img-center" -3. IMAGE PATHS: Only use these exact paths (rotate through them): - - /support/images/en/blog/new-remote.png - - /support/images/en/blog/cloud-to-cloud-transfer-default.png - - /support/images/en/tutorials/wasabi-drag-and-drop.png - - /support/images/en/howto/rcloneview-basic/compare-display-select.png - - /support/images/en/howto/rcloneview-basic/job-run-click.png - - /support/images/en/tutorials/wasabi-real-time-monitoring-transferring.png - - /support/images/en/howto/rcloneview-advanced/create-job-schedule.png - - /support/images/en/howto/rcloneview-basic/job-history.png - - /support/images/en/howto/rcloneview-basic/mount-from-remote-explorer.png - - /support/images/en/howto/rcloneview-basic/mount-from-mount-manager.png - - /support/images/en/blog/synology-nas-autodection-and-connection.png -4. IMPORTS: Always include all three imports EXACTLY as shown (no @site/ prefix) -5. RvCta: Always include immediately after the intro paragraph -6. TRUNCATE: Always include after RvCta -7. TAGS: Every tag MUST exist in tags.yml. Always include "RcloneView" as the first tag -8. WORD COUNT: Each post should be 400-600 words (excluding frontmatter and code) -9. EM DASH: Use — (em dash) in titles, not - (hyphen) for separators -10. RELATED GUIDES: Link to 3 existing blog posts that are topically related. Use actual slugs from existing posts -11. CLOSING: Always end with as the very last line -12. KEYWORDS: 8-10 SEO-optimized keywords per post, mix of short-tail and long-tail -13. NO EMPTY LINES between frontmatter fields -14. DESCRIPTION: Must be in double quotes in frontmatter -15. TITLE: Must be in double quotes in frontmatter -16. EACH POST: Must have 3-5 images distributed throughout the content sections -17. SLUG: Must NOT include the date prefix — only the topic slug -18. AUTHORS: Always exactly "- tayson" (indented with 2 spaces) - -═══════════════════════════════════════════════════════════════════ -STEP 6: WRITE FILES -═══════════════════════════════════════════════════════════════════ - -Write each file to: blog/{DATE}-{slug}.md - -After writing all 2 files, output a numbered list of all created files with their full paths. - -═══════════════════════════════════════════════════════════════════ -CONTENT QUALITY GUIDELINES -═══════════════════════════════════════════════════════════════════ - -- Write as if you are an expert cloud infrastructure consultant -- Be specific: mention actual provider features and API behaviors from RCLONEVIEW_FEATURE_SPEC.md -- Include practical scenarios (e.g., "a photography studio with 2TB of RAW files") -- Avoid generic filler like "In today's digital world" or "Cloud storage is important" -- Each section should provide actionable information, not just describe features -- Use active voice and direct language -- Vary sentence structure and paragraph length for readability -- Related Guides should link to REAL existing posts (check filenames from Step 2) -- NEVER mention specific pricing of any cloud provider or RcloneView itself -- NEVER fabricate installation commands — only use methods from RCLONEVIEW_FEATURE_SPEC.md Section 18 - -Now execute all steps. Generate and write 2 blog posts. -``` diff --git a/docs/journals/2026-07-16-build-size-reduction_ko.md b/docs/journals/2026-07-16-build-size-reduction_ko.md deleted file mode 100644 index 537d4c52..00000000 --- a/docs/journals/2026-07-16-build-size-reduction_ko.md +++ /dev/null @@ -1,189 +0,0 @@ -# 2026-07-16 — 빌드 크기 감축 (feature/i18n) - -> 9로케일 빌드가 1,264MB 였다. 843MB 로 줄였다 (**-421MB, -33%**). -> 콘텐츠는 한 줄도 고치지 않았다 — 전부 템플릿·설정 변경이라 앞으로 쓰는 모든 글에 자동 적용된다. - -## 요약 - -| | before | after | 절감 | -|---|---|---|---| -| ja | 145M | 94M | -51M | -| ko | 140M | 91M | -49M | -| fr | 132M | 85M | -47M | -| zh-Hant | 133M | 87M | -46M | -| zh-Hans | 132M | 86M | -46M | -| es | 131M | 85M | -46M | -| de | 130M | 84M | -46M | -| id | 128M | 83M | -45M | -| blog (en) | 79M | 41M | -38M | -| assets (en) | 39M | 34M | -5M | -| img | 2.7M | 1.0M | -1.7M | -| **합계** | **~1,264M** | **~843M** | **-421M (-33%)** | - -측정: `npm run build` (9로케일 + postbuild 프룬) 후 `du -sh *`. - -## 진단 — 크기가 어디서 왔나 - -원본 마크다운은 로케일당 5.8MB 인데 빌드는 1,264MB 였다. 약 23배. - -구성 비율을 재보니 **HTML 740MB (62%) + JS 326MB (27%)** 였고 **이미지는 전체의 7.5%** 에 불과했다. -즉 애셋이 아니라 페이지 수가 문제였다: 626 포스트 × 9 로케일 = 5,571 페이지, 각각 HTML + 하이드레이션용 JS 청크. - -ko 로케일 blog 디렉토리(79.5MB)를 페이지 종류별로 쪼개니 진짜 원인이 나왔다: - -| 페이지 종류 | 개수 | 크기 | 평균 | -|---|---|---|---| -| 실제 포스트 | 626 | 25.5MB | 41.7KB | -| **태그 페이지** | **459** | **39.2MB** | **87.5KB** | -| authors | 66 | 7.1MB | 110.8KB | -| 페이지네이션 | 61 | 7.4MB | 123.9KB | - -**목록 페이지(53.7MB)가 실제 포스트(25.5MB)보다 2배 컸다.** 목록 페이지가 제목 목록이 아니라 -**포스트 미리보기 전체를 임베드**하기 때문이다 (`security` 태그 페이지 = 108.7KB 중 101.6KB 가 미리보기 10개). -포스트당 평균 태그가 5.59개라 모든 포스트의 미리보기가 5.59회 중복 렌더된다. - -## 변경 내역 - -### 1. archive 청크에서 미사용 `content` 제거 — `8257ae7` + `b0d2ccc` - -Docusaurus 블로그 플러그인이 archive 라우트에 포스트 객체를 통째로 넘긴다 -(`plugin-content-blog/lib/routes.js:88` — `archive: {blogPosts: listedBlogPosts}`). -각 글의 원본 마크다운 `content` 까지 청크에 실린다. 그런데 `src/theme/BlogArchivePage` 가 실제로 읽는 건 -`permalink`/`date`/`title`/`tags` 4개뿐 — `content` 는 아무도 안 쓴다. - -`archiveBasePath: null` 로 기본 라우트를 끄고, `src/plugins/blog-archive-slim.js` 가 `allContentLoaded` -훅에서 같은 경로·같은 컴포넌트를 슬림한 props 로 재등록한다. - -- 청크 **9,273,815B → 810,128B (-91.3%)**, 9로케일 합계 약 62MB → 5.85MB -- 렌더 결과 바이트 단위 동일 (차이는 `` 줄바꿈 1개 + 에셋 해시) -- 619개 포스트 링크 유지 (626 중 7개는 `unlisted: true` 라 원래 제외됨) -- `b0d2ccc` 는 리뷰 지적 반영: `@docusaurus/utils` 가 hoisting 으로만 잡히고 있어 `package.json` 에 3.7.0 선언 - -**주의:** 플러그인 이름이 `docusaurus-plugin-blog` 인 것은 의도적이다. theme-common 의 접두어 제거 -정규식이 이 이름에서 `plugin-blog` html 클래스를 그대로 유지시킨다. 업스트림이 그 정규식을 조이면 -**아무 에러 없이** 클래스가 바뀐다. 지금 이 클래스를 쓰는 CSS 는 없다. - -### 2. og-image 최적화 — `8ba9b09` - -`static/img/og-image.png` 가 **4482×2016 RGBA, 1,893,268B** 였다. OG 규격은 1200×630. - -- **1200×630, 91,151B** 로 축소 (-95%) -- 크롭이 아니라 **축소 + 레터박스**. 원본 콘텐츠가 캔버스를 거의 꽉 채워(우측 여백 14px) 크롭하면 - 좌측 마스코트와 우측 로고 그리드가 잘린다. 원본 배경이 검정이라 레터박스가 보이지 않는다. -- 9로케일 복사 기준 약 -15MB - -### 3. 태그/저자 목록을 압축 항목으로 전환 — `90f0be4` - -목록 페이지가 미리보기 전체 대신 **제목 + 날짜 + description** 만 렌더한다. - -- `src/theme/BlogPostItemsCompact/` — 신규 항목 렌더러 (`BlogArchivePage` 의 목록 톤을 따름) -- `src/theme/BlogTagsPostsPage/` — eject swizzle -- `src/theme/Blog/Pages/BlogAuthorsPostsPage/` — eject swizzle - (3.7 에서 최상위가 아니라 `Blog/Pages/` 하위에 있다) - -실측: - -| | before | after | -|---|---|---| -| ko 태그 459p | 41,108,812B | **6,679,839B (-83.8%)** | -| ko 저자 66p | 7.1MB | **1.2MB (-83%)** | - -- **페이지 개수 459/66 은 9로케일 전부 유지.** 페이지 수가 아니라 페이지당 바이트를 줄인 것이다. -- **`/blog` 메인 목록과 페이지네이션은 손대지 않았다** — 블로그의 정문이라 미리보기를 유지. - 바이트 동일 확인(차이는 에셋 해시 2곳). - -**왜 `BlogPostItems` 가 아니라 페이지 2개를 eject 했나:** 세 목록 페이지가 모두 `@theme/BlogPostItems` -를 타므로 그걸 고치면 `/blog` 까지 바뀐다. eject 하면 범위가 구조적으로 격리된다 — `/blog` 는 -미리보기 렌더러를 import 하는 유일한 곳(`src/theme/BlogListPage/index.js:17`)으로 남는다. -업스트림 대비 델타는 파일당 정확히 2줄이며, 각 파일 헤더 주석에 무엇을 왜 바꿨는지 남겼다. - -## 되돌린 것 — 태그 제거 (`4cb2f51` → `0d4571e`) - -포스트당 태그를 5.59 → 3.13 개로 줄이는 작업을 구현했다가 **되돌렸다.** - -**구현 결함이 아니다.** 검증은 전부 통과했다 (평균 3.13 정확히 달성, 태그 0개 포스트 0건, -로케일 간 태그 집합 일치, 태그만 변경되고 본문/keywords 무변경). - -**접근이 지속 불가능해서다.** 새 글마다 태그 규율을 강제하고, 주제 태그 페이지 4개 -(cloud-storage/backup/guide/cloud-sync)의 SEO 표면을 버려야 했다. 대신 템플릿을 고치니 -약 5배 더 줄었고, 태그 177개를 전부 유지하며, 앞으로 쓰는 글에 자동 적용된다. -템플릿 수정 후 태그 제거의 한계 이득은 로케일당 3MB 로 쪼그라들었다. - -**교훈: 콘텐츠가 아니라 템플릿을 고쳐라.** - -## 이미 되어 있던 것 (내가 뒤늦게 발견) - -- **로케일 static 프룬** — `scripts/prune-locale-static.mjs` + `package.json` 의 `postbuild` 훅 - (`8111194`, tayson-jeong, 7/15). Docusaurus 는 `static/` 을 로케일마다 복사하는데, 콘텐츠가 - 이미지를 루트 절대경로(`/support/images/...`)로 참조하므로 로케일 사본은 죽은 파일이다. - `images`/`videos`/`icons` 를 지우고 **`img/` 는 유지**한다 (favicon·로고·preview 3개 파일이 - `useBaseUrl` 경유로 로케일 경로 참조됨). 실측 **-544MB**, 깨진 참조 0건. - → 빌드 결과에서 `images 67M` 이 **루트에만** 있고 로케일 디렉토리엔 없는 이유가 이것이다. -- **R2 배포** — `d0f845c`. `rclone sync build/ r2:rcloneview-support` → Worker 가 서빙. - 빌드 산출물을 git 에 커밋하지 않는다. (아직 `feature/i18n` 에만 있고 main 에는 없음.) - -## 발견한 기존 문제 (이번 작업과 무관, 미해결) - -### 1. 참조되는데 존재하지 않는 이미지 37개 — 라이브 버그 - -`blog/` 가 참조하는 고유 이미지 302개 중 **37개가 `static/` 에 없다.** 전 로케일 합계 666건 참조 → -**지금 프로덕션에서 깨진 이미지로 뜨고 있다.** - -``` -/support/images/en/howto/rcloneview-basic/sync-tab.png -/support/images/en/howto/remote-storage-connection-settings/add-azure-blob-storage.png -... 외 35개 -``` - -`onBrokenLinks: 'throw'` 가 못 잡는다 — 그건 **라우트**를 검사하지 static 파일 존재 여부를 검사하지 않는다. -소유자가 필요하다. - -### 2. ko 태그 페이지 H1 번역 깨짐 - -``` -"가이드" 태그로 연결된 166개 게시물개의 게시물이 있습니다. - ^^^^^^^^^^^^^^^ 중복 -``` - -`i18n/ko/code.json:397` 의 `{nPosts}` 가 이미 "166개 게시물" 로 전개되는데 템플릿이 "개의 게시물" 을 -또 붙인다. 90f0be4 전후 바이트 동일로 기존 버그임이 확인됐다. - -## 미결 판단 항목 - -- **schema.org 마이크로데이터 손실.** 상위 `BlogPostItemContainer` 는 각 항목을 - `
` 로 감싸는데 - 압축 목록은 `
  • ` 만 낸다. 태그 페이지마다 있던 BlogPosting 블록 10개가 0이 되고, - `BlogListPageStructuredData` 는 `/blog` 에만 걸려 있어 JSON-LD 폴백도 없다. - 본문 텍스트 손실 외의 **두 번째 SEO 비용**이며, `
  • ` 에 복원하는 건 값싸다. -- **MIT 저작권 고지.** eject 한 파일들이 상위 MIT 헤더를 한글 주석으로 대체했다 - (`grep -rl "MIT license" src/theme/` → 0건). 기존 swizzle 도 전부 그러고 있어 이 저장소의 - 관행이지만, 이 파일들은 95% 원본 그대로이고 MIT 는 substantial portions 에 고지 유지를 요구한다. -- **archive 슬림 payload 의 `tags`.** 슬림 JSON 628KB 중 약 495KB(79%)가 태그 객체인데 - 소비처는 `tags[].label` 만 읽는다. `{label}` 만 남기면 9로케일 합계 약 3MB 추가 절감. -- **프룬 스크립트의 `--out-dir` 미지원.** `BUILD_DIR` 이 `/build` 하드코딩이라 - `--out-dir` 빌드에서 **조용히 no-op** 한다 (에러도 없음). 현재 `deploy.yml` 은 `npm run build` - 를 쓰므로 문제없다. `--out-dir` 을 쓸 계획이 생기면 먼저 고쳐야 한다. - -## 이 저장소에서 일할 때 주의할 것 - -- **`yarn build --locale ko` 는 로케일 경로를 테스트하지 않는다.** `defaultLocale: 'en'` 이라 - 단일 로케일 빌드는 `build/` 루트로 평탄화된다 (`buildLocale.js:33`: - `localizePath: cliOptions.locale?.length === 1 ? false : undefined`). 진짜 `build/ko/` 가 - 필요하면 `--locale en --locale ko`. 전체 빌드는 약 13~15분. -- **`--out-dir` 빌드는 프룬이 안 걸린다.** 그 출력을 실제 배포 상태로 착각하면 546MB 를 - "중복됐다" 고 오판하게 된다. (이번에 내가 그랬다.) -- **grep 이 CJK 빌드 HTML 을 binary 로 취급해 조용히 0을 반환한다.** 검증 스크립트는 python 을 쓸 것. -- **프룬 판별식을 함부로 고치지 말 것.** `currentLocale !== defaultLocale` 만으로 판단하면 - `--locale ko` (루트 평탄화)와 `--locale ko --locale ja` (루트 static 부재) 두 경우에서 - 사이트를 깨뜨린다. 현재 스크립트는 구조적 로케일 감지 + 루트 사본 존재 확인 **두 가드**를 쓴다. - -## 커밋 - -``` -90f0be4 perf(blog): 태그/저자 목록을 압축 항목으로 전환 (로케일당 -38MB) -0d4571e Revert "blog: remove 5 near-universal tags to cut tag-page duplication" -b0d2ccc fix(blog-archive-slim): declare @docusaurus/utils dep, correct route-drift comment -4cb2f51 blog: remove 5 near-universal tags to cut tag-page duplication (되돌림) -8ba9b09 og-image.png를 1200x630 OG 규격으로 최적화 -8257ae7 perf(blog): archive 청크에서 미사용 포스트 content 제거 -``` diff --git a/docs/journals/2026-07-18-broken-images-and-plural-fixes_ko.md b/docs/journals/2026-07-18-broken-images-and-plural-fixes_ko.md deleted file mode 100644 index 220bf69f..00000000 --- a/docs/journals/2026-07-18-broken-images-and-plural-fixes_ko.md +++ /dev/null @@ -1,67 +0,0 @@ -# 2026-07-18 — 깨진 이미지 근본 원인 제거 + 로케일 복수형 번역 교정 - -2026-07-16 저널(빌드 크기 감축)의 미결 항목 중 ①깨진 이미지 37개, ②ko 태그 -페이지 H1 중복을 조사·수정했다. 둘 다 보고된 것보다 범위가 넓었다. - -## 1. 깨진 이미지 — 원인은 template.md의 가짜 카탈로그 - -실측: blog가 참조하는 고유 이미지 305개 중 **40개가 static/에 없음** -(저널의 37개와 집계 방식 차이). howto/tutorials/release-notes의 참조 -297개는 전부 정상 — 문제는 블로그에만 있었다. - -추적 결과 누락 40개의 출처는 두 갈래: - -- **36개 = `blog/template.md`의 이미지 카탈로그에 실린 가짜 항목.** - git 전 이력·라이브 배포본(www `support/`) 어디에도 존재한 적 없는 - 파일명들이다(`add-webdav-remote.png` 등 — 실제 파일은 - `add-webdav-remote-name.png`처럼 다른 이름). 템플릿 작성 시점에 - 추측으로 만들어진 목록으로 보인다. 봇이 글을 쓸 때 이 카탈로그에서 - 이미지를 고르므로, **여기 가짜가 있는 한 깨진 이미지는 계속 재생산된다.** -- **4개 = 발행 글 4편이 위 패턴대로 지어낸 tutorials 경로.** 이 중 실제 - ``로 노출된 것은 1편(2025-09-24 Storj 글, ×9로케일)뿐이고 나머지 - 3편은 HTML 주석(placeholder)이라 빌드에서 제거되어 화면 노출은 없었다. - -수정: - -- template.md에서 가짜 항목 36개(라벨+img 72줄) 제거 → 카탈로그 376개 - 참조 전부 실재 확인 -- 글 4편 × 9로케일(en+8)에서 깨진 img/placeholder 제거. Storj 글의 - 이미지는 **대체하지 않고 제거** — Storj용 실물 스크린샷이 없는 상태에서 - 다른 저장소(Box/Mega) 화면을 넣는 것은 오정보라서다. -- **재발 방지: `scripts/check-image-refs.mjs` 신설, `prebuild` 훅 연결.** - 전 콘텐츠(원문+8로케일)의 `/images|/icons|/img|/videos` 참조 실재 여부를 - 검사하고 누락 시 빌드를 실패시킨다. 외부 URL 예시 - (`https://cdn.example.com/videos/...`)는 룩비하인드로 제외. - 수동 실행: `npm run check:images`. - -## 2. 태그 페이지 제목 — ko만이 아니라 ja·id도 깨져 있었다 - -`Intl.PluralRules` 카테고리 수와 code.json 메시지의 `|` 분절 수를 8로케일 -전수 대조한 결과(Docusaurus `selectMessage` 로직 재현): - -| 로케일 | 증상 | 원인 | -|---|---|---| -| ko | ""가이드" 태그로 연결된 166개 게시물**개의 게시물**이 있습니다" | `{nPosts}`가 이미 "166개 게시물"인데 단위를 또 붙임 | -| ja | "タグの記事が166**件件**あります" | 동일 (件 중복) | -| id | 태그 166개 글이 "**Satu pos**(1개)"로, 모든 글 읽기 시간이 "**Satu menit**(1분)"으로 표시 | 인도네시아어는 복수형 카테고리가 `other` 1개뿐 → 2형 메시지에서 항상 첫 형(단수)이 선택됨. **5개 키 전부 해당** (post/readingTime/DocCard/SearchPage/nDocsTagged) | -| es·fr | 표면상 정상 | 카테고리 3형(one/many/other) vs 메시지 2형 — many는 100만 이상에서만 선택되어 실害 없음. 정합을 위해 3형으로 정렬 | -| de·zh-Hans·zh-Hant | 정상 | — | - -수정: i18n/{ko,ja,id,es,fr}/code.json 19줄. ja는 docs 태그 문구 -`{count}記事`→`{count}件の記事` 어색함도 함께 교정. - -규칙(런북 4장에 추가): 복수형 메시지의 `|` 분절 수는 로케일의 -`Intl.PluralRules` 카테고리 수와 일치시킬 것 — ko/ja/zh/id=1형, de=2형, -es/fr=3형. `{nPosts}`류 삽입값 뒤에 단위 반복 금지. - -## 검증 - -- `npm run check:images` → 고유 자산 420개 전부 실재, exit 0 -- 클린 재빌드(9로케일) exit 0 + ko/ja/id/es 태그 페이지 제목, - id 글 목록 읽기 시간 표기 확인 - -## 남은 것 (이번 범위 밖) - -- schema.org 마이크로데이터 복원(2026-07-16 저널 미결 ③) — - `BlogPostItemsCompact` 수정 사안이라 별도 진행 -- eject된 테마 파일 14개의 MIT 고지 부재 — 저장소 관행 논의 필요 diff --git a/docs/journals/2026-07-20-list-page-structured-data_ko.md b/docs/journals/2026-07-20-list-page-structured-data_ko.md deleted file mode 100644 index 0537f7cb..00000000 --- a/docs/journals/2026-07-20-list-page-structured-data_ko.md +++ /dev/null @@ -1,46 +0,0 @@ -# 2026-07-20 — 태그/저자 목록 페이지에 schema.org 구조화 데이터 추가 - -2026-07-16 저널 미결 항목 ③(schema.org 마이크로데이터 손실)의 해소. -착수 전 조사에서 **전제 두 가지가 사실과 달라** 기록해 둔다. - -## 조사에서 바로잡은 사실 - -1. **감축 작업이 마이크로데이터를 지운 것이 아니다.** Docusaurus는 3.5에서 - 마이크로데이터를 제거하고 JSON-LD로 전환했다. 3.7 업스트림 테마에는 - `itemProp`이 빵부스러기·수정일 표시 2곳뿐이며, `BlogPostItemContainer`는 - 평범한 `
    `이다. 즉 **태그/저자 페이지는 교체 전에도 구조화 - 데이터가 0건**이었고, 압축 렌더러가 잃게 한 것이 없다. -2. **/blog 목록의 JSON-LD는 살아 있다** (Blog + BlogPosting 10건, 10.9KB). - 앞선 세션 보고에서 "0건"이라 했던 것은 측정 명령 오류였다. 개별 글 - 페이지의 BlogPosting JSON-LD도 정상. - -따라서 이번 작업의 성격은 "복원"이 아니라 **"업스트림도 안 해주는 태그/저자 -목록 4,707페이지에 구조화 데이터를 처음 추가"**다. - -## 방식 선택 — 실측 비교 - -| 방식 | 페이지당 | 4,707페이지 합계 | 판단 | -|---|---|---|---| -| 업스트림 JSON-LD 재사용(`useBlogListPageStructuredData`) | 10.9KB | **+50MB** | 감축분(-421MB)의 12%를 되무름. 탈락 | -| 경량 JSON-LD(설명·이미지·키워드 제외) | ~2.5KB | +11.5MB | 제목·날짜를 HTML과 이중 보유 | -| **마이크로데이터를 기존 요소에 부착** | ~1.7KB | **+12MB(du 기준 858MB, +1.4%)** | 데이터 복제 없음. 2026-07-16 저널이 제안한 방식. 채택 | - -JSON-LD가 구글 권장 형식이긴 하나 마이크로데이터도 정식 지원 대상이고, -목록 페이지는 검색 유입의 보조 표면이라 엔티티 힌트로 충분하다고 판단. - -## 구현 - -`src/theme/BlogPostItemsCompact/index.js` 한 파일: -`
      `에 `Blog` 스코프, 각 `
    • `에 `blogPost`/`BlogPosting` 스코프, -기존 제목·링크·날짜·설명 요소에 `headline`/`url`/`datePublished`/`description` -속성 부착. 화면 변화 없음(속성만 추가). - -## 검증 (클린 재빌드, exit 0) - -- en/ko/ja 태그 페이지·페이지네이션 2페이지·저자 페이지 표본: 페이지당 - Blog 1 + BlogPosting 10 + headline/url/datePublished/description 각 10 ✔ -- `datetime` ISO 형식 유지 ✔ -- 격리: /blog 목록(JSON-LD 1) · /blog/archive(마이크로데이터 0) · 개별 글 - (JSON-LD 1) 모두 영향 없음 ✔ -- 크기 846→858MB(du), 파일 수 33,035 동일. 사전 견적(+5MB)보다 큰 것은 - du 블록(4KB) 반올림 영향 — 실 바이트 증가는 페이지당 ~1.7KB × 4,707 ≈ 8MB diff --git a/scripts/blog-i18n-batch.workflow.js b/scripts/blog-i18n-batch.workflow.js index 069c331e..81f338d2 100644 --- a/scripts/blog-i18n-batch.workflow.js +++ b/scripts/blog-i18n-batch.workflow.js @@ -15,7 +15,7 @@ // // 동작: posts × 8로케일 쌍마다 Sonnet 에이전트가 blog/ 원문을 읽어 번역하고 // i18n/{locale}/docusaurus-plugin-content-blog/ 에 직접 파일을 쓴다. -// 실행 후 반드시 I18N_RUNBOOK_ko.md 2장 ③의 검증 단계를 거칠 것. +// 실행 후 반드시 rcloneview-blog-automation/I18N_RUNBOOK_ko.md 2장 ③의 검증 단계를 거칠 것. export const meta = { name: 'blog-i18n-batch', diff --git a/scripts/check-provider-support.mjs b/scripts/check-provider-support.mjs index 0dea1118..2c007d42 100644 --- a/scripts/check-provider-support.mjs +++ b/scripts/check-provider-support.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node // 블로그가 rclone/RcloneView 가 지원하지 않는 스토리지 서비스를 다루거나 -// 언급하지 않는지 검사한다. 지원 목록의 근거는 RCLONEVIEW_FEATURE_SPEC.md +// 언급하지 않는지 검사한다. 지원 목록의 근거는 bdrive/rcloneview-blog-automation 의 RCLONEVIEW_FEATURE_SPEC.md // Section 10 (BLOG_FACTCHECK_GUIDELINE.md Section 1.7 참조). // // 재발 방지 장치: 블로그 봇이 rclone 백엔드가 없는 TeraBox 를 "provider @@ -61,7 +61,7 @@ if (hits.length === 0) { process.exit(0); } -console.error(`✘ 미지원 스토리지 서비스 언급 ${hits.length}건 — 블로그는 Feature Spec Section 10 의 서비스만 다룰 수 있다 (BLOG_FACTCHECK_GUIDELINE.md §1.7)`); +console.error(`✘ 미지원 스토리지 서비스 언급 ${hits.length}건 — 블로그는 Feature Spec Section 10 의 서비스만 다룰 수 있다 (rcloneview-blog-automation/BLOG_FACTCHECK_GUIDELINE.md §1.7)`); for (const h of hits) { console.error(` ${h.file}:${h.line} [${h.service}] ${h.text}`); } diff --git a/scripts/validate_i18n.py b/scripts/validate_i18n.py index f1f01c4b..35b9b060 100644 --- a/scripts/validate_i18n.py +++ b/scripts/validate_i18n.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """i18n 번역본 구조/YAML 검증 + 알려진 아티팩트 자동 교정. -번역 배치 후 검증 파이프라인의 1+2단계 (I18N_RUNBOOK_ko.md 참고): +번역 배치 후 검증 파이프라인의 1+2단계 (rcloneview-blog-automation/I18N_RUNBOOK_ko.md 참고): .venv/bin/python scripts/validate_i18n.py # "문제 0건"이어야 통과 이후 3단계 `node scripts/mdx_check.mjs`, 4단계 전체 빌드로 이어진다. diff --git a/specs/2026-07-28-support-www-sync-design.md b/specs/2026-07-28-support-www-sync-design.md deleted file mode 100644 index c1516140..00000000 --- a/specs/2026-07-28-support-www-sync-design.md +++ /dev/null @@ -1,418 +0,0 @@ -# support 빌드 산출물 → rcloneview_www 자동 동기화 설계 - -- 작성일: 2026-07-28 -- 대상 저장소: `bdrive/rcloneview-support` (워크플로 위치), `bdrive/rcloneview_www` (반영 대상) -- 상태: 설계 확정, 구현 대기 - -## 1. 배경 - -`rcloneview-support`는 Docusaurus 소스 저장소이고(`baseUrl: /support/`), 그 빌드 산출물이 -`rcloneview_www/support/`에 통째로 커밋되어 Cloudflare Pages로 서빙된다. - -현재 이 반영은 **전부 수동**이다. `BLOG_FACTCHECK_PROMPT.md` STEP 5~6.5에 적힌 대로 -사람(또는 Claude 루틴)이 로컬에서 빌드하고, `rm -rf` + `cp -a`로 www 체크아웃을 덮어쓰고, -브랜치를 만들어 PR을 올린다. - -GitHub Actions는 두 저장소 어디에도 없다. 과거 `rcloneview-support`에 -`.github/workflows/deploy.yml`("Deploy support to R2")이 있었으나 R2 대상이었고, -2026-07-18 단 1회 실행 후 워크플로 파일 오류로 실패했으며(`if:` 에 `secrets` 컨텍스트 사용 — -해당 컨텍스트는 `if` 표현식에서 허용되지 않는다), 커밋 `89061fb`에서 킷 전체가 제거되었다. -팀 결정(2026-07-17)은 "기존 Pages 방식 유지"였다. - -### 현재 실측치 - -| 항목 | 값 | -|---|---| -| 빌드 산출물 | 880MB / 33,609 파일 (postbuild 프룬 후) | -| 프룬 전 중간 산출물 | 약 1.4GB (`prune-locale-static.mjs`가 539MB 제거) | -| 로컬 빌드 시간 | 약 14분 (9로케일 풀빌드 9회) | -| `node_modules` | 6.7GB | -| www 저장소 크기 | GitHub 기준 1.56GB / 로컬 `.git` 1.77GiB | -| 배포 커밋 1건 diff | 약 16,000~18,500 파일 | -| 배포 커밋 1건 영구 증가분 | **약 40MB** (신규 blob 약 16,000개) | -| www main 브랜치 보호 | 없음 | -| bdrive 조직 플랜 | Free (private 저장소 Actions 월 2,000분) | - -## 2. 목표 / 비목표 - -**목표** - -- `rcloneview-support` main이 갱신되면 자동으로 9로케일 빌드를 수행한다. -- 그 결과로 `rcloneview_www/support/`를 통째로 교체하는 PR을 자동 생성/갱신한다. -- 머지 전에 빌드가 깨지지 않도록 support PR에서 빌드를 검증한다. -- 실패를 사람이 놓치지 않게 알린다. -- 자동화와 중복되는 기존 수동 루틴 단계를 문서에서 제거한다. - -**비목표** - -- www main 자동 머지 (사람이 머지 버튼을 누른다). -- 빌드 산출물을 git 밖으로 빼는 배포 방식 전환 (10장에 별건으로 기록). -- `yarn.lock` / `package-lock.json` 이중 lockfile 정리 (11장에 기록만). - -## 3. 확정된 결정 - -| 결정 | 선택 | 이유 | -|---|---|---| -| 워크플로 위치 | `rcloneview-support` (public) | public 저장소는 Actions 무제한 무료. www는 private + 조직 Free 플랜이라 월 2,000분 한도이고 빌드 1회 25분이면 80회에 소진된다 | -| 반영 방식 | PR 자동 생성, 사람이 머지 | 프로덕션에 사람 게이트 유지 | -| 트리거 | main push마다 (경로 필터 없음) | 저장소 용량 증가는 push가 아니라 **머지** 횟수에 비례하므로(10장), push마다 빌드해도 용량 비용이 없다 | -| 브랜치/PR | 단일 브랜치 `deploy/support` 재사용 | 열린 PR이 항상 0개 또는 1개, 내용은 항상 최신 | -| 인증 | GitHub App 설치 토큰 | 만료 관리 불필요, 개인 퇴사와 무관, 커밋 작성자가 봇으로 남음 | -| 커밋 생성 방식 | raw git + `gh` CLI | 33,609파일 규모에서 동작이 예측 가능하고 "main 기준 리셋"을 직접 제어할 수 있다. `peter-evans/create-pull-request`는 그 제어가 어려워 제외 | - -## 4. 아키텍처 - -파일 **1개**, 잡 **1개**로 구성한다. - -``` -.github/workflows/deploy-www.yml -``` - -잡을 build/deploy로 나누면 880MB · 33,609파일을 아티팩트로 넘겨야 하는데, -그 업로드만 수 분이 걸리고 스토리지도 소모한다. 한 잡 안에서 빌드 직후 바로 복사한다. -PR 이벤트에서는 배포 스텝만 건너뛴다. - -```yaml -on: - push: - branches: [main] # 빌드 + www PR - pull_request: - branches: [main] # 빌드 검증만 - workflow_dispatch: # 수동 재실행 - -concurrency: - # 이벤트별로 그룹을 가른다 (아래 설명) - group: deploy-support-${{ github.event_name == 'pull_request' && github.head_ref || 'main' }} - cancel-in-progress: true # 최신 main 상태만 의미가 있으므로 이전 실행은 취소 - -permissions: - contents: read - issues: write # 실패 이슈/코멘트용 (support 저장소 내부) -``` - -`cancel-in-progress: true`가 안전한 이유: www로의 반영은 마지막 단계의 단일 ref -force-push 한 번뿐이고 git의 ref 갱신은 원자적이다. 중간에 취소되면 아무것도 반영되지 않는다. - -**그룹을 이벤트별로 가르는 이유:** 그룹 이름이 상수면 트리거 종류와 무관하게 모든 실행이 -같은 그룹에 들어간다. 그러면 배포가 도는 25~40분 사이에 누가 PR을 하나 열기만 해도 -진행 중인 프로덕션 배포가 취소된다. 게다가 취소는 `failure()`가 아니라서 -`if: failure()`로 걸어 둔 실패 알림 스텝이 돌지 않는다. www PR도 없고 이슈도 없는 채로 -히스토리만 초록에 가깝게 남아 아무도 눈치채지 못한다. - -push끼리의 취소는 그대로 유지해야 한다(더 새 빌드가 이전 빌드를 대체하는 것이 맞다). -그래서 `pull_request`일 때만 `github.head_ref`로 그룹을 갈라 PR 실행이 자기들끼리만 -취소하게 하고, push와 `workflow_dispatch`는 `main` 그룹을 공유하게 둔다. - -## 5. 실행 순서 - -``` -[모든 이벤트 공통] -1. support 체크아웃 (fetch-depth: 1) -2. setup-node 20 + npm ci -3. npm run build # prebuild 이미지검사 → 빌드 → postbuild 프룬 -4. rm -rf node_modules # 6.7GB 회수 (11장 디스크 항목) - -[push / workflow_dispatch 에서만] -5. GitHub App 토큰 발급 -6. www 체크아웃 (fetch-depth: 1, path: www) -7. deploy/support 브랜치를 www main HEAD에서 새로 생성 -8. rm -rf www/support && cp -a build www/support -9. git add -A -f support → 파일 수 불변식 검증 → commit → force-push -10. 열린 PR 있으면 본문 갱신, 없으면 생성 - -[실패 시] -11. deploy-failure 라벨의 열린 이슈에 코멘트, 없으면 이슈 생성 -``` - -### 스텝 정의 - -```yaml -jobs: - build-and-sync: - runs-on: ubuntu-latest - timeout-minutes: 90 - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: npm - - - run: npm ci --prefer-offline --no-audit --fund=false - - - name: Build (9 locales) - env: - NODE_OPTIONS: --max-old-space-size=6144 - run: npm run build - - - name: Free disk - run: rm -rf node_modules - - - id: app-token - if: github.event_name != 'pull_request' - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: bdrive - repositories: rcloneview_www - - - name: Checkout www - if: github.event_name != 'pull_request' - uses: actions/checkout@v4 - with: - repository: bdrive/rcloneview_www - ref: main - token: ${{ steps.app-token.outputs.token }} - path: www - fetch-depth: 1 - - - name: Replace support/ and push - if: github.event_name != 'pull_request' - working-directory: www - env: - APP_SLUG: ${{ steps.app-token.outputs.app-slug }} - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - # 봇 아이덴티티는 앱 슬러그에서 유도한다 (하드코딩 없음) - UID_BOT=$(gh api "/users/${APP_SLUG}[bot]" --jq .id) - git config user.name "${APP_SLUG}[bot]" - git config user.email "${UID_BOT}+${APP_SLUG}[bot]@users.noreply.github.com" - - git switch -C deploy/support # 체크아웃 HEAD == www main - - rm -rf support - cp -a ../build support - git add -A -f support # -f: www .gitignore 우회 (6장) - - built=$(find ../build -type f | wc -l) - staged=$(git ls-files support | wc -l) - if [ "$built" != "$staged" ]; then - echo "::error::파일 수 불일치 — build=$built support=$staged" - exit 1 - fi - - if git diff --cached --quiet; then - echo "변경 없음 — 푸시 생략" - echo "changed=false" >> "$GITHUB_ENV" - exit 0 - fi - echo "changed=true" >> "$GITHUB_ENV" - - git commit -m "deploy(support): ${GITHUB_SHA::9} 빌드 산출물 동기화" - git push --force origin deploy/support - - - name: Create or update PR - if: github.event_name != 'pull_request' && env.changed == 'true' - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - # 주의: heredoc 본문에 선행 공백이 있으면 마크다운이 코드블록으로 렌더된다. - # 실제 YAML에서는 들여쓰기 없이 작성할 것. - cat > body.md < **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** `rcloneview-support` main이 갱신되면 GitHub Actions가 9로케일 빌드를 수행하고, 그 산출물로 `rcloneview_www/support/`를 통째로 교체하는 PR을 자동 생성·갱신한다. - -**Architecture:** 워크플로는 public 저장소인 `rcloneview-support`에 둔다(Actions 무료). 위험한 파일 교체·검증 로직은 `scripts/sync-www-support.mjs`로 분리해 `node --test`로 로컬 검증하고, YAML은 그 스크립트를 호출하는 얇은 껍데기로 유지한다. www 접근은 bdrive 조직 GitHub App 설치 토큰으로 한다. - -**Tech Stack:** GitHub Actions, Node 20(러너) / Node 20+ ESM 스크립트, `node --test`(내장), js-yaml(워크플로 구조 테스트), `gh` CLI(러너 기본 제공), Docusaurus 3. - -설계 근거는 `specs/2026-07-28-support-www-sync-design.md`에 있다. 이 계획은 그 스펙의 구현 단계다. - -## Global Constraints - -- 작업 저장소: `/Users/ysh/work/rcloneview-support`, 브랜치 `feat/deploy-www-automation` (스펙 커밋 `c1abbb2`가 이미 올라가 있다) -- 커밋 메시지는 한글로 쓴다. `Co-Authored-By` 줄은 넣지 않는다. -- 러너 Node 버전은 **20**으로 고정한다(`package.json`의 `engines.node`는 `>=18`). Node 21 이상에서만 되는 API(`import.meta.dirname` 등)를 쓰지 않는다. -- 테스트 러너는 Node 내장 `node --test`다. 새 테스트 프레임워크를 추가하지 않는다. -- 새 런타임 의존성을 추가하지 않는다. 워크플로 구조 테스트용 `js-yaml`만 `devDependencies`에 명시한다 — 이미 Docusaurus의 전이 의존으로 `node_modules/js-yaml` 4.1.0이 설치되어 있어 추가 다운로드가 없다. -- **`secrets` 컨텍스트를 `if:` 표현식에 절대 쓰지 않는다.** 2026-07-18의 구 `deploy.yml`이 이것 때문에 잡 생성 단계에서 실패했다. -- 반영 대상: `bdrive/rcloneview_www`, base `main`, head `deploy/support` -- 시크릿 이름: `APP_ID`, `APP_PRIVATE_KEY` -- 불변식: `build/`의 파일 수 == 커밋 후 `git ls-files support`의 줄 수 -- **Docusaurus 콘텐츠 경로에 파일을 만들지 않는다** — `blog/`, `docs/`, `howto/`, `tutorials/`, `release-notes/`, `i18n/`, `src/`, `static/`에 넣은 파일은 사이트에 발행된다. 이 계획의 산출물은 `scripts/`, `.github/`, `specs/`, 저장소 루트에만 놓는다. - ---- - -## File Structure - -| 파일 | 책임 | -|---|---| -| `scripts/sync-www-support.mjs` (신규) | 빌드 산출물로 www 체크아웃의 `support/`를 교체하고, 파일 수 불변식을 검증하고, 변경이 있으면 커밋한다. push와 PR 생성은 하지 않는다(네트워크·자격증명이 필요해 테스트 불가). | -| `scripts/sync-www-support.test.mjs` (신규) | 위 스크립트의 단위 테스트. 임시 git 저장소를 만들어 실제 git 명령으로 검증한다. | -| `scripts/deploy-workflow.test.mjs` (신규) | 워크플로 YAML의 구조 단언. 트리거·동시성·스텝 가드, 그리고 `secrets`-in-`if` 회귀 방지. | -| `.github/workflows/deploy-www.yml` (신규) | 트리거, 빌드, www 체크아웃, 동기화 스크립트 호출, push, PR 생성/갱신, 실패 알림. | -| `.github/workflows/README.md` (신규) | GitHub App 생성·설치·시크릿 등록 절차와 롤백 방법. | -| `package.json` (수정) | `scripts.test` 추가, `devDependencies.js-yaml` 추가. | -| `BLOG_FACTCHECK_PROMPT.md` (수정) | 자동화와 중복되는 수동 빌드·복사·www PR 단계 제거. | -| `SCHEDULE_FACTCHECKER_PROMPT.md` (수정) | 동일. | -| `I18N_RUNBOOK_ko.md` (수정) | 124행의 수동 rsync 설명을 자동화 설명으로 교체. | - ---- - -### Task 1: 파일 교체·스테이징 로직 - -**Files:** -- Create: `scripts/sync-www-support.mjs` -- Test: `scripts/sync-www-support.test.mjs` -- Modify: `package.json` (scripts.test 추가) - -**Interfaces:** -- Consumes: 없음 (첫 태스크) -- Produces: `stageBuild({ buildDir, repoDir, branch })` — `repoDir`에서 `branch`를 www main HEAD 기준으로 새로 만들고(`git switch -C`), `repoDir/support`를 지운 뒤 `buildDir`를 그 자리에 복사하고, `git add -A -f support`까지 수행한다. 반환값 없음. Task 2가 이 함수를 감싼다. - -- [ ] **Step 1: `package.json`에 test 스크립트 추가** - -`scripts` 객체에서 `"docusaurus": "docusaurus",` 바로 위에 다음 줄을 넣는다. - -```json - "test": "node --test scripts/", -``` - -- [ ] **Step 2: 실패하는 테스트 작성** - -`scripts/sync-www-support.test.mjs`를 만든다. - -```js -// sync-www-support.mjs 단위 테스트. -// 임시 git 저장소에 www 체크아웃을 흉내 내고 실제 git 명령으로 결과를 확인한다. -import { test } from 'node:test'; -import assert from 'node:assert/strict'; -import fs from 'node:fs'; -import os from 'node:os'; -import path from 'node:path'; -import { execFileSync } from 'node:child_process'; - -import { stageBuild } from './sync-www-support.mjs'; - -function tmpdir() { - return fs.mkdtempSync(path.join(os.tmpdir(), 'sync-www-')); -} - -// { '상대경로': '내용' } 모양으로 빌드 산출물을 만든다 -function makeBuild(files) { - const dir = path.join(tmpdir(), 'build'); - for (const [rel, content] of Object.entries(files)) { - const p = path.join(dir, rel); - fs.mkdirSync(path.dirname(p), { recursive: true }); - fs.writeFileSync(p, content); - } - return dir; -} - -// support/ 가 이미 커밋되어 있는 www 체크아웃을 흉내 낸다 -function makeRepo({ gitignore = '', support = {} } = {}) { - const dir = path.join(tmpdir(), 'www'); - fs.mkdirSync(dir, { recursive: true }); - const g = (...args) => execFileSync('git', ['-C', dir, ...args], { encoding: 'utf8' }); - g('init', '-q', '-b', 'main'); - g('config', 'user.email', 'test@example.com'); - g('config', 'user.name', 'Test'); - fs.writeFileSync(path.join(dir, '.gitignore'), gitignore); - for (const [rel, content] of Object.entries(support)) { - const p = path.join(dir, 'support', rel); - fs.mkdirSync(path.dirname(p), { recursive: true }); - fs.writeFileSync(p, content); - } - g('add', '-A'); - g('commit', '-q', '-m', 'init'); - return dir; -} - -function tracked(repo) { - return execFileSync('git', ['-C', repo, 'ls-files', 'support'], { encoding: 'utf8' }) - .split('\n') - .filter(Boolean) - .sort(); -} - -test('빌드 산출물이 support/ 로 그대로 복사된다', () => { - const build = makeBuild({ 'index.html': 'A', 'ko/index.html': 'B' }); - const repo = makeRepo(); - - stageBuild({ buildDir: build, repoDir: repo, branch: 'deploy/support' }); - - assert.deepEqual(tracked(repo), ['support/index.html', 'support/ko/index.html']); - assert.equal(fs.readFileSync(path.join(repo, 'support/ko/index.html'), 'utf8'), 'B'); -}); - -test('브랜치가 새로 만들어진다', () => { - const build = makeBuild({ 'index.html': 'A' }); - const repo = makeRepo(); - - stageBuild({ buildDir: build, repoDir: repo, branch: 'deploy/support' }); - - const branch = execFileSync('git', ['-C', repo, 'branch', '--show-current'], { - encoding: 'utf8', - }).trim(); - assert.equal(branch, 'deploy/support'); -}); - -test('이전 support/ 에만 있던 파일은 사라진다', () => { - const build = makeBuild({ 'index.html': 'new' }); - const repo = makeRepo({ support: { 'index.html': 'old', 'gone.html': 'old' } }); - - stageBuild({ buildDir: build, repoDir: repo, branch: 'deploy/support' }); - - assert.deepEqual(tracked(repo), ['support/index.html']); - assert.equal(fs.existsSync(path.join(repo, 'support/gone.html')), false); -}); - -test('.gitignore 패턴에 걸리는 파일도 전부 스테이징된다', () => { - // www 의 실제 .gitignore 에는 dist/ build/ *.log 가 들어 있다 - const build = makeBuild({ - 'index.html': 'A', - 'docs/build/x.html': 'B', // build/ 패턴 - 'dist/y.html': 'C', // dist/ 패턴 - 'debug.log': 'D', // *.log 패턴 - }); - const repo = makeRepo({ gitignore: 'node_modules/\ndist/\nbuild/\n*.log\n' }); - - stageBuild({ buildDir: build, repoDir: repo, branch: 'deploy/support' }); - - assert.deepEqual(tracked(repo), [ - 'support/debug.log', - 'support/dist/y.html', - 'support/docs/build/x.html', - 'support/index.html', - ]); -}); -``` - -- [ ] **Step 3: 테스트 실행해 실패 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: FAIL — `Cannot find module '.../scripts/sync-www-support.mjs'` - -- [ ] **Step 4: 최소 구현 작성** - -`scripts/sync-www-support.mjs`를 만든다. - -```js -#!/usr/bin/env node -// 빌드 산출물(build/)로 www 체크아웃의 support/ 를 통째로 교체한다. -// -// push 와 PR 생성은 워크플로가 맡는다 — 자격증명과 네트워크가 필요해 -// 로컬에서 테스트할 수 없기 때문이다. 이 파일은 테스트 가능한 부분만 담는다. -import fs from 'node:fs'; -import path from 'node:path'; -import { execFileSync } from 'node:child_process'; - -export function git(repoDir, args) { - return execFileSync('git', ['-C', repoDir, ...args], { encoding: 'utf8' }); -} - -// 브랜치를 현재 HEAD(= www main) 기준으로 새로 만들고 support/ 를 교체한다. -// -C 는 같은 이름의 브랜치가 이미 있어도 덮어쓴다. -export function stageBuild({ buildDir, repoDir, branch }) { - if (!fs.existsSync(buildDir)) { - throw new Error(`빌드 디렉터리가 없다: ${buildDir}`); - } - - git(repoDir, ['switch', '-C', branch]); - - const dest = path.join(repoDir, 'support'); - fs.rmSync(dest, { recursive: true, force: true }); - // cp -a 로 권한·타임스탬프를 보존한다. 기존 수동 절차와 동일한 명령이다. - execFileSync('cp', ['-a', buildDir, dest]); - - // -f 는 www 의 .gitignore(dist/ build/ *.log)를 우회한다. - // 이게 없으면 산출물 일부가 말없이 빠진다. - git(repoDir, ['add', '-A', '-f', 'support']); -} -``` - -- [ ] **Step 5: 테스트 통과 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: PASS — 4개 테스트 모두 통과 - -- [ ] **Step 6: 커밋** - -```bash -cd /Users/ysh/work/rcloneview-support -git add package.json scripts/sync-www-support.mjs scripts/sync-www-support.test.mjs -git commit -m "feat(sync): 빌드 산출물로 www support/ 교체하는 로직 추가 - -- .gitignore 우회(-f)와 삭제 반영(rm -rf 후 cp -a)을 단위 테스트로 고정 -- node --test 를 npm test 로 연결" -``` - ---- - -### Task 2: 불변식 검증·커밋·CLI - -**Files:** -- Modify: `scripts/sync-www-support.mjs` -- Modify: `scripts/sync-www-support.test.mjs` - -**Interfaces:** -- Consumes: Task 1의 `stageBuild({ buildDir, repoDir, branch })` -- Produces: - - `countFiles(dir): number` — 디렉터리 아래 파일 개수(재귀) - - `countStaged(repoDir): number` — `git ls-files support`의 줄 수 - - `verifyCounts(buildDir, repoDir): number` — 두 개수가 같으면 그 값을 돌려주고, 다르면 `파일 수 불일치 — build=N support=M` 메시지로 예외를 던진다. - - `sync({ buildDir, repoDir, branch, message }): { changed: boolean, count: number }` — stageBuild → verifyCounts → (변경이 있으면) 커밋. - - CLI: `node scripts/sync-www-support.mjs --build --repo --branch --message ` — `GITHUB_OUTPUT`에 `changed`와 `count`를 기록한다. 워크플로의 `steps.sync.outputs.changed` / `.count`가 여기서 나온다. - -- [ ] **Step 1: 실패하는 테스트 추가** - -`scripts/sync-www-support.test.mjs`의 import 줄을 다음으로 바꾼다. - -```js -import { stageBuild, sync, verifyCounts } from './sync-www-support.mjs'; -``` - -그리고 파일 끝에 다음 테스트를 덧붙인다. - -```js -test('파일 수가 일치하면 커밋하고 개수를 돌려준다', () => { - const build = makeBuild({ 'index.html': 'A', 'ko/index.html': 'B' }); - const repo = makeRepo(); - - const result = sync({ - buildDir: build, - repoDir: repo, - branch: 'deploy/support', - message: '테스트 커밋', - }); - - assert.equal(result.changed, true); - assert.equal(result.count, 2); - - const subject = execFileSync('git', ['-C', repo, 'log', '-1', '--format=%s'], { - encoding: 'utf8', - }).trim(); - assert.equal(subject, '테스트 커밋'); -}); - -test('파일 수가 맞으면 verifyCounts 가 개수를 돌려준다', () => { - const build = makeBuild({ 'index.html': 'A', 'ko/index.html': 'B' }); - const repo = makeRepo(); - - stageBuild({ buildDir: build, repoDir: repo, branch: 'deploy/support' }); - - assert.equal(verifyCounts(build, repo), 2); -}); - -test('파일 수가 어긋나면 verifyCounts 가 예외를 던진다', () => { - const build = makeBuild({ 'index.html': 'A', 'ko/index.html': 'B' }); - const repo = makeRepo(); - - // 스테이징까지 마친 뒤 인덱스에서 한 개를 빼 불일치를 만든다. - // 실제로는 .gitignore 나 중첩 .git 때문에 add 가 파일을 빠뜨릴 때 이 상태가 된다. - stageBuild({ buildDir: build, repoDir: repo, branch: 'deploy/support' }); - execFileSync('git', ['-C', repo, 'rm', '--cached', '-q', 'support/ko/index.html']); - - assert.throws(() => verifyCounts(build, repo), /파일 수 불일치 — build=2 support=1/); -}); - -test('변경이 없으면 changed=false 이고 커밋이 늘지 않는다', () => { - const build = makeBuild({ 'index.html': 'A' }); - const repo = makeRepo(); - - sync({ buildDir: build, repoDir: repo, branch: 'deploy/support', message: '1차' }); - const before = execFileSync('git', ['-C', repo, 'rev-list', '--count', 'HEAD'], { - encoding: 'utf8', - }).trim(); - - const result = sync({ buildDir: build, repoDir: repo, branch: 'deploy/support', message: '2차' }); - - const after = execFileSync('git', ['-C', repo, 'rev-list', '--count', 'HEAD'], { - encoding: 'utf8', - }).trim(); - assert.equal(result.changed, false); - assert.equal(after, before); -}); -``` - -- [ ] **Step 2: 테스트 실행해 실패 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: FAIL — `sync`, `countFiles`, `countStaged`가 export되지 않아 `SyntaxError: The requested module ... does not provide an export named 'sync'` - -- [ ] **Step 3: 구현 추가** - -`scripts/sync-www-support.mjs`의 `stageBuild` 아래에 다음을 덧붙인다. `import` 줄에 `fileURLToPath`를 추가한다. - -```js -import { fileURLToPath } from 'node:url'; -``` - -```js -// 재귀로 파일 개수를 센다. readdirSync 의 recursive 옵션은 Node 20.1+ 전용이라 -// 저장소의 다른 스크립트(check-image-refs.mjs)와 같은 수동 순회를 쓴다. -export function countFiles(dir) { - let n = 0; - for (const e of fs.readdirSync(dir, { withFileTypes: true })) { - const p = path.join(dir, e.name); - if (e.isDirectory()) n += countFiles(p); - else n += 1; - } - return n; -} - -export function countStaged(repoDir) { - return git(repoDir, ['ls-files', 'support']).split('\n').filter(Boolean).length; -} - -// support/ 가 build/ 의 정확한 사본인지 확인한다. -// www 의 .gitignore(dist/ build/ *.log)나 중첩 .git 때문에 add 가 파일을 -// 말없이 빠뜨리면 여기서 걸린다. -export function verifyCounts(buildDir, repoDir) { - const built = countFiles(buildDir); - const staged = countStaged(repoDir); - if (built !== staged) { - throw new Error(`파일 수 불일치 — build=${built} support=${staged}`); - } - return built; -} - -function hasStagedChanges(repoDir) { - try { - git(repoDir, ['diff', '--cached', '--quiet']); - return false; // 종료코드 0 = 차이 없음 - } catch { - return true; - } -} - -export function sync({ buildDir, repoDir, branch, message }) { - stageBuild({ buildDir, repoDir, branch }); - - const built = verifyCounts(buildDir, repoDir); - - if (!hasStagedChanges(repoDir)) { - return { changed: false, count: built }; - } - - git(repoDir, ['commit', '-m', message]); - return { changed: true, count: built }; -} - -function parseArgs(argv) { - const out = {}; - for (let i = 0; i < argv.length; i += 2) { - const key = argv[i].replace(/^--/, ''); - out[key] = argv[i + 1]; - } - return out; -} - -function main() { - const a = parseArgs(process.argv.slice(2)); - for (const k of ['build', 'repo', 'branch', 'message']) { - if (!a[k]) { - console.error(`::error::--${k} 인자가 없다`); - process.exit(1); - } - } - - let result; - try { - result = sync({ - buildDir: a.build, - repoDir: a.repo, - branch: a.branch, - message: a.message, - }); - } catch (err) { - console.error(`::error::${err.message}`); - process.exit(1); - } - - const line = `changed=${result.changed}\ncount=${result.count}\n`; - if (process.env.GITHUB_OUTPUT) { - fs.appendFileSync(process.env.GITHUB_OUTPUT, line); - } - process.stdout.write(line); -} - -if (process.argv[1] === fileURLToPath(import.meta.url)) { - main(); -} -``` - -- [ ] **Step 4: 테스트 통과 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: PASS — 8개 테스트 모두 통과 - -- [ ] **Step 5: 커밋** - -```bash -cd /Users/ysh/work/rcloneview-support -git add scripts/sync-www-support.mjs scripts/sync-www-support.test.mjs -git commit -m "feat(sync): 파일 수 불변식 검증과 커밋, CLI 진입점 추가 - -- build/ 파일 수와 git ls-files support 수가 어긋나면 실패시킨다 -- 변경이 없으면 커밋하지 않고 changed=false 를 GITHUB_OUTPUT 으로 넘긴다" -``` - ---- - -### Task 3: 워크플로 골격 + 빌드/검증 경로 - -**Files:** -- Create: `.github/workflows/deploy-www.yml` -- Create: `scripts/deploy-workflow.test.mjs` -- Modify: `package.json` (devDependencies에 js-yaml 추가) - -**Interfaces:** -- Consumes: Task 2의 `npm test` -- Produces: 워크플로 잡 `build-and-sync`. Task 4가 이 잡의 `steps` 배열 뒤에 배포 스텝을 덧붙인다. - -- [ ] **Step 1: `package.json`에 js-yaml 추가** - -`devDependencies` 객체에 다음 줄을 알파벳 순서에 맞게 넣는다. 이미 전이 의존으로 설치되어 있어 `npm install` 시 추가 다운로드가 없다. - -```json - "js-yaml": "^4.1.0", -``` - -넣은 뒤 lockfile을 갱신한다. - -```bash -cd /Users/ysh/work/rcloneview-support && npm install --package-lock-only -``` - -- [ ] **Step 2: 실패하는 워크플로 구조 테스트 작성** - -`scripts/deploy-workflow.test.mjs`를 만든다. - -```js -// deploy-www.yml 의 구조 단언. -// YAML 문법 오류나 가드 누락을 GitHub 에 올리기 전에 잡는다. -import { test } from 'node:test'; -import assert from 'node:assert/strict'; -import fs from 'node:fs'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import yaml from 'js-yaml'; - -// import.meta.dirname 은 Node 21.2+ 전용이라 쓰지 않는다 (러너는 Node 20) -const here = path.dirname(fileURLToPath(import.meta.url)); -const wfPath = path.join(here, '..', '.github', 'workflows', 'deploy-www.yml'); -const wf = yaml.load(fs.readFileSync(wfPath, 'utf8')); -const job = wf.jobs['build-and-sync']; - -test('트리거가 push(main), pull_request(main), workflow_dispatch 다', () => { - // js-yaml 4 는 YAML 1.2 core schema 라 on 키가 boolean 으로 바뀌지 않는다 - assert.deepEqual(wf.on.push.branches, ['main']); - assert.deepEqual(wf.on.pull_request.branches, ['main']); - assert.ok('workflow_dispatch' in wf.on); -}); - -test('동시성 그룹이 잡혀 있고 이전 실행을 취소한다', () => { - assert.equal(wf.concurrency.group, 'deploy-support'); - assert.equal(wf.concurrency['cancel-in-progress'], true); -}); - -test('어떤 if 표현식에도 secrets 컨텍스트를 쓰지 않는다', () => { - // 2026-07-18 의 구 deploy.yml 이 secrets 를 step if 에 써서 - // 잡 생성 단계에서 통째로 실패했다. 그 재발을 막는다. - const conditions = [wf.on.if, job.if, ...job.steps.map((s) => s.if)].filter(Boolean); - for (const c of conditions) { - assert.ok(!String(c).includes('secrets'), `if 에 secrets 사용: ${c}`); - } -}); - -test('빌드 경로 스텝에는 조건이 없다 — PR 에서도 검증돼야 한다', () => { - const unconditional = job.steps.filter((s) => !s.if); - const runs = unconditional.map((s) => s.run ?? s.uses).join('\n'); - assert.ok(runs.includes('npm ci'), 'npm ci 가 무조건 실행돼야 한다'); - assert.ok(runs.includes('npm test'), 'npm test 가 무조건 실행돼야 한다'); - assert.ok(runs.includes('npm run build'), 'npm run build 가 무조건 실행돼야 한다'); -}); - -test('단위 테스트가 빌드보다 먼저 돈다', () => { - const idx = (needle) => job.steps.findIndex((s) => (s.run ?? '').includes(needle)); - const testIdx = idx('npm test'); - const buildIdx = idx('npm run build'); - assert.notEqual(testIdx, -1, 'npm test 스텝이 있어야 한다'); - assert.notEqual(buildIdx, -1, 'npm run build 스텝이 있어야 한다'); - assert.ok(testIdx < buildIdx); -}); - -test('빌드가 실패하면 뒤 스텝으로 넘어가지 않는다', () => { - // continue-on-error 가 붙으면 빌드가 깨져도 배포 스텝이 이어진다 - for (const s of job.steps) { - assert.notEqual(s['continue-on-error'], true, `continue-on-error 사용: ${s.name ?? s.uses}`); - } -}); - -test('러너 Node 는 20 이고 타임아웃이 잡혀 있다', () => { - const setup = job.steps.find((s) => String(s.uses ?? '').startsWith('actions/setup-node')); - assert.equal(setup.with['node-version'], 20); - assert.ok(job['timeout-minutes'] >= 60); -}); -``` - -- [ ] **Step 3: 테스트 실행해 실패 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: FAIL — `ENOENT: no such file or directory, open '.../.github/workflows/deploy-www.yml'` - -- [ ] **Step 4: 워크플로 파일 생성 (빌드/검증 경로만)** - -`.github/workflows/deploy-www.yml`을 만든다. - -```yaml -# support 사이트 빌드 → rcloneview_www/support 동기화 PR 생성 -# -# 흐름: main push → 9로케일 빌드 → www 체크아웃 → support/ 통째 교체 -# → deploy/support 브랜치 force-push → PR 생성/갱신 → 사람이 머지 -# → Cloudflare Pages 가 www main 을 자동 배포 -# PR 이벤트에서는 빌드 검증만 하고 배포하지 않는다. -# -# 필요한 시크릿은 .github/workflows/README.md 참고. -# -# 주의: `secrets` 컨텍스트는 `if:` 표현식에서 쓸 수 없다. -# 2026-07-18 의 구 deploy.yml 이 이 때문에 잡 생성 단계에서 실패했다. - -name: Deploy support build to www - -on: - push: - branches: [main] - pull_request: - branches: [main] - workflow_dispatch: - -concurrency: - group: deploy-support - cancel-in-progress: true # 최신 main 상태만 의미가 있다 - -permissions: - contents: read - issues: write # 실패 알림용 (support 저장소 내부) - -jobs: - build-and-sync: - runs-on: ubuntu-latest - timeout-minutes: 90 - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: npm - - - name: Install dependencies - run: npm ci --prefer-offline --no-audit --fund=false - - - name: Unit tests - run: npm test - - - name: Build (9 locales) - env: - NODE_OPTIONS: --max-old-space-size=6144 - run: npm run build - - - name: Free disk space - # node_modules 가 6.7GB 다. www 체크아웃 전에 비워야 러너 디스크(약 14GB)가 버틴다. - run: rm -rf node_modules -``` - -- [ ] **Step 5: 테스트 통과 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: PASS — 15개 테스트 모두 통과 - -- [ ] **Step 6: 커밋** - -```bash -cd /Users/ysh/work/rcloneview-support -git add package.json package-lock.json .github/workflows/deploy-www.yml scripts/deploy-workflow.test.mjs -git commit -m "feat(ci): support 빌드 검증 워크플로 추가 - -- push(main)·PR·수동 트리거, 동시성 그룹으로 중복 실행 취소 -- 구조 테스트로 secrets-in-if 재발 방지 (2026-07-18 실패 원인)" -``` - ---- - -### Task 4: 배포 경로 - -**Files:** -- Modify: `.github/workflows/deploy-www.yml` -- Modify: `scripts/deploy-workflow.test.mjs` - -**Interfaces:** -- Consumes: Task 2의 CLI(`node scripts/sync-www-support.mjs --build --repo --branch --message`, 출력 `changed`/`count`), Task 3의 잡 `build-and-sync` -- Produces: 스텝 id `app-token`(출력 `token`, `app-slug`), 스텝 id `sync`(출력 `changed`, `count`). Task 5가 이 뒤에 알림 스텝을 붙인다. - -- [ ] **Step 1: 실패하는 테스트 추가** - -`scripts/deploy-workflow.test.mjs` 끝에 덧붙인다. - -```js -test('배포 스텝은 전부 pull_request 를 배제하는 가드를 갖는다', () => { - const tokenIdx = job.steps.findIndex((s) => s.id === 'app-token'); - assert.ok(tokenIdx > 0, 'app-token 스텝이 있어야 한다'); - - for (const s of job.steps.slice(tokenIdx)) { - assert.ok(s.if, `가드 없는 배포 스텝: ${s.name ?? s.uses}`); - assert.ok( - String(s.if).includes("github.event_name != 'pull_request'"), - `pull_request 가드 없음: ${s.name ?? s.uses}`, - ); - } -}); - -test('www 체크아웃이 얕은 클론이고 www/ 하위로 간다', () => { - const co = job.steps.find((s) => s.with?.repository === 'bdrive/rcloneview_www'); - assert.equal(co.with.path, 'www'); - assert.equal(co.with['fetch-depth'], 1); - assert.equal(co.with.ref, 'main'); -}); - -test('앱 토큰은 www 저장소 하나로만 범위가 좁혀져 있다', () => { - const t = job.steps.find((s) => s.id === 'app-token'); - assert.ok(String(t.uses).startsWith('actions/create-github-app-token@')); - assert.equal(t.with.owner, 'bdrive'); - assert.equal(t.with.repositories, 'rcloneview_www'); -}); - -test('push 와 PR 생성은 변경이 있을 때만 돈다', () => { - const gated = job.steps.filter((s) => - String(s.if ?? '').includes("steps.sync.outputs.changed == 'true'"), - ); - const bodies = gated.map((s) => s.run ?? '').join('\n'); - assert.equal(gated.length, 2, 'push 스텝과 PR 스텝 두 개여야 한다'); - assert.ok(bodies.includes('push --force origin deploy/support')); - assert.ok(bodies.includes('gh pr create')); - assert.ok(bodies.includes('gh pr edit')); -}); -``` - -- [ ] **Step 2: 테스트 실행해 실패 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: FAIL — `app-token 스텝이 있어야 한다` - -- [ ] **Step 3: 배포 스텝 추가** - -`.github/workflows/deploy-www.yml`의 `Free disk space` 스텝 뒤에 이어 붙인다. - -heredoc 본문은 다른 줄과 **같은 들여쓰기**로 쓴다. YAML 블록 스칼라는 공통 들여쓰기를 일괄 제거하므로, 그래야 본문이 0열에서 시작해 마크다운이 코드블록으로 렌더되지 않는다. - -```yaml - - name: Generate app token - id: app-token - if: github.event_name != 'pull_request' - uses: actions/create-github-app-token@v2 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: bdrive - repositories: rcloneview_www - - - name: Checkout www - if: github.event_name != 'pull_request' - uses: actions/checkout@v4 - with: - repository: bdrive/rcloneview_www - ref: main - token: ${{ steps.app-token.outputs.token }} - path: www - fetch-depth: 1 - - - name: Configure bot identity - if: github.event_name != 'pull_request' - env: - APP_SLUG: ${{ steps.app-token.outputs.app-slug }} - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - BOT_ID=$(gh api "/users/${APP_SLUG}[bot]" --jq .id) - git -C www config user.name "${APP_SLUG}[bot]" - git -C www config user.email "${BOT_ID}+${APP_SLUG}[bot]@users.noreply.github.com" - - - name: Sync support/ and commit - id: sync - if: github.event_name != 'pull_request' - run: | - node scripts/sync-www-support.mjs \ - --build build \ - --repo www \ - --branch deploy/support \ - --message "deploy(support): ${GITHUB_SHA:0:9} 빌드 산출물 동기화" - - - name: Push deploy branch - if: github.event_name != 'pull_request' && steps.sync.outputs.changed == 'true' - run: git -C www push --force origin deploy/support - - - name: Create or update PR - if: github.event_name != 'pull_request' && steps.sync.outputs.changed == 'true' - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - FILE_COUNT: ${{ steps.sync.outputs.count }} - run: | - cat > body.md < { - const notify = job.steps.find((s) => String(s.if ?? '').includes('failure()')); - assert.ok(notify, '실패 알림 스텝이 있어야 한다'); - assert.ok(String(notify.if).includes("github.event_name != 'pull_request'")); - assert.equal(notify.env.GH_TOKEN, '${{ github.token }}'); - assert.ok(notify.run.includes('gh issue create')); - assert.ok(notify.run.includes('gh issue comment'), '중복 이슈 대신 코멘트를 달아야 한다'); - assert.ok(notify.run.includes('gh label create'), '라벨이 없으면 issue create 가 실패한다'); -}); -``` - -- [ ] **Step 2: 테스트 실행해 실패 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: FAIL — `실패 알림 스텝이 있어야 한다` - -- [ ] **Step 3: 알림 스텝과 README 작성** - -`.github/workflows/deploy-www.yml` 맨 끝에 덧붙인다. - -```yaml - - name: Report failure - if: failure() && github.event_name != 'pull_request' - env: - GH_TOKEN: ${{ github.token }} - run: | - RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" - gh label create deploy-failure --force -c B60205 -d "support 배포 자동화 실패" - ISSUE=$(gh issue list -R "${GITHUB_REPOSITORY}" --label deploy-failure \ - --state open --json number --jq '.[0].number // empty') - if [ -z "$ISSUE" ]; then - gh issue create -R "${GITHUB_REPOSITORY}" --label deploy-failure \ - --title "support 배포 자동화 실패" \ - --body "커밋 ${GITHUB_SHA} 처리 중 실패했습니다. 실행 로그: ${RUN_URL}" - else - gh issue comment "$ISSUE" -R "${GITHUB_REPOSITORY}" \ - --body "커밋 ${GITHUB_SHA} 에서 다시 실패했습니다: ${RUN_URL}" - fi -``` - -`.github/workflows/README.md`를 만든다. - -````markdown -# 워크플로 설정 - -## deploy-www.yml — support 빌드 산출물을 rcloneview_www 로 동기화 - -`rcloneview-support` main 이 갱신되면 9로케일 빌드를 돌리고, 그 결과로 -`bdrive/rcloneview_www` 의 `support/` 를 통째로 교체하는 PR 을 만든다. -PR 을 사람이 머지하면 Cloudflare Pages 가 프로덕션에 배포한다. - -설계 배경은 `specs/2026-07-28-support-www-sync-design.md` 를 참고한다. - -## 최초 1회 설정 (사람이 수행) - -### 1. GitHub App 만들기 - -bdrive 조직 → Settings → Developer settings → GitHub Apps → **New GitHub App** - -- Homepage URL: 아무 값 (예: `https://rcloneview.com`) -- Webhook: **Active 체크 해제** -- Repository permissions: - - **Contents: Read and write** - - **Pull requests: Read and write** -- Where can this GitHub App be installed?: Only on this account - -### 2. 설치 - -만든 앱의 Install App → bdrive → **Only select repositories** → -**`rcloneview_www` 만** 선택해 설치한다. support 에는 설치하지 않는다. - -### 3. 시크릿 등록 - -앱 설정 화면에서 App ID 를 확인하고, Private keys → Generate a private key 로 -`.pem` 파일을 받는다. - -`rcloneview-support` → Settings → Secrets and variables → Actions → New repository secret - -| 이름 | 값 | -|---|---| -| `APP_ID` | 앱 설정 화면의 App ID (숫자) | -| `APP_PRIVATE_KEY` | 받은 `.pem` 파일의 내용 전체 (`-----BEGIN...` 줄 포함) | - -봇 커밋 아이덴티티는 워크플로가 앱 슬러그에서 유도하므로 따로 설정할 것이 없다. - -### 4. 확인 - -Actions 탭 → **Deploy support build to www** → Run workflow 로 수동 실행한 뒤, -`bdrive/rcloneview_www` 에 `deploy/support` 브랜치와 PR 이 생기는지 확인한다. - -## 왜 support(public) 에서 도는가 - -bdrive 조직은 Free 플랜이라 private 저장소의 Actions 는 월 2,000분 한도다. -빌드 1회가 25분 안팎이라 80회면 소진된다. public 저장소는 무제한 무료다. - -`push` 트리거는 포크 PR 에 시크릿을 넘기지 않으므로 support 가 public 이어도 -시크릿은 노출되지 않는다. 앱을 `rcloneview_www` 하나에만 설치해 영향 범위를 좁혔다. - -## 문제가 생기면 - -- 실패하면 support 저장소에 `deploy-failure` 라벨의 이슈가 열리고, 이후 실패는 - 같은 이슈에 코멘트로 쌓인다. -- 워크플로를 잠시 끄려면 Actions 탭 → 해당 워크플로 → ⋯ → Disable workflow -- 잘못 배포된 내용은 www 에서 해당 머지 커밋을 revert 하면 Pages 가 다시 배포한다. -- 앱 권한을 회수하려면 조직 설정에서 설치를 제거하거나 private key 를 폐기한다. - -## 알려진 제약 - -- `deploy/support` 브랜치에도 Cloudflare Pages 가 프리뷰 배포를 붙인다. - 배포 1사이클당 CF 빌드가 프리뷰 1회 + 프로덕션 1회로 총 2회 소모된다. -- 머지된 배포 1건마다 www 저장소가 약 40MB 커진다. 자세한 내용과 대응책은 - 설계 문서 10장에 있다. -```` - -- [ ] **Step 4: 테스트 통과 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: PASS — 20개 테스트 모두 통과 - -- [ ] **Step 5: 커밋** - -```bash -cd /Users/ysh/work/rcloneview-support -git add .github/workflows/deploy-www.yml .github/workflows/README.md scripts/deploy-workflow.test.mjs -git commit -m "feat(ci): 배포 실패 알림과 GitHub App 설정 문서 추가 - -- 실패 시 deploy-failure 라벨 이슈를 열고 재실패는 코멘트로 누적 -- 앱 생성·설치·시크릿 등록 절차와 롤백 방법을 저장소에 기록" -``` - ---- - -### Task 6: 기존 수동 루틴 문서 정리 - -**Files:** -- Modify: `BLOG_FACTCHECK_PROMPT.md` -- Modify: `SCHEDULE_FACTCHECKER_PROMPT.md` -- Modify: `I18N_RUNBOOK_ko.md` - -**Interfaces:** -- Consumes: Task 5까지 완성된 워크플로 -- Produces: 없음 - -정리하지 않으면 루틴과 Actions 가 **양쪽에서 www PR 을 만든다.** - -- [ ] **Step 1: `BLOG_FACTCHECK_PROMPT.md` 수정** - -여섯 군데를 고친다. - -(0) 6행의 저장소 목록 — 루틴이 더는 www 를 건드리지 않으므로 다음 줄을 - -``` -> **Repositories:** bdrive/rcloneview-support + bdrive/rcloneview_www (둘 다 등록) -``` - -다음으로 바꾼다. - -``` -> **Repositories:** bdrive/rcloneview-support -``` - -(1) STEP 0 의 sibling 디렉터리 확인(55~59행) — 항목 4 전체를 지운다. 지울 내용: - -``` -4. Verify rcloneview_www exists as a sibling directory: - - ls ../rcloneview_www/ - -If not found, report the directory structure (ls ../) and stop. -``` - -(2) STEP 5 의 미러링 문단(285~297행) — "Then mirror the fresh build into the www checkout's support/ folder" 로 시작해 `cp -a build ../rcloneview_www/support` 와 그 아래 괄호 설명까지를 다음으로 교체한다. - -``` -빌드가 통과하면 여기서 끝이다. www 반영은 자동이다 — -STEP 6 에서 support 브랜치를 push 하고 그 PR 이 main 에 머지되면, -.github/workflows/deploy-www.yml 이 같은 빌드를 다시 돌려 -rcloneview_www/support/ 를 교체하는 PR 을 자동으로 만든다. -이 단계의 빌드는 머지 전에 깨진 콘텐츠를 걸러내기 위한 검증이다. -``` - -(3) STEP 6 — 제목을 `STEP 6: DEPLOY — PUSH BOTH REPOSITORIES` 에서 `STEP 6: PUSH VERIFIED SOURCE` 로 바꾸고, `6-A. Push rcloneview_www (build output):` 블록(308~312행의 명령 포함)을 통째로 지운다. `6-B.` 는 `6.` 으로 번호를 바꾼다. - -(4) STEP 6.5 — `PR 2 — rcloneview_www (build output):` 블록 전체를 지운다. PR 1 본문의 `## Companion PR` 절도 지운다. "Create both PRs simultaneously." 를 "Create the PR." 로 바꾼다. - -(5) STEP 7 — 요약 목록에서 `- rcloneview_www: blog/deploy/{DATE} (build output)` 과 `- rcloneview_www: {PR URL}` 두 줄을 지우고, `- Action needed: "Merge both PRs to main"` 을 다음으로 바꾼다. - -``` -- Action needed: "Merge the support PR to main — www 반영은 Actions 가 자동으로 처리한다" -``` - -- [ ] **Step 2: `SCHEDULE_FACTCHECKER_PROMPT.md` 수정** - -세 군데를 고친다. - -(1) STEP 0 (25~29행) — 다음 블록을 지운다. - -``` -Also sync rcloneview_www (needed later for deployment): - cd ../rcloneview_www - git checkout main - git pull origin main - cd ../rcloneview-support -``` - -(2) STEP 5 (150~151행) — 구식 명령 두 줄을 - -``` - yarn install --frozen-lockfile - yarn build --out-dir ../rcloneview_www/support -``` - -다음으로 교체한다. `--out-dir` 형식은 postbuild 프룬을 건너뛰어 산출물이 부푼다. - -``` - npm ci - npm run build -``` - -(3) STEP 6 — 제목을 `STEP 6: PUSH SOURCE` 로 바꾸고 `6-A. Commit and push rcloneview_www (build output):` 블록(166~173행)을 지운다. `6-B.` 를 `6.` 으로 바꾼다. STEP 7 요약에서 ` - rcloneview_www: blog/deploy/{DATE}` 줄을 지우고 마지막 줄을 다음으로 바꾼다. - -``` -- Action needed: "Merge the support branch to main via GitHub PR — www 반영은 Actions 가 자동으로 처리한다" -``` - -- [ ] **Step 3: `I18N_RUNBOOK_ko.md` 수정** - -124행에서 다음 부분을 찾는다. - -``` -STEP 5 빌드는 `npm run build`(prebuild 이미지검사 + postbuild 프룬) 후 `rsync -a --delete build/ ../rcloneview_www/support/` 로 반영 — 구 `yarn build --out-dir`(프룬 no-op) 교체 완료. -``` - -다음으로 교체한다. - -``` -STEP 5 빌드는 `npm run build`(prebuild 이미지검사 + postbuild 프룬)로 검증만 한다 — www 반영은 `.github/workflows/deploy-www.yml` 이 main 머지 후 자동으로 처리한다(2026-07-28). -``` - -- [ ] **Step 4: 잔재가 없는지 확인** - -```bash -cd /Users/ysh/work/rcloneview-support -grep -n "rcloneview_www" BLOG_FACTCHECK_PROMPT.md SCHEDULE_FACTCHECKER_PROMPT.md I18N_RUNBOOK_ko.md -``` - -Expected: 세 파일 모두 결과 없음. 남아 있다면 그 줄이 수동 배포 지시인지 확인하고 마저 고친다. - -`LOCAL_TESTING_ko.md`(18·19·50행)와 `I18N_OVERVIEW_ko.md`(118행)에도 `rcloneview_www` 가 나오지만 각각 로컬 프리뷰 안내와 "별건: www 자체 다국어화" 언급이라 배포 지시가 아니다. **손대지 않는다.** - -- [ ] **Step 5: 테스트가 여전히 통과하는지 확인** - -```bash -cd /Users/ysh/work/rcloneview-support && npm test -``` - -Expected: PASS — 20개 테스트 모두 통과 (문서 수정이 워크플로에 영향을 주지 않았음을 확인) - -- [ ] **Step 6: 커밋** - -```bash -cd /Users/ysh/work/rcloneview-support -git add BLOG_FACTCHECK_PROMPT.md SCHEDULE_FACTCHECKER_PROMPT.md I18N_RUNBOOK_ko.md -git commit -m "docs(routine): 자동화와 중복되는 수동 www 배포 단계 제거 - -- 루틴은 support PR 하나만 만들고, www 반영은 Actions 가 처리한다 -- 구식 yarn build --out-dir 지시를 npm run build 로 교체" -``` - ---- - -### Task 7: 통합 검증 - -**Files:** 없음 (검증 전용) - -**Interfaces:** -- Consumes: Task 1~6 전체 -- Produces: 없음 - -이 태스크는 **사람이 GitHub App 을 설정해야** 진행할 수 있다. 앞 태스크와 달리 코드 변경이 없다. - -- [ ] **Step 1: 브랜치 push 하고 PR 을 연다** - -```bash -cd /Users/ysh/work/rcloneview-support -git push -u origin feat/deploy-www-automation -gh pr create -R bdrive/rcloneview-support --base main --head feat/deploy-www-automation \ - --title "feat(ci): support 빌드 산출물 www 자동 동기화" \ - --body "설계: specs/2026-07-28-support-www-sync-design.md -계획: specs/2026-07-28-support-www-sync-plan.md - -main 머지 전에 GitHub App 설정(.github/workflows/README.md)이 필요합니다." -``` - -- [ ] **Step 2: PR 검증 경로가 도는지 확인** - -이 PR 자체가 `pull_request` 트리거를 발동시킨다. - -```bash -RUN=$(gh run list -R bdrive/rcloneview-support --branch feat/deploy-www-automation \ - --workflow deploy-www.yml --limit 1 --json databaseId --jq '.[0].databaseId') -gh run view -R bdrive/rcloneview-support "$RUN" -``` - -Expected: `Install dependencies` → `Unit tests` → `Build (9 locales)` → `Free disk space` 까지만 실행되고, `Generate app token` 이하는 전부 skipped - -- [ ] **Step 3: 빌드 실패가 게이트로 작동하는지 확인** - -깨진 이미지 참조가 `prebuild`에서 걸리는지 확인한다. 워크플로의 `run: npm run build`는 종료 코드를 그대로 전파하고 `continue-on-error`가 없으므로(Task 3 테스트로 고정), 여기서 실패하면 배포 스텝에 도달하지 않는다. - -```bash -cd /Users/ysh/work/rcloneview-support -cat > blog/9999-01-01-temp-gate-check.md <<'EOF' ---- -title: 게이트 확인용 임시 글 -authors: [jay] ---- - -![없는 이미지](/images/this-file-does-not-exist-gate-check.png) -EOF -npm run build; echo "exit=$?" -rm blog/9999-01-01-temp-gate-check.md -``` - -Expected: `✘ static/ 에 없는 자산 참조` 메시지와 함께 `exit=1` - -- [ ] **Step 4: GitHub App 설정 (사람)** - -`.github/workflows/README.md` 의 "최초 1회 설정" 절차대로 앱을 만들고 `rcloneview_www` 에만 설치한 뒤 `APP_ID`, `APP_PRIVATE_KEY` 를 support 시크릿에 등록한다. - -- [ ] **Step 5: PR 을 머지하고 배포 경로를 확인** - -머지하면 `push` 트리거가 돈다. - -```bash -gh run list -R bdrive/rcloneview-support --branch main --limit 3 -gh pr list -R bdrive/rcloneview_www --head deploy/support -``` - -Expected: www 에 `deploy/support` 브랜치와 PR 1개 - -- [ ] **Step 6: PR 내용이 올바른지 확인** - -```bash -PR=$(gh pr list -R bdrive/rcloneview_www --head deploy/support --state open \ - --json number --jq '.[0].number') -echo "PR #$PR" -gh pr diff -R bdrive/rcloneview_www "$PR" --name-only | grep -cv '^support/' -``` - -Expected: `0` — `support/` 밖의 변경이 하나도 없어야 한다 - -```bash -gh pr view -R bdrive/rcloneview_www "$PR" --json body --jq .body -find /Users/ysh/work/rcloneview-support/build -type f | wc -l -``` - -Expected: 본문의 "support/ 파일 수" 가 아래 `find` 결과와 일치 - -- [ ] **Step 7: 재실행 시 PR 이 새로 생기지 않는지 확인** - -support 에서 workflow_dispatch 로 한 번 더 실행한다. - -```bash -gh workflow run "Deploy support build to www" -R bdrive/rcloneview-support -# 완료 후 -gh pr list -R bdrive/rcloneview_www --head deploy/support --state open \ - --json number,updatedAt -``` - -Expected: PR 이 여전히 1개이고 번호가 `$PR` 과 같으며 `updatedAt` 만 갱신됨 - -- [ ] **Step 8: 머지하고 프로덕션 확인** - -www 의 PR 을 머지한 뒤 Cloudflare Pages 프로덕션 배포가 성공하는지, `https://rcloneview.com/support/` 가 정상인지 확인한다. - ---- - -## 완료 조건 - -- `npm test` 20개 통과 -- support PR 에서 빌드 검증이 돌고 배포 스텝은 skip 된다 -- main 머지 시 www 에 `deploy/support` PR 이 자동 생성되고, diff 가 `support/` 로만 한정된다 -- 같은 브랜치 재실행 시 PR 이 갱신되고 새로 생기지 않는다 -- 루틴 문서에 수동 www 배포 지시가 남아 있지 않다 diff --git a/src/theme/BlogArchivePage/categories.js b/src/theme/BlogArchivePage/categories.js index 98d3a632..336bb3c8 100644 --- a/src/theme/BlogArchivePage/categories.js +++ b/src/theme/BlogArchivePage/categories.js @@ -1,7 +1,7 @@ /** * 블로그 아카이브 카테고리 분류 규칙. * - * 규칙 설계 근거와 갱신 방법: 저장소 루트의 BLOG_ARCHIVE_CATEGORIES.md 참조. + * 규칙 설계 근거와 갱신 방법: bdrive/rcloneview-blog-automation 의 BLOG_ARCHIVE_CATEGORIES.md 참조. * 판정 순서: ① 슬러그 동사 프리픽스 → ② 태그(우선순위순) → ③ 프로바이더 태그 * → ④ 폴백(platforms). 순서가 분포를 결정하므로 임의로 바꾸지 말 것. */