7.7 KiB
| title | description |
|---|---|
| Development | How to build, test, and contribute to Core IDE. |
Development
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| Go | 1.26+ | Backend compilation |
| Node.js | 22+ | Angular frontend build |
| npm | (bundled with Node) | Frontend dependency management |
| Wails 3 CLI | alpha.64+ | Desktop application framework (wails3) |
core CLI |
latest | Build system (core build) |
The module lives inside a Go workspace (~/Code/go.work) and depends on three sibling modules via replace directives in go.mod:
replace (
forge.lthn.ai/core/go => ../go
forge.lthn.ai/core/go-process => ../go-process
forge.lthn.ai/core/gui => ../gui
)
Ensure these directories exist alongside the ide/ directory before building.
Building
Development mode (hot-reload)
wails3 dev
This starts the Angular dev server, watches Go files for changes, rebuilds, and re-launches the application automatically. The Wails dev mode configuration is in build/config.yml under the dev_mode key.
Production build
Using the Core CLI (preferred):
core build
This reads .core/build.yaml and produces a platform-native binary. The build configuration enables CGO (required by Wails), strips debug symbols (-s -w), and uses -trimpath.
Using Wails directly:
wails3 build
Cross-compilation targets
The .core/build.yaml defines three targets:
| OS | Architecture |
|---|---|
| darwin | arm64 |
| linux | amd64 |
| windows | amd64 |
Frontend-only build
To build or serve the Angular frontend independently (useful for UI-only development):
cd frontend
npm install
npm run dev # Development server with hot-reload
npm run build # Production build to frontend/dist/
npm run test # Run Jasmine/Karma tests
Testing
Go tests
core go test # Run all tests
core go test --run TestName # Run a specific test
core go cov # Generate coverage report
core go cov --open # Open coverage HTML in browser
Frontend tests
cd frontend
npm run test
This runs the Angular test suite via Karma with Chrome.
Quality assurance
core go qa # Format + vet + lint + test
core go qa full # + race detector, vulnerability scan, security audit
CI pipelines
Two Forgejo workflows are configured in .forgejo/workflows/:
| Workflow | Trigger | Description |
|---|---|---|
test.yml |
Push to main/dev, PRs to main |
Runs Go tests with race detection and coverage |
security-scan.yml |
Push to main/dev/feat/*, PRs to main |
Runs security scanning |
Both workflows are reusable, imported from core/go-devops.
Project structure
ide/
main.go # Entry point
mcp_bridge.go # MCPBridge Wails service (GUI mode)
claude_bridge.go # WebSocket relay to upstream MCP
headless.go # Headless daemon (job runner)
headless_mcp.go # Headless MCP HTTP server
greetservice.go # Sample Wails service
icons/
icons.go # Embedded icon assets
apptray.png # System tray icon
systray-mac-template.png
systray-default.png
frontend/
src/
app/
app.ts # Root component (router outlet)
app.routes.ts # Route definitions (/tray, /ide)
app.config.ts # Angular providers
pages/
tray/ # System tray panel component
ide/ # Full IDE layout component
components/
sidebar/ # Navigation sidebar component
bindings/ # Auto-generated Go method bindings
package.json # npm dependencies
angular.json # Angular CLI configuration
build/
config.yml # Wails 3 project configuration
appicon.png # Application icon
darwin/ # macOS-specific (Info.plist, .icns)
linux/ # Linux-specific (systemd, AppImage, nfpm)
windows/ # Windows-specific (NSIS, MSIX, manifest)
.core/
build.yaml # core build configuration
.forgejo/
workflows/ # CI pipeline definitions
go.mod
go.sum
Adding a new Wails service
- Create a new Go file with a struct and methods you want to expose to the frontend:
// myservice.go
package main
type MyService struct{}
func (s *MyService) DoSomething(input string) (string, error) {
return "result: " + input, nil
}
- Register the service in
main.go:
Services: []application.Service{
application.NewService(&GreetService{}),
application.NewService(mcpBridge),
application.NewService(&MyService{}), // add here
},
-
Run
wails3 devorwails3 buildto regenerate TypeScript bindings infrontend/bindings/. -
Import and call the generated function from Angular:
import { DoSomething } from '../bindings/changeme/myservice';
const result = await DoSomething('hello');
Adding a new MCP tool
To add a new webview tool to the MCP bridge:
- Add the tool metadata to the
handleMCPToolsmethod inmcp_bridge.go:
{"name": "webview_my_tool", "description": "What it does"},
- Add a case to the
executeWebviewToolswitch inmcp_bridge.go:
case "webview_my_tool":
windowName := getStringParam(params, "window")
// Call webview.Service methods...
result, err := b.webview.SomeMethod(windowName)
if err != nil {
return map[string]any{"error": err.Error()}
}
return map[string]any{"result": result}
- The tool is immediately available via
POST /mcp/call.
Adding a new Angular page
- Create a new component:
cd frontend
npx ng generate component pages/my-page --standalone
- Add a route in
frontend/src/app/app.routes.ts:
import { MyPageComponent } from './pages/my-page/my-page.component';
export const routes: Routes = [
{ path: 'my-page', component: MyPageComponent },
// ... existing routes
];
- If the page needs to communicate with Go, use the Wails runtime:
import { Events } from '@wailsio/runtime';
// Listen for Go events
Events.On('my-event', (data) => { ... });
// Send events to Go
Events.Emit('my-action', payload);
Platform-specific notes
macOS
- The application runs as an "accessory" (
ActivationPolicyAccessory), meaning it has no Dock icon and only appears in the system tray. - Bundle identifier:
com.lethean.core-ide - Minimum macOS version: 10.15 (Catalina)
- The
Info.plistis atbuild/darwin/Info.plist.
Linux
- A systemd service file is provided at
build/linux/core-ide.servicefor running in headless mode. - A user-scoped service file is also available at
build/linux/core-ide.user.service. - nfpm packaging configuration is at
build/linux/nfpm/nfpm.yaml. - AppImage build script is at
build/linux/appimage/build.sh. - Display detection uses
DISPLAYorWAYLAND_DISPLAYenvironment variables.
Windows
- NSIS installer configuration:
build/windows/nsis/project.nsi - MSIX package template:
build/windows/msix/template.xml hasDisplay()always returnstrueon Windows.
Coding standards
- UK English in all documentation and user-facing strings (colour, organisation, centre).
- Strict typing -- all Go functions have explicit parameter and return types.
- Formatting -- run
core go fmtbefore committing. - Linting -- run
core go lintto catch issues. - Licence -- EUPL-1.2. Include the copyright header where appropriate.
Commit conventions
Use conventional commits:
type(scope): description
Include the co-author line:
Co-Authored-By: Virgil <virgil@lethean.io>