@starlove/orbit 1.0.1 → 1.0.3

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/.dockerignore CHANGED
@@ -2,7 +2,6 @@
2
2
  .claude
3
3
  .orbit
4
4
  data
5
- dist
6
5
  node_modules
7
6
  npm-debug.log*
8
7
  pnpm-debug.log*
package/Dockerfile CHANGED
@@ -1,19 +1,5 @@
1
1
  # syntax=docker/dockerfile:1
2
2
 
3
- FROM node:22-slim AS build
4
- WORKDIR /app
5
-
6
- ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
7
-
8
- RUN corepack enable && corepack prepare pnpm@10.20.0 --activate
9
-
10
- COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
11
- RUN pnpm install --frozen-lockfile
12
-
13
- COPY build.mjs ./
14
- COPY public ./public
15
- RUN pnpm run build:full
16
-
17
3
  FROM node:22-slim AS runtime
18
4
  WORKDIR /app
19
5
 
@@ -25,7 +11,7 @@ COPY package.json ./
25
11
  COPY SKILL-ORBIT.md ./SKILL-ORBIT.md
26
12
  COPY docs ./docs
27
13
  COPY src ./src
28
- COPY --from=build /app/dist/full ./dist/full
14
+ COPY dist/full ./dist/full
29
15
 
30
16
  VOLUME ["/data"]
31
17
  EXPOSE 3337
package/README.md CHANGED
@@ -37,6 +37,7 @@ From the repo you want a board for:
37
37
  cd path/to/your-app
38
38
  orbit init # creates .orbit/board.db + SKILL-ORBIT.md + AGENTS.md
39
39
  orbit init --example # optional: add onboarding example tickets
40
+ orbit init --no-ai # optional: create or update the board with AI disabled
40
41
  ```
41
42
 
42
43
  Start one runtime and keep using it:
@@ -67,9 +68,9 @@ Wipe a single board and start over with `orbit reset` (deletes `.orbit/`, `SKILL
67
68
 
68
69
  ## Use with AI
69
70
 
70
- Orbit ships with everything an agent needs to claim work, read tickets, and write back implementation notes — but it stays out of your way until you turn it on.
71
+ Orbit ships with everything an agent needs to claim work, read tickets, and write back implementation notes. New boards have AI collaboration enabled by default; pass `orbit init --no-ai` or turn off **Enable AI** in Settings → AI if you want a human-only board.
71
72
 
72
- 1. **Enable AI on the board.** Open Settings (gear icon) → **AI** tab → toggle **Enable AI**. 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.
73
+ 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.
73
74
  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.
74
75
  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.
75
76
  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.).
@@ -80,7 +81,7 @@ If you initialized with `--example`, ticket #12 (`Try Orbit MCP on this ticket`)
80
81
  ## Vocabulary
81
82
 
82
83
  - **Board** — one repo's planning surface. Each board carries its own `agent_instructions`, lanes, tickets, and memory entries.
83
- - **Lane** — a column. Lanes are user-defined and freely named/reordered. The seed gives you `Backlog`, `Todo`, `In Progress`, `Review`, `Done`, `Cancelled`; turning on AI also pins `AI Ready`, `In Progress`, and `Review` as anchor lanes the agent flow keys off.
84
+ - **Lane** — a column. Lanes are user-defined and freely named/reordered. The default seed gives you `Backlog`, `Todo`, `AI Ready`, `In Progress`, `Review`, `Done`, `Cancelled`; `AI Ready`, `In Progress`, and `Review` are anchor lanes the agent flow keys off. `AI Ready` is inserted between `Todo` and `In Progress` when AI is enabled.
84
85
  - **Ticket types**:
85
86
  - `epic` — index card for a multi-feature initiative. Owns child tickets via `parent_ticket_id`.
86
87
  - `feature` — a standalone capability or new behavior.
@@ -101,7 +102,7 @@ Bun is not used as the Orbit runtime because Orbit depends on Node's built-in `n
101
102
 
102
103
  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`.
103
104
 
104
- - **Per-repo board** — `.orbit/board.db` lives in the repo it tracks. `orbit init` creates it, drops `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. Add `--example` to create onboarding cards.
105
+ - **Per-repo board** — `.orbit/board.db` lives in the repo it tracks. `orbit init` creates it, drops `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. Add `--example` to create onboarding cards, or `--no-ai` to disable AI collaboration for the board.
105
106
  - **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.
106
107
  - **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.
107
108
  - **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.
@@ -167,7 +168,7 @@ A copy-editable client config lives at [docs/mcp-client.example.json](docs/mcp-c
167
168
  - **Board**: name from `BOARD_NAME` env var, otherwise inferred from `package.json` `name` or the repo folder name. Slug from `BOARD_SLUG` or derived from the name.
168
169
  - **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`.
