@starlove/orbit 1.2.1 → 1.3.1

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/Dockerfile CHANGED
@@ -4,7 +4,7 @@ FROM node:22-slim AS runtime
4
4
  WORKDIR /app
5
5
 
6
6
  ENV NODE_ENV=production \
7
- PORT=3337 \
7
+ PORT=13701 \
8
8
  DATA_DIR=/data
9
9
 
10
10
  COPY package.json ./
@@ -14,7 +14,7 @@ COPY src ./src
14
14
  COPY dist/full ./dist/full
15
15
 
16
16
  VOLUME ["/data"]
17
- EXPOSE 3337
17
+ EXPOSE 13701
18
18
 
19
19
  ENTRYPOINT ["node", "/app/src/cli/orbit.js"]
20
20
  CMD ["serve", "--cwd", "/workspace"]
package/README.md CHANGED
@@ -51,28 +51,28 @@ orbit init --no-ai # optional: create or update the board with AI disabled
51
51
  Start one runtime and keep using it:
52
52
 
53
53
  ```bash
54
- orbit serve # host runtime, uses ~/.orbit, refreshes managed SKILL-ORBIT.md copies
54
+ orbit run # host runtime, uses ~/.orbit, refreshes managed SKILL-ORBIT.md copies
55
55
  # or
56
56
  orbit docker # Docker runtime, uses <repo>/.orbit/docker-data
57
57
  ```
58
58
 
59
- Both serve `http://localhost:3337`. Use `--port 3400` to change ports and `--cwd path/to/repo` to bind a specific repo.
59
+ Both runtimes serve from `http://localhost:13701` by default; `orbit run` auto-increments if that port is busy. Use `--port <n>` to force an exact port and `--cwd path/to/repo` to bind a specific repo. Use `orbit run -d` to start the host runtime in the background.
60
60
 
61
- `orbit serve` and `orbit docker` run the same app but use different registries by default. A board registered in one mode will not appear in the other unless you share `DATA_DIR`, re-register it, or import a snapshot.
61
+ `orbit run` and `orbit docker` run the same app but use different registries by default. A board registered in one mode will not appear in the other unless you share `DATA_DIR`, re-register it, or import a snapshot.
62
62
 
63
- For multiple boards, run your chosen runtime once. In another terminal, `cd` into another repo and run `orbit init`; the board joins that runtime's board picker without a restart. `SKILL-ORBIT.md` is Orbit-managed guidance and may be overwritten by `orbit init` or refreshed by `orbit serve`; keep repo/team-specific agent rules in `AGENTS.md` or board *Agent Instructions*.
63
+ For multiple boards, run your chosen runtime once. In another terminal, `cd` into another repo and run `orbit init`; the board joins that runtime's board picker without a restart. `SKILL-ORBIT.md` is Orbit-managed guidance and may be overwritten by `orbit init` or refreshed by `orbit run`; keep repo/team-specific agent rules in `AGENTS.md` or board *Agent Instructions*.
64
64
 
65
65
  Docker options:
66
66
 
67
67
  ```bash
68
- orbit docker # builds starscape-orbit:local, then serves http://localhost:3337
69
- orbit docker --port 3400 # same container flow on a different port
68
+ orbit docker # builds starscape-orbit:local, then serves http://localhost:13701
69
+ orbit docker --port 13702 # force a different published port
70
70
  orbit docker --no-build # reuse an existing starscape-orbit:local image
71
71
  ```
72
72
 
73
73
  `orbit docker` mounts the selected project into the container. Board data still lives in `.orbit/board.db`; Docker-only registry, exports, and backups live under `<repo>/.orbit/docker-data` by default.
74
74
 
75
- Wipe a single board and start over with `orbit reset` (deletes `.orbit/`, `SKILL-ORBIT.md`, and the registry row), then `orbit init` again. On Windows, close `orbit serve` terminals and restart any AI client using Orbit MCP before deleting or recloning a repo; those helper processes keep SQLite handles open while they are running.
75
+ Wipe a single board and start over with `orbit reset` (deletes `.orbit/`, `SKILL-ORBIT.md`, and the registry row), then `orbit init` again. On Windows, close Orbit runtime terminals and restart any AI client using Orbit MCP before deleting or recloning a repo; those helper processes keep SQLite handles open while they are running.
76
76
 
77
77
  ## Use with AI
78
78
 
@@ -80,7 +80,7 @@ Orbit ships with everything an agent needs to claim work, read tickets, and writ
80
80
 
