Skip to content

Commit 91b74ce

Browse files
1 parent f59e584 commit 91b74ce

10 files changed

Lines changed: 179 additions & 43 deletions

File tree

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Sky β€” Deep Dive
2+
3+
This document provides the technical foundation for the Sky UI component layer
4+
within the Land ecosystem. **Sky** renders the complete editor interface inside
5+
the Tauri webview using Astro, consuming state and services from the Wind
6+
service layer.
7+
8+
---
9+
10+
## Architecture
11+
12+
Sky is organized into three tiers: page routes that define Tauri webview entry
13+
points, workbench components that compose the VSCode-compatible editor layout,
14+
and utility functions that support the build and runtime process.
15+
16+
```mermaid
17+
graph TB
18+
subgraph "Sky β€” UI Component Layer"
19+
Pages["Pages\nindex / Browser / Electron / Mountain / Isolation"]
20+
Workbenches["Workbench Components\nBrowser / Mountain / Default / NLS"]
21+
WorkbenchImpl["Workbench Implementations\nBrowserProxy/ Β· Electron/"]
22+
Functions["Function/\nDebug Β· Shared Β· Meta Β· Markup/Base"]
23+
end
24+
25+
subgraph "Wind β€” Service Layer"
26+
Preload["Preload.js β€” Environment Shim"]
27+
WindServices["Effect-TS Services"]
28+
TauriIntegrations["Tauri IPC Integrations"]
29+
end
30+
31+
subgraph "Mountain β€” Rust Backend"
32+
TauriEvents["Tauri Event System"]
33+
MountainCore["Mountain Core"]
34+
end
35+
36+
Pages --> Workbenches
37+
Pages --> WorkbenchImpl
38+
Workbenches --> Preload
39+
WorkbenchImpl --> Preload
40+
Workbenches --> WindServices
41+
WorkbenchImpl --> WindServices
42+
WindServices --> TauriIntegrations
43+
TauriIntegrations --> TauriEvents
44+
TauriEvents --> MountainCore
45+
```
46+
47+
---
48+
49+
## Key Modules
50+
51+
| Path | Description |
52+
| :--- | :--- |
53+
| `Source/pages/index.astro` | Default entry point; reads environment variables to select workbench variant |
54+
| `Source/pages/Mountain.astro` | A2 workbench page β€” recommended production entry point |
55+
| `Source/pages/Browser.astro` | A1 browser-only workbench page |
56+
| `Source/pages/BrowserProxy.astro` | A1 browser workbench with services proxy |
57+
| `Source/pages/Electron.astro` | A3 workbench page with Electron polyfills |
58+
| `Source/pages/Isolation.astro` | Isolated mode page for extension sandboxing |
59+
| `Source/Workbench/Mountain.astro` | A2 workbench component β€” loads VSCode UI with Mountain providers |
60+
| `Source/Workbench/Browser.astro` | A1 workbench component β€” pure browser workbench |
61+
| `Source/Workbench/BrowserProxy/Layout.astro` | A1 layout with service proxy bootstrapping |
62+
| `Source/Workbench/BrowserProxy/Bootstrap.ts` | Initializes Effect-TS runtime and services for BrowserProxy |
63+
| `Source/Workbench/BrowserProxy/ServicesProxy.ts` | Service proxy implementation |
64+
| `Source/Workbench/Electron/Layout.astro` | A3 layout with Electron polyfill injection |
65+
| `Source/Workbench/Electron/Polyfills.ts` | Electron compatibility shims |
66+
| `Source/Workbench/NLS.astro` | Natural language support component |
67+
| `Source/Function/Debug.ts` | Build-time debug utilities |
68+
| `Source/Function/Shared.ts` | Shared runtime utilities |
69+
| `Source/Function/Meta.astro` | HTML meta tag component |
70+
| `Source/Function/Markup/Base.astro` | Base HTML layout skeleton |
71+
| `astro.config.ts` | Astro build configuration, alias resolution, Vite settings |
72+
73+
---
74+
75+
## Data Flow
76+
77+
The following sequence shows how a user action travels from the Sky UI through
78+
Wind services to the Mountain backend and back.
79+
80+
```mermaid
81+
sequenceDiagram
82+
participant User as User Interaction
83+
participant Sky as Sky Component
84+
participant Wind as Wind Service
85+
participant Tauri as Tauri IPC
86+
participant Mountain as Mountain Backend
87+
88+
User->>Sky: Click / Keystroke
89+
Sky->>Wind: Call service method (e.g. DialogService)
90+
Wind->>Tauri: tauri invoke command
91+
Tauri->>Mountain: Rust command handler
92+
Mountain->>Tauri: Return result
93+
Tauri->>Wind: Resolve Effect
94+
Wind->>Sky: Updated state
95+
Sky->>User: Re-render component
96+
```
97+
98+
**Startup sequence:**
99+
100+
1. Tauri loads the webview pointing at Sky's built output.
101+
2. The page route reads environment variables and selects a workbench variant.
102+
3. Wind's `Preload.ts` shims `window.vscode` globals before VSCode code runs.
103+
4. Wind bootstraps the Effect-TS service layer and establishes Tauri IPC.
104+
5. Sky components subscribe to Wind services for live state updates.
105+
6. Sky listens for Tauri events from Mountain (`sky://terminal/data`,
106+
`sky://scm/update-group`, `sky://configuration/changed`) to update UI.
107+
108+
---
109+
110+
## Integration Points
111+
112+
| Connecting Element | Direction | Mechanism | Description |
113+
| :--- | :--- | :--- | :--- |
114+
| **Wind** | Inbound | Direct import | Sky consumes Wind Effect-TS services for all business logic |
115+
| **Mountain** | Bidirectional | Tauri IPC + Events | Commands sent via Tauri invoke; updates received as Tauri events |
116+
| **Output** | Inbound | Static bundle | VSCode core UI components loaded from `@codeeditorland/output` |
117+
| **Worker** | Inbound | Web Worker API | Web workers for background processing imported from `@codeeditorland/worker` |
118+
119+
---
120+
121+
## Configuration
122+
123+
| Variable | Default | Description |
124+
| :--- | :--- | :--- |
125+
| `Mountain` | unset | Set to `true` to load the A2 Mountain workbench (recommended) |
126+
| `Electron` | unset | Set to `true` to load the A3 Electron workbench |
127+
| `BrowserProxy` | unset | Set to `true` to load the A1 BrowserProxy workbench |
128+
| `Browser` | unset | Set to `true` to load the A1 Browser workbench |
129+
| `NODE_ENV` | `production` | Controls source map generation and debug output |
130+
131+
When no variant flag is set, `index.astro` loads `Workbench/Default.astro`.
132+
The recommended deployment always sets `Mountain=true`.
133+
134+
**Astro configuration** (`astro.config.ts`) resolves Wind and other
135+
`@codeeditorland/*` packages through Vite aliases, sets `Source/` as the
136+
content root, and directs build output to `Target/`.