169
170
  - **Default branch**: `DEFAULT_BRANCH` env var, otherwise the current git branch.
170
- - **Lanes (6)**: `Backlog`, `Todo` (default), `In Progress`, `Review`, `Done`, `Cancelled`.
171
+ - **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.
171
172
  - **Labels (7)**: `human-only`, `needs-human-input`, `needs-decomposition`, `needs-followup`, `tech-debt`, `security`, `onboarding`.
172
173
  - **Onboarding cards (optional)**: pass `--example` to create an epic `#1` plus children `#2`, `#3`, and `#12 — Try Orbit MCP on this ticket`.
173
174
  - **Free-form fields**: `project_notes` (Notes tab) and `agent_instructions` (AI tab) get placeholder text you should replace.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starlove/orbit",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "edition": "full",
5
- "builtAt": "2026-05-19T04:43:51.010Z"
5
+ "builtAt": "2026-05-19T05:38:00.174Z"
6
6
  }
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. Add `--ai` to enable the AI Ready / In Progress / Review agent lanes immediately, 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 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.
17
17
 
18
18
  The generated format changes by app:
19
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starlove/orbit",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Starscape Orbit — SQLite-backed, agent-first task board (Starscape suite).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,8 +15,6 @@
15
15
  "build.mjs",
16
16
  "docs",
17
17
  "dist/full",
18
- "pnpm-lock.yaml",
19
- "pnpm-workspace.yaml",
20
18
  "public",
21
19
  "src",
22
20
  "package.json"
package/src/cli/orbit.js CHANGED
@@ -23,7 +23,7 @@ Options (init / reset / serve / docker / mcp):
23
23
  --cwd <dir> Project root (default: process.cwd())
24
24
 
25
25
  Options (init only):
26
- --ai Enable AI collaboration lanes
26
+ --no-ai Create the board with AI collaboration disabled
27
27
  --example Create example onboarding tickets
28
28
  --refresh-agents-md Overwrite SKILL-ORBIT.md and refresh Orbit section in AGENTS.md
29
29
 
@@ -34,7 +34,8 @@ Options (docker only):
34
34
  --image <name> Docker image tag (default: starscape-orbit:local)
35
35
  --data-dir <dir> Docker registry/export data dir (default: <cwd>/.orbit/docker-data)
36
36
  --name <name> Optional Docker container name
37
- --detach Run the container in the background
37
+ -d, --detach Run the container in the background (default)
38
+ --foreground Run attached in the foreground
38
39
  --no-build Skip docker build and run an existing image