81
81
  1. **Confirm AI is enabled.** Open Settings (gear icon) → **AI** tab → toggle **Enable AI** if needed. Orbit provisions the `AI Ready`, `In Progress`, and `Review` lanes if they're missing, surfaces the agent-context fields, and reveals the MCP setup snippet.
82
82
  2. **Fill in agent context.** Settings → AI → *Agent Instructions* is the project-level briefing every agent reads before touching a ticket. Describe what the project is, who it serves, the stack, and any rules of the road.
83
- 3. **Register the MCP server with your agent.** The AI tab generates copy-pasteable snippets for Claude Code, Cursor, Codex, OpenCode, OpenClaw, and other MCP-capable clients — pick your OS + client and paste the command into your agent's MCP config.
83
+ 3. **Register the MCP server with your agent.** The AI tab generates copy-pasteable snippets for Claude Code, VS Code, Cursor, Codex, OpenCode, OpenClaw, and other MCP-capable clients — pick your OS + client and paste the command into your agent's MCP config.
84
84
  4. **Restart the agent.** On its next boot it discovers the Orbit MCP tools (`board_claim_next`, `board_get_ticket_context`, `board_update_ticket`, etc.).
85
85
  5. **Point the agent at a ticket.** From inside the repo, ask the agent to read `SKILL-ORBIT.md` and then work on a ticket via the Orbit MCP — e.g., *"Use the Orbit MCP to claim the next AI-ready card and start work."* It pulls a focused context pack, claims the ticket, and updates the board as it goes.
86
86
 
@@ -115,7 +115,7 @@ Dispatch validates the local board, ticket, blockers, and Hermes availability be
115
115
 
116
116
  ## Requirements
117
117
 
118
- - **Node.js 22+**. The server uses the built-in `node:sqlite` module (an experimental Node feature). On boot you'll see a Node experimental-feature warning — that's expected.
118
+ - **Node.js 22.13+**. The server uses the built-in `node:sqlite` module, which is available without an experimental flag starting in 22.13 (or 23.4+). You'll still see an experimental-feature warning on boot — that's expected until the module stabilizes.
119
119
  - **pnpm 10+ for development**. The repo pins pnpm through `packageManager`; use Corepack (`corepack enable`) to get the right version.
120
120
 
121
121
  Bun is not used as the Orbit runtime because Orbit depends on Node's built-in `node:sqlite` module.
@@ -124,9 +124,9 @@ Bun is not used as the Orbit runtime because Orbit depends on Node's built-in `n
124
124
 
125
125
  Each repo gets its own board database. Orbit keeps a small central registry that maps repo paths to their board files; the CLI, web app, and MCP server use explicit project roots when provided, then fall back to walking upward to find `.orbit/board.db`.
126
126
 
127
- - **Per-repo board** — `.orbit/board.db` lives in the repo it tracks. `orbit init` creates it, writes the managed `SKILL-ORBIT.md` at the repo root, and creates/updates `AGENTS.md` with a terse pointer so agents load the full Orbit protocol only when relevant. `orbit serve` refreshes managed `SKILL-ORBIT.md` copies for registered repos on startup. Add `--example` to create onboarding cards, or `--no-ai` to disable AI collaboration for the board.
128
- - **Central registry** — `registry.db` records each board's path, slug, and last-active timestamp. Host `orbit serve` uses `~/.orbit`; `orbit docker` uses `<repo>/.orbit/docker-data`. Keep one mode unless you intentionally share `DATA_DIR`, re-register boards, or import snapshots.
129
- - **Project-root discovery** — `orbit serve`, `orbit mcp`, and MCP-attached agents resolve a board from an explicit `--cwd` / `PROJECT_ROOT` first, then fall back to walking up from process cwd to find `.orbit/board.db`. Persistent MCP configs should use an explicit root so the right board attaches even when the agent launches elsewhere.
127
+ - **Per-repo board** — `.orbit/board.db` lives in the repo it tracks. `orbit init` creates it, writes the managed `SKILL-ORBIT.md` at the repo root, and creates/updates `AGENTS.md` with a terse pointer so agents load the full Orbit protocol only when relevant. `orbit run` refreshes managed `SKILL-ORBIT.md` copies for registered repos on startup. Add `--example` to create onboarding cards, or `--no-ai` to disable AI collaboration for the board.
128
+ - **Central registry** — `registry.db` records each board's path, slug, and last-active timestamp. Host `orbit run` uses `~/.orbit`; `orbit docker` uses `<repo>/.orbit/docker-data`. Keep one mode unless you intentionally share `DATA_DIR`, re-register boards, or import snapshots.
129
+ - **Project-root discovery** — `orbit run`, `orbit mcp`, and MCP-attached agents resolve a board from an explicit `--cwd` / `PROJECT_ROOT` first, then fall back to walking up from process cwd to find `.orbit/board.db`. Persistent MCP configs should use an explicit root so the right board attaches even when the agent launches elsewhere.
130
130
  - **Two channels for AI** — `AGENTS.md` is the auto-loaded briefing, with an Orbit-managed pointer to `SKILL-ORBIT.md`; the *MCP config* tells the agent runtime how to launch Orbit's MCP server for the right project. The briefing travels with the repo; the MCP registration is per-agent-install.
