@rool-dev/extension 0.3.8-dev.b3f8671 → 0.3.9-dev.e980598

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,10 +14,10 @@ Everything else (Vite config, entry point, HTML, Tailwind CSS) is provided by th
14
14
  ## Quick Start
15
15
 
16
16
  ```bash
17
- npx rool-extension init my-extension
17
+ npx @rool-dev/cli extension create my-extension
18
18
  cd my-extension
19
19
  pnpm install
20
- npx rool-extension dev
20
+ pnpm dev
21
21
  ```
22
22
 
23
23
  This opens a dev host at `/__rool-host/` that loads your extension in a sandboxed iframe, connected to a real Rool Space.
@@ -344,7 +344,7 @@ await thread.rename('Research Thread');
344
344
  thread.close(); // Stop listening for updates
345
345
  ```
346
346
 
347
- Conversations are auto-created on first interaction — no explicit create step needed. All conversations share one bridge connection. The 50-message cap applies per conversation.
347
+ Conversations are auto-created on first interaction — no explicit create step needed. All conversations share one bridge connection. The 200-interaction cap applies per conversation.
348
348
 
349
349
  ### Events
350
350
 
@@ -428,10 +428,10 @@ const host = createBridgeHost({
428
428
 
429
429
  | Command | Description |
430
430
  |---------|-------------|
431
- | `rool-extension init [name]` | Scaffold a new extension project |
432
- | `rool-extension dev` | Start the dev server with host shell |
433
- | `rool-extension build` | Build the extension |
434
- | `rool-extension publish` | Build and publish the extension |
431
+ | `rool extension create [name]` | Scaffold a new extension project |
432
+ | `rool extension dev` | Start the dev server with host shell |
433
+ | `rool extension build` | Build the extension |
434
+ | `rool extension publish` | Build and publish the extension |
435
435
 
436
436
  ## Exported Types
437
437
 
@@ -443,6 +443,7 @@ import type {
443
443
  ReactiveWatch,
444
444
  WatchOptions,
445
445
  BridgeUser,
446
+ ColorScheme,
446
447
  RoolObject,
447
448
  RoolObjectStat,
448
449
  SpaceSchema,
@@ -38,7 +38,7 @@ function roolExtensionBuildPlugin(root, tailwindCssPath) {
38
38
  },
39
39
  load(id) {
40
40
  if (id === RESOLVED_CSS)
41
- return `@import "${tailwindCssPath}";`;
41
+ return `@import "${tailwindCssPath}";\n@custom-variant dark (&:where(.dark, .dark *));`;
42
42
  if (id !== RESOLVED_ENTRY)
43
43
  return;
44
44
  return [
package/dist/cli/dev.js CHANGED
@@ -79,7 +79,7 @@ function roolExtensionPlugin(root, tailwindCssPath) {
79
79
  },
80
80
  load(id) {
81
81
  if (id === RESOLVED_CSS)
82
- return `@import "${tailwindCssPath}";`;
82
+ return `@import "${tailwindCssPath}";\n@custom-variant dark (&:where(.dark, .dark *));`;
83
83
  if (id !== RESOLVED_ENTRY)
84
84
  return;
85
85
  return [
package/dist/cli/init.js CHANGED
@@ -93,7 +93,7 @@ Additional \`.svelte\` and \`.ts\` files can be imported from \`App.svelte\`.
93
93
  ## Dev server
94
94
 
95
95
  \`\`\`
96
- npx rool-extension dev
96
+ pnpm dev
97
97
  \`\`\`
98
98
  `;