39
40
  --dry-run Print docker commands without running them`);
40
41
  }
@@ -134,29 +135,37 @@ function syncAgentsMd(projectRoot, options) {
134
135
  console.log(`Appended Orbit instructions to ${agentsPath}`);
135
136
  }
136
137
 
137
- function enableAiIfRequested(options, registryRow, core) {
138
+ function enableAiIfEnabled(options, registryRow, core) {
138
139
  if (!options.ai || !registryRow) return;
139
140
  const { enableAiCollaboration, openConnection } = core;
140
141
  const db = openConnection(registryRow.db_path);
141
- enableAiCollaboration(db, registryRow.id, { stageOnboardingTicket: options.example, actor: "orbit init --ai" });
142
+ enableAiCollaboration(db, registryRow.id, { stageOnboardingTicket: options.example, actor: "orbit init" });
142
143
  const suffix = options.example ? "; example ticket #12 is staged in AI Ready." : ".";
143
144
  console.log(`AI collaboration enabled — AI Ready, In Progress, and Review lanes are present${suffix}`);
144
145
  }
145
146
 
147
+ function disableAiIfRequested(options, registryRow, core) {
148
+ if (options.ai || !registryRow) return;
149
+ const { openConnection } = core;
150
+ const db = openConnection(registryRow.db_path);
151
+ db.prepare("UPDATE boards SET ai_enabled = 0, updated_at = ? WHERE id = ?").run(new Date().toISOString(), registryRow.id);
152
+ console.log("AI collaboration disabled for this board.");
153
+ }
154
+
146
155
  function parseArgs(argv) {
147
156
  const args = {
148
157
  command: null,
149
158
  cwd: process.env.PROJECT_ROOT ? resolve(process.env.PROJECT_ROOT) : process.cwd(),
150
159
  cwdProvided: false,
151
160
  refreshAgentsMd: false,
152
- ai: false,
161
+ ai: true,
153
162
  example: false,
154
163
  port: null,
155
164
  image: "starscape-orbit:local",
156
165
  dataDir: null,
157
166
  containerName: null,
158
167
  buildImage: true,
159
- detach: false,
168
+ detach: true,
160
169
  dryRun: false
161
170
  };
162
171
  const rest = argv.slice(2);
@@ -168,7 +177,7 @@ function parseArgs(argv) {
168
177
  for (let i = 1; i < rest.length; i++) {
169
178
  const a = rest[i];
170
179
  if (a === "--refresh-agents-md") args.refreshAgentsMd = true;
171
- else if (a === "--ai") args.ai = true;
180
+ else if (a === "--no-ai") args.ai = false;
172
181
  else if (a === "--example") args.example = true;
173
182
  else if (a === "--cwd" && rest[i + 1]) {
174
183
  args.cwdProvided = true;
@@ -194,8 +203,10 @@ function parseArgs(argv) {
194
203
  args.containerName = a.slice("--name=".length);
195
204
  } else if (a === "--no-build") {
196
205
  args.buildImage = false;
197
- } else if (a === "--detach") {
206
+ } else if (a === "-d" || a === "--detach") {
198
207
  args.detach = true;
208
+ } else if (a === "--foreground") {
209
+ args.detach = false;
199
210
  } else if (a === "--dry-run") {
200
211
  args.dryRun = true;
201
212
  } else {
@@ -214,7 +225,7 @@ async function runInit(options) {
214
225
  mkdirSync(DATA_DIR, { recursive: true });
215
226
  createRegistrySchema();
216
227
 
217
- const result = provisionRepoBoard(projectRoot, { includeExamples: options.example });
228
+ const result = provisionRepoBoard(projectRoot, { enableAi: options.ai, includeExamples: options.example });
218
229
  const skillSrc = resolve(ROOT_DIR, "SKILL-ORBIT.md");
219
230
  const skillDest = resolve(projectRoot, "SKILL-ORBIT.md");
220
231
 
@@ -232,7 +243,8 @@ async function runInit(options) {
232
243
  syncAgentsMd(projectRoot, options);
233
244
  }
234
245
 
235
- enableAiIfRequested(options, result.registryRow, core);
246
+ enableAiIfEnabled(options, result.registryRow, core);
247
+ disableAiIfRequested(options, result.registryRow, core);
236
248
 
237
249
  if (result.message && result.status === "skipped") {
238
250
  console.log(result.message);
@@ -251,7 +263,7 @@ ${mcpLine}
251
263
  --- Next: agent prompt (from this repo) ---
252
264
  Read AGENTS.md in this repository, then use the Orbit MCP tools. Use board_list, board_set_active, and ticket context tools per docs/AGENT_PROTOCOL.md before claiming or updating work.
253
265
 
254
- ${options.example ? (options.ai ? "Example ticket #12 is \"Try Orbit MCP on this ticket\" in AI Ready — good first exercise after MCP is connected." : "Example tickets were created. Add `--ai` to also create AI collaboration lanes and stage ticket #12 in AI Ready.") : "No example tickets were created. Rerun on a fresh board with `orbit init --example` if you want the onboarding examples."}
266
+ ${options.example ? (options.ai ? "Example ticket #12 is \"Try Orbit MCP on this ticket\" in AI Ready — good first exercise after MCP is connected." : "Example tickets were created. AI collaboration was disabled with `--no-ai`, so ticket #12 remains in Backlog.") : "No example tickets were created. Rerun on a fresh board with `orbit init --example` if you want the onboarding examples."}
255
267
  `);
256
268
 