131
131
  - **Snapshot-portable** — Settings → Repository → Export downloads a `.orbit.json` snapshot, with an option to embed attached images. Import on another install (or in the browser preview at [orbit.starscape.app/app](https://orbit.starscape.app/app)) to restore the same board.
132
132
 
@@ -139,7 +139,7 @@ pnpm test
139
139
  pnpm run build
140
140
  ```
141
141
 
142
- Open `http://localhost:3337`.
142
+ Open the URL printed by `orbit run` (normally `http://localhost:13701`).
143
143
 
144
144
  If you want an AI agent to work this board, point it at [SKILL-ORBIT.md](SKILL-ORBIT.md). Agent-facing HTTP/MCP details live in [docs/AGENT_PROTOCOL.md](docs/AGENT_PROTOCOL.md).
145
145
 
@@ -209,8 +209,7 @@ BOARD_NAME="My App" BOARD_SLUG=my-app REPO_URL=https://github.com/you/my-app orb
209
209
 
210
210
  - **UI loads but lanes are blank** — usually a cached `app.js`. Hard-refresh the page (Ctrl+Shift+R) and check the browser console.
211
211
  - **`node:sqlite` is not a known module** — you're on Node < 22. Upgrade to Node 22+.
212
- - **Port 3337 already in use** — run `orbit serve --port 3340` or `orbit docker --port 3340`.
213
- - **Windows says `.orbit/board.db` is busy during cleanup** - an Orbit web server, MCP helper, editor, or terminal still has the SQLite file open. Stop `orbit serve`, close or restart AI clients with Orbit MCP enabled, then retry delete from Settings or run `orbit reset --cwd <repo>` before recloning or deleting the folder.
212
+ - **Windows says `.orbit/board.db` is busy during cleanup** - an Orbit web server, MCP helper, editor, or terminal still has the SQLite file open. Stop the Orbit runtime, close or restart AI clients with Orbit MCP enabled, then retry delete from Settings or run `orbit reset --cwd <repo>` before recloning or deleting the folder.
214
213
 
215
214
  ## Data
216
215
 
@@ -223,12 +222,12 @@ Orbit stores each board in the repo it belongs to:
223
222
  Override runtime data with:
224
223
 
225
224
  ```bash
226
- DATA_DIR=/path/to/data orbit serve
225
+ DATA_DIR=/path/to/data orbit run
227
226
  orbit docker --data-dir /path/to/data
228
227
  ```
229
228
 
230
229
  ```powershell
231
- $env:DATA_DIR="C:\path\to\data"; orbit serve
230
+ $env:DATA_DIR="C:\path\to\data"; orbit run
232
231
  ```
233
232
 
234
233
  The UI exposes **Export** and **Import** from **Settings → Repository**.
package/SKILL-ORBIT.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Read this before repo work. This board is the repo-local memory and execution layer.
4
4
 
5
- This file is managed by Orbit and may be overwritten by `orbit init` or refreshed by `orbit serve`. Put repo/team-specific agent rules in `AGENTS.md` or board `agent_instructions`, not here.
5
+ This file is managed by Orbit and may be overwritten by `orbit init` or refreshed by `orbit run`. Put repo/team-specific agent rules in `AGENTS.md` or board `agent_instructions`, not here.
6
6
 
7
7
  ## MCP, cwd, and this file
8
8
 
@@ -33,14 +33,14 @@
33
33
  } catch (e) {}
34
34
  </script>
35
35
  <link rel="preload" as="image" href="./orbits-logo.png" />
36
- <link rel="stylesheet" href="styles.b7c19a07.css" />
36
+ <link rel="stylesheet" href="styles.65b79f8a.css" />
37
37
  <!-- Boot splash — the canonical ss-ui loading screen (see the package's
38
38
  components/loader.css). Inline critical CSS so it paints before
39
39
  /js/main.js loads. The logo grows in then breathes; no spinner.
40
- Keyframes namespaced `ss-loader-*`. Under reduced motion the grow-in
40
+ Keyframes namespaced `starscape-loader-*`. Under reduced motion the grow-in
41
41
  is dropped and the dot grid stops; the gentle breathe stays. -->
42
42
  <style>
43
- .ss-loader {
43
+ .loader {
44
44
  position: fixed;
45
45
  inset: 0;
46
46
  z-index: 99999;
@@ -60,7 +60,7 @@
60
60
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
61
61
  Roboto, "Helvetica Neue", Arial, sans-serif;
62
62
  }
63
- .ss-loader::before {
63
+ .loader::before {
64
64
  content: "";
65
65
  position: absolute;
66
66
  width: 200%;
@@ -72,24 +72,28 @@
72
72
  );
73
73
  background-size: 50px 50px;
74
74
  will-change: transform;
75
- animation: ss-loader-drift 20s linear infinite;
75
+ animation: starscape-loader-drift 20s linear infinite;
76
76
  }
77
- .ss-loader.is-hiding {
77
+ .loader.is-hiding {
78
78
  opacity: 0;
79
79
  pointer-events: none;
80
80
  }
81
- .ss-loader__logo {
81
+ .loader__logo {
82
82
  width: 120px;
83
83
  height: 120px;
84
84
  object-fit: contain;
85
85
  filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.3));
86
86
  transform-origin: center;
87
+ /* translateZ in the keyframes + backface-visibility keep the star
88
+ on a stable GPU layer, so it doesn't snap ~1px as the grow
89
+ starts. Keep in sync with the package components/loader.css. */
90
+ backface-visibility: hidden;
87
91
  will-change: transform;
88
92
  animation:
89
- ss-loader-grow 0.6s cubic-bezier(0.22, 1, 0.36, 1) both,
90
- ss-loader-breathe 3s ease-in-out 0.6s infinite;
93
+ starscape-loader-grow 0.6s cubic-bezier(0.22, 1, 0.36, 1) both,
94
+ starscape-loader-breathe 3s ease-in-out 0.6s infinite;
91
95
  }
92
- .ss-loader__label {
96
+ .loader__label {
93
97
  margin: 0;
94
98
  color: #fff;
95
99
  font-size: 1.25rem;
@@ -97,45 +101,45 @@
97
101
  letter-spacing: 0.5px;
98
102
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
99
103
  }
100
- @keyframes ss-loader-drift {
104
+ @keyframes starscape-loader-drift {
101
105
  from { transform: translate(0, 0); }
102
106
  to { transform: translate(-50px, -50px); }
103
107
  }
104
- @keyframes ss-loader-grow {
105
- from { transform: scale(0); opacity: 0; }
106
- to { transform: scale(1); opacity: 1; }
108
+ @keyframes starscape-loader-grow {
109
+ from { transform: scale(0) translateZ(0); opacity: 0; }
110
+ to { transform: scale(1) translateZ(0); opacity: 1; }
107
111
  }
108
- @keyframes ss-loader-breathe {
109
- 0%, 100% { transform: scale(1); }
110
- 50% { transform: scale(1.06); }
112
+ @keyframes starscape-loader-breathe {
113
+ 0%, 100% { transform: scale(1) translateZ(0); }
114
+ 50% { transform: scale(1.06) translateZ(0); }
111
115
  }
112
116
  @media (prefers-reduced-motion: reduce) {
113
- :root:not([data-motion="full"]) .ss-loader::before {
117
+ :root:not([data-motion="full"]) .loader::before {
114
118
  animation: none;
115
119
  }
116
- :root:not([data-motion="full"]) .ss-loader__logo {
117
- animation: ss-loader-breathe 3s ease-in-out infinite;
120
+ :root:not([data-motion="full"]) .loader__logo {
121
+ animation: starscape-loader-breathe 3s ease-in-out infinite;
118
122
  }
119
123
  }
120
- [data-motion="reduce"] .ss-loader::before {
124
+ [data-motion="reduce"] .loader::before {
121
125
  animation: none;
122
126
  }
123
- [data-motion="reduce"] .ss-loader__logo {
124
- animation: ss-loader-breathe 3s ease-in-out infinite;
127
+ [data-motion="reduce"] .loader__logo {
128
+ animation: starscape-loader-breathe 3s ease-in-out infinite;
125
129
  }
126
130
  </style>
127
131
  </head>
128
132
  <body>
129
133
  <!-- Boot splash - shown immediately, removed once the app is ready. -->
130
- <div id="ss-loader" class="ss-loader" role="status" aria-live="polite">
134
+ <div id="loader" class="loader" role="status" aria-live="polite">
131
135
  <img
132
- class="ss-loader__logo"
136
+ class="loader__logo"
133
137
  src="./orbits-logo.png"
134
138
  alt="Orbit"
135
139
  width="120"
136
140
  height="120"
137
141
  />
138
- <p class="ss-loader__label">Loading Orbit…</p>
142
+ <p class="loader__label">Loading Orbit…</p>
139
143
  </div>
140
144
 
141
145
  <div class="grain">
@@ -143,9 +147,40 @@
143
147
  </div>
144
148
  <header class="topbar">
145
149
  <div class="brand" aria-label="Orbit">
146
- <img class="mark" src="./orbits-logo.png" alt="Orbits logo" />
150
+ <button
151
+ id="brandFocusBtn"
152
+ type="button"
153
+ class="brand-focus-btn"
154
+ data-variant="brand-focus"
155
+ aria-label="Show board notes"
156
+ aria-expanded="false"
157
+ aria-controls="brandFocusPopover"
158
+ >
159
+ <img class="mark" src="./orbits-logo.png" alt="Orbits logo" />
160
+ </button>
161
+ <div
162
+ id="brandFocusPopover"
163
+ class="brand-focus-popover"
164
+ role="dialog"
165
+ aria-label="Board notes"
166
+ hidden
167
+ >
168
+ <div class="brand-focus-popover__eyebrow">Board notes</div>
169
+ <div id="brandFocusNotes" class="brand-focus-notes-body">No board notes yet</div>
170
+ </div>
147
171
  </div>
148
172
  <div class="controls">
173
+ <button
174
+ id="brandNotesBtn"
175
+ type="button"
176
+ class="topbar-notes brand-notes-strip"
177
+ data-variant="topbar-notes"
178
+ aria-label="Show board notes"
179
+ aria-expanded="false"
180
+ aria-controls="brandFocusPopover"
181
+ >
182
+ <span id="brandNotesText" class="topbar-notes__text"></span>
183
+ </button>
149
184
  <span class="topbar-controls-gap" aria-hidden="true"></span>
150
185
  <div class="topbar-search" id="topbarSearch">
151
186
  <input
@@ -235,6 +270,32 @@
235
270
  />
236
271
  </svg>
237
272
  </button>
273
+ <button
274
+ id="helpBtn"
275
+ type="button"
276
+ class="topbar-btn topbar-ctl-shrink"
277
+ data-variant="translucent"
278
+ aria-haspopup="dialog"
279
+ aria-controls="helpDialog"
280
+ >
281
+ <svg
282
+ class="topbar-icon"
283
+ width="16"
284
+ height="16"
285
+ viewBox="0 0 24 24"
286
+ fill="none"
287
+ stroke="currentColor"
288
+ stroke-width="2"
289
+ stroke-linecap="round"
290
+ stroke-linejoin="round"
291
+ aria-hidden="true"
292
+ >
293
+ <circle cx="12" cy="12" r="10" />
294
+ <path d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3" />
295
+ <path d="M12 17h.01" />
296
+ </svg>
297
+ Help
298
+ </button>
238
299
  <button
239
300
  id="settingsBtn"
240
301
  type="button"
@@ -424,14 +485,149 @@
424
485
  </div>
425
486
  </dialog>
426
487
 
427
- <script src="js/app.ccc442f7.js" type="module"></script>
488
+ <!-- Help & About. Reuses the .orbit-dialog shell + welcome-dialog-*
489
+ styling so it inherits the modal chrome; opened from the topbar
490
+ Help button and wired through modal.js (Escape/backdrop close). -->
491
+ <dialog
492
+ id="helpDialog"
493
+ class="orbit-dialog"
494
+ aria-labelledby="helpDialogTitle"
495
+ >
496
+ <div class="welcome-dialog-inner help-dialog-inner">
497
+ <div class="welcome-dialog-head">
498
+ <img
499
+ class="welcome-dialog-logo"
500
+ src="./orbits-logo.png"
501
+ alt=""
502
+ aria-hidden="true"
503
+ />
504
+ <span
505
+ class="welcome-dialog-edition-pill"
506
+ id="helpDialogVersion"
507
+ >Orbit</span
508
+ >
509
+ <button
510
+ type="button"
511
+ class="help-dialog-close"
512
+ aria-label="Close"
513
+ data-modal-close
514
+ >
515
+ ×
516
+ </button>
517
+ </div>
518
+ <div class="welcome-dialog-body">
519
+ <h2 id="helpDialogTitle" class="welcome-dialog-title">
520
+ Starscape Orbit
521
+ </h2>
522
+ <p class="welcome-dialog-lede">
523
+ A developer-first kanban board built for teams working
524
+ alongside AI agents. Track the motion of your project —
525
+ and hand work to your coding agent through the Orbit MCP
526
+ tools.
527
+ </p>
528
+
529
+ <section
530
+ class="help-dialog-section"
531
+ aria-label="Getting started"
532
+ >
533
+ <h3 class="help-dialog-heading">Getting started</h3>
534
+ <ol class="help-dialog-steps">
535
+ <li class="help-dialog-step">
536
+ <span class="help-dialog-step__index">01</span>
537
+ <div>
538
+ <h4>Create a board</h4>
539
+ <p>
540
+ Use the <strong>Board</strong> menu →
541
+ New board. Optionally point it at a
542
+ coding project folder so Orbit can drop
543
+ <code>SKILL-ORBIT.md</code> and
544
+ <code>AGENTS.md</code> for your agent.
545
+ </p>
546
+ </div>
547
+ </li>
548
+ <li class="help-dialog-step">
549
+ <span class="help-dialog-step__index">02</span>
550
+ <div>
551
+ <h4>Add cards &amp; the AI Ready lane</h4>
552
+ <p>
553
+ Capture work with
554
+ <strong>New Card</strong>. Move cards
555
+ into <strong>AI Ready</strong> to stage
556
+ them for an agent to claim.
557
+ </p>
558
+ </div>
559
+ </li>
560
+ <li class="help-dialog-step">
561
+ <span class="help-dialog-step__index">03</span>
562
+ <div>
563
+ <h4>Connect your coding agent</h4>
564
+ <p>
565
+ Add the Orbit MCP server from
566
+ <strong>Settings</strong>, then ask your
567
+ agent to read <code>AGENTS.md</code> and
568
+ claim the next ticket.
569
+ </p>
570
+ </div>
571
+ </li>
572
+ </ol>
573
+ </section>
574
+
575
+ <section
576
+ class="help-dialog-section"
577
+ aria-label="Links"
578
+ >
579
+ <h3 class="help-dialog-heading">Links</h3>
580
+ <ul class="help-dialog-links">
581
+ <li>
582
+ <a
583
+ class="welcome-dialog-link"
584
+ href="https://orbit.starscape.app"
585
+ target="_blank"
586
+ rel="noopener"
587
+ >Documentation</a
588
+ >
589
+ </li>
590
+ <li>
591
+ <a
592
+ class="welcome-dialog-link"
593
+ href="https://github.com/brucestarlove/ss-orbit/blob/master/docs/MCP_SETUP.md"
594
+ target="_blank"
595
+ rel="noopener"
596
+ >MCP setup</a
597
+ >
598
+ </li>
599
+ <li>
600
+ <a
601
+ class="welcome-dialog-link"
602
+ href="https://orbit.starscape.app/support"
603
+ target="_blank"
604
+ rel="noopener"
605
+ >Support / Tip</a
606
+ >
607
+ </li>
608
+ </ul>
609
+ </section>
610
+ </div>
611
+ <footer class="welcome-dialog-footer">
612
+ <button
613
+ type="button"
614
+ class="welcome-dialog-cta"
615
+ data-modal-close
616
+ >
617
+ Got it
618
+ </button>
619
+ </footer>
620
+ </div>
621
+ </dialog>
622
+
623
+ <script src="js/app.b8296a78.js" type="module"></script>
428
624
  <!-- Fade out the boot splash once the DOM is ready. The /js/main.js
429
625
  module runs before DOMContentLoaded, so theme/motion + wiring are
430
626
  already applied by the time this fires. -->
431
627
  <script>
432
628
  (function () {
433
629
  function hideSplash() {
434
- var splash = document.getElementById("ss-loader");
630
+ var splash = document.getElementById("loader");
435
631
  if (!splash) return;
436
632
  // Keep the splash up for a minimum of 786ms (measured from
437
633
  // navigation start) so a fast load doesn't flash it in and out.