Separate GUI Repository
In smaller Oidis projects, the frontend lives under the Gui/ subdirectory of the same repository as the backend. For larger projects — Hub, Home, and Studio — the frontend is extracted into its own git repository. Understanding this pattern is essential to working on these projects correctly.
Why a Separate Repository?
The primary reason is dependency isolation.
Every Oidis project's Gui/ subtree is compiled into a browser bundle. The browser has no knowledge of Node.js built-ins (fs, path, child_process, etc.). If any import chain from Gui/ reaches a file that imports a native Node.js module, the browser bundle will fail to load.
In a single-repo project this is enforced by code discipline — developers simply don't import backend modules from Gui/. In a large project spanning hundreds of files and multiple contributors, this discipline is harder to maintain.
Splitting the GUI into a separate repository creates a hard technical boundary: the GUI repo has no access to backend source files at all, making accidental cross-boundary imports structurally impossible.
Repository Layout
The canonical example is io-oidis-hub (backend) and io-oidis-hub-gui (frontend):
io-oidis-hub/ ← Backend git repository
├── source/typescript/Io/Oidis/Hub/ ← All backend code
├── dependencies/
│ └── io-oidis-hub-gui/ ← Frontend repo, cloned here by oidis install
│ └── source/typescript/Io/Oidis/Hub/Gui/
└── package.conf.jsonp ← Declares io-oidis-hub-gui as a dependency
io-oidis-hub-gui/ ← Frontend git repository (standalone clone)
├── source/typescript/Io/Oidis/Hub/Gui/
├── test/unit/typescript/ ← FE-only unit tests
└── package.conf.jsonp ← noServer: true
The dependencies/ directory is gitignored in the backend repo. It is populated by oidis install from the declarations in package.conf.jsonp.
noServer: true
The GUI package.conf.jsonp contains:
{
"noServer": true,
...
}
This tells the Builder that this project produces no backend artifact — only a browser bundle. The GUI can be installed and compiled in isolation, but has no HTTP server of its own.
GUI Projects and Their Backend Pairs
| GUI repository | Backend repository | Domain |
|---|---|---|
io-oidis-hub-gui | io-oidis-hub | Authentication, user/group management, agent forwarding |
io-oidis-home-gui | io-oidis-home | Home / landing application |
io-oidis-studio-gui | io-oidis-studio | Studio application |
Each GUI has exactly one backend. The backend declares the GUI as a dependency and serves the compiled browser bundle via its FrontEndLoader.ts resolver.
Developer Workflow
Working on a GUI project in this pattern is more complex than in a single-repo project. The recommended approach is to develop inside the dependencies/ folder of the backend (where you have a live server context) and then synchronize changes back to the standalone GUI clone for committing.
This section covers the GUI-specific aspects of the sync process. For the complete workflow — including merge pitfalls, three-way conflict detection, reverse sync, post-transfer validation, and Claude Code automation via the /sync-dependency skill — see Cross-Repository Workflow.
Step 1 — Edit in the dependencies context
Open the backend project in IntelliJ IDEA. The GUI source is available at:
dependencies/io-oidis-hub-gui/source/typescript/Io/Oidis/Hub/Gui/
Working here gives you:
- A running backend server for live testing
- Full tsconfig path aliases (both
@io-oidis-hub-gui/*and@io-oidis-hub/*are resolved) - Hot-reload of frontend changes
Step 2 — Synchronize to the standalone clone
After completing a logical unit of work, transfer the changed source files to the standalone GUI clone (e.g. D:\__PROJECTS__\Oidis\Source\io-oidis-hub-gui\).
Do not use simple copy-paste between the two locations. The Builder modifies several files during oidis install to adapt them to the dependencies/ subdirectory context:
| What the Builder modifies | Why it differs |
|---|---|
| Absolute paths in configuration files | Adjusted for the dependencies/ depth |
tsconfig.json path aliases | Generated; differ between root and dependency context |
package.json | Generated from package.conf.jsonp; never hand-edited |
webpack.config.js | Generated SCSS alias file; context-specific |
Additionally, the dependencies/ folder contains .idea/ files and other artefacts that should not be committed to the GUI repository.
Recommended approach: IntelliJ Compare with / Beyond Compare
Use IntelliJ's built-in Directory Diff (View → Compare with... or right-click the folder) or an external tool like Beyond Compare to:
- Open a diff between
dependencies/io-oidis-hub-gui/source/andio-oidis-hub-gui/source/ - Selectively transfer only the source files you modified (
.ts,.scss,.html,.bsdesign, JSONP data files, etc.) - Review each change before transferring — Builder-modified lines should be skipped
Step 3 — Commit from the standalone clone
Pre-commit hooks run only in the standalone GUI repository, not inside dependencies/. These hooks validate:
- TypeScript compilation (no type errors)
- Linting (Oidis formatting rules)
- Copyright headers
Commit from the standalone clone to trigger validation:
cd D:\__PROJECTS__\Oidis\Source\io-oidis-hub-gui
git add source/typescript/Io/Oidis/Hub/Gui/Controllers/...
git commit -m "[HUB-123] Add filter to users panel"
Any changes made inside dependencies/io-oidis-hub-gui/ bypass all pre-commit validation. You must commit from the standalone GUI clone to ensure compilation and linting are enforced.
Files to Transfer vs. Files to Skip
| Transfer ✅ | Skip ❌ |
|---|---|
source/typescript/**/*.ts | tsconfig.json (generated) |
source/html/**/*.html | package.json (generated) |
source/html/**/*.bsdesign | webpack.config.js (generated) |
resource/sass/**/*.scss | .idea/ directory |
resource/data/**/*.jsonp | dependencies/ subdirectory |
test/unit/typescript/**/*.ts | build/, build_cache/ |
bin/project/configs/*.jsonp | node_modules/ |
package.conf.jsonp | Any *.compiled.d.scss |
Standalone GUI Development
The GUI repository is self-contained — you can install and build it without the backend:
cd io-oidis-hub-gui
oidis install
oidis rebuild
However, without a backend, the application has no data source. All API calls will fail, which requires either:
- Mocking — significant effort to set up mock data for every connector
- Live backend — the typical approach (develop in
dependencies/context)
For this reason, standalone GUI development is rarely used in practice. The noServer: true flag ensures the project can be built independently for CI purposes, but day-to-day development relies on the backend context.
See also: Architecture Overview | Cross-Repository Workflow | Request Forwarding | Testing