@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/src/core/db.js
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
// Connection management. There is intentionally no module-level "active board"
|
|
2
|
-
// singleton: every caller resolves a per-board DB connection via openConnection
|
|
3
|
-
// and threads it through. This is what makes the server safe under concurrent
|
|
4
|
-
// HTTP requests for different boards — a global active-pointer would race
|
|
5
|
-
// across requests that interleave around `await readJson`.
|
|
6
|
-
|
|
7
|
-
import { DatabaseSync } from "node:sqlite";
|
|
8
|
-
import { REGISTRY_DB_PATH } from "./paths.js";
|
|
9
|
-
import { __enterEventTx, __settleEventTx } from "./events.js";
|
|
10
|
-
|
|
11
|
-
const connections = new Map();
|
|
12
|
-
|
|
13
|
-
/** Open (or return cached) per-database connection. Safe to share within a process. */
|
|
14
|
-
export function openConnection(dbPath) {
|
|
15
|
-
if (connections.has(dbPath)) return connections.get(dbPath);
|
|
16
|
-
const conn = new DatabaseSync(dbPath);
|
|
17
|
-
conn.exec("PRAGMA foreign_keys = ON;");
|
|
18
|
-
conn.exec("PRAGMA busy_timeout = 5000;");
|
|
19
|
-
conn.exec("PRAGMA journal_mode = WAL;");
|
|
20
|
-
// busy_timeout (set above) makes a second writer from another process (MCP
|
|
21
|
-
// server, CLI) wait instead of failing immediately with SQLITE_BUSY when an
|
|
22
|
-
// agent commit and a UI drag overlap. NORMAL is the recommended
|
|
23
|
-
// durability/throughput tradeoff under WAL (a power-loss can lose the last
|
|
24
|
-
// commit but never corrupts the DB).
|
|
25
|
-
conn.exec("PRAGMA synchronous = NORMAL;");
|
|
26
|
-
connections.set(dbPath, conn);
|
|
27
|
-
return conn;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function closeConnection(dbPath) {
|
|
31
|
-
const conn = connections.get(dbPath);
|
|
32
|
-
if (!conn) return;
|
|
33
|
-
try {
|
|
34
|
-
conn.exec("PRAGMA wal_checkpoint(TRUNCATE);");
|
|
35
|
-
} catch {
|
|
36
|
-
// Another process may still be attached; closing this connection is enough
|
|
37
|
-
// to release our file handle.
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
conn.close();
|
|
41
|
-
} finally {
|
|
42
|
-
connections.delete(dbPath);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function hasConnection(dbPath) {
|
|
47
|
-
return connections.has(dbPath);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function closeAllConnections() {
|
|
51
|
-
for (const dbPath of [...connections.keys()]) {
|
|
52
|
-
try {
|
|
53
|
-
closeConnection(dbPath);
|
|
54
|
-
} catch {
|
|
55
|
-
// Shutdown cleanup should release every handle it can without masking
|
|
56
|
-
// the original exit path.
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Reentrancy depth per connection. Only the outermost tx() issues
|
|
62
|
-
// BEGIN/COMMIT/ROLLBACK; inner calls (a tx-wrapped function calling another)
|
|
63
|
-
// fold into the enclosing transaction. Execution is synchronous and a request
|
|
64
|
-
// never awaits between BEGIN and COMMIT, so per-connection depth is race-free.
|
|
65
|
-
const txDepth = new WeakMap();
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Run `fn` inside an IMMEDIATE transaction on `db` so a multi-statement
|
|
69
|
-
* mutation is atomic: it either fully lands or fully rolls back. BEGIN
|
|
70
|
-
* IMMEDIATE takes the write lock up front, which also makes read-then-write
|
|
71
|
-
* sequences (e.g. `MAX(number)+1` ticket numbering) safe against concurrent
|
|
72
|
-
* writer processes. SSE broadcasts for events recorded inside the transaction
|
|
73
|
-
* are buffered and only fan out after COMMIT (see events.js).
|
|
74
|
-
*/
|
|
75
|
-
export function tx(db, fn) {
|
|
76
|
-
const depth = txDepth.get(db) || 0;
|
|
77
|
-
if (depth === 0) db.exec("BEGIN IMMEDIATE;");
|
|
78
|
-
txDepth.set(db, depth + 1);
|
|
79
|
-
__enterEventTx();
|
|
80
|
-
try {
|
|
81
|
-
const result = fn();
|
|
82
|
-
const next = txDepth.get(db) - 1;
|
|
83
|
-
txDepth.set(db, next);
|
|
84
|
-
if (next === 0) db.exec("COMMIT;");
|
|
85
|
-
__settleEventTx(true);
|
|
86
|
-
return result;
|
|
87
|
-
} catch (error) {
|
|
88
|
-
const next = txDepth.get(db) - 1;
|
|
89
|
-
txDepth.set(db, next);
|
|
90
|
-
if (next === 0) {
|
|
91
|
-
try {
|
|
92
|
-
db.exec("ROLLBACK;");
|
|
93
|
-
} catch {
|
|
94
|
-
// A failed BEGIN leaves no transaction to roll back; ignore.
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
__settleEventTx(false);
|
|
98
|
-
throw error;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function getRegistry() {
|
|
103
|
-
return openConnection(REGISTRY_DB_PATH);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Add a column to an existing table only if it is missing. Idempotent: safe to
|
|
107
|
-
* call on every startup. SQLite has no `ADD COLUMN IF NOT EXISTS`, so we probe
|
|
108
|
-
* `PRAGMA table_info` first. */
|
|
109
|
-
function ensureColumn(reg, table, column, definition) {
|
|
110
|
-
const cols = reg.prepare(`PRAGMA table_info(${table})`).all();
|
|
111
|
-
if (cols.some((c) => c.name === column)) return;
|
|
112
|
-
reg.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition};`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/** Registry metadata table (not the per-board `boards` content row). */
|
|
116
|
-
export function createRegistrySchema(reg = getRegistry()) {
|
|
117
|
-
reg.exec(`
|
|
118
|
-
CREATE TABLE IF NOT EXISTS boards (
|
|
119
|
-
id TEXT PRIMARY KEY,
|
|
120
|
-
slug TEXT NOT NULL UNIQUE,
|
|
121
|
-
name TEXT NOT NULL,
|
|
122
|
-
repo_path TEXT NOT NULL DEFAULT '',
|
|
123
|
-
db_path TEXT NOT NULL,
|
|
124
|
-
repo_url TEXT NOT NULL DEFAULT '',
|
|
125
|
-
default_branch TEXT NOT NULL DEFAULT 'main',
|
|
126
|
-
last_active_at TEXT,
|
|
127
|
-
created_at TEXT NOT NULL,
|
|
128
|
-
updated_at TEXT NOT NULL
|
|
129
|
-
);
|
|
130
|
-
CREATE INDEX IF NOT EXISTS idx_registry_boards_repo_path ON boards(repo_path);
|
|
131
|
-
`);
|
|
132
|
-
// Whether Orbit keeps SKILL-ORBIT.md / AGENTS.md in sync inside repo_path.
|
|
133
|
-
// Defaults to 1 so pre-existing boards (created when files were always
|
|
134
|
-
// written) keep their managed copies refreshed on startup.
|
|
135
|
-
ensureColumn(reg, "boards", "manage_helper_files", "INTEGER NOT NULL DEFAULT 1");
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** Full Kanban schema on a per-board database connection. */
|
|
139
|
-
export function createBoardSchema(db) {
|
|
140
|
-
db.exec(`
|
|
141
|
-
CREATE TABLE IF NOT EXISTS boards (
|
|
142
|
-
id TEXT PRIMARY KEY,
|
|
143
|
-
slug TEXT NOT NULL UNIQUE,
|
|
144
|
-
name TEXT NOT NULL,
|
|
145
|
-
repo_url TEXT NOT NULL DEFAULT '',
|
|
146
|
-
system_path TEXT NOT NULL DEFAULT '',
|
|
147
|
-
default_branch TEXT NOT NULL DEFAULT 'main',
|
|
148
|
-
project_notes TEXT NOT NULL DEFAULT '',
|
|
149
|
-
agent_instructions TEXT NOT NULL DEFAULT '',
|
|
150
|
-
ai_enabled INTEGER NOT NULL DEFAULT 0,
|
|
151
|
-
created_at TEXT NOT NULL,
|
|
152
|
-
updated_at TEXT NOT NULL
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
CREATE TABLE IF NOT EXISTS states (
|
|
156
|
-
id TEXT PRIMARY KEY,
|
|
157
|
-
board_id TEXT NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
|
158
|
-
name TEXT NOT NULL,
|
|
159
|
-
position INTEGER NOT NULL,
|
|
160
|
-
is_default INTEGER NOT NULL DEFAULT 0,
|
|
161
|
-
role TEXT,
|
|
162
|
-
created_at TEXT NOT NULL,
|
|
163
|
-
UNIQUE(board_id, name)
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
CREATE TABLE IF NOT EXISTS tickets (
|
|
167
|
-
id TEXT PRIMARY KEY,
|
|
168
|
-
board_id TEXT NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
|
169
|
-
number INTEGER NOT NULL,
|
|
170
|
-
title TEXT NOT NULL,
|
|
171
|
-
description TEXT NOT NULL DEFAULT '',
|
|
172
|
-
type TEXT NOT NULL DEFAULT 'task',
|
|
173
|
-
parent_ticket_id TEXT,
|
|
174
|
-
ai_plan TEXT NOT NULL DEFAULT '',
|
|
175
|
-
plan_artifact_path TEXT NOT NULL DEFAULT '',
|
|
176
|
-
implementation_summary TEXT NOT NULL DEFAULT '',
|
|
177
|
-
implementation_artifact_path TEXT NOT NULL DEFAULT '',
|
|
178
|
-
implementation_updates TEXT NOT NULL DEFAULT '',
|
|
179
|
-
state_id TEXT NOT NULL REFERENCES states(id),
|
|
180
|
-
priority INTEGER NOT NULL DEFAULT 2,
|
|
181
|
-
created_by TEXT NOT NULL DEFAULT 'human',
|
|
182
|
-
created_at TEXT NOT NULL,
|
|
183
|
-
updated_at TEXT NOT NULL,
|
|
184
|
-
archived_at TEXT,
|
|
185
|
-
UNIQUE(board_id, number)
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
CREATE TABLE IF NOT EXISTS comments (
|
|
189
|
-
id TEXT PRIMARY KEY,
|
|
190
|
-
ticket_id TEXT NOT NULL REFERENCES tickets(id) ON DELETE CASCADE,
|
|
191
|
-
author TEXT NOT NULL,
|
|
192
|
-
kind TEXT NOT NULL DEFAULT 'comment',
|
|
193
|
-
body TEXT NOT NULL,
|
|
194
|
-
omitted_for_ai INTEGER NOT NULL DEFAULT 0,
|
|
195
|
-
created_at TEXT NOT NULL
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
CREATE TABLE IF NOT EXISTS review_verdicts (
|
|
199
|
-
id TEXT PRIMARY KEY,
|
|
200
|
-
ticket_id TEXT NOT NULL REFERENCES tickets(id) ON DELETE CASCADE,
|
|
201
|
-
verdict TEXT NOT NULL CHECK (verdict IN ('PASS', 'BLOCK', 'QUESTION')),
|
|
202
|
-
blocking_findings_json TEXT NOT NULL DEFAULT '[]',
|
|
203
|
-
optional_findings_json TEXT NOT NULL DEFAULT '[]',
|
|
204
|
-
evidence_commands_json TEXT NOT NULL DEFAULT '[]',
|
|
205
|
-
reviewer_profile TEXT NOT NULL DEFAULT '',
|
|
206
|
-
reviewer_session_id TEXT NOT NULL DEFAULT '',
|
|
207
|
-
reviewed_commit_sha TEXT NOT NULL DEFAULT '',
|
|
208
|
-
dispatch_run_id TEXT NOT NULL DEFAULT '',
|
|
209
|
-
supersedes_prior_review_id TEXT REFERENCES review_verdicts(id) ON DELETE SET NULL,
|
|
210
|
-
created_by TEXT NOT NULL DEFAULT 'human',
|
|
211
|
-
created_at TEXT NOT NULL
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
CREATE TABLE IF NOT EXISTS ticket_attachments (
|
|
215
|
-
id TEXT PRIMARY KEY,
|
|
216
|
-
ticket_id TEXT NOT NULL REFERENCES tickets(id) ON DELETE CASCADE,
|
|
217
|
-
board_id TEXT NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
|
218
|
-
original_name TEXT NOT NULL,
|
|
219
|
-
stored_path TEXT NOT NULL,
|
|
220
|
-
mime_type TEXT NOT NULL,
|
|
221
|
-
size_bytes INTEGER NOT NULL,
|
|
222
|
-
sha256 TEXT NOT NULL,
|
|
223
|
-
created_by TEXT NOT NULL DEFAULT 'human',
|
|
224
|
-
created_at TEXT NOT NULL
|
|
225
|
-
);
|
|
226
|
-
|
|
227
|
-
CREATE TABLE IF NOT EXISTS board_entries (
|
|
228
|
-
id TEXT PRIMARY KEY,
|
|
229
|
-
board_id TEXT NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
|
230
|
-
type TEXT NOT NULL,
|
|
231
|
-
title TEXT NOT NULL,
|
|
232
|
-
body TEXT NOT NULL DEFAULT '',
|
|
233
|
-
ticket_id TEXT REFERENCES tickets(id) ON DELETE SET NULL,
|
|
234
|
-
created_by TEXT NOT NULL DEFAULT 'human',
|
|
235
|
-
created_at TEXT NOT NULL,
|
|
236
|
-
updated_at TEXT NOT NULL,
|
|
237
|
-
struck_at TEXT
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
CREATE TABLE IF NOT EXISTS labels (
|
|
241
|
-
id TEXT PRIMARY KEY,
|
|
242
|
-
board_id TEXT NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
|
243
|
-
name TEXT NOT NULL,
|
|
244
|
-
color TEXT NOT NULL DEFAULT '#64748b',
|
|
245
|
-
created_at TEXT NOT NULL,
|
|
246
|
-
UNIQUE(board_id, name)
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
CREATE TABLE IF NOT EXISTS ticket_labels (
|
|
250
|
-
ticket_id TEXT NOT NULL REFERENCES tickets(id) ON DELETE CASCADE,
|
|
251
|
-
label_id TEXT NOT NULL REFERENCES labels(id) ON DELETE CASCADE,
|
|
252
|
-
PRIMARY KEY(ticket_id, label_id)
|
|
253
|
-
);
|
|
254
|
-
|
|
255
|
-
CREATE TABLE IF NOT EXISTS relations (
|
|
256
|
-
id TEXT PRIMARY KEY,
|
|
257
|
-
source_ticket_id TEXT NOT NULL REFERENCES tickets(id) ON DELETE CASCADE,
|
|
258
|
-
target_ticket_id TEXT NOT NULL REFERENCES tickets(id) ON DELETE CASCADE,
|
|
259
|
-
type TEXT NOT NULL,
|
|
260
|
-
created_at TEXT NOT NULL,
|
|
261
|
-
UNIQUE(source_ticket_id, target_ticket_id, type)
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
CREATE TABLE IF NOT EXISTS events (
|
|
265
|
-
id TEXT PRIMARY KEY,
|
|
266
|
-
ticket_id TEXT REFERENCES tickets(id) ON DELETE SET NULL,
|
|
267
|
-
actor TEXT NOT NULL,
|
|
268
|
-
type TEXT NOT NULL,
|
|
269
|
-
body_json TEXT NOT NULL DEFAULT '{}',
|
|
270
|
-
created_at TEXT NOT NULL
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS ticket_fts USING fts5(
|
|
274
|
-
ticket_id UNINDEXED,
|
|
275
|
-
title,
|
|
276
|
-
description,
|
|
277
|
-
comments
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
CREATE INDEX IF NOT EXISTS idx_states_board ON states(board_id, position);
|
|
281
|
-
CREATE INDEX IF NOT EXISTS idx_states_role ON states(board_id, role);
|
|
282
|
-
CREATE INDEX IF NOT EXISTS idx_tickets_board_state ON tickets(board_id, state_id);
|
|
283
|
-
CREATE INDEX IF NOT EXISTS idx_tickets_archived ON tickets(board_id, archived_at);
|
|
284
|
-
CREATE INDEX IF NOT EXISTS idx_tickets_parent ON tickets(parent_ticket_id);
|
|
285
|
-
CREATE INDEX IF NOT EXISTS idx_comments_ticket ON comments(ticket_id, created_at);
|
|
286
|
-
CREATE INDEX IF NOT EXISTS idx_review_verdicts_ticket ON review_verdicts(ticket_id, created_at);
|
|
287
|
-
CREATE INDEX IF NOT EXISTS idx_review_verdicts_supersedes ON review_verdicts(supersedes_prior_review_id);
|
|
288
|
-
CREATE INDEX IF NOT EXISTS idx_ticket_attachments_ticket ON ticket_attachments(ticket_id, created_at);
|
|
289
|
-
CREATE INDEX IF NOT EXISTS idx_ticket_attachments_board ON ticket_attachments(board_id, created_at);
|
|
290
|
-
CREATE INDEX IF NOT EXISTS idx_board_entries_board ON board_entries(board_id, type, created_at);
|
|
291
|
-
CREATE INDEX IF NOT EXISTS idx_relations_source ON relations(source_ticket_id);
|
|
292
|
-
CREATE INDEX IF NOT EXISTS idx_relations_target ON relations(target_ticket_id);
|
|
293
|
-
CREATE INDEX IF NOT EXISTS idx_events_ticket ON events(ticket_id, created_at);
|
|
294
|
-
`);
|
|
295
|
-
ensureColumn(db, "tickets", "plan_artifact_path", "TEXT NOT NULL DEFAULT ''");
|
|
296
|
-
ensureColumn(db, "tickets", "implementation_artifact_path", "TEXT NOT NULL DEFAULT ''");
|
|
297
|
-
ensureColumn(db, "comments", "omitted_for_ai", "INTEGER NOT NULL DEFAULT 0");
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export function resetBoard(db) {
|
|
301
|
-
db.exec(`
|
|
302
|
-
DELETE FROM ticket_fts;
|
|
303
|
-
DELETE FROM ticket_labels;
|
|
304
|
-
DELETE FROM relations;
|
|
305
|
-
DELETE FROM comments;
|
|
306
|
-
DELETE FROM review_verdicts;
|
|
307
|
-
DELETE FROM ticket_attachments;
|
|
308
|
-
DELETE FROM board_entries;
|
|
309
|
-
DELETE FROM events;
|
|
310
|
-
DELETE FROM tickets;
|
|
311
|
-
DELETE FROM labels;
|
|
312
|
-
DELETE FROM states;
|
|
313
|
-
DELETE FROM boards;
|
|
314
|
-
`);
|
|
315
|
-
}
|
package/src/core/delete-board.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { existsSync, rmSync } from "node:fs";
|
|
2
|
-
import { basename, dirname, join, relative } from "node:path";
|
|
3
|
-
import { removeOrbitAgentsSection } from "./agents-md.js";
|
|
4
|
-
import { requireBoardAccess } from "./auth.js";
|
|
5
|
-
import { backupBoardDatabase, backupRegistry, cancelAutomaticBoardBackup } from "./backups.js";
|
|
6
|
-
import { closeConnection } from "./db.js";
|
|
7
|
-
import { BOARDS_DIR, DATA_DIR, DISPATCH_RUNS_DIR } from "./paths.js";
|
|
8
|
-
import { deleteBoard, listBoards, openBoardDb } from "./registry.js";
|
|
9
|
-
import { httpError, normalizePath } from "./util.js";
|
|
10
|
-
|
|
11
|
-
function isInside(parent, child) {
|
|
12
|
-
const rel = relative(parent, child);
|
|
13
|
-
return rel && !rel.startsWith("..") && !rel.startsWith("/") && rel !== "..";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function boardDbDeleteTargets(boardRow) {
|
|
17
|
-
const dbPath = normalizePath(boardRow.db_path || "");
|
|
18
|
-
if (!dbPath || basename(dbPath) !== "board.db") {
|
|
19
|
-
throw httpError(409, "unsafe_board_db_path");
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Central storage: db lives inside DATA_DIR/boards/<slug>/board.db
|
|
23
|
-
const boardsDirNorm = normalizePath(BOARDS_DIR);
|
|
24
|
-
if (dbPath.startsWith(boardsDirNorm + "/")) {
|
|
25
|
-
const boardDir = dirname(dbPath);
|
|
26
|
-
// Safety: boardDir must be exactly one level below BOARDS_DIR
|
|
27
|
-
if (normalizePath(dirname(boardDir)) !== boardsDirNorm) {
|
|
28
|
-
throw httpError(409, "unsafe_board_db_path");
|
|
29
|
-
}
|
|
30
|
-
return [boardDir];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Legacy in-repo storage: db lives inside <repo>/.orbit/
|
|
34
|
-
const repoRoot = normalizePath(boardRow.repo_path || "");
|
|
35
|
-
const orbitRoot = normalizePath(join(repoRoot, ".orbit"));
|
|
36
|
-
if (!repoRoot || !isInside(orbitRoot, dbPath)) {
|
|
37
|
-
throw httpError(409, "unsafe_board_db_path");
|
|
38
|
-
}
|
|
39
|
-
const boardDir = dirname(dbPath);
|
|
40
|
-
const boardsRoot = normalizePath(join(orbitRoot, "boards"));
|
|
41
|
-
if (isInside(boardsRoot, boardDir)) return [boardDir];
|
|
42
|
-
return [dbPath, `${dbPath}-wal`, `${dbPath}-shm`, `${dbPath}-journal`];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isLastBoardForRepo(boardRow) {
|
|
46
|
-
const repoRoot = normalizePath(boardRow.repo_path || "");
|
|
47
|
-
return !listBoards().some((row) => row.id !== boardRow.id && normalizePath(row.repo_path || "") === repoRoot);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function repoArtifactTargets(boardRow) {
|
|
51
|
-
const repoRoot = normalizePath(boardRow.repo_path || "");
|
|
52
|
-
const dbPath = normalizePath(boardRow.db_path || "");
|
|
53
|
-
if (!repoRoot || !dbPath || basename(dbPath) !== "board.db") {
|
|
54
|
-
throw httpError(409, "unsafe_board_db_path");
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
orbitRoot: normalizePath(join(repoRoot, ".orbit")),
|
|
58
|
-
skillMd: join(repoRoot, "SKILL-ORBIT.md")
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function removeOptions(recursive = false) {
|
|
63
|
-
const options = { force: true };
|
|
64
|
-
if (recursive) options.recursive = true;
|
|
65
|
-
if (process.platform === "win32") {
|
|
66
|
-
options.maxRetries = 10;
|
|
67
|
-
options.retryDelay = 100;
|
|
68
|
-
}
|
|
69
|
-
return options;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function isBusyFilesystemError(error) {
|
|
73
|
-
const message = String(error?.message || "").toLowerCase();
|
|
74
|
-
return (
|
|
75
|
-
["EBUSY", "EPERM", "ENOTEMPTY"].includes(error?.code) ||
|
|
76
|
-
(error?.code === "ERR_SQLITE_ERROR" && (message.includes("locked") || message.includes("busy")))
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function boardFilesBusyError(error, boardRow) {
|
|
81
|
-
if (!isBusyFilesystemError(error)) return error;
|
|
82
|
-
const wrapped = new Error(
|
|
83
|
-
[
|
|
84
|
-
`Orbit could not remove local board files for "${boardRow.slug}".`,
|
|
85
|
-
"On Windows this usually means an Orbit web server, MCP helper, AI client, editor, or terminal still has .orbit/board.db open.",
|
|
86
|
-
"Close those processes, then retry the delete from Settings or run orbit reset --cwd <repo>.",
|
|
87
|
-
`Original error: ${error.message}`
|
|
88
|
-
].join("\n")
|
|
89
|
-
);
|
|
90
|
-
wrapped.status = 409;
|
|
91
|
-
wrapped.code = "board_files_busy";
|
|
92
|
-
wrapped.cause = error;
|
|
93
|
-
return wrapped;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export function deleteRegisteredBoard(boardRow, body, actor) {
|
|
97
|
-
requireBoardAccess(actor, { slug: boardRow.slug });
|
|
98
|
-
|
|
99
|
-
const confirmation = String(body?.confirm_slug || "").trim();
|
|
100
|
-
if (confirmation !== boardRow.slug) throw httpError(400, "board_slug_confirmation_required");
|
|
101
|
-
|
|
102
|
-
const deleteFiles = body?.delete_files !== false;
|
|
103
|
-
const removeRepoArtifacts = deleteFiles && isLastBoardForRepo(boardRow);
|
|
104
|
-
const repoArtifacts = removeRepoArtifacts ? repoArtifactTargets(boardRow) : null;
|
|
105
|
-
// Always delete the board's own db files/directory; when it is the last board
|
|
106
|
-
// for a repo also sweep in-repo artifacts (.orbit/, SKILL-ORBIT.md, AGENTS.md).
|
|
107
|
-
// Also remove the board's central dispatch-runs directory.
|
|
108
|
-
const dispatchRunsDir = join(DISPATCH_RUNS_DIR, boardRow.slug);
|
|
109
|
-
const targets = deleteFiles
|
|
110
|
-
? [
|
|
111
|
-
...boardDbDeleteTargets(boardRow),
|
|
112
|
-
...(repoArtifacts ? [repoArtifacts.orbitRoot] : []),
|
|
113
|
-
...(existsSync(dispatchRunsDir) ? [dispatchRunsDir] : [])
|
|
114
|
-
]
|
|
115
|
-
: [];
|
|
116
|
-
const artifactResults = [];
|
|
117
|
-
cancelAutomaticBoardBackup(boardRow.id);
|
|
118
|
-
if (deleteFiles) {
|
|
119
|
-
try {
|
|
120
|
-
backupBoardDatabase(boardRow, openBoardDb(boardRow), "pre-board-delete");
|
|
121
|
-
} catch (error) {
|
|
122
|
-
throw boardFilesBusyError(error, boardRow);
|
|
123
|
-
} finally {
|
|
124
|
-
closeConnection(boardRow.db_path);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
backupRegistry("pre-board-delete");
|
|
128
|
-
closeConnection(boardRow.db_path);
|
|
129
|
-
|
|
130
|
-
try {
|
|
131
|
-
for (const target of targets) {
|
|
132
|
-
if (existsSync(target)) {
|
|
133
|
-
rmSync(target, removeOptions(true));
|
|
134
|
-
artifactResults.push({ path: target, removed: true });
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (repoArtifacts?.skillMd && existsSync(repoArtifacts.skillMd)) {
|
|
138
|
-
rmSync(repoArtifacts.skillMd, removeOptions(false));
|
|
139
|
-
artifactResults.push({ path: repoArtifacts.skillMd, removed: true });
|
|
140
|
-
}
|
|
141
|
-
} catch (error) {
|
|
142
|
-
throw boardFilesBusyError(error, boardRow);
|
|
143
|
-
}
|
|
144
|
-
if (removeRepoArtifacts) {
|
|
145
|
-
const agentsCleanup = removeOrbitAgentsSection(boardRow.repo_path);
|
|
146
|
-
artifactResults.push({
|
|
147
|
-
path: agentsCleanup.path,
|
|
148
|
-
removed: agentsCleanup.removed,
|
|
149
|
-
ok: agentsCleanup.ok,
|
|
150
|
-
reason: agentsCleanup.reason
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
deleteBoard(boardRow.id);
|
|
155
|
-
return {
|
|
156
|
-
ok: true,
|
|
157
|
-
deleted_board_id: boardRow.id,
|
|
158
|
-
deleted_board_slug: boardRow.slug,
|
|
159
|
-
deleted_files: deleteFiles,
|
|
160
|
-
deleted_repo_artifacts: removeRepoArtifacts,
|
|
161
|
-
artifacts: artifactResults
|
|
162
|
-
};
|
|
163
|
-
}
|