β€ŽSource/Function/BuildVSCode.tsβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ export async function copyVSCodeOutput(): Promise<void> {
8282

8383
try {
8484
await cp(sourcePath, VSCodeOutput, { recursive: true });
85-
console.log("[BuildVSCode] βœ“ VSCode output copied successfully");
85+
console.log("[BuildVSCode]β€βœ“ VSCode output copied successfully");
8686
} catch (error) {
87-
console.error("[BuildVSCode] βœ— Failed to copy VSCode output:", error);
87+
console.error("[BuildVSCode]β€βœ— Failed to copy VSCode output:", error);
8888
throw error;
8989
}
9090

@@ -110,7 +110,7 @@ async function verifyVSCodeOutput(vscodePath: string): Promise<void> {
110110
if (!fs.existsSync(fullPath)) {
111111
console.warn(`[BuildVSCode] WARNING: Missing required file: ${file}`);
112112
} else {
113-
console.log(`[BuildVSCode] βœ“ Found: ${file}`);
113+
console.log(`[BuildVSCode]β€βœ“ Found: ${file}`);
114114
}
115115
}
116116
}

β€ŽSource/Workbench/BrowserProxy/Bootstrap.tsβ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ try {
2424
const { runBootstrap } =
2525
await import("@codeeditorland/wind/Target/Effect/Bootstrap");
2626

27-
console.log("[BrowserProxy] βœ“ Bootstrap module loaded successfully");
27+
console.log("[BrowserProxy]β€βœ“ Bootstrap module loaded successfully");
2828

2929
// Run the bootstrap with options
3030
const bootstrapResult: BootstrapResult = await runBootstrap({
@@ -33,7 +33,7 @@ try {
3333
});
3434

3535
if (bootstrapResult.success) {
36-
console.log("[BrowserProxy] βœ“ Bootstrap completed successfully");
36+
console.log("[BrowserProxy]β€βœ“ Bootstrap completed successfully");
3737
console.log(
3838
"[BrowserProxy] - Total duration:",
3939
bootstrapResult.totalDuration,
@@ -49,12 +49,12 @@ try {
4949
});
5050
} else {
5151
console.error(
52-
"[BrowserProxy] βœ— Bootstrap failed:",
52+
"[BrowserProxy]β€βœ— Bootstrap failed:",
5353
bootstrapResult.error,
5454
);
5555
}
5656
} catch (error: unknown) {
57-
console.error("[BrowserProxy] βœ— Failed to load/run bootstrap:", error);
57+
console.error("[BrowserProxy]β€βœ— Failed to load/run bootstrap:", error);
5858
}
5959

6060
console.log("[BrowserProxy] ===== Wind bootstrap sequence complete =====");

β€ŽSource/Workbench/BrowserProxy/ServicesProxy.tsβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ console.log("[BrowserProxy] and route them through Mountain services.");
1515
try {
1616
// The services proxy will intercept window.vscode API calls
1717
// and forward them to Mountain services via IPC
18-
console.log("[BrowserProxy] βœ“ Services proxy initialized");
18+
console.log("[BrowserProxy]β€βœ“ Services proxy initialized");
1919
console.log(
2020
"[BrowserProxy] - Proxied APIs: ipcRenderer, process, shell, clipboard, etc.",
2121
);
2222
console.log("[BrowserProxy] - Proxy target: Mountain services");
2323
} catch (error: unknown) {
2424
console.error(
25-
"[BrowserProxy] βœ— Failed to initialize services proxy:",
25+
"[BrowserProxy]β€βœ— Failed to initialize services proxy:",
2626
error,
2727
);
2828
}

β€ŽSource/Workbench/BrowserProxy/WindPreload.tsβ€Ž

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,39 @@ console.log(
1616
// Install the Wind preload polyfill (window.vscode globals)
1717
Install()
1818
.then(() => {
19-
console.log("[BrowserProxy] βœ“ Wind preload installed successfully");
19+
console.log("[BrowserProxy]β€βœ“ Wind preload installed successfully");
2020

2121
// Verify preloadGlobals is available
2222
if (window.preloadGlobals && window.preloadGlobals.process) {
23-
console.log("[BrowserProxy] βœ“ preloadGlobals.process is available");
23+
console.log("[BrowserProxy]β€βœ“ preloadGlobals.process is available");
2424
const process = window.preloadGlobals.process;
2525
console.log("[BrowserProxy] - Platform:", process.platform);
2626
console.log("[BrowserProxy] - Arch:", process.arch);
2727
console.log("[BrowserProxy] - Type:", process.type);
2828
} else {
2929
console.warn(
30-
"[BrowserProxy] ⚠ preloadGlobals.process not available",
30+
"[BrowserProxy]β€βš  preloadGlobals.process not available",
3131
);
3232
}
3333

3434
// Verify window.vscode is available
3535
if (window.vscode) {
36-
console.log("[BrowserProxy] βœ“ window.vscode is available");
36+
console.log("[BrowserProxy]β€βœ“ window.vscode is available");
3737
} else {
38-
console.error("[BrowserProxy] βœ— window.vscode not available");
38+
console.error("[BrowserProxy]β€βœ— window.vscode not available");
3939
}
4040

4141
// Verify Wind preload ready flag
4242
if (window.__WIND_PRELOAD_READY__) {
43-
console.log("[BrowserProxy] βœ“ Wind preload ready flag is set");
43+
console.log("[BrowserProxy]β€βœ“ Wind preload ready flag is set");
4444
} else {
45-
console.warn("[BrowserProxy] ⚠ Wind preload ready flag is not set");
45+
console.warn("[BrowserProxy]β€βš  Wind preload ready flag is not set");
4646
}
4747

4848
console.log(
4949
"[BrowserProxy] ===== Wind preload installation complete =====",
5050
);
5151
})
5252
.catch((error: unknown) => {
53-
console.error("[BrowserProxy] βœ— Wind preload install error:", error);
53+
console.error("[BrowserProxy]β€βœ— Wind preload install error:", error);
5454
});

β€ŽSource/Workbench/BrowserProxy/Workbench.tsβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ try {
1616
await import("@codeeditorland/output/vs/code/browser/workbench/workbench.js");
1717

1818
console.log(
19-
"[BrowserProxy] βœ“ Browser workbench script loaded successfully",
19+
"[BrowserProxy]β€βœ“ Browser workbench script loaded successfully",
2020
);
2121
console.log("[BrowserProxy] ===== Workbench load complete =====");
2222

@@ -32,7 +32,7 @@ try {
3232
);
3333
}, 2000);
3434
} catch (error: unknown) {
35-
console.error("[BrowserProxy] βœ— Failed to load browser workbench:", error);
35+
console.error("[BrowserProxy]β€βœ— Failed to load browser workbench:", error);
3636
}
3737

