4 plans across 3 waves to expand from 7 to 17 rclone backends: - Plan 01 (W1): Registry refactoring, BackendType derivation, 10 new entries - Plan 02 (W2): OAuthInstructions, GdriveAuthToggle, BackendIcons components - Plan 03 (W2): BackendSelectionStep UX overhaul with categories, search, icons - Plan 04 (W3): RemoteConfigStep wiring for all new backends + visual verify Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
11 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13-add-remaining-rclone-remotes | 01 | execute | 1 |
|
true |
|
|
Purpose: This is the data foundation every other plan in Phase 13 depends on. No UI work can proceed until the registry has all backends, the types are derived, and schemas auto-generate. Output: Updated registry.ts, index.ts, types.ts, rclone-conf.ts with all 17 backends, full test coverage.
<execution_context> @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/13-add-remaining-rclone-remotes/13-CONTEXT.md @.planning/phases/13-add-remaining-rclone-remotes/13-RESEARCH.mdFrom src/schemas/registry.ts:
export type BackendType = 'azureblob' | 's3' | 's3-compatible' | 'onedrive' | 'sftp' | 'gcs' | 'b2';
export interface FieldDef {
key: string;
label: string;
inputType: 'text' | 'password' | 'select' | 'toggle';
required: boolean;
placeholder?: string;
helpText?: string;
options?: { value: string; label: string }[];
validate?: { regex: RegExp; message: string };
tooltipText?: string;
}
// Current cast at bottom (must be removed):
// } as Record<BackendType, { displayName: string; description: string; fields: FieldDef[] }>;
From src/schemas/index.ts:
export const BACKEND_SCHEMAS = {
azureblob: buildZodSchema('azureblob'),
// ... explicit per-backend calls
} as const;
From src/generators/rclone-conf.ts:
const RCLONE_TYPE_MAP: Record<string, string> = {
azureblob: 'azureblob',
s3: 's3',
's3-compatible': 's3',
onedrive: 'onedrive',
sftp: 'sftp',
gcs: 'google cloud storage',
b2: 'b2',
};
From src/store/types.ts:
import type { BackendType } from '../schemas/registry';
export type { BackendType };
-
Add
categoryfield to the backend entry shape. Update the interface used by entries to includecategory: BackendCategory. -
Remove the explicit
BackendTypeunion literal. Instead, addas constto the BACKEND_REGISTRY object and derive:export type BackendType = keyof typeof BACKEND_REGISTRY; -
CRITICAL: Remove the
as Record<BackendType, ...>cast at the bottom of the registry object. Withas const, TypeScript infers the precise type. The cast creates a circular reference when BackendType is derived from keyof. -
Add
categoryto all 7 existing entries:- azureblob: 'cloud-object-storage'
- s3: 'cloud-object-storage'
- s3-compatible: 'cloud-object-storage'
- gcs: 'cloud-object-storage'
- b2: 'cloud-object-storage'
- onedrive: 'cloud-drives'
- sftp: 'protocol-based'
-
Add 10 new backend entries (see 13-RESEARCH.md for field details):
Cloud Object Storage:
azure-files: displayName 'Azure Files', fields: account (text, required), key (password, required). Verify field names against rclone.org/azurefiles/ — account + key is the standard pattern.swift: displayName 'OpenStack Swift', fields: user (text, required), key (password, required), auth (text, required, placeholder 'https://auth.example.com/v3'), tenant (text, required), region (text, optional)
Cloud Drives (OAuth token-paste):
gdrive: displayName 'Google Drive', fields: token (password, required, helpText about rclone authorize "drive"), service_account_credentials (password, optional, helpText for service account JSON), root_folder_id (text, optional)dropbox: displayName 'Dropbox', fields: token (password, required, helpText about rclone authorize "dropbox")box: displayName 'Box', fields: token (password, required), box_sub_type (select: user/enterprise, default 'user')pcloud: displayName 'pCloud', fields: token (password, required), hostname (select: api.pcloud.com/eapi.pcloud.com with labels 'US (default)'/'EU')
Protocol-based:
ftp: displayName 'FTP', fields: host (text, required), user (text, optional, placeholder 'anonymous'), pass (password, optional), port (text, optional, placeholder '21'), explicit_tls (select: ''/true with labels 'Plain FTP'/'Explicit FTPS')webdav: displayName 'WebDAV', fields: url (text, required, placeholder 'https://example.com/dav'), user (text, required), pass (password, required), vendor (select: nextcloud/owncloud/sharepoint/sharepoint-ntlm/other)smb: displayName 'SMB / Windows Share', fields: host (text, required), user (text, required), pass (password, optional), domain (text, optional, placeholder 'WORKGROUP'), port (text, optional, placeholder '445')http: displayName 'HTTP (read-only)', fields: url (text, required, placeholder 'https://example.com/path/')seafile: displayName 'Seafile', fields: url (text, required, placeholder 'https://cloud.seafile.com'), user (text, required), pass (password, required)
-
Add appropriate helpText and tooltipText to new backend fields following existing patterns (see 13-RESEARCH.md pitfalls section for OAuth token fields).
-
Verify src/store/types.ts still works — it does
import type { BackendType } from '../schemas/registry'andexport type { BackendType }. No changes needed since the derived type exports identically.
IMPORTANT: Do NOT pass real placeholder text to fields that will be rendered by TextFieldMD3 — TextFieldMD3 uses placeholder=" " internally for floating labels. Use helpText instead for descriptive hints. Placeholders are only safe on fields NOT rendered via TextFieldMD3 (select fields, or fields where the placeholder is a format example like 'AKIAIOSFODNN7EXAMPLE').
npx vitest run src/schemas/registry.test.ts src/store/ --reporter=verbose 2>&1 | tail -30
BACKEND_REGISTRY has 17 entries each with displayName, description, category, and fields. BackendType is derived from keyof typeof BACKEND_REGISTRY. No circular type reference. TypeScript compiles cleanly.
-
In src/generators/rclone-conf.ts: Add entries to RCLONE_TYPE_MAP for all 10 new backends. Verified type strings from rclone docs:
- 'azure-files': 'azurefiles'
- 'swift': 'swift'
- 'gdrive': 'drive'
- 'dropbox': 'dropbox'
- 'box': 'box'
- 'pcloud': 'pcloud'
- 'ftp': 'ftp'
- 'webdav': 'webdav'
- 'smb': 'smb'
- 'http': 'http'
- 'seafile': 'seafile'
-
Update src/schemas/registry.test.ts:
- Add test: every backend has displayName, description, category, and at least one field
- Add test: BackendCategory values are one of the three valid categories
- Verify all 17 backend keys are present
-
Update/create src/schemas/index.test.ts:
- Test that BACKEND_SCHEMAS has an entry for every key in BACKEND_REGISTRY (no undefined)
- Test that each schema is a ZodObject (not undefined)
-
Update src/generators/rclone-conf.test.ts:
- Add test: RCLONE_TYPE_MAP has entry for every BackendType
- Add a buildRcloneConf snapshot test for at least 3 new backends (gdrive, ftp, smb) to confirm correct output format npx vitest run src/schemas/ src/generators/rclone-conf.test.ts --reporter=verbose 2>&1 | tail -40 BACKEND_SCHEMAS auto-generates for all 17 backends. RCLONE_TYPE_MAP covers all 17 backends. All tests pass including new coverage for auto-generation, type mapping, and rclone.conf output for new backends.
<success_criteria>
- 17 backends in BACKEND_REGISTRY with category field
- BackendType = keyof typeof BACKEND_REGISTRY (derived, not explicit)
- BACKEND_SCHEMAS auto-generated from registry keys
- RCLONE_TYPE_MAP has all 17 entries with verified rclone type strings
- All existing + new tests pass
- TypeScript compiles without errors </success_criteria>