99
99
  writeFileSync(resolve(dir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n');
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { RoolClient } from '@rool-dev/sdk';
13
13
  import type { RoolSpaceInfo, PublishedExtensionInfo } from '@rool-dev/sdk';
14
+ import type { ColorScheme } from '../protocol.js';
14
15
  import type { Manifest, Environment } from '../manifest.js';
15
16
  export interface ExtensionTab {
16
17
  id: string;
@@ -34,6 +35,7 @@ export declare class DevHostController {
34
35
  publishedExtensions: PublishedExtensionInfo[];
35
36
  installedExtensionIds: string[];
36
37
  sidebarCollapsed: boolean;
38
+ colorScheme: ColorScheme;
37
39
  publishState: 'idle' | 'building' | 'uploading' | 'done' | 'error';
38
40
  publishMessage: string | null;
39
41
  publishUrl: string | null;
@@ -68,6 +70,7 @@ export declare class DevHostController {
68
70
  publish(): Promise<void>;
69
71
  switchEnv(newEnv: Environment): Promise<void>;
70
72
  toggleSidebar(): void;
73
+ toggleColorScheme(): void;
71
74
  registerIframe(tabId: string, el: HTMLIFrameElement): void;
72
75
  unregisterIframe(tabId: string): void;
73
76
  logout(): void;
@@ -82,5 +85,6 @@ export declare class DevHostController {
82
85
  */
83
86
  private _syncManifest;
84
87
  private _getSavedEnv;
88
+ private _getSavedColorScheme;
85
89
  }
86
90
  //# sourceMappingURL=DevHostController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevHostController.d.ts","sourceRoot":"","sources":["../../src/dev/DevHostController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DevHostController.d.ts","sourceRoot":"","sources":["../../src/dev/DevHostController.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,7 @@ export class DevHostController {
53
53
  publishedExtensions = [];
54
54
  installedExtensionIds = [];
55
55
  sidebarCollapsed = false;
56
+ colorScheme = 'light';
56
57
  publishState = 'idle';
57
58
  publishMessage = null;
58
59
  publishUrl = null;
@@ -76,6 +77,7 @@ export class DevHostController {
76
77
  // Restore persisted state
77
78
  this.env = this._getSavedEnv();
78
79
  this.sidebarCollapsed = storageGet('rool-devhost:collapsed') === 'true';
80
+ this.colorScheme = this._getSavedColorScheme();
79
81
  }
80
82
  // ---------------------------------------------------------------------------
81
83
  // Derived
@@ -338,6 +340,14 @@ export class DevHostController {
338
340
  storageSet('rool-devhost:collapsed', String(this.sidebarCollapsed));
339
341
  this._onChange();
340
342
  }
343
+ toggleColorScheme() {
344
+ this.colorScheme = this.colorScheme === 'light' ? 'dark' : 'light';
345
+ storageSet('rool-devhost:colorScheme', this.colorScheme);
346
+ for (const host of Object.values(this.bridgeHosts)) {
347
+ host.setColorScheme(this.colorScheme);
348
+ }
349
+ this._onChange();
350
+ }
341
351
  // ---------------------------------------------------------------------------
342
352
  // Iframe registration (called by Svelte action)
343
353
  // ---------------------------------------------------------------------------
@@ -366,7 +376,7 @@ export class DevHostController {
366
376
  const el = this.iframeEls[tabId];
367
377
  const ch = this.channels[tabId];
368
378
  if (el && ch && !this.bridgeHosts[tabId]) {
369
- this.bridgeHosts[tabId] = createBridgeHost({ channel: ch, iframe: el, user: this._bridgeUser });
379
+ this.bridgeHosts[tabId] = createBridgeHost({ channel: ch, iframe: el, user: this._bridgeUser, colorScheme: this.colorScheme });
370
380
  }
371
381
  }
372
382
  _bindAllBridges() {
@@ -430,4 +440,11 @@ export class DevHostController {
430
440
  return saved;
431
441
  return 'prod';
432
442
  }
443
+ _getSavedColorScheme() {
444
+ const saved = storageGet('rool-devhost:colorScheme');
445
+ if (saved === 'light' || saved === 'dark')
446
+ return saved;
447
+ // Fall back to OS preference
448
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
449
+ }
433
450
  }
@@ -32,6 +32,7 @@
32
32
  let publishedExtensions: PublishedExtensionInfo[] = $state([]);
33
33
  let installedExtensionIds: string[] = $state([]);
34
34
  let tabs: ExtensionTab[] = $state([]);
35
+ let colorScheme: 'light' | 'dark' = $state('light');
35
36
  let publishState: 'idle' | 'building' | 'uploading' | 'done' | 'error' = $state('idle');
36
37
  let publishMessage: string | null = $state(null);
37
38
  let publishUrl: string | null = $state(null);
@@ -52,6 +53,7 @@
52
53
  statusState = controller.statusState;
53
54
  placeholderText = controller.placeholderText;
54
55
  sidebarCollapsed = controller.sidebarCollapsed;
56
+ colorScheme = controller.colorScheme;
55
57
  env = controller.env;
56
58
  publishedExtensions = controller.publishedExtensions;
57
59
  installedExtensionIds = controller.installedExtensionIds;
@@ -97,6 +99,7 @@
97
99
  {statusText}
98
100
  {statusState}
99
101
  {sidebarCollapsed}
102
+ {colorScheme}
100
103
  {publishState}
101
104
  {publishMessage}
102
105
  {publishUrl}
@@ -1 +1 @@
1
- {"version":3,"file":"HostShell.svelte.d.ts","sourceRoot":"","sources":["../../src/dev/HostShell.svelte.ts"],"names":[],"mappings":"AAkHA,QAAA,MAAM,SAAS,2DAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"HostShell.svelte.d.ts","sourceRoot":"","sources":["../../src/dev/HostShell.svelte.ts"],"names":[],"mappings":"AAoHA,QAAA,MAAM,SAAS,2DAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -15,6 +15,7 @@
15
15
  statusText: string;
16
16
  statusState: 'ok' | 'loading' | 'off';
17
17
  sidebarCollapsed: boolean;
18
+ colorScheme: 'light' | 'dark';
18
19
  publishState: 'idle' | 'building' | 'uploading' | 'done' | 'error';
19
20
  publishMessage: string | null;
20
21
  publishUrl: string | null;
@@ -31,6 +32,7 @@
31
32
  statusText,
32
33
  statusState,
33
34
  sidebarCollapsed,
35
+ colorScheme,
34
36
  publishState,
35
37
  publishMessage,
36
38
  publishUrl,
@@ -272,13 +274,24 @@
272
274
  <!-- Footer -->
273
275
  <div class="px-4 py-3 mt-auto flex items-center justify-between">
274
276
  <a
275
- href="https://docs.rool.dev/app"
277
+ href="https://docs.rool.dev/extension"
276
278
  target="_blank"
277
279
  rel="noopener noreferrer"
278
280
  class="text-[11px] text-slate-400 hover:text-indigo-500 transition-colors"
279
281
  >
280
282
  Documentation
281
283
  </a>
284
+ <button
285
+ class="p-1 text-slate-400 hover:text-indigo-500 transition-colors"
286
+ onclick={() => controller.toggleColorScheme()}
287
+ title={colorScheme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'}
288
+ >
289
+ {#if colorScheme === 'light'}
290
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
291
+ {:else}
292
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
293
+ {/if}
294
+ </button>
282
295
  <button
283
296
  class="text-[11px] text-slate-400 hover:text-red-500 transition-colors"
284
297
  onclick={() => controller.logout()}
@@ -11,6 +11,7 @@ interface Props {
11
11
  statusText: string;
12
12
  statusState: 'ok' | 'loading' | 'off';
13
13
  sidebarCollapsed: boolean;
14
+ colorScheme: 'light' | 'dark';
14
15
  publishState: 'idle' | 'building' | 'uploading' | 'done' | 'error';
15
16
  publishMessage: string | null;
16
17
  publishUrl: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.svelte.d.ts","sourceRoot":"","sources":["../../src/dev/Sidebar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI1D,UAAU,KAAK;IACb,UAAU,EAAE,iBAAiB,CAAC;IAE9B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,EAAE,WAAW,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IACnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;CACvB;AA8NH,QAAA,MAAM,OAAO,uDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Sidebar.svelte.d.ts","sourceRoot":"","sources":["../../src/dev/Sidebar.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI1D,UAAU,KAAK;IACb,UAAU,EAAE,iBAAiB,CAAC;IAE9B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,EAAE,WAAW,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IACnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;CACvB;AAsOH,QAAA,MAAM,OAAO,uDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
package/dist/dev/app.css CHANGED
@@ -1 +1,2 @@
1
1
  @import "tailwindcss";
2
+ @custom-variant dark (&:where(.dark, .dark *));
@@ -3213,6 +3213,52 @@ function from_html(content, flags) {
3213
3213
  };
3214
3214
  }
3215
3215
  /**
3216
+ * @param {string} content
3217
+ * @param {number} flags
3218
+ * @param {'svg' | 'math'} ns
3219
+ * @returns {() => Node | Node[]}
3220
+ */
3221
+ /* @__NO_SIDE_EFFECTS__ */
3222
+ function from_namespace(content, flags, ns = "svg") {
3223
+ /**
3224
+ * Whether or not the first item is a text/element node. If not, we need to
3225
+ * create an additional comment node to act as `effect.nodes.start`
3226
+ */
3227
+ var has_start = !content.startsWith("<!>");
3228
+ var is_fragment = (flags & 1) !== 0;
3229
+ var wrapped = `<${ns}>${has_start ? content : "<!>" + content}</${ns}>`;
3230
+ /** @type {Element | DocumentFragment} */
3231
+ var node;
3232
+ return () => {
3233
+ if (hydrating) {
3234
+ assign_nodes(hydrate_node, null);
3235
+ return hydrate_node;
3236
+ }
3237
+ if (!node) {
3238
+ var root = /* @__PURE__ */ get_first_child(create_fragment_from_html(wrapped));
3239
+ if (is_fragment) {
3240
+ node = document.createDocumentFragment();
3241
+ while (/* @__PURE__ */ get_first_child(root)) node.appendChild(/* @__PURE__ */ get_first_child(root));
3242
+ } else node = /* @__PURE__ */ get_first_child(root);
3243
+ }
3244
+ var clone = node.cloneNode(true);
3245
+ if (is_fragment) {
3246
+ var start = /* @__PURE__ */ get_first_child(clone);
3247
+ var end = clone.lastChild;
3248
+ assign_nodes(start, end);
3249
+ } else assign_nodes(clone, clone);
3250
+ return clone;
3251
+ };
3252
+ }
3253
+ /**
3254
+ * @param {string} content
3255
+ * @param {number} flags
3256
+ */
3257
+ /* @__NO_SIDE_EFFECTS__ */
3258
+ function from_svg(content, flags) {
3259
+ return /* @__PURE__ */ from_namespace(content, flags, "svg");
3260
+ }
3261
+ /**
3216
3262
  * Don't mark this as side-effect-free, hydration needs to walk all nodes
3217
3263
  * @param {any} value
3218
3264
  */
@@ -9003,12 +9049,14 @@ var BridgeHost = class {
9003
9049
  channel;
9004
9050
  iframe;
9005
9051
  user;
9052
+ _colorScheme;
9006
9053
  eventCleanups = [];
9007
9054
  _destroyed = false;
9008
9055
  constructor(options) {
9009
9056
  this.channel = options.channel;
9010
9057
  this.iframe = options.iframe;
9011
9058
  this.user = options.user;
9059
+ this._colorScheme = options.colorScheme ?? "light";
9012
9060
  window.addEventListener("message", this._onMessage);
9013
9061
  for (const eventName of FORWARDED_EVENTS) {
9014
9062
  const handler = (data) => {
@@ -9034,6 +9082,7 @@ var BridgeHost = class {
9034
9082
  linkAccess: this.channel.linkAccess,
9035
9083
  userId: this.channel.userId,
9036
9084
  user: this.user,
9085
+ colorScheme: this._colorScheme,
9037
9086
  schema: this.channel.getSchema(),
9038
9087
  metadata: this.channel.getAllMetadata()
9039
9088
  };
@@ -9089,6 +9138,15 @@ var BridgeHost = class {
9089
9138
  });
9090
9139
  }
9091
9140
  }
9141
+ /** Update the color scheme and push to the extension iframe. */
9142
+ setColorScheme(colorScheme) {
9143
+ this._colorScheme = colorScheme;
9144
+ this._postToApp({
9145
+ type: "rool:event",
9146
+ name: "colorSchemeChanged",
9147
+ data: { colorScheme }
9148
+ });
9149
+ }
9092
9150
  _postToApp(message) {
9093
9151
  if (this._destroyed) return;
9094
9152
  this.iframe.contentWindow?.postMessage(message, "*");
@@ -9176,6 +9234,7 @@ var DevHostController = class {
9176
9234
  publishedExtensions = [];
9177
9235
  installedExtensionIds = [];
9178
9236
  sidebarCollapsed = false;
9237
+ colorScheme = "light";
9179
9238
  publishState = "idle";
9180
9239
  publishMessage = null;
9181
9240
  publishUrl = null;
@@ -9195,6 +9254,7 @@ var DevHostController = class {
9195
9254
  this._spaceKey = `rool-devhost:${options.channelId}:space`;
9196
9255
  this.env = this._getSavedEnv();
9197
9256
  this.sidebarCollapsed = storageGet("rool-devhost:collapsed") === "true";
9257
+ this.colorScheme = this._getSavedColorScheme();
9198
9258
  }
9199
9259
  get tabs() {
9200
9260
  return [{
@@ -9396,6 +9456,12 @@ var DevHostController = class {
9396
9456
  storageSet("rool-devhost:collapsed", String(this.sidebarCollapsed));
9397
9457
  this._onChange();
9398
9458
  }
9459
+ toggleColorScheme() {
9460
+ this.colorScheme = this.colorScheme === "light" ? "dark" : "light";
9461
+ storageSet("rool-devhost:colorScheme", this.colorScheme);
9462
+ for (const host of Object.values(this.bridgeHosts)) host.setColorScheme(this.colorScheme);
9463
+ this._onChange();
9464
+ }
9399
9465
  registerIframe(tabId, el) {
9400
9466
  this.iframeEls[tabId] = el;
9401
9467
  this._bindBridge(tabId);
@@ -9421,7 +9487,8 @@ var DevHostController = class {
9421
9487
  if (el && ch && !this.bridgeHosts[tabId]) this.bridgeHosts[tabId] = createBridgeHost({
9422
9488
  channel: ch,
9423
9489
  iframe: el,
9424
- user: this._bridgeUser
9490
+ user: this._bridgeUser,
9491
+ colorScheme: this.colorScheme
9425
9492
  });
9426
9493
  }
9427
9494
  _bindAllBridges() {
@@ -9464,6 +9531,11 @@ var DevHostController = class {
9464
9531
  if (saved === "local" || saved === "dev" || saved === "prod") return saved;
9465
9532
  return "prod";
9466
9533
  }
9534
+ _getSavedColorScheme() {
9535
+ const saved = storageGet("rool-devhost:colorScheme");
9536
+ if (saved === "light" || saved === "dark") return saved;
9537
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
9538
+ }
9467
9539
  };
9468
9540
  //#endregion
9469
9541
  //#region src/dev/Sidebar.svelte
@@ -9490,7 +9562,9 @@ var root_19 = /* @__PURE__ */ from_html(`<div class="absolute top-full mt-1 left
9490
9562
  var root_28 = /* @__PURE__ */ from_html(`<a target="_blank" rel="noopener noreferrer" class="block text-[11px] text-indigo-500 hover:text-indigo-600 mt-1.5 truncate"> </a>`);
9491
9563
  var root_29 = /* @__PURE__ */ from_html(`<div class="text-[11px] text-red-500 mt-1.5"> </div>`);
9492
9564
  var root_22 = /* @__PURE__ */ from_html(`<div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Publish</div> <button><!></button> <!></div>`);
9493
- var root_2$1 = /* @__PURE__ */ from_html(`<div class="w-[280px] shrink-0 bg-white border-r border-slate-200 flex flex-col overflow-y-auto"><div class="px-4 pt-4 pb-3 border-b border-slate-100"><div class="flex items-start justify-between mb-1"><!> <button class="p-1 -mr-1 text-slate-400 hover:text-slate-600 transition-colors shrink-0" title="Collapse sidebar"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"></path></svg></button></div> <!> <!> <!></div> <!> <!> <!> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Environment</div> <div class="flex rounded-md border border-slate-200 overflow-hidden"><button>Local</button> <button>Dev</button> <button>Prod</button></div> <div class="text-[10px] text-slate-400 mt-1 font-mono"> </div></div> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Space</div> <div class="relative" data-dropdown=""><button type="button"> <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"></path></svg></button> <!></div> <div class="text-[11px] text-slate-400 leading-normal mt-1.5"><span></span> </div></div> <!> <div class="px-4 py-3 mt-auto flex items-center justify-between"><a href="https://docs.rool.dev/app" target="_blank" rel="noopener noreferrer" class="text-[11px] text-slate-400 hover:text-indigo-500 transition-colors">Documentation</a> <button class="text-[11px] text-slate-400 hover:text-red-500 transition-colors">Sign out</button></div></div>`);
9565
+ var root_30 = /* @__PURE__ */ from_svg(`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>`);
9566
+ var root_31 = /* @__PURE__ */ from_svg(`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>`);
9567
+ var root_2$1 = /* @__PURE__ */ from_html(`<div class="w-[280px] shrink-0 bg-white border-r border-slate-200 flex flex-col overflow-y-auto"><div class="px-4 pt-4 pb-3 border-b border-slate-100"><div class="flex items-start justify-between mb-1"><!> <button class="p-1 -mr-1 text-slate-400 hover:text-slate-600 transition-colors shrink-0" title="Collapse sidebar"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"></path></svg></button></div> <!> <!> <!></div> <!> <!> <!> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Environment</div> <div class="flex rounded-md border border-slate-200 overflow-hidden"><button>Local</button> <button>Dev</button> <button>Prod</button></div> <div class="text-[10px] text-slate-400 mt-1 font-mono"> </div></div> <div class="px-4 py-3 border-b border-slate-100"><div class="text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-1.5">Space</div> <div class="relative" data-dropdown=""><button type="button"> <svg class="absolute right-2.5 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"></path></svg></button> <!></div> <div class="text-[11px] text-slate-400 leading-normal mt-1.5"><span></span> </div></div> <!> <div class="px-4 py-3 mt-auto flex items-center justify-between"><a href="https://docs.rool.dev/extension" target="_blank" rel="noopener noreferrer" class="text-[11px] text-slate-400 hover:text-indigo-500 transition-colors">Documentation</a> <button class="p-1 text-slate-400 hover:text-indigo-500 transition-colors"><!></button> <button class="text-[11px] text-slate-400 hover:text-red-500 transition-colors">Sign out</button></div></div>`);
9494
9568
  function Sidebar($$anchor, $$props) {
9495
9569
  push($$props, true);
9496
9570
  let dropdownOpen = prop($$props, "dropdownOpen", 15);
@@ -9511,7 +9585,7 @@ function Sidebar($$anchor, $$props) {
9511
9585
  delegated("click", button, () => $$props.controller.toggleSidebar());
9512
9586
  append($$anchor, div);
9513
9587
  };
9514
- var alternate_2 = ($$anchor) => {
9588
+ var alternate_3 = ($$anchor) => {
9515
9589
  var div_2 = root_2$1();
9516
9590
  var div_3 = child(div_2);
9517
9591
  var div_4 = child(div_3);
@@ -9818,6 +9892,19 @@ function Sidebar($$anchor, $$props) {
9818
9892
  });
9819
9893
  var div_38 = sibling(node_14, 2);
9820
9894
  var button_8 = sibling(child(div_38), 2);
9895
+ var node_17 = child(button_8);
9896
+ var consequent_22 = ($$anchor) => {
9897
+ append($$anchor, root_30());
9898
+ };
9899
+ var alternate_2 = ($$anchor) => {
9900
+ append($$anchor, root_31());
9901
+ };
9902
+ if_block(node_17, ($$render) => {
9903
+ if ($$props.colorScheme === "light") $$render(consequent_22);
9904
+ else $$render(alternate_2, -1);
9905
+ });
9906
+ reset(button_8);
9907
+ var button_9 = sibling(button_8, 2);
9821
9908
  reset(div_38);
9822
9909
  reset(div_2);
9823
9910
  template_effect(() => {
@@ -9829,6 +9916,7 @@ function Sidebar($$anchor, $$props) {
9829
9916
  set_text(text_12, `${get(selectedSpace)?.name ?? "Select a space..." ?? ""} `);
9830
9917
  set_class(span_6, 1, `inline-block w-1.5 h-1.5 rounded-full mr-1 align-middle ${$$props.statusState === "ok" ? "bg-green-500" : $$props.statusState === "loading" ? "bg-amber-500" : "bg-slate-400"}`);
9831
9918
  set_text(text_14, ` ${$$props.statusText ?? ""}`);
9919
+ set_attribute(button_8, "title", $$props.colorScheme === "light" ? "Switch to dark mode" : "Switch to light mode");
9832
9920
  });
9833
9921
  delegated("click", button_1, () => $$props.controller.toggleSidebar());
9834
9922
  delegated("click", button_2, () => $$props.controller.switchEnv("local"));
@@ -9838,12 +9926,13 @@ function Sidebar($$anchor, $$props) {
9838
9926
  e.stopPropagation();
9839
9927
  dropdownOpen(!dropdownOpen());
9840
9928
  });
9841
- delegated("click", button_8, () => $$props.controller.logout());
9929
+ delegated("click", button_8, () => $$props.controller.toggleColorScheme());
9930
+ delegated("click", button_9, () => $$props.controller.logout());
9842
9931
  append($$anchor, div_2);
9843
9932
  };
9844
9933
  if_block(node, ($$render) => {
9845
9934
  if ($$props.sidebarCollapsed) $$render(consequent);
9846
- else $$render(alternate_2, -1);
9935
+ else $$render(alternate_3, -1);
9847
9936
  });
9848
9937
  append($$anchor, fragment);
9849
9938
  pop();
@@ -15247,6 +15336,7 @@ function HostShell($$anchor, $$props) {
15247
15336
  let publishedExtensions = /* @__PURE__ */ state(proxy([]));
15248
15337
  let installedExtensionIds = /* @__PURE__ */ state(proxy([]));
15249
15338
  let tabs = /* @__PURE__ */ state(proxy([]));
15339
+ let colorScheme = /* @__PURE__ */ state("light");
15250
15340
  let publishState = /* @__PURE__ */ state("idle");
15251
15341
  let publishMessage = /* @__PURE__ */ state(null);
15252
15342
  let publishUrl = /* @__PURE__ */ state(null);
@@ -15264,6 +15354,7 @@ function HostShell($$anchor, $$props) {
15264
15354
  set(statusState, controller.statusState, true);
15265
15355
  set(placeholderText, controller.placeholderText, true);
15266
15356
  set(sidebarCollapsed, controller.sidebarCollapsed, true);
15357
+ set(colorScheme, controller.colorScheme, true);
15267
15358
  set(env, controller.env, true);
15268
15359
  set(publishedExtensions, controller.publishedExtensions, true);
15269
15360
  set(installedExtensionIds, controller.installedExtensionIds, true);
@@ -15312,6 +15403,9 @@ function HostShell($$anchor, $$props) {
15312
15403
  get sidebarCollapsed() {
15313
15404
  return get(sidebarCollapsed);
15314
15405
  },
15406
+ get colorScheme() {
15407
+ return get(colorScheme);
15408
+ },
15315
15409
  get publishState() {
15316
15410
  return get(publishState);
15317
15411
  },