3838
console.log("[BrowserProxy] ===== Workbench load sequence complete =====");

β€ŽSource/Workbench/Electron/Bootstrap.tsβ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ try {
2424
const { runBootstrap } =
2525
await import("@codeeditorland/wind/Target/Effect/Bootstrap");
2626

27-
console.log("[Electron] βœ“ Bootstrap module loaded successfully");
27+
console.log("[Electron]β€βœ“ Bootstrap module loaded successfully");
2828

2929
// Run the bootstrap with options
3030
const bootstrapResult: BootstrapResult = await runBootstrap({
@@ -33,7 +33,7 @@ try {
3333
});
3434

3535
if (bootstrapResult.success) {
36-
console.log("[Electron] βœ“ Bootstrap completed successfully");
36+
console.log("[Electron]β€βœ“ Bootstrap completed successfully");
3737
console.log(
3838
"[Electron] - Total duration:",
3939
bootstrapResult.totalDuration,
@@ -48,10 +48,10 @@ try {
4848
);
4949
});
5050
} else {
51-
console.error("[Electron] βœ— Bootstrap failed:", bootstrapResult.error);
51+
console.error("[Electron]β€βœ— Bootstrap failed:", bootstrapResult.error);
5252
}
5353
} catch (error: unknown) {
54-
console.error("[Electron] βœ— Failed to load/run bootstrap:", error);
54+
console.error("[Electron]β€βœ— Failed to load/run bootstrap:", error);
5555
}
5656

