Skip to content

Orca-style refactor phase 1: conventions, architecture & quality gates - #9

Merged
yandanp merged 35 commits into
mainfrom
refactor-project-like-orca-dev-https-github.com-stablyai-orca
Aug 15, 2026
Merged

yandanp merged 35 commits into
mainfrom
refactor-project-like-orca-dev-https-github.com-stablyai-orca

Conversation

@yandanp

@yandanp yandanp commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Orca-style Refactor — Phase 1: Conventions & Architecture

Refactors Connexio's codebase following Orca's engineering discipline: small focused files with concrete domain names, colocated tests, CI quality gates, and written conventions. No feature or behavior changes — the public window.connexio API shape is locked by tests.

What changed

Frontend: monolith → modular architecture

src/renderer/
├── core/                    # kernel (importable by all features)
│   ├── api/                 # 18 per-domain IPC wrappers (replaces tauri-api.ts)
│   │   └── api-shape.test.ts  # locks the window.connexio shape
│   ├── api-remote/ · hooks/ · stores/ · ui/
│   └── tauri-shim.ts
└── features/                # 12 self-contained slices
    ai · editor · explorer · git · notifications · projects
    remote · settings · ssh · tasks · terminal · workspace

Former giants split up: tauri-api.ts (857), SSHManagerPanel.tsx (1949), SourcePanel.tsx (1182), SettingsModal.tsx (944), Workspace.tsx, aiStore.ts, projectStore.ts, …

Rust: two biggest modules split

  • modules/ssh.rs (750) → ssh/ folder: types, storage, command_builder, trust, connection, sftp, secrets
  • modules/remote/server.rs (963) → state, commands, http, websocket, pty_bridge, wol, power, tailscale + thin orchestrator

Public paths & Tauri commands unchanged (lib.rs invoke_handler only repointed).

Quality gates (Orca-style, all in CI)

  • Pre-commit hooks (Husky): oxfmt + oxlint
  • max-lines ratchet: new files ≤ 400 lines; existing giants baselined (may only shrink) — covers frontend and Rust
  • feature boundary checker: slices cannot import each other; @tauri-apps/* confined to core/api*
  • CI workflow: typecheck, oxlint, vitest, ratchet, boundaries, cargo fmt/clippy/test

Tests (from zero)

  • 20 vitest tests: API shape, split-layout, git file grouping, SSH command builder, stores, notification sound validation
  • 12 cargo tests: characterization for ssh (command builder, trust) and remote (WOL parse_mac, PIN generator) + sound file validation

Bug fix included

  • Notification sound upload never worked (backend was a stub ignoring the selected path): now validates wav/mp3/ogg, copies into app data, persists the setting; custom playback switched from blocked file:// URLs to convertFileSrc + asset protocol (d5825c6)

Docs

  • AGENTS.md, docs/STYLEGUIDE.md, CODEOWNERS, README project structure rewritten

Success criteria (§11 design spec)

  • No file > 400 lines outside config/max-lines-baseline.txt (ratchet enforced, Rust included)
  • All §4 monolith targets split; features/ + core/ stand per §3; all three boundary rules pass CI
  • Full CI gate suite runs on every PR: typecheck, oxlint, vitest, cargo fmt/clippy, max-lines, feature-imports
  • Characterization tests green for every split pure module; cargo tests for ssh & remote
  • AGENTS.md and docs/STYLEGUIDE.md committed as review references
  • window.connexio shape unchanged (api-shape test); no feature/behavior changes — verified by manual smoke test

Known debt (documented, intentionally deferred)

  • workspace-store.ts (1026) and a handful of baselined files need dedicated split tasks with tests
  • SearchPanel is orphaned dead code (kept during composition; cleanup candidate)

yandanp added 11 commits August 6, 2026 13:23
Lint triage: disabled eslint/no-unused-vars in .oxlintrc.json — 23 pre-existing findings across 8 files (unused destructured hook values, '_e' catch parameters, unused imports); removing them is code cleanup outside this tooling task, to be re-enabled in a dedicated cleanup task. Fixed the single trivial no-unused-expressions finding (ternary used as statement in Terminal.tsx search key handler -> if/else), hence Terminal.tsx is included here.
@yandanp
yandanp force-pushed the refactor-project-like-orca-dev-https-github.com-stablyai-orca branch from 728b184 to 3cc72af Compare August 6, 2026 08:11
yandanp added 18 commits August 7, 2026 08:15
Also git-mv ssh.rs to ssh/mod.rs (pure rename, no content change) as
preparation for the submodule split in the next commit.
Convert src-tauri/src/modules/ssh.rs (902 lines) into a module folder:

- mod.rs: pub mod + pub use facade; all public paths
  (modules::ssh::<item>) unchanged, lib.rs untouched
- types.rs: SSHConnection, SSHAuthMethod, SSHIdentity, SSHSecretRef,
  SSHSecretProvider, SSHConnectionTestResult, SSHKnownHost,
  SSHHostTrustStatus, SFTPEntry, SSHTunnelConfig, SSHTunnelType
- storage.rs: data-dir path helpers, ssh_list/save (+global),
  known-hosts JSON load/save
- command_builder.rs: shell_quote, ssh_build_command(_args)
- trust.rs: host fingerprint/trust status, known-hosts commands,
  ssh_forget_openssh_host
- connection.rs: ssh_test_connection, ssh_connect_session (pub(crate))
- sftp.rs: all ssh_sftp_* commands
- secrets.rs: keychain ssh_secret_* commands + ssh_key_exists

Only visibility adjustments for cross-submodule use: known-hosts
load/save and fingerprint/trust-status helpers became pub(super).
No logic changes; verified verbatim against the original file.
Six inline tests in modules::ssh::command_builder locking current
behavior of the pure command-building logic:

- ssh_build_command_args: port flag + user@host target, default-port
  omission, exact arg order with key/keep-alive
- shell_quote: safe-char passthrough, platform-specific wrapping of
  unsafe input (double quotes on Windows, single quotes elsewhere)
- ssh_build_command: startup-command join skips blanks and trims

Characterization notes: expectations match the actual implementation
(e.g. the args builder passes the key path through unquoted, unlike
the string builder); shell_quote wrapping is platform-dependent, so
that assertion is cfg-gated. Verified RED via a temporary assertion
mutation (1 failure), then restored to GREEN.
Move CodeBlock/inlineMd/Markdown/MessageBubble (214 lines) into
features/ai/AIMessageBubble.tsx — pure presentation, props-only, no
logic change. AIChatPanel 746 -> 523 lines.
yandanp added 6 commits August 9, 2026 16:38
check-max-lines.mjs now also scans git-tracked src-tauri/src/**/*.rs
(previously filtered to src/ only, so Rust was outside the ratchet).
Baseline entries added for the three existing >400-line Rust files at
their actual sizes (ratchet may only go down):
  modules/notification.rs 667, modules/git.rs 612, modules/pty/manager.rs 523.