257
269
  if (result.registryRow) {
@@ -1,5 +1,5 @@
1
1
  import { getRegistry, tx } from "./db.js";
2
- import { boardById } from "./queries.js";
2
+ import { boardById, compactStatePositions } from "./queries.js";
3
3
  import {
4
4
  computeNewBoardDbPath,
5
5
  ensureBoardDbFileAndSchema,
@@ -33,14 +33,23 @@ export function createBoard(body, ctx) {
33
33
  const time = now();
34
34
  const sniff = buildBoardFromRepo(repoPath);
35
35
 
36
- const defaultStates = body.states || [
36
+ const aiEnabled = body.ai_enabled === undefined ? true : Boolean(body.ai_enabled);
37
+ const defaultStates = body.states || (aiEnabled ? [
37
38
  ["Backlog", null],
38
39
  ["Todo", null],
40
+ ["AI Ready", "ai_ready"],
39
41
  ["In Progress", "in_progress"],
40
42
  ["Review", "review"],
41
43
  ["Done", "done"],
42
44
  ["Cancelled", null]
43
- ];
45
+ ] : [
46
+ ["Backlog", null],
47
+ ["Todo", null],
48
+ ["In Progress", "in_progress"],
49
+ ["Review", "review"],
50
+ ["Done", "done"],
51
+ ["Cancelled", null]
52
+ ]);
44
53
 
45
54
  // Board row + lanes + creation event land atomically in the board DB. The
46
55
  // registry insert below is a different database (can't share this
@@ -49,8 +58,8 @@ export function createBoard(body, ctx) {
49
58
  tx(db, () => {
50
59
  db.prepare(
51
60
  `INSERT INTO boards
52
- (id, slug, name, repo_url, system_path, default_branch, created_at, updated_at)
53
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
61
+ (id, slug, name, repo_url, system_path, default_branch, ai_enabled, created_at, updated_at)
62
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
54
63
  ).run(
55
64
  boardId,
56
65
  slug,
@@ -58,6 +67,7 @@ export function createBoard(body, ctx) {
58
67
  body.repo_url || sniff.repoUrl || "",
59
68
  repoPath,
60
69
  body.default_branch || sniff.defaultBranch || "main",
70
+ aiEnabled ? 1 : 0,
61
71
  time,
62
72
  time
63
73
  );
@@ -70,6 +80,7 @@ export function createBoard(body, ctx) {
70
80
  ).run(id(), boardId, stateName, position, stateName === "Todo" ? 1 : 0, role || null, time);
71
81
  });
72
82
 
83
+ if (aiEnabled) ensureAgentLanes(db, boardId);
73
84
  recordEvent(db, boardId, "board_created", null, actor.name, { board_id: boardId, slug });
74
85
  });
75
86
 
@@ -95,24 +106,58 @@ const AGENT_LANES = [
95
106
  { name: "Review", role: "review" }
96
107
  ];
97
108
 
98
- /** Ensure the three role-bearing lanes that agent flow depends on
99
- * (ai_ready / in_progress / review) exist on the board. Missing lanes are
100
- * appended at the end of the lane order. Idempotent. */
109
+ function desiredAgentLanePosition(db, boardId, role) {
110
+ if (role === "ai_ready") {
111
+ const todo = db.prepare("SELECT position FROM states WHERE board_id = ? AND name = 'Todo'").get(boardId);
112
+ if (todo) return Number(todo.position) + 1;
113
+ const inProgress = db.prepare("SELECT position FROM states WHERE board_id = ? AND role = 'in_progress'").get(boardId);
114
+ if (inProgress) return Number(inProgress.position);
115
+ }
116
+ const maxPosition = db
117
+ .prepare("SELECT MAX(position) AS value FROM states WHERE board_id = ?")
118
+ .get(boardId).value;
119
+ return Number(maxPosition ?? -1) + 1;
120
+ }
121
+
122
+ function openStateSlot(db, boardId, position, exceptStateId = null) {
123
+ db.prepare(
124
+ `UPDATE states
125
+ SET position = position + 1
126
+ WHERE board_id = ?
127
+ AND position >= ?
128
+ AND (? IS NULL OR id != ?)`
129
+ ).run(boardId, position, exceptStateId, exceptStateId);
130
+ }
131
+
132
+ /** Ensure the role-bearing lanes that agent flow depends on exist on the
133
+ * board. AI Ready is kept directly after Todo so claim-next has a predictable
134
+ * handoff column. Idempotent. */
101
135
  export function ensureAgentLanes(db, boardId) {
102
136
  const time = now();
103
137
  for (const lane of AGENT_LANES) {
104
138
  const existing = db
105
- .prepare("SELECT id FROM states WHERE board_id = ? AND role = ?")
139
+ .prepare("SELECT id, position FROM states WHERE board_id = ? AND role = ?")
106
140
  .get(boardId, lane.role);
107
- if (existing) continue;
108
- const maxPosition = db
109
- .prepare("SELECT MAX(position) AS value FROM states WHERE board_id = ?")
110
- .get(boardId).value;
141
+ if (existing) {
142
+ if (lane.role === "ai_ready") {
143
+ let desiredPosition = desiredAgentLanePosition(db, boardId, lane.role);
144
+ if (Number(existing.position) !== desiredPosition) {
145
+ db.prepare("UPDATE states SET position = -1 WHERE id = ?").run(existing.id);
146
+ compactStatePositions(db, boardId);
147
+ desiredPosition = desiredAgentLanePosition(db, boardId, lane.role);
148
+ openStateSlot(db, boardId, desiredPosition, existing.id);
149
+ db.prepare("UPDATE states SET position = ? WHERE id = ?").run(desiredPosition, existing.id);
150
+ }
151
+ }
152
+ continue;
153
+ }
154
+ const position = desiredAgentLanePosition(db, boardId, lane.role);
155
+ openStateSlot(db, boardId, position);
111
156
  db.prepare(
112
157
  `INSERT INTO states
113
158
  (id, board_id, name, position, is_default, role, created_at)
114
159
  VALUES (?, ?, ?, ?, 0, ?, ?)`
115
- ).run(id(), boardId, lane.name, Number(maxPosition || 0) + 1, lane.role, time);
160
+ ).run(id(), boardId, lane.name, position, lane.role, time);
116
161
  }
117
162
  }
118
163
 
@@ -45,7 +45,10 @@ export function provisionRepoBoard(repoPathRaw, options = {}) {
45
45
 
46
46
  const db = openConnection(dbPath);
47
47
  createBoardSchema(db);
48
- const seeded = seedIfEmpty(db, repoRoot, { includeExamples: options.includeExamples });
48
+ const seeded = seedIfEmpty(db, repoRoot, {
49
+ enableAi: options.enableAi,
50
+ includeExamples: options.includeExamples
51
+ });
49
52
  if (!seeded) {
50
53
  const boardMeta = readBoardMetaFromSqlite(db);
51
54
  if (!boardMeta) {
@@ -60,7 +63,10 @@ export function provisionRepoBoard(repoPathRaw, options = {}) {
60
63
  function provisionExistingDbFile(repoRoot, dbPath, options = {}) {
61
64
  const db = openConnection(dbPath);
62
65
  createBoardSchema(db);
63
- const seeded = seedIfEmpty(db, repoRoot, { includeExamples: options.includeExamples });
66
+ const seeded = seedIfEmpty(db, repoRoot, {
67
+ enableAi: options.enableAi,
68
+ includeExamples: options.includeExamples
69
+ });
64
70
  if (seeded) {
65
71
  return insertAfterSeed(repoRoot, dbPath, db, seeded, "repaired");
66
72
  }
package/src/core/seed.js CHANGED
@@ -23,8 +23,8 @@ export function seedIfEmpty(db, repoPath, options = {}) {
23
23
  db.prepare(
24
24
  `INSERT INTO boards
25
25
  (id, slug, name, repo_url, system_path, default_branch,
26
- project_notes, agent_instructions, created_at, updated_at)
27
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
26
+ project_notes, agent_instructions, ai_enabled, created_at, updated_at)
27
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
28
28
  ).run(
29
29
  boardId,
30
30
  seed.boardSlug,
@@ -34,17 +34,26 @@ export function seedIfEmpty(db, repoPath, options = {}) {
34
34
  seed.defaultBranch,
35
35
  seed.projectNotes,
36
36
  seed.agentInstructions,
37
+ options.enableAi === false ? 0 : 1,
37
38
  time,
38
39
  time
39
40
  );
40
41
 
41
- const states = [
42
+ const states = options.enableAi === false ? [
42
43
  ["Backlog", null],
43
44
  ["Todo", null],
44
45
  ["In Progress", "in_progress"],
45
46
  ["Review", "review"],
46
47
  ["Done", "done"],
47
48
  ["Cancelled", null]
49
+ ] : [
50
+ ["Backlog", null],
51
+ ["Todo", null],
52
+ ["AI Ready", "ai_ready"],
53
+ ["In Progress", "in_progress"],
54
+ ["Review", "review"],
55
+ ["Done", "done"],
56
+ ["Cancelled", null]
48
57
  ];
49
58
  const stateIds = new Map();
50
59
  states.forEach(([name, role], position) => {
@@ -1,2 +0,0 @@
1
- onlyBuiltDependencies:
2
- - esbuild