@starlove/orbit 1.0.6 → 1.1.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.
Files changed (58) hide show
  1. package/README.md +22 -7
  2. package/SKILL-ORBIT.md +28 -1
  3. package/build.mjs +2 -2
  4. package/dist/full/index.html +2 -2
  5. package/dist/full/js/app.a4f045fc.js +676 -0
  6. package/dist/full/js/app.a4f045fc.js.map +7 -0
  7. package/dist/full/{styles.c2e3d20a.css → styles.836872e7.css} +1117 -47
  8. package/dist/full/version.json +2 -2
  9. package/docs/AGENT_PROTOCOL.md +27 -5
  10. package/docs/MCP_SETUP.md +7 -3
  11. package/docs/ORBIT_DISPATCH.md +185 -0
  12. package/docs/setup/orbit-init-wizard.md +174 -0
  13. package/package.json +2 -2
  14. package/public/js/actor-labels.js +65 -0
  15. package/public/js/api.js +5 -1
  16. package/public/js/app.js +8 -1
  17. package/public/js/card-actions.js +526 -0
  18. package/public/js/config.js +2 -1
  19. package/public/js/drawer.js +2 -0
  20. package/public/js/format.js +336 -0
  21. package/public/js/kanban.js +25 -2
  22. package/public/js/local-backend.js +24 -8
  23. package/public/js/main.js +14 -6
  24. package/public/js/motion-preference.js +53 -0
  25. package/public/js/router.js +78 -58
  26. package/public/js/search.js +6 -3
  27. package/public/js/settings-tabs.js +1 -1
  28. package/public/js/settings.js +192 -29
  29. package/public/js/starscape.js +25 -18
  30. package/public/js/state.js +61 -2
  31. package/public/js/theme-preference.js +88 -0
  32. package/public/js/ticket-detail.js +432 -126
  33. package/public/js/url-routes.js +94 -0
  34. package/public/styles.css +1117 -47
  35. package/src/cli/orbit.js +217 -32
  36. package/src/core/agent.js +1 -18
  37. package/src/core/agents-md.js +16 -10
  38. package/src/core/attachments.js +238 -0
  39. package/src/core/auth.js +36 -0
  40. package/src/core/backups.js +9 -3
  41. package/src/core/board.js +32 -1
  42. package/src/core/boards.js +1 -1
  43. package/src/core/bootstrap.js +9 -1
  44. package/src/core/db.js +42 -2
  45. package/src/core/delete-board.js +87 -21
  46. package/src/core/dispatch.js +532 -0
  47. package/src/core/http.js +31 -11
  48. package/src/core/migrate.js +198 -0
  49. package/src/core/paths.js +6 -0
  50. package/src/core/registry.js +12 -9
  51. package/src/core/router.js +62 -6
  52. package/src/core/search.js +56 -22
  53. package/src/core/snapshots.js +14 -2
  54. package/src/mcp/orbit-client.js +223 -0
  55. package/src/mcp-server.js +89 -129
  56. package/src/server.js +20 -0
  57. package/dist/full/js/app.aedc1bfe.js +0 -554
  58. package/dist/full/js/app.aedc1bfe.js.map +0 -7
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starlove/orbit",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "edition": "full",
5
- "builtAt": "2026-05-20T07:25:07.448Z"
5
+ "builtAt": "2026-05-26T04:59:52.730Z"
6
6
  }
@@ -4,6 +4,8 @@ The board is intentionally agent-first. Agents should not scrape the UI. They sh
4
4
 
5
5
  If an MCP client is available, use the MCP server instead of rebuilding these HTTP calls yourself. The MCP tools map directly to the same core operations.
6
6
 
7
+ Never edit `.orbit/board.db` directly to create or mutate cards. The SQLite file is Orbit's storage detail; use the HTTP API or MCP tools so validation, events, search indexing, backups, and cross-process locking all run.
8
+
7
9
  ## Core Flow
8
10
 
9
11
  1. `POST /api/agent/claim-next`
@@ -70,7 +72,19 @@ Returns the first schedulable `AI Ready` ticket. The scheduler skips tickets blo
70
72
 
71
73
  By default, `claim-next` skips `epic` cards because they are index/planning cards. To claim an epic for planning, pass `"type": "epic"` or `"include_epics": true`.
72
74
 
73
- The response shape is `{ claimed: true, ticket_id, context }` where `context` is the lightweight `board_read_ticket` pack (`ticket` with title/description/labels/state, full `comments`, and the `board_manual`). For the heavier ticket pack with relations, blockers, and child cards, call `GET /api/tickets/:id/context` (or MCP `board_get_ticket_context`).
75
+ The response shape is `{ claimed: true, ticket_id, context }` where `context` is the lightweight `board_read_ticket` pack (`ticket` with title/description/labels/state and the `board_manual`). Ticket comments are not included in the default claim context; call `GET /api/tickets/:id/comments` (or MCP `board_read_comments`) when an explicit chat/comment surface needs them. For the heavier ticket pack with relations, blockers, implementation fields, and child cards, call `GET /api/tickets/:id/context` (or MCP `board_get_ticket_context`).
76
+
77
+ ### Read Lightweight Ticket
78
+
79
+ ```http
80
+ GET /api/tickets/:id
81
+ GET /api/tickets/lookup?board=your-board-slug&number=42
82
+ GET /api/tickets/lookup?board=your-board-slug&title=Exact%20Title
83
+ ```
84
+
85
+ MCP equivalent: `board_read_ticket`.
86
+
87
+ Returns the lightweight agent read shape: `ticket` with identity, title, description, labels, state/type/priority, plus `board_manual`. Ticket comments, relations, blockers, child cards, and implementation fields are intentionally omitted. Use this for quick orientation and claim context. The `lookup` form is exact by per-board ticket number or exact title; it does not use fuzzy search or comment/implementation indexes.
74
88
 
75
89
  ### Get Context Pack
76
90
 
@@ -82,14 +96,20 @@ Returns:
82
96
 
83
97
  - Ticket, board, state, labels.
84
98
  - The board manual (`board_manual`), including `agent_instructions` and `project_notes`.
85
- - Full comments for the assigned ticket.
86
99
  - Dedicated implementation fields: `ai_plan`, `implementation_summary`, and `implementation_updates`.
87
100
  - Parent epic/story ticket when present.
88
101
  - Child feature cards when the ticket is an epic/story.
89
102
  - Related tickets.
90
- - Recent comments from directly related tickets.
91
103
  - Blockers and blocking tickets.
92
104
 
105
+ Ticket comments are intentionally omitted from this default agent context. Explicit comment/chat consumers should call:
106
+
107
+ ```http
108
+ GET /api/tickets/:id/comments
109
+ ```
110
+
111
+ MCP equivalent: `board_read_comments`.
112
+
93
113
  ### Get Ticket Relations
94
114
 
95
115
  ```http
@@ -212,10 +232,10 @@ Content-Type: application/json
212
232
  ### Export Board Snapshot
213
233
 
214
234
  ```http
215
- GET /api/boards/:board_id/export
235
+ GET /api/boards/:board_id/export?include_attachments=true
216
236
  ```
217
237
 
218
- Returns a JSON snapshot of the board, states, tickets, comments, relations, board entries, and relevant event history.
238
+ Returns a JSON snapshot of the board, states, tickets, comments, relations, image attachment metadata, board entries, and relevant event history. Image bytes are excluded by default; pass `include_attachments=true` (or `include_images=true`) to embed present attachment files as base64. Missing attachment files are marked in metadata instead of failing the export.
219
239
 
220
240
  ### Import Board Snapshot
221
241
 
@@ -298,6 +318,8 @@ Over MCP these are exposed as `board_archive_ticket`, `board_restore_ticket`, `b
298
318
 
299
319
  Ticket types are `epic`, `feature`, `task`, and `bug`.
300
320
 
321
+ MCP equivalent: `board_create_ticket`. Use it for new cards instead of modifying `.orbit/board.db`.
322
+
301
323
  Create the epic/story parent first:
302
324
 
303
325
  ```http
package/docs/MCP_SETUP.md CHANGED
@@ -13,7 +13,7 @@ Orbit generates neutral template paths for Windows, macOS, and Linux. Replace th
13
13
 
14
14
  Board data lives under each tracked repo at `.orbit/board.db` (flat file or `.orbit/boards/<slug>/` for extra boards)—not beside the MCP script.
15
15
 
16
- After installing Orbit as a package, run **`orbit init`** in (or with `--cwd` pointing at) the repo where you want `.orbit/`, **`AGENTS.md`**, and a copy of **`SKILL-ORBIT.md`** so agents and MCP line up with that tree. Orbit enables the AI Ready / In Progress / Review agent lanes by default. Add `--no-ai` if you want AI collaboration disabled, and add `--example` if you want the onboarding example tickets.
16
+ After installing Orbit as a package, run **`orbit init`** in (or with `--cwd` pointing at) the repo where you want `.orbit/`, **`AGENTS.md`**, and the managed **`SKILL-ORBIT.md`** so agents and MCP line up with that tree. Orbit enables the AI Ready / In Progress / Review agent lanes by default. Add `--no-ai` if you want AI collaboration disabled, and add `--example` if you want the onboarding example tickets. Keep repo-specific agent customization in `AGENTS.md` or board *Agent Instructions*; `SKILL-ORBIT.md` is Orbit-managed and may be overwritten by `orbit init` or refreshed by `orbit serve`.
17
17
 
18
18
  The generated format changes by app:
19
19
 
@@ -29,11 +29,13 @@ The checked-in example file is not read automatically by Starscape Orbit. It exi
29
29
  3. Replace the path to `src/mcp-server.js` with the absolute path on your machine.
30
30
  4. Restart the MCP client.
31
31
 
32
- The MCP server finds a board from an explicit project root first: pass `orbit mcp --cwd <repo>` or set `PROJECT_ROOT=<repo>` in persistent MCP configs. If neither is set, it falls back to the process cwd and walks upward to the first ancestor with `.orbit/board.db`. Prefer explicit roots for long-lived agent configs so launching the agent from another folder does not attach the wrong board. **`AGENTS.md` / `SKILL-ORBIT.md`** are unrelated to MCP transport: agents open them via the workspace file tree, and `orbit init` keeps a terse Orbit pointer section in `AGENTS.md`.
32
+ By default MCP runs in local mode. It finds a board from an explicit project root first: pass `orbit mcp --cwd <repo>` or set `PROJECT_ROOT=<repo>` in persistent MCP configs. If neither is set, it falls back to the process cwd and walks upward to the first ancestor with `.orbit/board.db`. Prefer explicit roots for long-lived agent configs so launching the agent from another folder does not attach the wrong board.
33
+
34
+ For a shared/deployed board, run MCP in remote mode instead: set `ORBIT_MODE=remote`, `ORBIT_API_URL=<server origin>`, and usually `ORBIT_DEFAULT_BOARD=<slug-or-id>`. Remote mode calls the HTTP API and does not open or auto-create local `.orbit` databases; it fails at startup if `ORBIT_API_URL` is missing. **`AGENTS.md` / `SKILL-ORBIT.md`** are unrelated to MCP transport: agents open them via the workspace file tree, `orbit init` keeps a terse Orbit pointer section in `AGENTS.md`, and `orbit serve` refreshes managed `SKILL-ORBIT.md` copies for registered repos.
33
35
 
34
36
  Typical use:
35
37
 
36
- - Keep the web UI running with `node src/server.js`.
38
+ - Keep the web UI running with `orbit serve` (`node src/server.js` is fine for source-tree development, but `orbit serve` is the package command that refreshes managed `SKILL-ORBIT.md` copies).
37
39
  - Point the MCP client at `node src/cli/orbit.js mcp --cwd /absolute/project`, set `PROJECT_ROOT=/absolute/project` with `node src/mcp-server.js`, or paste the generated setup from Settings -> AI.
38
40
  - Use the MCP tools to claim tickets, read context, update implementation fields, and write project memory.
39
41
 
@@ -41,6 +43,8 @@ Typical use:
41
43
 
42
44
  Running the MCP server starts a small local helper process. It reads and updates the same local board data as the web app, does not publish the board to the internet, and can be removed from your AI app's MCP settings whenever you want.
43
45
 
46
+ On Windows, that helper process can keep `.orbit/board.db` and its WAL/SHM sidecar files locked while the AI client is running. Before deleting or recloning a repo that has an Orbit board, close or restart the AI client, stop any `orbit serve` terminal, and prefer `orbit reset --cwd <repo>` for cleanup.
47
+
44
48
  The MCP server is only the bridge. Your AI app is still the part that decides what to do, and that app may send ticket context to its AI provider when you ask it to work on cards. Only connect AI apps you trust with this project.
45
49
 
46
50
  Important:
@@ -0,0 +1,185 @@
1
+ # Orbit Dispatch
2
+
3
+ `orbit dispatch` is the local Orbit-to-Hermes handoff command. It turns a local Orbit ticket into a bounded agent run without relying on a temporary prompt file as the source of truth.
4
+
5
+ The design intent is simple:
6
+
7
+ - Git remains canonical for code.
8
+ - Orbit remains canonical for planning, handoff, run records, and implementation notes.
9
+ - The ticket becomes the shared communication surface between the human, orchestrator, and dispatched agent.
10
+
11
+ ## Current remote-board contract
12
+
13
+ `orbit dispatch` is intentionally local-board only right now. It resolves boards through the local Orbit registry and mutates the local SQLite board file.
14
+
15
+ Because of that, `--server-url` and `--remote` are refused before side effects. They do not silently target a hosted board.
16
+
17
+ For hosted/remote boards, use remote MCP/manual orchestration or run `orbit dispatch` on the board host without `--server-url`/`--remote`.
18
+
19
+ ## Basic use
20
+
21
+ From the code repository you are working in, target the local Orbit board explicitly:
22
+
23
+ ```bash
24
+ orbit dispatch \
25
+ --board my-app \
26
+ --ticket 12 \
27
+ --profile agent \
28
+ --worktree
29
+ ```
30
+
31
+ Common variants:
32
+
33
+ ```bash
34
+ # Preview only. No files, worktrees, ticket fields, comments, or agents change.
35
+ orbit dispatch --board my-app --ticket 12 --dry-run
36
+
37
+ # Prepare the handoff/comment/worktree, but do not spawn Hermes and do not move the card to In Progress.
38
+ orbit dispatch --board my-app --ticket 12 --profile agent --worktree --no-spawn
39
+
40
+ # Attach the Hermes child process to the current terminal instead of detaching it.
41
+ orbit dispatch --board my-app --ticket 12 --profile agent --worktree --foreground
42
+
43
+ # Use an explicit branch/worktree name.
44
+ orbit dispatch --board my-app --ticket 12 --profile agent --worktree \
45
+ --branch orbit/my-app-12-search \
46
+ --worktree-path .worktrees/my-app-12-search
47
+ ```
48
+
49
+ ## Preflight order
50
+
51
+ Before any filesystem writes, worktree creation, ticket mutation, or agent spawn, dispatch now:
52
+
53
+ 1. Refuses `--server-url` / `--remote`.
54
+ 2. Resolves the local board from `--board` or from `--cwd` / the current repo.
55
+ 3. Resolves the ticket from `--ticket` by number or id.
56
+ 4. Refuses archived tickets.
57
+ 5. Refuses blocked tickets unless `--force` is passed.
58
+ 6. For spawn mode, checks that the Hermes binary exists and the requested profile is plausible.
59
+ 7. Handles `--dry-run` as a true no-write preview.
60
+
61
+ Only after those checks does dispatch create run artifacts/worktrees, write the handoff/comment, move the ticket, or spawn Hermes.
62
+
63
+ ## What dispatch does
64
+
65
+ In normal spawn mode:
66
+
67
+ 1. Builds a run id such as `orbit-12-agent-abc123def0`.
68
+ 2. Creates `.orbit/dispatch-runs/<run-id>/` for run metadata and policy wrappers.
69
+ 3. Creates and preserves a git worktree/branch when `--worktree` is used.
70
+ 4. Generates a full agent handoff and writes the canonical copy to the ticket's **AI Written-Plan** (`ai_plan`) field.
71
+ 5. Moves the ticket to **In Progress**.
72
+ 6. Starts Hermes.
73
+ 7. Comments a run record back onto the ticket.
74
+
75
+ In `--no-spawn` mode, dispatch writes the handoff and run-record comment but leaves the ticket in its current lane.
76
+
77
+ The run record includes profile, policy, ticket, branch, worktree, policy-bin path, child process id, command, and mode. This makes the card the visible cockpit for the run.
78
+
79
+ ## The AI Written-Plan handoff
80
+
81
+ Dispatch stores the generated handoff in the ticket's AI Written-Plan field. It includes:
82
+
83
+ - mission and ticket metadata
84
+ - repository root, worktree, branch, and run id
85
+ - required reading order: `AGENTS.md`, `SKILL-ORBIT.md`, then the handoff
86
+ - ticket description
87
+ - implementation fields (`ai_plan`, `implementation_summary`, `implementation_updates`)
88
+ - board-level agent instructions and notes
89
+ - board journal lessons/decisions
90
+ - parent/child ticket context
91
+ - unresolved blockers
92
+ - scope boundaries
93
+ - autonomous policy
94
+ - completion protocol
95
+
96
+ The short prompt passed to `hermes chat -q` is intentionally small. The ticket is the source of truth; the CLI argument is only a bootstrap pointer.
97
+
98
+ ## Preserved worktrees
99
+
100
+ Use `--worktree` when the agent will edit code. Dispatch creates a normal git worktree under `.worktrees/` by default and gives the agent that directory as its working directory.
101
+
102
+ This solves the ephemeral-agent problem: humans can test the branch/worktree before cleanup.
103
+
104
+ Default shape:
105
+
106
+ ```text
107
+ .worktrees/<board>-<ticket>-<profile>-<shortid>
108
+ orbit/<board>-<ticket>-<profile>-<shortid>
109
+ ```
110
+
111
+ `.worktrees/` is ignored by git.
112
+
113
+ ## Safe autonomous policy
114
+
115
+ The default policy prepends `.orbit/dispatch-runs/<run-id>/policy-bin` to the child agent's `PATH`. That directory contains wrappers for commands that should be restricted during an autonomous run.
116
+
117
+ Allowed:
118
+
119
+ - file reads/searches and local edits
120
+ - `git status`, `git diff`, `git log`, `git show`, `git add`, local `git commit`, safe branch inspection/creation
121
+ - package test/build/lint/check/typecheck scripts
122
+
123
+ Blocked or requiring human approval:
124
+
125
+ - Docker
126
+ - `git push`
127
+ - destructive git commands such as reset, clean, rebase, merge, checkout/switch/restore, tag, cherry-pick, worktree mutation
128
+ - package install/publish/version/deploy/release commands
129
+ - recursive or force `rm`
130
+ - SSH/SCP/rsync
131
+ - GitHub CLI
132
+ - direct curl/wget network calls
133
+ - cloud/deploy CLIs
134
+ - `sudo`
135
+
136
+ Use `--policy none` only when you intentionally want to dispatch without wrappers.
137
+
138
+ ## Agent completion protocol
139
+
140
+ The dispatched agent should:
141
+
142
+ 1. Run relevant tests and focused manual/API checks.
143
+ 2. Commit locally on the dispatch branch.
144
+ 3. Update **AI Implementation Summary** (`implementation_summary`) with what changed, commit SHA, branch/worktree, verification, and manual checks still needed.
145
+ 4. Add **Implementation Updates/Lessons** (`implementation_updates`) for pitfalls, remediation, and reusable guidance.
146
+ 5. Add a completion comment/run record.
147
+ 6. Move the card to **Review**, not Done, unless the human explicitly asked for auto-completion.
148
+
149
+ ## Installing / enabling the command
150
+
151
+ For source installs:
152
+
153
+ ```bash
154
+ cd /path/to/ss-orbit
155
+ pnpm install
156
+ pnpm run build:full
157
+ pnpm link --global
158
+ ```
159
+
160
+ Then from a project repo with an Orbit board:
161
+
162
+ ```bash
163
+ orbit init # if the repo does not have a board yet
164
+ orbit dispatch --board my-app --ticket 12 --profile agent --worktree --no-spawn
165
+ ```
166
+
167
+ For support, bug reports, and reproducibility notes, human users can print the installed CLI version with either form:
168
+
169
+ ```bash
170
+ orbit -v
171
+ orbit --version
172
+ ```
173
+
174
+ ## Operator notes for orchestrators
175
+
176
+ - Prefer `orbit dispatch` over writing a temporary handoff prompt file when targeting a local board.
177
+ - Use `--dry-run` when you want proof of what would happen without any side effects.
178
+ - Use `--no-spawn` when you want to inspect the generated handoff/worktree/comment before starting an agent.
179
+ - Use `--worktree` for code edits so the human can test before cleanup.
180
+ - Treat the ticket fields as durable surfaces:
181
+ - AI Written-Plan: generated handoff
182
+ - AI Implementation Summary: final summary of completed work
183
+ - Implementation Updates/Lessons: pitfalls, remediation, future-agent guidance
184
+ - Comments: run records and transient breadcrumbs
185
+ - Do not push, deploy, or open PRs from the dispatched agent unless the human explicitly asked for that run to do so.
@@ -0,0 +1,174 @@
1
+ # Orbit init wizard
2
+
3
+ Status: focused implementation spec for ticket #61.
4
+
5
+ This replaces the older Mission Control-shaped setup-mode design from Orbit tickets #26 and #27. Keep the useful lesson: `orbit init` should make the first board choice clear. Cut the rest. Orbit setup creates a project board and, optionally, the agent-ready affordances around that board. Suite and Sync concerns stay out.
6
+
7
+ ## Goal
8
+
9
+ `orbit init` supports two first-pass modes:
10
+
11
+ 1. Local board / no AI
12
+ 2. AI-assisted board
13
+
14
+ Anything beyond those modes belongs to Starscape Suite, Starscape Sync, or an app-specific integration ticket.
15
+
16
+ ## Command contract
17
+
18
+ These commands must work:
19
+
20
+ ```bash
21
+ orbit init
22
+ orbit init --ai
23
+ orbit init --no-ai
24
+ ```
25
+
26
+ | Command | Mode | Contract |
27
+ | --- | --- | --- |
28
+ | `orbit init` | AI-assisted board | Backwards-compatible default. |
29
+ | `orbit init --ai` | AI-assisted board | Explicit alias for the default. |
30
+ | `orbit init --no-ai` | Local board / no AI | No AI collaboration assumptions. |
31
+
32
+ Keep existing init flags:
33
+
34
+ - `--cwd <dir>` selects the project root.
35
+ - `--example` creates onboarding example tickets.
36
+
37
+ `SKILL-ORBIT.md` is managed Orbit guidance: `orbit init` writes it, and `orbit serve` refreshes registered repo copies on startup. Repo/team customization belongs in `AGENTS.md` or board `agent_instructions`, not in `SKILL-ORBIT.md`.
38
+
39
+ Do not add `--multi-ai`, `--output=starlog-authored`, `--starlog`, `--suite`, `--forge`, `--sync`, hosted-service flags, agent-guidance refresh flags, or remote-sync flags in this pass.
40
+
41
+ ## Wizard rules
42
+
43
+ The first implementation should be clear without breaking scripts:
44
+
45
+ - If `--ai` or `--no-ai` is present, do not prompt.
46
+ - If running non-interactively, default to AI-assisted board.
47
+ - If an interactive prompt is added, Enter chooses AI-assisted board.
48
+ - Ask only for local/no-AI vs AI-assisted. Do not ask about Starlog, Suite dashboard, Nebula, Forgejo, Auth, hosted service, Sync links, artifacts, events, or remote sync.
49
+
50
+ Suggested prompt:
51
+
52
+ ```text
53
+ Initialize Orbit for this repo
54
+
55
+ Orbit keeps a project board next to your code. Git stays the truth for code;
56
+ Orbit becomes the truth for tickets, planning state, handoff, and implementation notes.
57
+
58
+ Choose a first-run mode:
59
+
60
+ 1. Local board / no AI
61
+ A local kanban board. No AI Ready lane or MCP setup step.
62
+
63
+ 2. AI-assisted board (recommended)
64
+ Adds AI Ready, agent handoff fields, generated agent instructions, and MCP setup guidance.
65
+
66
+ Select a mode [2]:
67
+ ```
68
+
69
+ ## Mode behavior
70
+
71
+ ### Local board / no AI
72
+
73
+ Triggered by `orbit init --no-ai`.
74
+
75
+ Behavior:
76
+
77
+ - Create or repair the board database and registry row for the selected project root.
78
+ - Persist `ai_enabled = 0`.
79
+ - Do not create the `AI Ready` lane.
80
+ - Keep ordinary lanes: `Backlog`, `Todo`, `In Progress`, `Review`, `Done`, `Cancelled`.
81
+ - Keep Orbit usable for human planning, ticket history, blockers, comments, and implementation notes.
82
+ - Generate `AGENTS.md` and `SKILL-ORBIT.md`, but do not present MCP connection as a required next step.
83
+ - If `--example` is used, keep example tickets out of AI Ready.
84
+
85
+ Success copy should say the board path returned by init, the selected mode, and the next `orbit serve` step. It should not imply AI is required.
86
+
87
+ ### AI-assisted board
88
+
89
+ Triggered by `orbit init` and `orbit init --ai`.
90
+
91
+ Behavior:
92
+
93
+ - Create or repair the board database and registry row for the selected project root.
94
+ - Persist `ai_enabled = 1`.
95
+ - Ensure `AI Ready`, `In Progress`, and `Review` exist for agent flow.
96
+ - Create/update `AGENTS.md` as the repo-owned pointer and write the managed `SKILL-ORBIT.md` so agents know to read board context, respect blockers, use MCP/API tools, and update `ai_plan`, `implementation_summary`, and `implementation_updates`.
97
+ - Print MCP setup guidance after init, including project-root-specific `orbit mcp --cwd <repo>` / `PROJECT_ROOT=<repo>` guidance or the generated client snippet.
98
+ - If `--example` is used, stage the stable MCP exercise ticket in `AI Ready`.
99
+
100
+ Success copy should say AI collaboration lanes are present and the next step is connecting an agent through MCP.
101
+
102
+ ## Generated guidance files
103
+
104
+ `orbit init` preserves generation of:
105
+
106
+ - `AGENTS.md`
107
+ - `SKILL-ORBIT.md`
108
+
109
+ `AGENTS.md` should stay terse and repo-owned: when work mentions Orbit/tickets/boards, read `SKILL-ORBIT.md` first. `SKILL-ORBIT.md` is Orbit-managed durable protocol and may be overwritten by `orbit init` or refreshed by `orbit serve`; it tells agents to read board context, check blockers, use Orbit API/MCP instead of editing SQLite directly, update implementation fields, and hand off through Review.
110
+
111
+ For local/no-AI boards, these files are still useful if an agent later opens the repo, but init output should not frame MCP as mandatory.
112
+
113
+ ## MCP setup guidance
114
+
115
+ For AI-assisted boards, keep the current guidance:
116
+
117
+ - MCP config tells the AI client how to spawn Orbit's helper.
118
+ - `AGENTS.md` and `SKILL-ORBIT.md` are normal repo files, not streamed through MCP.
119
+ - Persistent MCP configs should use explicit `--cwd <repo>` / `PROJECT_ROOT=<repo>` so the helper attaches to the right board.
120
+
121
+ For local/no-AI boards, omit MCP guidance or label it optional later setup.
122
+
123
+ ## Board mode metadata
124
+
125
+ First pass can keep `boards.ai_enabled` as the source of truth:
126
+
127
+ ```text
128
+ ai_enabled = 0 -> local board / no AI
129
+ ai_enabled = 1 -> AI-assisted board
130
+ ```
131
+
132
+ If a mode field is added, keep it deliberately small:
133
+
134
+ ```json
135
+ {
136
+ "setup_mode": "ai-assisted",
137
+ "setup_schema_version": 1
138
+ }
139
+ ```
140
+
141
+ Allowed `setup_mode` values: `local`, `ai-assisted`.
142
+
143
+ Compatibility:
144
+
145
+ ```text
146
+ missing setup_mode + ai_enabled = 0 -> local
147
+ missing setup_mode + ai_enabled = 1 -> ai-assisted
148
+ ```
149
+
150
+ Do not persist Starlog output mode, Suite profile, Forge mode, Sync mode, hosted Auth state, or remote-sync configuration in Orbit setup metadata.
151
+
152
+ ## Explicitly out of scope
153
+
154
+ | Deferred concern | Route |
155
+ | --- | --- |
156
+ | Starscape Suite dashboard, module/plugin setup, unified launcher, ecosystem settings | `ss-suite` #1 |
157
+ | Nebula / whiteboard setup | `ss-suite` #1 or the Nebula board |
158
+ | Starlog output/reporting mode, authored HTML outputs, templates | Suite/app integration work, not Orbit init |
159
+ | Forgejo/Gitea suite mode, local forge provisioning, themed forge navigation | `ss-suite` #1 |
160
+ | Starscape Auth, hosted service, cloud accounts, managed hosting | `ss-suite` #1 / hosted-service follow-up |
161
+ | Cross-app registry, object identity, links/backrefs, artifacts, activity/events, export/import, remote sync | `ss-sync` #1 |
162
+ | Mission Briefs, named agent ecology, wave execution, multi-agent orchestration | Later Orbit Mission Control work, not this wizard |
163
+
164
+ Mapping note: Orbit keeps local project boards, generated agent guidance, agent-ready lanes, MCP setup, and ticket implementation records. Suite composition maps to `ss-suite` #1. Registry/link/artifact/event/sync semantics map to `ss-sync` #1.
165
+
166
+ ## Implementation checklist for the next build ticket
167
+
168
+ - `orbit init`, `orbit init --ai`, and `orbit init --no-ai` all work.
169
+ - `orbit init --ai` is an explicit alias for the default AI-assisted path.
170
+ - Local/no-AI mode creates no `AI Ready` lane and does not require MCP setup.
171
+ - AI-assisted mode keeps AI lanes, generated guidance files, MCP guidance, and example-ticket staging behavior.
172
+ - Generated `AGENTS.md` / `SKILL-ORBIT.md` keep agents on Orbit API/MCP rather than direct SQLite edits.
173
+ - Setup metadata is limited to `local` / `ai-assisted` plus schema version, or remains derived from `ai_enabled`.
174
+ - No Suite, Sync, Starlog, Nebula, Forgejo, Auth, hosted service, artifact, link, event, or remote-sync setup enters Orbit init.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@starlove/orbit",
3
- "version": "1.0.6",
4
- "description": "Starscape Orbit — SQLite-backed, agent-first task board (Starscape suite).",
3
+ "version": "1.1.0",
4
+ "description": "Starscape Orbit ??? zero-dependency, pretty, human-ai-first kanban system.",
5
5
  "license": "AGPL-3.0",
6
6
  "type": "module",
7
7
  "packageManager": "pnpm@10.20.0",
@@ -0,0 +1,65 @@
1
+ // Human-facing actor labels for ticket activity. The storage layer keeps
2
+ // compact/internal identifiers such as "local" and "local-agent"; the drawer
3
+ // should translate those into labels that explain who acted without exposing
4
+ // implementation details or blaming agent actions on the current user.
5
+
6
+ const INTERNAL_LOCAL_NAMES = new Set(["local", "local-owner", "owner"]);
7
+ const GENERIC_AGENT_NAMES = new Set(["agent", "local-agent", "orbit-agent"]);
8
+ const AGENT_COMMENT_KINDS = new Set(["agent_note", "checkpoint", "completion"]);
9
+
10
+ function clean(value) {
11
+ return String(value || "").trim();
12
+ }
13
+
14
+ function humanizeIdentifier(value) {
15
+ const raw = clean(value);
16
+ if (!raw) return "";
17
+ return raw
18
+ .replace(/^@+/, "")
19
+ .replace(/[-_]+/g, " ")
20
+ .replace(/\s+/g, " ")
21
+ .trim()
22
+ .replace(/\b\w/g, (char) => char.toUpperCase());
23
+ }
24
+
25
+ function agentNameFrom({ actor, actorId } = {}) {
26
+ const name = clean(actor);
27
+ const id = clean(actorId);
28
+ const lowerName = name.toLowerCase();
29
+ const lowerId = id.toLowerCase();
30
+
31
+ if (name && !INTERNAL_LOCAL_NAMES.has(lowerName) && !GENERIC_AGENT_NAMES.has(lowerName)) {
32
+ return humanizeIdentifier(name);
33
+ }
34
+ if (id && !INTERNAL_LOCAL_NAMES.has(lowerId) && !GENERIC_AGENT_NAMES.has(lowerId)) {
35
+ return humanizeIdentifier(id);
36
+ }
37
+ return "";
38
+ }
39
+
40
+ export function formatActorLabel({ actor, actorType, actorId } = {}) {
41
+ const type = clean(actorType).toLowerCase();
42
+ const name = clean(actor);
43
+ const lowerName = name.toLowerCase();
44
+
45
+ if (type === "agent") {
46
+ const agentName = agentNameFrom({ actor: name, actorId });
47
+ return agentName ? `Agent · ${agentName}` : "Agent";
48
+ }
49
+
50
+ if (!name || INTERNAL_LOCAL_NAMES.has(lowerName)) return "You";
51
+ return humanizeIdentifier(name);
52
+ }
53
+
54
+ export function formatCommentAuthor(comment = {}) {
55
+ const kind = clean(comment.kind).toLowerCase();
56
+ const author = clean(comment.author);
57
+ const isAgentKind = AGENT_COMMENT_KINDS.has(kind) || (kind && kind !== "human_comment");
58
+
59
+ if (isAgentKind) {
60
+ const agentName = agentNameFrom({ actor: author });
61
+ return agentName ? `Agent · ${agentName}` : "Agent";
62
+ }
63
+
64
+ return formatActorLabel({ actor: author, actorType: "human" });
65
+ }
package/public/js/api.js CHANGED
@@ -9,7 +9,11 @@ import { request } from "./transport.js";
9
9
 
10
10
  /** Bootstrap for the currently selected board (server opens the right DB). */
11
11
  export function bootstrapPath() {
12
- const q = state.boardId ? `?board_id=${encodeURIComponent(state.boardId)}` : "";
12
+ const q = state.boardId
13
+ ? `?board_id=${encodeURIComponent(state.boardId)}`
14
+ : state.boardSlug
15
+ ? `?board=${encodeURIComponent(state.boardSlug)}`
16
+ : "";
13
17
  return `/api/bootstrap${q}`;
14
18
  }
15
19
 
package/public/js/app.js CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { state, syncBoardSelection } from "./state.js";
6
6
  import { api, bootstrapPath } from "./api.js";
7
- import { renderBoard } from "./kanban.js";
7
+ import { renderBoard, renderBoardSelection } from "./kanban.js";
8
8
  import { renderDetail } from "./ticket-detail.js";
9
9
  import { closeMenuFlyouts, updateTopbarChips } from "./board-menu.js";
10
10
  import { connectEventStream } from "./sse.js";
@@ -33,3 +33,10 @@ export async function render() {
33
33
  renderBoard();
34
34
  await renderDetail();
35
35
  }
36
+
37
+ export async function renderDetailOnly() {
38
+ syncBoardSelection();
39
+ updateTopbarChips();
40
+ renderBoardSelection();
41
+ await renderDetail();
42
+ }