Verified FAIL->PASS: temporary 451-line probe file under src-tauri/src
failed the check, removing it restored PASS.
- projects-store.ts: merge duplicate '../workspace' import statements
- FileExplorer.tsx: drop redundant 'as FileEntry[]' cast in toggleExpand
  (explorer.listDir already returns Promise<FileEntry[]>)
No behavior change.
Ratchet only moves down. Tightened to actual sizes:
- CodeEditor.tsx 537 -> 533
- FileExplorer.tsx 926 -> 917
- AIChatPanel.tsx 750 -> 523 (after AIMessageBubble extraction)
No entries removed: all baselined files still exist.
README: rewrite 'Project Structure' to the actual core/ + features/
layout (core api/api-remote/ui/hooks/stores/tauri-shim; 12 feature
slices) and src-tauri ssh/ & remote/ module folders.

STYLEGUIDE: format with oxfmt (was failing format:check); fix heading
'9 kelas inti' -> '11 kelas inti' to match the table; add one-line note
that status tokens are consumed via var(--*) (not in Tailwind palette).

AGENTS.md: drop stale legacy components/ migration note; clarify the
<=400-line ratchet now covers both TS and Rust.
- notification_upload_sound was a stub that always returned an error and
  ignored the selected file path; now validates the audio file (wav/mp3/ogg),
  copies it into the app data dir, and persists customSoundPath
- move the three sound commands into modules/notification_sound.rs with
  characterization tests for file validation (notification.rs 667->639,
  baseline tightened)
- custom sound playback now uses convertFileSrc + asset protocol instead of
  file:// URLs, which the webview blocks (protocol-asset feature enabled,
  assetProtocol scope $APPDATA/**)
- uploadSound no longer invokes the backend when the dialog is cancelled
@yandanp yandanp changed the title WIP: orca-style refactor phase 1 (Tasks 1-2: tooling + CI gates) Orca-style refactor phase 1: conventions, architecture & quality gates Aug 9, 2026
@yandanp
yandanp marked this pull request as ready for review August 9, 2026 10:56
@yandanp
yandanp merged commit bb3aa67 into main Aug 15, 2026
2 checks passed
@yandanp
yandanp deleted the refactor-project-like-orca-dev-https-github.com-stablyai-orca branch August 19, 2026 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant