@starlove/orbit 1.4.1 → 2.0.0
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 +10 -8
- package/README.md +146 -164
- package/dist/full/csp.txt +1 -0
- package/dist/full/fonts/JetBrains_Mono/JetBrainsMono-subset.woff2 +0 -0
- package/dist/full/fonts/JetBrains_Mono/README.txt +5 -0
- package/dist/full/fonts/Mona_Sans/MonaSans-subset.woff2 +0 -0
- package/{public/fonts/Open_Sans → dist/full/fonts/Mona_Sans}/OFL.txt +93 -93
- package/dist/full/fonts/Mona_Sans/README.txt +10 -0
- package/{public/fonts/JetBrains_Mono → dist/full/fonts/Newsreader}/OFL.txt +93 -93
- package/dist/full/fonts/Newsreader/README.txt +8 -0
- package/dist/full/fonts/Newsreader/newsreader.woff2 +0 -0
- package/dist/full/index.html +36 -653
- package/dist/full/js/app.BmuponPJ.js +32 -0
- package/dist/full/js/app.BmuponPJ.js.map +1 -0
- package/dist/full/js/chunk.1fJGQGbW.js +2 -0
- package/dist/full/js/chunk.1fJGQGbW.js.map +1 -0
- package/dist/full/js/chunk.5D7JO2zp.js +2 -0
- package/dist/full/js/chunk.5D7JO2zp.js.map +1 -0
- package/dist/full/js/chunk.BrNn_D79.js +2 -0
- package/dist/full/js/chunk.BrNn_D79.js.map +1 -0
- package/dist/full/js/chunk.CokJXIqM.js +2 -0
- package/dist/full/js/chunk.CokJXIqM.js.map +1 -0
- package/dist/full/js/chunk.D_Haqy6R.js +2 -0
- package/dist/full/js/chunk.D_Haqy6R.js.map +1 -0
- package/dist/full/js/chunk.RO0jsH6I.js +15 -0
- package/dist/full/js/chunk.RO0jsH6I.js.map +1 -0
- package/dist/full/js/chunk.dqWOEtBM.js +2 -0
- package/dist/full/js/chunk.dqWOEtBM.js.map +1 -0
- package/dist/full/js/warm.f260bbbc.js +15 -0
- package/dist/full/orbits-favicon.png +0 -0
- package/dist/full/orbits-logo-bg-wide.png +0 -0
- package/dist/full/orbits-logo-bg.png +0 -0
- package/dist/full/orbits-logo.png +0 -0
- package/dist/full/styles.2b154ffe.css +1 -0
- package/dist/full/vendor/starlove-ui/theme-init.js +66 -0
- package/dist/full/version.json +2 -2
- package/docs/AGENT_GUIDE.md +114 -0
- package/docs/UPDATING.md +249 -64
- package/lib/adapters/indexeddb/blobs.d.ts +3 -0
- package/lib/adapters/indexeddb/blobs.js +54 -0
- package/lib/adapters/indexeddb/database.d.ts +60 -0
- package/lib/adapters/indexeddb/database.js +126 -0
- package/lib/adapters/indexeddb/index.d.ts +5 -0
- package/lib/adapters/indexeddb/index.js +3 -0
- package/lib/adapters/indexeddb/locks.d.ts +14 -0
- package/lib/adapters/indexeddb/locks.js +40 -0
- package/lib/adapters/indexeddb/store.d.ts +40 -0
- package/lib/adapters/indexeddb/store.js +424 -0
- package/lib/adapters/indexeddb/tables.d.ts +43 -0
- package/lib/adapters/indexeddb/tables.js +127 -0
- package/lib/adapters/memory/blobs.d.ts +3 -0
- package/lib/adapters/memory/blobs.js +44 -0
- package/lib/adapters/memory/board.d.ts +41 -0
- package/lib/adapters/memory/board.js +521 -0
- package/lib/adapters/memory/index.d.ts +2 -0
- package/lib/adapters/memory/index.js +2 -0
- package/lib/adapters/memory/search.d.ts +6 -0
- package/lib/adapters/memory/search.js +30 -0
- package/lib/adapters/memory/store.d.ts +34 -0
- package/lib/adapters/memory/store.js +266 -0
- package/lib/adapters/sqlite/backups.d.ts +53 -0
- package/lib/adapters/sqlite/backups.js +232 -0
- package/lib/adapters/sqlite/blobs.d.ts +14 -0
- package/lib/adapters/sqlite/blobs.js +109 -0
- package/lib/adapters/sqlite/board.d.ts +77 -0
- package/lib/adapters/sqlite/board.js +328 -0
- package/lib/adapters/sqlite/database.d.ts +67 -0
- package/lib/adapters/sqlite/database.js +285 -0
- package/lib/adapters/sqlite/index.d.ts +3 -0
- package/lib/adapters/sqlite/index.js +2 -0
- package/lib/adapters/sqlite/lock.d.ts +11 -0
- package/lib/adapters/sqlite/lock.js +34 -0
- package/lib/adapters/sqlite/records.d.ts +54 -0
- package/lib/adapters/sqlite/records.js +546 -0
- package/lib/adapters/sqlite/schema.d.ts +54 -0
- package/lib/adapters/sqlite/schema.js +276 -0
- package/lib/adapters/sqlite/store.d.ts +39 -0
- package/lib/adapters/sqlite/store.js +385 -0
- package/lib/browser/in-page.d.ts +31 -0
- package/lib/browser/in-page.js +46 -0
- package/lib/browser/old-preview.d.ts +13 -0
- package/lib/browser/old-preview.js +80 -0
- package/lib/browser/preview-board.d.ts +8 -0
- package/lib/browser/preview-board.js +69 -0
- package/lib/cli/main.d.ts +7 -0
- package/lib/cli/main.js +343 -0
- package/lib/cli/orbit.d.ts +8 -0
- package/lib/cli/orbit.js +25 -0
- package/lib/client/http.d.ts +38 -0
- package/lib/client/http.js +334 -0
- package/lib/client/local.d.ts +26 -0
- package/lib/client/local.js +190 -0
- package/lib/client/object-url.d.ts +8 -0
- package/lib/client/object-url.js +21 -0
- package/lib/client/types.d.ts +268 -0
- package/lib/client/types.js +8 -0
- package/lib/commands/agent-tools.d.ts +31 -0
- package/lib/commands/agent-tools.js +100 -0
- package/lib/commands/index.d.ts +56 -0
- package/lib/commands/index.js +298 -0
- package/lib/commands/parse.d.ts +73 -0
- package/lib/commands/parse.js +231 -0
- package/lib/commands/present.d.ts +134 -0
- package/lib/commands/present.js +198 -0
- package/lib/commands/session.d.ts +85 -0
- package/lib/commands/session.js +138 -0
- package/lib/commands/verbs.d.ts +35 -0
- package/lib/commands/verbs.js +842 -0
- package/lib/core/actors.d.ts +18 -0
- package/lib/core/actors.js +45 -0
- package/lib/core/agent.d.ts +128 -0
- package/lib/core/agent.js +323 -0
- package/lib/core/boards.d.ts +113 -0
- package/lib/core/boards.js +288 -0
- package/lib/core/bootstrap.d.ts +47 -0
- package/lib/core/bootstrap.js +100 -0
- package/lib/core/bytes.d.ts +10 -0
- package/lib/core/bytes.js +52 -0
- package/lib/core/card-paths.d.ts +25 -0
- package/lib/core/card-paths.js +44 -0
- package/lib/core/context.d.ts +60 -0
- package/lib/core/context.js +42 -0
- package/lib/core/cross-board.d.ts +81 -0
- package/lib/core/cross-board.js +228 -0
- package/lib/core/describe.d.ts +21 -0
- package/lib/core/describe.js +81 -0
- package/lib/core/errors.d.ts +159 -0
- package/lib/core/errors.js +160 -0
- package/lib/core/files.d.ts +79 -0
- package/lib/core/files.js +262 -0
- package/lib/core/history.d.ts +20 -0
- package/lib/core/history.js +53 -0
- package/lib/core/image-types.d.ts +16 -0
- package/lib/core/image-types.js +36 -0
- package/lib/core/model.d.ts +263 -0
- package/lib/core/model.js +34 -0
- package/lib/core/nebula-link.d.ts +14 -0
- package/lib/core/nebula-link.js +39 -0
- package/lib/core/relations.d.ts +58 -0
- package/lib/core/relations.js +112 -0
- package/lib/core/search.d.ts +38 -0
- package/lib/core/search.js +92 -0
- package/lib/core/sessions.d.ts +44 -0
- package/lib/core/sessions.js +158 -0
- package/lib/core/snapshot-schema.d.ts +295 -0
- package/lib/core/snapshot-schema.js +82 -0
- package/lib/core/snapshots.d.ts +75 -0
- package/lib/core/snapshots.js +409 -0
- package/lib/core/states.d.ts +25 -0
- package/lib/core/states.js +126 -0
- package/lib/core/text.d.ts +40 -0
- package/lib/core/text.js +113 -0
- package/lib/core/tickets.d.ts +69 -0
- package/lib/core/tickets.js +311 -0
- package/lib/core/trello.d.ts +17 -0
- package/lib/core/trello.js +269 -0
- package/lib/core/verdicts.d.ts +28 -0
- package/lib/core/verdicts.js +92 -0
- package/lib/core/views.d.ts +95 -0
- package/lib/core/views.js +186 -0
- package/lib/http/app.d.ts +46 -0
- package/lib/http/app.js +491 -0
- package/lib/mcp-server.d.ts +10 -0
- package/lib/mcp-server.js +120 -0
- package/lib/node/assets.d.ts +7 -0
- package/lib/node/assets.js +68 -0
- package/lib/node/data-folder.d.ts +21 -0
- package/lib/node/data-folder.js +34 -0
- package/lib/node/env.d.ts +38 -0
- package/lib/node/env.js +49 -0
- package/lib/node/host-check.d.ts +24 -0
- package/lib/node/host-check.js +53 -0
- package/lib/node/host-services.d.ts +9 -0
- package/lib/node/host-services.js +150 -0
- package/lib/node/local.d.ts +22 -0
- package/lib/node/local.js +61 -0
- package/lib/node/migrate.d.ts +53 -0
- package/lib/node/migrate.js +635 -0
- package/lib/node/package.d.ts +7 -0
- package/lib/node/package.js +14 -0
- package/lib/node/repo-board.d.ts +49 -0
- package/lib/node/repo-board.js +245 -0
- package/lib/node/serve.d.ts +8 -0
- package/lib/node/serve.js +106 -0
- package/lib/orbit.d.ts +47 -0
- package/lib/orbit.js +44 -0
- package/lib/quiet-sqlite-warning.d.ts +1 -0
- package/lib/quiet-sqlite-warning.js +18 -0
- package/lib/store/blob-path.d.ts +6 -0
- package/lib/store/blob-path.js +12 -0
- package/lib/store/conformance.d.ts +52 -0
- package/lib/store/conformance.js +1449 -0
- package/lib/store/search-words.d.ts +10 -0
- package/lib/store/search-words.js +19 -0
- package/lib/store/types.d.ts +452 -0
- package/lib/store/types.js +34 -0
- package/llms.txt +63 -0
- package/package.json +109 -25
- package/src/cli/orbit.js +11 -658
- package/src/mcp-server.js +16 -876
- package/SKILL-ORBIT.md +0 -151
- package/build.mjs +0 -210
- package/dist/full/js/app.4e6fbe20.js +0 -952
- package/dist/full/js/app.4e6fbe20.js.map +0 -7
- package/dist/full/styles.4e60d824.css +0 -1
- package/docs/AGENT_PROTOCOL.md +0 -424
- package/docs/MCP_SETUP.md +0 -54
- package/docs/ORBIT_DISPATCH.md +0 -280
- package/docs/SS-Orbit-Dark.png +0 -0
- package/docs/SS-Orbit-Light.png +0 -0
- package/docs/mcp-client.example.json +0 -13
- package/docs/setup/orbit-init-wizard.md +0 -174
- package/public/apple-touch-icon.png +0 -0
- package/public/cursors/live_arrow.cur +0 -0
- package/public/cursors/live_link.cur +0 -0
- package/public/cursors/live_move.cur +0 -0
- package/public/cursors/live_select.cur +0 -0
- package/public/cursors/live_unavail.cur +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Bold.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-BoldItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Italic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Light.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-LightItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Medium.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-MediumItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-Regular.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-SemiBold.ttf +0 -0
- package/public/fonts/Chakra_Petch/ChakraPetch-SemiBoldItalic.ttf +0 -0
- package/public/fonts/Chakra_Petch/OFL.txt +0 -93
- package/public/fonts/Inter/Inter-Italic-VariableFont_opsz,wght.ttf +0 -0
- package/public/fonts/Inter/Inter-VariableFont_opsz,wght.ttf +0 -0
- package/public/fonts/Inter/OFL.txt +0 -93
- package/public/fonts/Inter/README.txt +0 -118
- package/public/fonts/JetBrains_Mono/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- package/public/fonts/JetBrains_Mono/JetBrainsMono-VariableFont_wght.ttf +0 -0
- package/public/fonts/JetBrains_Mono/README.txt +0 -79
- package/public/fonts/OpenRing-Regular.ttf +0 -0
- package/public/fonts/Open_Sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/public/fonts/Open_Sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- package/public/fonts/Open_Sans/README.txt +0 -100
- package/public/fonts/Orbitron/OFL.txt +0 -93
- package/public/fonts/Orbitron/Orbitron-VariableFont_wght.ttf +0 -0
- package/public/fonts/Orbitron/README.txt +0 -68
- package/public/fonts/Rajdhani/OFL.txt +0 -93
- package/public/fonts/Rajdhani/Rajdhani-Bold.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Light.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Medium.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-Regular.ttf +0 -0
- package/public/fonts/Rajdhani/Rajdhani-SemiBold.ttf +0 -0
- package/public/fonts/runescape-uf.ttf +0 -0
- package/public/index.html +0 -769
- package/public/js/actor-labels.js +0 -65
- package/public/js/api.js +0 -39
- package/public/js/app.js +0 -45
- package/public/js/artifact-drawer.js +0 -79
- package/public/js/board-export.js +0 -161
- package/public/js/board-menu.js +0 -374
- package/public/js/card-actions.js +0 -545
- package/public/js/config.js +0 -20
- package/public/js/create-card.js +0 -190
- package/public/js/dom.js +0 -19
- package/public/js/drawer.js +0 -273
- package/public/js/font-preference.js +0 -230
- package/public/js/format.js +0 -433
- package/public/js/help-menu.js +0 -31
- package/public/js/icons.js +0 -16
- package/public/js/kanban.js +0 -694
- package/public/js/local-backend.js +0 -1015
- package/public/js/main.js +0 -161
- package/public/js/modal.js +0 -33
- package/public/js/motion-preference.js +0 -64
- package/public/js/panel.js +0 -58
- package/public/js/router.js +0 -134
- package/public/js/search.js +0 -56
- package/public/js/settings-tabs.js +0 -7
- package/public/js/settings.js +0 -1634
- package/public/js/sse.js +0 -159
- package/public/js/starscape.js +0 -332
- package/public/js/state.js +0 -129
- package/public/js/text-editing.js +0 -128
- package/public/js/theme-preference.js +0 -95
- package/public/js/ticket-detail.js +0 -1516
- package/public/js/ticket-typeahead.js +0 -49
- package/public/js/toast.js +0 -89
- package/public/js/topbar-notes.js +0 -155
- package/public/js/transport.js +0 -22
- package/public/js/typeahead.js +0 -206
- package/public/js/unread.js +0 -121
- package/public/js/update-check.js +0 -58
- package/public/js/url-routes.js +0 -94
- package/public/orbits-favicon.png +0 -0
- package/public/orbits-logo-bg-wide.png +0 -0
- package/public/orbits-logo-bg.png +0 -0
- package/public/orbits-logo.png +0 -0
- package/public/styles.css +0 -7709
- package/src/core/agent.js +0 -387
- package/src/core/agents-md.js +0 -109
- package/src/core/artifacts.js +0 -149
- package/src/core/attachments.js +0 -238
- package/src/core/auth.js +0 -85
- package/src/core/backups.js +0 -142
- package/src/core/board.js +0 -148
- package/src/core/boards.js +0 -409
- package/src/core/bootstrap.js +0 -170
- package/src/core/css-bundle.js +0 -30
- package/src/core/db.js +0 -315
- package/src/core/delete-board.js +0 -163
- package/src/core/dispatch.js +0 -1007
- package/src/core/events.js +0 -314
- package/src/core/http.js +0 -115
- package/src/core/migrate.js +0 -198
- package/src/core/paths.js +0 -55
- package/src/core/provision-repo-board.js +0 -119
- package/src/core/queries.js +0 -246
- package/src/core/registry.js +0 -211
- package/src/core/relations.js +0 -163
- package/src/core/review-verdicts.js +0 -138
- package/src/core/router.js +0 -556
- package/src/core/search.js +0 -183
- package/src/core/seed.js +0 -234
- package/src/core/snapshots.js +0 -692
- package/src/core/states.js +0 -167
- package/src/core/system-picker.js +0 -109
- package/src/core/tickets.js +0 -400
- package/src/core/util.js +0 -106
- package/src/core/version-check.js +0 -154
- package/src/mcp/orbit-client.js +0 -287
- package/src/server.js +0 -115
package/Dockerfile
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# syntax=docker/dockerfile:1
|
|
2
|
+
# Build the web app and the server first, as npm pack does:
|
|
3
|
+
# node build.mjs --edition=full && npx tsc -p tsconfig.build.json
|
|
4
|
+
# The image installs only Orbit's runtime libraries (package.json dependencies).
|
|
2
5
|
|
|
3
|
-
FROM node:
|
|
6
|
+
FROM node:24-slim AS runtime
|
|
4
7
|
WORKDIR /app
|
|
5
8
|
|
|
6
9
|
ENV NODE_ENV=production \
|
|
7
10
|
PORT=13701 \
|
|
8
|
-
DATA_DIR=/data
|
|
9
|
-
ORBIT_USE_DIST=1
|
|
11
|
+
DATA_DIR=/data
|
|
10
12
|
|
|
11
|
-
COPY package.json ./
|
|
12
|
-
|
|
13
|
+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
|
14
|
+
RUN corepack enable && pnpm install --prod --frozen-lockfile --ignore-scripts
|
|
13
15
|
COPY docs ./docs
|
|
14
|
-
COPY
|
|
16
|
+
COPY lib ./lib
|
|
15
17
|
COPY dist/full ./dist/full
|
|
16
18
|
|
|
17
19
|
VOLUME ["/data"]
|
|
18
20
|
EXPOSE 13701
|
|
19
21
|
|
|
20
|
-
ENTRYPOINT ["node", "/app/
|
|
21
|
-
CMD ["
|
|
22
|
+
ENTRYPOINT ["node", "/app/lib/cli/orbit.js"]
|
|
23
|
+
CMD ["run"]
|
package/README.md
CHANGED
|
@@ -2,239 +2,221 @@
|
|
|
2
2
|
|
|
3
3
|
*Spin up an Orbit to track the motion of your project.*
|
|
4
4
|
|
|
5
|
-
**Orbit
|
|
5
|
+
**Tell your agent to use Orbit.** Your agent keeps the tickets, plans, and decisions. You get a calm, beautiful board to watch the work move.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Orbit is a local-first kanban board for people and their AI agents. Boards stand alone; a code repository is optional. Each board has its own SQLite database, and Orbit keeps every board together in one data folder on your computer or your own server. Agents work the board through one small command language, the same in a shell, over MCP and over HTTP; you watch it live in the browser.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- Agent API/MCP for claiming work, reading context, updating implementation notes, commenting, and writing project memory.
|
|
9
|
+
## Quick start
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
Say this to your AI agent (Claude Code, Codex, Cursor, Hermes, or any MCP client):
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
> Install Starscape Orbit and use it to manage this project. Setup: orbit.starscape.app/llms.txt
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-

|
|
19
|
-
|
|
20
|
-
## 🛰️ Zero external runtime dependencies
|
|
21
|
-
|
|
22
|
-
**Orbit's server, CLI, and MCP layer run with zero external runtime dependencies.** They use Node.js built-ins: `node:sqlite`, `node:http`, `node:crypto`, and friends.
|
|
23
|
-
|
|
24
|
-
Build-time packages include Starscape's own `@starlove/ui` styling and [`esbuild`](https://esbuild.github.io/) for bundling the web UI. They are not needed by initialized project boards at runtime.
|
|
25
|
-
|
|
26
|
-
## Install and use Orbit
|
|
27
|
-
|
|
28
|
-
Install the CLI:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
corepack enable
|
|
32
|
-
pnpm add -g @starlove/orbit
|
|
33
|
-
|
|
34
|
-
# or, from source:
|
|
35
|
-
git clone git@github.com:brucestarlove/ss-orbit.git
|
|
36
|
-
cd ss-orbit
|
|
37
|
-
pnpm install
|
|
38
|
-
pnpm run build:bundle
|
|
39
|
-
pnpm link --global
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
From the repo you want a board for:
|
|
15
|
+
Or do it yourself:
|
|
43
16
|
|
|
44
17
|
```bash
|
|
45
|
-
|
|
46
|
-
orbit
|
|
47
|
-
orbit init --example # optional: add onboarding example tickets
|
|
48
|
-
orbit init --no-ai # optional: create or update the board with AI disabled
|
|
18
|
+
npm i -g @starlove/orbit && orbit run -d # starts Orbit at http://localhost:13701
|
|
19
|
+
claude mcp add --scope user orbit --env ORBIT_AGENT_NAME=claude -- orbit mcp # connect your agent (other apps: Help, Connect your agents)
|
|
49
20
|
```
|
|
50
21
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
orbit run # host runtime, uses ~/.orbit, refreshes managed SKILL-ORBIT.md copies
|
|
55
|
-
# or
|
|
56
|
-
orbit docker # Docker runtime, uses <repo>/.orbit/docker-data
|
|
57
|
-
```
|
|
22
|
+
**For AI agents:** full setup steps for every client, including running Orbit on a private server, are at [orbit.starscape.app/llms.txt](https://orbit.starscape.app/llms.txt). Orbit speaks one small command language everywhere: `orbit view`, `orbit take`, `orbit finish 12 -m "..."` in a shell, or the same lines through the `orbit_read` and `orbit_write` MCP tools. `help` lists them all.
|
|
58
23
|
|
|
59
|
-
|
|
24
|
+

|
|
25
|
+

|
|
60
26
|
|
|
61
|
-
|
|
27
|
+
## Install and run
|
|
62
28
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Docker options:
|
|
29
|
+
Requires **Node.js 22.16 or newer**; 24 is recommended. (Orbit searches with SQLite's full-text search, which Node's own SQLite has from 22.16; `orbit` says so on an older Node.) Orbit supports Node 22 until Node's own security support for it ends, on April 30, 2027; the first Orbit release after that needs Node 24. Node from [nodejs.org](https://nodejs.org) or a version manager starts each `orbit` command about three times faster than Ubuntu's `nodejs` package. Install once, then start Orbit **from any directory**:
|
|
66
30
|
|
|
67
31
|
```bash
|
|
68
|
-
|
|
69
|
-
orbit
|
|
70
|
-
orbit docker --no-build # reuse an existing starscape-orbit:local image
|
|
32
|
+
npm install -g @starlove/orbit
|
|
33
|
+
orbit run
|
|
71
34
|
```
|
|
72
35
|
|
|
73
|
-
|
|
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 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.
|
|
36
|
+
Open the URL printed in the terminal (normally `http://localhost:13701`). Choose **Create a board** or **Import a board**. Orbit starts with no boards and makes only the ones you choose.
|
|
76
37
|
|
|
77
|
-
|
|
38
|
+
The server listens on **127.0.0.1** by default. `orbit run -d` keeps it running in the background (its log: `orbit-run.log` in the data folder); `--port <n>` chooses an exact port, otherwise Orbit takes the first free port from 13701. Set `DATA_DIR` to choose where boards live, and give the server, the CLI and every MCP server the same value.
|
|
78
39
|
|
|
79
|
-
Orbit
|
|
40
|
+
**Coming from Orbit 1.x?** Orbit 2.0 keeps its boards in a new folder, `~/.starscape/orbit`, and doesn't open a 1.x data folder. From any 1.x (1.0 to 1.4) or the 2.0 preview:
|
|
80
41
|
|
|
81
|
-
1.
|
|
82
|
-
2.
|
|
83
|
-
3.
|
|
84
|
-
4.
|
|
85
|
-
5.
|
|
42
|
+
1. Stop the old Orbit and its MCP servers, then `npm i -g @starlove/orbit@2`.
|
|
43
|
+
2. `orbit migrate` brings every board, card, comment, image and journal entry from `~/.orbit`, boards 1.x kept inside a project included, checks each against the original, and never changes the old folder. Kept your boards somewhere else? `orbit migrate <old folder>`.
|
|
44
|
+
3. `orbit run`.
|
|
45
|
+
4. Reconnect your agents with `orbit mcp` (Settings, AI). Setups made by 1.x still start until Orbit 3.0.
|
|
46
|
+
5. Remove the `SKILL-ORBIT.md` and `AGENTS.md` block 1.x wrote into your projects.
|
|
86
47
|
|
|
87
|
-
|
|
48
|
+
[Updating](docs/UPDATING.md) has the details, and the steps for a git checkout, a server and Docker. [The changelog](CHANGELOG.md) has what's new.
|
|
88
49
|
|
|
89
|
-
|
|
50
|
+
**Orbit 1.x stays.** 1.x's server, CLI and MCP run on Node's built-ins alone. It keeps that promise on its own line (`npm i -g @starlove/orbit@1`), and gets its own update after 2.0. Orbit 2.0 takes four runtime libraries, listed below, each for something 1.x wrote by hand.
|
|
90
51
|
|
|
91
|
-
|
|
52
|
+
### From source
|
|
92
53
|
|
|
93
54
|
```bash
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
55
|
+
git clone https://github.com/brucestarlove/ss-orbit.git
|
|
56
|
+
cd ss-orbit
|
|
57
|
+
pnpm install
|
|
58
|
+
npm run build:bundle && npm run build:node # the web app into dist/full, the server into lib/
|
|
59
|
+
node lib/cli/orbit.js run
|
|
98
60
|
```
|
|
99
61
|
|
|
100
|
-
|
|
62
|
+
Node 24 also runs the TypeScript directly: `node src/cli/orbit.ts run`. `npm run verify` is the check before a change (types, lint, the tests and the contract fixtures); [contributing](CONTRIBUTING.md) has the rest.
|
|
101
63
|
|
|
102
|
-
|
|
64
|
+
## How it's built
|
|
103
65
|
|
|
104
|
-
|
|
66
|
+
Orbit is one core with several doors, over a storage contract any database can implement.
|
|
105
67
|
|
|
106
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
- `task` — a smaller, scoped unit of work.
|
|
112
|
-
- `bug` — defect, regression, or broken behavior.
|
|
113
|
-
- **Checkpoint** — mid-work human judgment: call `checkpoint` with your question. The ticket moves to `Review`; the `checkpoint` comment marks the blocking fork. Use `complete` when work is finished.
|
|
114
|
-
- **Two relationship models** — hierarchy (`parent_ticket_id`, set on the row, only epics own children) is separate from the relations table (`relates_to`, `blocks`, `blocked_by`). The server keeps them disjoint.
|
|
115
|
-
- **Blockers** — a per-card `blocked_by` row in the relations table is the single source of truth. If the row exists, the ticket is blocked. Rows are removed two ways: the user deletes the relation manually in the UI, **or** the *blocking* ticket lands in the **Done** lane and the server auto-deletes every relation row that named it as a blocker. (Epic targets expand to their open children — see `GET /api/tickets/:id/blockers`.)
|
|
68
|
+
- **The core** (`src/core/`) holds every rule: boards, cards, lanes, the journal, search, imports and exports. It runs on Node and in a browser alike, and touches storage only through the **storage port** (`src/store/types.ts`), an async interface with a conformance suite every adapter passes.
|
|
69
|
+
- **Three adapters** implement the port: SQLite on a computer or server (`node:sqlite`, a database per board), IndexedDB in the browser, and memory for tests and embedding.
|
|
70
|
+
- **The command language** (`src/commands/`) is what agents speak: `view`, `take`, `finish #12` and the rest, as short text answers built for models. The CLI, the MCP server and `POST /api/cmd` all run it.
|
|
71
|
+
- **The doors:** `orbit run` serves the JSON API and the web app; `orbit mcp` is a stdio MCP server with two tools, `orbit_read` and `orbit_write`; the `orbit` CLI runs commands in a shell. Each works on the data folder directly or, with `ORBIT_MODE=remote`, against a server.
|
|
72
|
+
- **The web app** (`web/`) is React with zustand, built by Vite. The full edition talks to `orbit run`; the browser edition at [orbit.starscape.app/app/](https://orbit.starscape.app/app/) runs the whole core in the page over IndexedDB, offline once loaded.
|
|
116
73
|
|
|
117
|
-
|
|
74
|
+
[Architecture](docs/ARCHITECTURE.md) has the map, the contracts and how to write an adapter of your own.
|
|
118
75
|
|
|
119
|
-
|
|
120
|
-
- **pnpm 10+ for development**. The repo pins pnpm through `packageManager`; use Corepack (`corepack enable`) to get the right version.
|
|
76
|
+
### Runtime libraries
|
|
121
77
|
|
|
122
|
-
|
|
78
|
+
What `npm install` brings, and what each is for:
|
|
123
79
|
|
|
124
|
-
|
|
80
|
+
| Library | For |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| [`hono`](https://hono.dev) | The JSON API's routes. The same app answers `orbit run`'s requests and, in the browser edition, the page's own. |
|
|
83
|
+
| [`@hono/node-server`](https://github.com/honojs/node-server) | Serves that app on Node's HTTP server for `orbit run`. |
|
|
84
|
+
| [`@modelcontextprotocol/server`](https://github.com/modelcontextprotocol/typescript-sdk) | The MCP protocol for `orbit mcp`: the handshake, the tool list and the calls. |
|
|
85
|
+
| [`zod`](https://zod.dev) | Checks an imported board's file before anything is written. Loaded only when an import runs. |
|
|
125
86
|
|
|
126
|
-
|
|
87
|
+
React, zustand and the web app's other code are compiled into the bundle Orbit ships (`dist/full`), so they aren't installed at runtime. SQLite is Node's own `node:sqlite`.
|
|
127
88
|
|
|
128
|
-
|
|
129
|
-
- **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.
|
|
130
|
-
- **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.
|
|
131
|
-
- **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.
|
|
132
|
-
- **Snapshot-portable** — Settings → Data → 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.
|
|
89
|
+
## Boards
|
|
133
90
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
pnpm install
|
|
138
|
-
pnpm run dev
|
|
139
|
-
pnpm test
|
|
140
|
-
pnpm run build
|
|
141
|
-
```
|
|
91
|
+
Make a board in **Board → New**, or let a connected agent run `boards new <name>` (`orbit boards new <name>` in a shell). A board's slug is its stable name. Every board lives in Orbit's data folder, whatever folder you or your agent work in.
|
|
142
92
|
|
|
143
|
-
|
|
93
|
+
Orbit never writes files into your repo. Agents learn Orbit from Orbit itself: the MCP instructions, `help`, and the guide. Put a project's rules for agents in the board's Agent Instructions (**Settings → AI**). Delete a board in **Settings → Data**; Orbit backs it up first.
|
|
144
94
|
|
|
145
|
-
|
|
95
|
+
### Agent use
|
|
146
96
|
|
|
147
|
-
**
|
|
97
|
+
AI is on by default (**Settings → AI**), where you also write Agent Instructions and copy the setup for your agent's app. Agents work the board through one command language, the same in every client: a shell runs `orbit view`, MCP clients get two tools (`orbit_read`, `orbit_write`) that take the same command lines, and other programs `POST /api/cmd`. Answers are short text built for models: one line per card, cards as `#12`, lanes by name. An agent learns the loop from the server: short instructions on connect, the board's rules and next steps with every card it takes, `help`, and the full guide ([`docs/AGENT_GUIDE.md`](docs/AGENT_GUIDE.md)). Set `ORBIT_AGENT_NAME` so the board shows who did what.
|
|
148
98
|
|
|
149
|
-
|
|
99
|
+
Day to day, move a card to **AI Ready** (the agent's `take` picks it up) or say "work on ticket 12" (`take #12`). The agent checks the card has enough context, asks if it doesn't, and hands finished work back in **Review**.
|
|
150
100
|
|
|
151
|
-
|
|
101
|
+
An agent picks a board by its slug. Starting MCP **makes no board**. With one board, commands use it; with several, name one (`view <board>`, `board#12`), let the repo name it (`orbit boards link <board>` writes a one-line `orbit.json` to commit, so every agent in the repo lands on it), or set a default with `orbit boards use <board>` in a terminal (for every folder on this computer) or `ORBIT_BOARD`. Over MCP, `boards use` chooses a board for that session only. See [MCP setup](docs/MCP_SETUP.md) and [the agent protocol](docs/AGENT_PROTOCOL.md).
|
|
152
102
|
|
|
153
|
-
|
|
154
|
-
2. **Human** or **Agent** breaks it into `feature` / `task` / `bug` cards under the epic and moves the workable ones to the `AI Ready` lane.
|
|
155
|
-
3. **Human** directs **Agent** to find a ticket by number or name, or tell it to call `claim-next` to get one from the `AI Ready` column, which gets context for the ticket and important project notes, and starts work. Blocked tickets are skipped automatically.
|
|
156
|
-
4. **Agent** either:
|
|
157
|
-
- calls `complete` with a summary and PR link, moving the card to `Review`; or
|
|
158
|
-
- calls `checkpoint` with a question if it is blocked mid-flight. Orbit moves the card to `Review` and records a checkpoint comment.
|
|
159
|
-
5. **Human** reviews, merges, and moves the card to the `Done` lane (or sends it back with comments).
|
|
103
|
+
## Storage, backup, and moving machines
|
|
160
104
|
|
|
161
|
-
|
|
105
|
+
By default Orbit uses `~/.starscape/orbit` (each Starscape product keeps its own folder under `~/.starscape`), made readable by you alone when Orbit creates it:
|
|
162
106
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
107
|
+
```text
|
|
108
|
+
DATA_DIR/
|
|
109
|
+
registry.db the boards: ids, slugs, and each board's folder
|
|
110
|
+
boards/<slug>/board.db one SQLite database per board
|
|
111
|
+
boards/<slug>/attachments/ image bytes, beside the database
|
|
112
|
+
boards/<slug>/artifacts/ a card's markdown files (plans, handoffs)
|
|
113
|
+
backups/boards/<board id>/ a copy of a board before it is replaced or deleted, and one a day
|
|
114
|
+
after writes; the newest 30 are kept, each made of:
|
|
115
|
+
<time>-<reason>-<slug>.board.db the database
|
|
116
|
+
<time>-<reason>-<slug>.files/ its attachments/ and artifacts/, beside the database
|
|
117
|
+
<time>-<reason>-<slug>.board.db.json what it holds
|
|
118
|
+
backups/registry/ the same for the list of boards
|
|
119
|
+
exports/ saved exports
|
|
168
120
|
```
|
|
169
121
|
|
|
170
|
-
|
|
122
|
+
A board keeps its folder when its slug changes, and a new board whose folder name is taken gets `<slug>-2`. The registry names folders, not full paths, so a whole data folder can move.
|
|
171
123
|
|
|
172
|
-
|
|
124
|
+
To move boards between machines, choose **Board → Export → Include attached images → Export All** to download a ZIP of `.orbit.json` snapshots. **Settings → Data → Version and updates → Back up all boards** downloads the same ZIP, images included. Import the ZIP on the other machine with **Import a board** on an empty install (or Board → Export → Import boards later). A single `.orbit.json` works too. **Matching slugs replace existing boards**, so take a backup before importing into an Orbit that has boards. Snapshots made without images keep the images' names but not their bytes. After importing, check the board and card counts and a few images.
|
|
173
125
|
|
|
174
|
-
|
|
126
|
+
Orbit's own copies hold a board's database and its images and markdown files together, so a deleted or replaced board comes back whole. A copy's files are hard links to the board's files, so an image that never changes takes no more disk in thirty copies than in one; where links aren't possible (another disk, a file system without them) the files are copied, and the copy's `.json` says which (`how`: linked, copied or mixed). The files folder of a copy goes with its database when old copies are cleaned up. If a copy's files couldn't be kept, Orbit logs it and keeps the database copy anyway. These copies sit on the same disk as the boards: they cover a mistake, not a dead disk. Back up the **whole data folder**, `backups/` and the images included, somewhere else too, and copy it with a tool that keeps hard links (`rsync -aH`, `tar`) or accept that each linked image is stored once per copy. If you change the data folder, give it to the server and MCP alike (`DATA_DIR=/path/to/data orbit run` on Unix; `$env:DATA_DIR='C:\path\to\data'; orbit run` in PowerShell).
|
|
175
127
|
|
|
128
|
+
### Restoring a copy
|
|
176
129
|
|
|
177
|
-
|
|
178
|
-
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
179
|
-
| Index | `board_list` (tiny registry), `board_set_active` |
|
|
180
|
-
| Board context | `board_context` (settings + journal + deployment; optional board + `include_struck`) |
|
|
181
|
-
| Read | `board_read_ticket`, `board_read_comments`, `board_get_ticket_context` (lean), `board_get_ticket_context_full` (manual/journal), `board_get_ticket_relations`, `board_get_ticket_blockers`, `board_search`, `board_list_archive` |
|
|
182
|
-
| Agent flow | `board_claim_next`, `board_checkpoint`, `board_complete` |
|
|
183
|
-
| Write | `board_update_ticket`, `board_add_comment`, `board_add_board_entry`, `board_archive_ticket`, `board_restore_ticket`, `board_delete_ticket` |
|
|
184
|
-
| Admin | `board_export_board`, `board_update_settings` |
|
|
130
|
+
Restoring is putting a copy back, with Orbit stopped (`orbit run`, and any `orbit mcp` or CLI process):
|
|
185
131
|
|
|
132
|
+
1. Open `backups/boards/<board id>/` and pick a copy: `<time>-<reason>-<slug>.board.db`, with a `.files/` folder of the same name beside it.
|
|
133
|
+
2. Copy the database to the board's folder as `boards/<folder>/board.db` (the folder is the board's own under `boards/`; the slug it was made with, unless that was taken). Delete `board.db-wal` and `board.db-shm` there if they exist.
|
|
134
|
+
3. Copy what is inside the `.files/` folder (`attachments/` and `artifacts/`) into the same board folder, beside `board.db`. Copy, don't move: the files in the copy stay as they are.
|
|
135
|
+
4. Start Orbit and open the board.
|
|
186
136
|
|
|
187
|
-
|
|
137
|
+
A board that was deleted is also off the list. Orbit copied the list before it deleted the board: put `backups/registry/<time>-pre-board-delete.registry.db` back as `registry.db` (delete `registry.db-wal` and `registry.db-shm`), then do steps 2 and 3 in a new `boards/<folder>/`. That puts the list back as it was then, so first copy the whole data folder, and expect boards made after it to leave the list. To keep them, export them first.
|
|
188
138
|
|
|
189
|
-
|
|
139
|
+
## On a server
|
|
190
140
|
|
|
191
|
-
|
|
192
|
-
- **Repo metadata**: `REPO_URL` env var or `git config --get remote.origin.url`; `SYSTEM_PATH` env var or the repo path passed to `orbit init`.
|
|
193
|
-
- **Default branch**: `DEFAULT_BRANCH` env var, otherwise the current git branch.
|
|
194
|
-
- **Lanes (7)**: `Backlog`, `Todo` (default), `AI Ready`, `In Progress`, `Review`, `Done`, `Cancelled`. Pass `--no-ai` to seed without `AI Ready` and leave AI collaboration disabled.
|
|
195
|
-
- **Labels (7)**: `human-only`, `needs-human-input`, `needs-decomposition`, `needs-followup`, `tech-debt`, `security`, `onboarding`.
|
|
196
|
-
- **Onboarding cards (optional)**: pass `--example` to create an epic `#1` plus children `#2`, `#3`, and `#12 — Try Orbit MCP on this ticket`.
|
|
197
|
-
- **Free-form fields**: `project_notes` (Notes tab) and `agent_instructions` (AI tab) get placeholder text you should replace.
|
|
141
|
+
Orbit is one Node process and its data folder, so the simplest reliable way to run it on a VPS is as a system service. Linux's service manager, systemd, starts it at boot, restarts it if it stops, keeps its logs, and locks it down nearly as tightly as a container would.
|
|
198
142
|
|
|
199
|
-
|
|
143
|
+
### As a service (recommended)
|
|
200
144
|
|
|
201
|
-
|
|
202
|
-
$env:BOARD_NAME="My App"; $env:BOARD_SLUG="my-app"; $env:REPO_URL="https://github.com/you/my-app"; orbit init
|
|
203
|
-
```
|
|
145
|
+
As root, with Node installed:
|
|
204
146
|
|
|
205
|
-
```
|
|
206
|
-
|
|
147
|
+
```sh
|
|
148
|
+
npm install -g @starlove/orbit
|
|
149
|
+
useradd --system --home-dir /var/lib/orbit --shell /usr/sbin/nologin orbit
|
|
150
|
+
command -v orbit # the path for ExecStart below
|
|
207
151
|
```
|
|
208
152
|
|
|
209
|
-
|
|
153
|
+
Save this as `/etc/systemd/system/orbit.service`, with that path in `ExecStart`:
|
|
154
|
+
|
|
155
|
+
```ini
|
|
156
|
+
[Unit]
|
|
157
|
+
Description=Starscape Orbit
|
|
158
|
+
After=network-online.target
|
|
159
|
+
Wants=network-online.target
|
|
160
|
+
|
|
161
|
+
[Service]
|
|
162
|
+
User=orbit
|
|
163
|
+
ExecStart=/usr/local/bin/orbit run --port 13701
|
|
164
|
+
Environment=NODE_ENV=production
|
|
165
|
+
Environment=DATA_DIR=/var/lib/orbit
|
|
166
|
+
StateDirectory=orbit
|
|
167
|
+
StateDirectoryMode=0700
|
|
168
|
+
Restart=on-failure
|
|
169
|
+
RestartSec=5
|
|
170
|
+
MemoryMax=512M
|
|
171
|
+
# Locked down: a read-only system, no home folders, no new privileges.
|
|
172
|
+
NoNewPrivileges=yes
|
|
173
|
+
ProtectSystem=strict
|
|
174
|
+
ProtectHome=yes
|
|
175
|
+
PrivateTmp=yes
|
|
176
|
+
PrivateDevices=yes
|
|
177
|
+
ProtectKernelTunables=yes
|
|
178
|
+
ProtectKernelModules=yes
|
|
179
|
+
ProtectKernelLogs=yes
|
|
180
|
+
ProtectControlGroups=yes
|
|
181
|
+
RestrictSUIDSGID=yes
|
|
182
|
+
RestrictNamespaces=yes
|
|
183
|
+
RestrictRealtime=yes
|
|
184
|
+
LockPersonality=yes
|
|
185
|
+
ProtectClock=yes
|
|
186
|
+
ProtectHostname=yes
|
|
187
|
+
ProtectProc=invisible
|
|
188
|
+
CapabilityBoundingSet=
|
|
189
|
+
SystemCallArchitectures=native
|
|
190
|
+
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
191
|
+
UMask=0077
|
|
192
|
+
|
|
193
|
+
[Install]
|
|
194
|
+
WantedBy=multi-user.target
|
|
195
|
+
```
|
|
210
196
|
|
|
211
|
-
|
|
212
|
-
- **`node:sqlite` is not a known module** — you're on Node < 22. Upgrade to Node 22+.
|
|
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 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.
|
|
197
|
+
Then run `systemctl enable --now orbit` and check it with `curl http://127.0.0.1:13701/api/health`. Its logs are in `journalctl -u orbit`. Boards live in `/var/lib/orbit`: back up that whole folder.
|
|
214
198
|
|
|
215
|
-
|
|
199
|
+
Orbit listens on 127.0.0.1 only. Reach it through a private tunnel, never a public address: `ssh -N -L 13701:127.0.0.1:13701 you@server`, then open `http://localhost:13701`; or, on a tailnet, `tailscale serve --bg --https=13701 http://127.0.0.1:13701` (never Funnel). Agents on the server talk to it over HTTP: `ORBIT_MODE=remote ORBIT_API_URL=http://127.0.0.1:13701 orbit mcp`, or the same variables for the `orbit` command.
|
|
216
200
|
|
|
217
|
-
Orbit
|
|
201
|
+
To update Orbit, run `npm install -g @starlove/orbit@latest`, then `systemctl restart orbit`. Take Node's security releases as they come, the same way you installed Node, then restart the service.
|
|
218
202
|
|
|
219
|
-
|
|
220
|
-
- Host registry and backups: `~/.orbit` by default
|
|
221
|
-
- Docker registry and backups: `<repo>/.orbit/docker-data` by default
|
|
203
|
+
### Docker (optional)
|
|
222
204
|
|
|
223
|
-
|
|
205
|
+
Orbit ships a `Dockerfile`, and Starscape's own Orbit runs in a locked-down container. From a source checkout, build the web app and the server first, then the image, and publish it only on **127.0.0.1**, with data kept on the host (`/data` in the container):
|
|
224
206
|
|
|
225
207
|
```bash
|
|
226
|
-
|
|
227
|
-
orbit
|
|
208
|
+
npm run build:bundle && npm run build:node && docker build --pull -t orbit .
|
|
209
|
+
docker run -d --name orbit --restart unless-stopped -p 127.0.0.1:13701:13701 -e HOST=0.0.0.0 -v ~/orbit-docker-data:/data orbit
|
|
228
210
|
```
|
|
229
211
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
212
|
+
`HOST=0.0.0.0` lets Docker's port mapping reach the server inside the container; the `127.0.0.1` in `-p` keeps it off your network. Behind a reverse proxy with its own domain, add `-e ORBIT_ALLOWED_HOSTS=orbit.example.com`: Orbit answers only names it knows (IP addresses, `localhost`, full `*.ts.net` names and `HOST`'s), and 421 to the rest, a short tailnet name or a `.local` name included, which go in `ORBIT_ALLOWED_HOSTS` too. Orbit on the host and Orbit in Docker have separate data folders this way; share one only if you understand what two processes on one folder mean for your file system. The image carries its own Node, so rebuild it with `--pull` when Node ships a security release.
|
|
213
|
+
|
|
214
|
+
### Security
|
|
233
215
|
|
|
234
|
-
|
|
216
|
+
Orbit's HTTP API serves **one trusted person and their agents**; it has no accounts. Keep Orbit's address private, the one agents on other computers use included: Orbit doesn't sign in remote clients, so anyone who reaches it owns your boards. Do **not** put it on a public address, rely on separate SQLite files to keep people apart, or treat a login page in front of it as hosted-service authorization. `HOST=0.0.0.0` deliberately opts into listening on the network; use it only inside a protected network. The API sends no CORS headers and refuses browser requests that come from another site (Fetch Metadata, falling back to `Origin`), so a web page you visit can't read or drive your boards through your browser; that adds to keeping the server private, it doesn't replace it. The app also refuses to be framed by other sites, sends a script policy that runs only its own scripts, and never shows an attachment as a page: images are PNG, JPEG, GIF, WebP or AVIF, and anything else (an SVG a shared board brought) is offered as a download. `orbit run` answers only a browser that reached it by an IP address, `localhost`, a full tailnet name (`*.ts.net`) or the name in `HOST`; any other name goes in `ORBIT_ALLOWED_HOSTS` (comma-separated), or Orbit answers 421: a reverse proxy's own domain, and also a short tailnet name (`http://mybox:13701`), a `.local` name or a name your LAN's DNS gives. That stops a DNS rebinding, where another site's name is pointed at your computer. Agents never see the server's folders, the board's private notes, or comments a person hid from AI. Accounts, board-scoped agent tokens and hosted multi-user Orbit are future work, not part of this setup.
|
|
235
217
|
|
|
236
|
-
|
|
218
|
+
For updates and moving from 1.x, see [updating](docs/UPDATING.md).
|
|
237
219
|
|
|
238
|
-
|
|
220
|
+
## License
|
|
239
221
|
|
|
240
|
-
|
|
222
|
+
AGPL-3.0. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
default-src 'self'; script-src 'self' 'sha256-kLYwoO3pLfw/PQENSuRkD8x0mBkQrv1A5fhVedYez3M=' 'sha256-UmjJBwGq+DKi5mG+H5TrVRzCLdnf+3YwUUV8EK/F77Y='; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'
|
|
Binary file
|
|
@@ -77,3 +77,8 @@ commercial or otherwise.
|
|
|
77
77
|
|
|
78
78
|
This isn't legal advice, please consider consulting a lawyer and see the full
|
|
79
79
|
license for all details.
|
|
80
|
+
|
|
81
|
+
JetBrainsMono-subset.woff2 is the same face (OFL.txt beside it) cut to
|
|
82
|
+
Starscape's subset, the file starscape.biz and Nebula serve: upright, weight
|
|
83
|
+
400 to 500, Basic Latin, Latin-1 and common punctuation. Orbit's landing sets
|
|
84
|
+
its commands and paths in it.
|
|
Binary file
|