5757
console.log("[Electron] ===== Wind bootstrap sequence complete =====");

β€ŽSource/Workbench/Electron/Polyfills.tsβ€Ž

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,37 @@ console.log("[Electron] Loading 7 polyfills to make browser act like Electron");
1818
try {
1919
// 1. Process Polyfill - Node.js process object
2020
await import("@codeeditorland/wind/Target/Polyfills/ProcessPolyfill");
21-
console.log("[Electron] βœ“ ProcessPolyfill loaded");
21+
console.log("[Electron]β€βœ“ ProcessPolyfill loaded");
2222

2323
// 2. File Protocol Shim - vscode-file:// protocol handling
2424
await import("@codeeditorland/wind/Target/Polyfills/FileProtocolShim");
25-
console.log("[Electron] βœ“ FileProtocolShim loaded");
25+
console.log("[Electron]β€βœ“ FileProtocolShim loaded");
2626

2727
// 3. File System Polyfill - fs module
2828
await import("@codeeditorland/wind/Target/Polyfills/FileSystemPolyfill");
29-
console.log("[Electron] βœ“ FileSystemPolyfill loaded");
29+
console.log("[Electron]β€βœ“ FileSystemPolyfill loaded");
3030

3131
// 4. IPC Renderer Shim - Electron IPC communication
3232
await import("@codeeditorland/wind/Target/Polyfills/IPCRendererShim");
33-
console.log("[Electron] βœ“ IPCRendererShim loaded");
33+
console.log("[Electron]β€βœ“ IPCRendererShim loaded");
3434

3535
// 5. Child Process Polyfill - child_process module
3636
await import("@codeeditorland/wind/Target/Polyfills/ChildProcessPolyfill");
37-
console.log("[Electron] βœ“ ChildProcessPolyfill loaded");
37+
console.log("[Electron]β€βœ“ ChildProcessPolyfill loaded");
3838

3939
// 6. Native Module Polyfill - native module loading
4040
await import("@codeeditorland/wind/Target/Polyfills/NativeModulePolyfill");
41-
console.log("[Electron] βœ“ NativeModulePolyfill loaded");
41+
console.log("[Electron]β€βœ“ NativeModulePolyfill loaded");
4242

4343
// 7. Shared Process Proxy - Shared process communication
4444
await import("@codeeditorland/wind/Target/Polyfills/SharedProcessProxy");
45-
console.log("[Electron] βœ“ SharedProcessProxy loaded");
45+
console.log("[Electron]β€βœ“ SharedProcessProxy loaded");
4646

4747
console.log(
4848
"[Electron] ===== All 7 Electron API polyfills loaded successfully =====",
4949
);
5050
} catch (error: unknown) {
51-
console.error("[Electron] βœ— Failed to load polyfills:", error);
51+
console.error("[Electron]β€βœ— Failed to load polyfills:", error);
5252
console.error("[Electron] This may cause Electron workbench to fail");
5353
}
5454

0 commit comments

Comments
Β (0)