kanbo-cli 0.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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/better-sqlite3-fU3G4xnX.cjs +2254 -0
  4. package/dist/better-sqlite3-fU3G4xnX.cjs.map +1 -0
  5. package/dist/cli.cjs +42949 -0
  6. package/dist/cli.cjs.map +1 -0
  7. package/dist/dist-Cd6wg8pp.cjs +942 -0
  8. package/dist/dist-Cd6wg8pp.cjs.map +1 -0
  9. package/dist/drizzle-postgres/0000_board.sql +135 -0
  10. package/dist/drizzle-postgres/0001_history_order.sql +2 -0
  11. package/dist/drizzle-postgres/0002_issue_pull_requests.sql +16 -0
  12. package/dist/drizzle-postgres/0003_milestone_start_date.sql +1 -0
  13. package/dist/drizzle-postgres/0004_status_entry_rules.sql +1 -0
  14. package/dist/drizzle-postgres/0005_run_external_session_ref.sql +1 -0
  15. package/dist/drizzle-postgres/README.md +61 -0
  16. package/dist/drizzle-postgres/meta/0000_snapshot.json +1078 -0
  17. package/dist/drizzle-postgres/meta/0001_snapshot.json +1090 -0
  18. package/dist/drizzle-postgres/meta/0002_snapshot.json +1239 -0
  19. package/dist/drizzle-postgres/meta/0003_snapshot.json +1245 -0
  20. package/dist/drizzle-postgres/meta/0004_snapshot.json +1251 -0
  21. package/dist/drizzle-postgres/meta/0005_snapshot.json +1257 -0
  22. package/dist/drizzle-postgres/meta/_journal.json +48 -0
  23. package/dist/drizzle-sqlite/0000_board.sql +133 -0
  24. package/dist/drizzle-sqlite/0001_issue_pull_requests.sql +15 -0
  25. package/dist/drizzle-sqlite/0002_milestone_start_date.sql +1 -0
  26. package/dist/drizzle-sqlite/0003_status_entry_rules.sql +1 -0
  27. package/dist/drizzle-sqlite/0004_run_external_session_ref.sql +1 -0
  28. package/dist/drizzle-sqlite/README.md +67 -0
  29. package/dist/drizzle-sqlite/meta/0000_snapshot.json +946 -0
  30. package/dist/drizzle-sqlite/meta/0001_snapshot.json +1054 -0
  31. package/dist/drizzle-sqlite/meta/0002_snapshot.json +1061 -0
  32. package/dist/drizzle-sqlite/meta/0003_snapshot.json +1068 -0
  33. package/dist/drizzle-sqlite/meta/0004_snapshot.json +1075 -0
  34. package/dist/drizzle-sqlite/meta/_journal.json +41 -0
  35. package/dist/lib/board-store-B16YarvX.d.mts +281 -0
  36. package/dist/lib/board-store-BHHo_ZlR.d.cts +281 -0
  37. package/dist/lib/index.cjs +340 -0
  38. package/dist/lib/index.cjs.map +1 -0
  39. package/dist/lib/index.d.cts +1608 -0
  40. package/dist/lib/index.d.mts +1608 -0
  41. package/dist/lib/index.mjs +284 -0
  42. package/dist/lib/index.mjs.map +1 -0
  43. package/dist/lib/manifest-C0EcwwgO.mjs +7866 -0
  44. package/dist/lib/manifest-C0EcwwgO.mjs.map +1 -0
  45. package/dist/lib/manifest-CpZOcB_6.cjs +8272 -0
  46. package/dist/lib/manifest-CpZOcB_6.cjs.map +1 -0
  47. package/dist/lib/mcp/index.cjs +184 -0
  48. package/dist/lib/mcp/index.cjs.map +1 -0
  49. package/dist/lib/mcp/index.d.cts +346 -0
  50. package/dist/lib/mcp/index.d.mts +346 -0
  51. package/dist/lib/mcp/index.mjs +173 -0
  52. package/dist/lib/mcp/index.mjs.map +1 -0
  53. package/dist/lib/migrate-BhYi9cXw.mjs +656 -0
  54. package/dist/lib/migrate-BhYi9cXw.mjs.map +1 -0
  55. package/dist/lib/migrate-DnMjTCvu.cjs +709 -0
  56. package/dist/lib/migrate-DnMjTCvu.cjs.map +1 -0
  57. package/dist/lib/migrations-path-CZxVOgeD.cjs +109 -0
  58. package/dist/lib/migrations-path-CZxVOgeD.cjs.map +1 -0
  59. package/dist/lib/migrations-path-Ciwan537.mjs +80 -0
  60. package/dist/lib/migrations-path-Ciwan537.mjs.map +1 -0
  61. package/dist/lib/postgres/index.cjs +56 -0
  62. package/dist/lib/postgres/index.cjs.map +1 -0
  63. package/dist/lib/postgres/index.d.cts +3403 -0
  64. package/dist/lib/postgres/index.d.mts +3403 -0
  65. package/dist/lib/postgres/index.mjs +35 -0
  66. package/dist/lib/postgres/index.mjs.map +1 -0
  67. package/dist/lib/roles.sql-B9rt-x4o.cjs +1033 -0
  68. package/dist/lib/roles.sql-B9rt-x4o.cjs.map +1 -0
  69. package/dist/lib/roles.sql-CvyCGt38.mjs +920 -0
  70. package/dist/lib/roles.sql-CvyCGt38.mjs.map +1 -0
  71. package/dist/lib/schema-epoch-ZyumVL_A.d.cts +16 -0
  72. package/dist/lib/schema-epoch-ZyumVL_A.d.mts +16 -0
  73. package/dist/lib/schema-fsHqNAip.d.cts +3612 -0
  74. package/dist/lib/schema-fsHqNAip.d.mts +3612 -0
  75. package/dist/lib/sqlite/index.cjs +23 -0
  76. package/dist/lib/sqlite/index.d.cts +175 -0
  77. package/dist/lib/sqlite/index.d.mts +175 -0
  78. package/dist/lib/sqlite/index.mjs +4 -0
  79. package/dist/lib/sqlite/schema.cjs +266 -0
  80. package/dist/lib/sqlite/schema.cjs.map +1 -0
  81. package/dist/lib/sqlite/schema.d.cts +2 -0
  82. package/dist/lib/sqlite/schema.d.mts +2 -0
  83. package/dist/lib/sqlite/schema.mjs +256 -0
  84. package/dist/lib/sqlite/schema.mjs.map +1 -0
  85. package/dist/lib/tool-names-9cmCn0gP.d.cts +112 -0
  86. package/dist/lib/tool-names-Dxg1UTUl.d.mts +112 -0
  87. package/dist/page/board.css +477 -0
  88. package/dist/page/board.js +2 -0
  89. package/drizzle-postgres/0000_board.sql +135 -0
  90. package/drizzle-postgres/0001_history_order.sql +2 -0
  91. package/drizzle-postgres/0002_issue_pull_requests.sql +16 -0
  92. package/drizzle-postgres/0003_milestone_start_date.sql +1 -0
  93. package/drizzle-postgres/0004_status_entry_rules.sql +1 -0
  94. package/drizzle-postgres/0005_run_external_session_ref.sql +1 -0
  95. package/drizzle-postgres/README.md +61 -0
  96. package/drizzle-postgres/meta/0000_snapshot.json +1078 -0
  97. package/drizzle-postgres/meta/0001_snapshot.json +1090 -0
  98. package/drizzle-postgres/meta/0002_snapshot.json +1239 -0
  99. package/drizzle-postgres/meta/0003_snapshot.json +1245 -0
  100. package/drizzle-postgres/meta/0004_snapshot.json +1251 -0
  101. package/drizzle-postgres/meta/0005_snapshot.json +1257 -0
  102. package/drizzle-postgres/meta/_journal.json +48 -0
  103. package/drizzle-sqlite/0000_board.sql +133 -0
  104. package/drizzle-sqlite/0001_issue_pull_requests.sql +15 -0
  105. package/drizzle-sqlite/0002_milestone_start_date.sql +1 -0
  106. package/drizzle-sqlite/0003_status_entry_rules.sql +1 -0
  107. package/drizzle-sqlite/0004_run_external_session_ref.sql +1 -0
  108. package/drizzle-sqlite/README.md +67 -0
  109. package/drizzle-sqlite/meta/0000_snapshot.json +946 -0
  110. package/drizzle-sqlite/meta/0001_snapshot.json +1054 -0
  111. package/drizzle-sqlite/meta/0002_snapshot.json +1061 -0
  112. package/drizzle-sqlite/meta/0003_snapshot.json +1068 -0
  113. package/drizzle-sqlite/meta/0004_snapshot.json +1075 -0
  114. package/drizzle-sqlite/meta/_journal.json +41 -0
  115. package/package.json +147 -0
@@ -0,0 +1,23 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_migrations_path = require("../migrations-path-CZxVOgeD.cjs");
3
+ const require_sqlite_schema = require("./schema.cjs");
4
+ const require_migrate = require("../migrate-DnMjTCvu.cjs");
5
+ exports.BOARD_SCHEMA_EPOCH = require_migrations_path.BOARD_SCHEMA_EPOCH;
6
+ exports.assertBoardSchema = require_migrate.assertBoardSchema;
7
+ exports.boardSqliteSchema = require_sqlite_schema.boardSqliteSchema;
8
+ exports.createSqliteBoardStore = require_migrate.createSqliteBoardStore;
9
+ exports.getBoardSqliteMigrationsPath = require_migrate.getBoardSqliteMigrationsPath;
10
+ exports.issueComments = require_sqlite_schema.issueComments;
11
+ exports.issueFieldChanges = require_sqlite_schema.issueFieldChanges;
12
+ exports.issueMilestones = require_sqlite_schema.issueMilestones;
13
+ exports.issueRelations = require_sqlite_schema.issueRelations;
14
+ exports.issueRuns = require_sqlite_schema.issueRuns;
15
+ exports.issueStatuses = require_sqlite_schema.issueStatuses;
16
+ exports.issues = require_sqlite_schema.issues;
17
+ exports.kanbanMeta = require_sqlite_schema.kanbanMeta;
18
+ exports.markBoardFileOwnedByKanbo = require_migrate.markBoardFileOwnedByKanbo;
19
+ exports.migrateBoardFile = require_migrate.migrateBoardFile;
20
+ exports.openBoardDatabase = require_migrate.openBoardDatabase;
21
+ exports.readBoardFileContents = require_migrate.readBoardFileContents;
22
+ exports.readBoardFileOwner = require_migrate.readBoardFileOwner;
23
+ exports.runSqliteTransaction = require_migrate.runSqliteTransaction;
@@ -0,0 +1,175 @@
1
+ import { _ as issueStatuses, c as IssueStatus, d as issueComments, f as issueFieldChanges, g as issueRuns, h as issueRelations, i as IssueMilestone, l as KanbanMeta, n as IssueComment, o as IssueRelation, p as issueMilestones, r as IssueFieldChange, s as IssueRun, t as Issue, u as boardSqliteSchema, v as issues, y as kanbanMeta } from "../schema-fsHqNAip.cjs";
2
+ import { a as BoardStore } from "../board-store-BHHo_ZlR.cjs";
3
+ import { t as BOARD_SCHEMA_EPOCH } from "../schema-epoch-ZyumVL_A.cjs";
4
+ import { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
5
+ import { Database } from "better-sqlite3";
6
+ //#region src/sqlite/transaction.d.ts
7
+ /**
8
+ * The database handle itself — what the host hands the board — and not an open
9
+ * transaction on it: the helper reaches for the driver connection, which a
10
+ * drizzle `SQLiteTransaction` does not carry.
11
+ *
12
+ * The schema parameter is `Record<string, unknown>` rather than any particular
13
+ * schema, which is what lets one type stand for all three of the files a board
14
+ * can live in (ruling 5-3): a handle drizzle was given a host app's whole schema
15
+ * satisfies it, and so does one given only the board's own nine tables. The
16
+ * board never reaches for `database.query`, so the relational builder those
17
+ * generics shape is not something this package gives up by asking for less —
18
+ * `src/sqlite/database-type.test.ts` is the probe that says both handles still
19
+ * arrive here.
20
+ */
21
+ type SqliteDatabase = BetterSQLite3Database<Record<string, unknown>>;
22
+ /**
23
+ * How the outer `begin` takes its write lock. `deferred` — the SQLite default —
24
+ * waits for the first write; `immediate` takes the lock up front, so two
25
+ * processes racing for the same file fail fast instead of half-way through.
26
+ * A nested scope is a savepoint and takes no lock of its own, so the mode only
27
+ * reaches the outer statement.
28
+ */
29
+ type SqliteTransactionMode = 'deferred' | 'immediate';
30
+ /**
31
+ * Run `fn` inside one SQLite transaction that is allowed to await.
32
+ *
33
+ * `database.transaction(...)` cannot serve here: it commits the moment its
34
+ * callback returns, and an async callback returns a pending promise, so the
35
+ * transaction would close before the work inside it ran. The statements are
36
+ * issued by hand instead, and the driver's own `inTransaction` flag picks which
37
+ * — the same branch better-sqlite3 takes. With nothing open: `begin`, then
38
+ * `commit`, or `rollback` when `fn` throws. With a transaction already open —
39
+ * another call to this helper, or one a module opened through
40
+ * `database.transaction` — a `savepoint` … `release` pair, undone by
41
+ * `rollback to` followed by its own `release`. A second `begin` would throw,
42
+ * which is why the flag decides and not a private counter. When SQLite has
43
+ * already aborted the transaction itself the undo is skipped: it would throw
44
+ * over the caller's error.
45
+ *
46
+ * **The callback must be the only database-touching async chain in flight —
47
+ * no `Promise.all` sibling, no lock hand-off, no fire-and-forget promise
48
+ * started before it — and inside it, only await operations that resolve
49
+ * without I/O: store methods, synchronous database writes.** Even a resolved
50
+ * promise yields to the microtask queue first, so a sibling chain already
51
+ * queued in the same macrotask still runs inside this open transaction; a
52
+ * chain started in a separate macrotask is unaffected. Awaiting anything that
53
+ * truly suspends — a timer, the filesystem, the network — hands the
54
+ * connection to whatever runs next, and its writes land in this transaction
55
+ * too.
56
+ */
57
+ declare function runSqliteTransaction<T>(database: SqliteDatabase, fn: () => Promise<T>, options?: {
58
+ mode?: SqliteTransactionMode;
59
+ }): Promise<T>;
60
+ //#endregion
61
+ //#region src/sqlite/board-store.sqlite.d.ts
62
+ /**
63
+ * `BoardStore` backed by SQLite: every method resolves immediately, because the
64
+ * core underneath it is synchronous.
65
+ *
66
+ * `database` is a function rather than a handle so the store follows whatever
67
+ * the host currently has open — a server passes its single connection
68
+ * accessor, a standalone reader passes its own.
69
+ */
70
+ declare function createSqliteBoardStore(options: {
71
+ database: () => SqliteDatabase;
72
+ }): BoardStore;
73
+ //#endregion
74
+ //#region src/sqlite/migrate.d.ts
75
+ /**
76
+ * The board's SQLite migrations for the file that is running right now — the
77
+ * ones that build a board *file of this package's own*. The two layouts this
78
+ * has to survive are `src/migrations-path.ts`'s subject.
79
+ */
80
+ declare function getBoardSqliteMigrationsPath(): string;
81
+ /**
82
+ * Create or update a board file this package owns.
83
+ *
84
+ * A host app's own database is not this: there the board is nine tables among
85
+ * the app's own, and the app's migration runner migrates the whole file — which
86
+ * may take two passes, because a migration that rebuilds a table has to drop
87
+ * it with foreign keys off. Nothing here rebuilds anything — `drizzle-sqlite/` starts at the
88
+ * board as it is now and will only ever be appended to — so drizzle's own
89
+ * migrator is the whole of what this needs, and a file that has been migrated
90
+ * before is a no-op by `__drizzle_migrations`.
91
+ *
92
+ * What the file holds afterwards is the board and nothing else: no
93
+ * `workspaces`, no `agents`, no `provider_targets`. Every reference out of the
94
+ * board is a plain text column for exactly that reason (ruling 5-1).
95
+ */
96
+ declare function migrateBoardFile(database: SqliteDatabase): void;
97
+ //#endregion
98
+ //#region src/sqlite/open-database.d.ts
99
+ /** One open board file: the drizzle handle, the driver beneath it, and the way to let go. */
100
+ interface BoardDatabase {
101
+ database: SqliteDatabase;
102
+ connection: Database;
103
+ close: () => void;
104
+ }
105
+ /**
106
+ * Open a board file with the runtime pragmas a long-running server sets on its
107
+ * own database, so a board read from a terminal behaves the same as one read
108
+ * from inside an app. Migrations are not applied here: the file's owner applies
109
+ * them (`kanbo init --file`, `kanbo migrate`, or the app the database belongs to).
110
+ *
111
+ * Asynchronous because the driver beneath it is loaded on demand — see
112
+ * `loadSqliteDriver`. The native module is asked for first, so an install
113
+ * without it hears the sentence above rather than a module-resolution stack
114
+ * from inside drizzle.
115
+ */
116
+ declare function openBoardDatabase(path: string): Promise<BoardDatabase>;
117
+ /**
118
+ * Refuse a board file this build cannot speak for, before any statement runs
119
+ * against it: one with no board in it (`missingTables`), one whose board a
120
+ * later migration has since added a table to (`missingAddedTables`) or a
121
+ * column to (`missingColumns`), and one stamped with another epoch. An app
122
+ * that migrates its own database on start need not call this; it is the guard a
123
+ * standalone reader puts in front of a file it did not create.
124
+ */
125
+ declare function assertBoardSchema(database: SqliteDatabase): void;
126
+ /**
127
+ * Who created this board file's tables from nothing: this package
128
+ * (`kanbo init --file`), or a host app whose own database the board lives in.
129
+ */
130
+ type BoardFileOwner = 'kanbo' | 'host';
131
+ /**
132
+ * Which of the two ever wrote this file's board, going by the `kanban_meta`
133
+ * marker `kanbo init --file` leaves behind (ruling 5-4).
134
+ *
135
+ * Absent reads as a host database — every file this package has never
136
+ * touched, and a file this build cannot make sense of at all: `assertBoardSchema` is what says a board is missing or too old,
137
+ * not this, so a table or a row that is not there yet is read as "not this
138
+ * package's file" rather than an error of its own.
139
+ */
140
+ declare function readBoardFileOwner(database: SqliteDatabase): BoardFileOwner;
141
+ /**
142
+ * Leave the marker that tells every later reader this file is this package's
143
+ * own, not a host app's. `kanbo init --file` calls this once, right after
144
+ * migrating; `insert or ignore` is what makes calling it again on the same
145
+ * file a no-op rather than a conflict.
146
+ */
147
+ declare function markBoardFileOwnedByKanbo(database: SqliteDatabase): void;
148
+ /** What a file already holds, before a board is opened on it or written into it. */
149
+ interface BoardFileContents {
150
+ /** No tables at all — a path nothing has been created in yet, or a zero-byte file. */
151
+ empty: boolean;
152
+ /** Whose board the tables are, by the `file_owner` marker (ruling 5-4). Says nothing about an empty file. */
153
+ owner: BoardFileOwner;
154
+ }
155
+ /**
156
+ * Look at a file on a connection of its own and hand it back closed, so a
157
+ * caller can decide what to do with it before opening it for real.
158
+ *
159
+ * Two callers, two different decisions off the same two facts: the command line
160
+ * asks whose file it is to know whether a host app's `workspaces` row may be
161
+ * looked up in it, and a host app asks before it writes a board into it, because
162
+ * a file with tables that are not this package's is somebody else's database
163
+ * and migrating it would contaminate it (ruling 5-8).
164
+ *
165
+ * A path that is not a SQLite database at all — a README, a half-downloaded
166
+ * file, a directory — throws, and that is deliberately not the same answer as
167
+ * "a database with somebody else's tables in it": one is a mistake about which
168
+ * path to use and the other is a mistake about which file is a board. No pragma
169
+ * is set and nothing is written, so a file that turns out not to be ours is
170
+ * left exactly as it was found, journal mode included.
171
+ */
172
+ declare function readBoardFileContents(path: string): BoardFileContents;
173
+ //#endregion
174
+ export { BOARD_SCHEMA_EPOCH, type BoardDatabase, type BoardFileContents, type BoardFileOwner, type Issue, type IssueComment, type IssueFieldChange, type IssueMilestone, type IssueRelation, type IssueRun, type IssueStatus, type KanbanMeta, type SqliteDatabase, type SqliteTransactionMode, assertBoardSchema, boardSqliteSchema, createSqliteBoardStore, getBoardSqliteMigrationsPath, issueComments, issueFieldChanges, issueMilestones, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta, markBoardFileOwnedByKanbo, migrateBoardFile, openBoardDatabase, readBoardFileContents, readBoardFileOwner, runSqliteTransaction };
175
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1,175 @@
1
+ import { _ as issueStatuses, c as IssueStatus, d as issueComments, f as issueFieldChanges, g as issueRuns, h as issueRelations, i as IssueMilestone, l as KanbanMeta, n as IssueComment, o as IssueRelation, p as issueMilestones, r as IssueFieldChange, s as IssueRun, t as Issue, u as boardSqliteSchema, v as issues, y as kanbanMeta } from "../schema-fsHqNAip.mjs";
2
+ import { a as BoardStore } from "../board-store-B16YarvX.mjs";
3
+ import { t as BOARD_SCHEMA_EPOCH } from "../schema-epoch-ZyumVL_A.mjs";
4
+ import { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
5
+ import { Database } from "better-sqlite3";
6
+ //#region src/sqlite/transaction.d.ts
7
+ /**
8
+ * The database handle itself — what the host hands the board — and not an open
9
+ * transaction on it: the helper reaches for the driver connection, which a
10
+ * drizzle `SQLiteTransaction` does not carry.
11
+ *
12
+ * The schema parameter is `Record<string, unknown>` rather than any particular
13
+ * schema, which is what lets one type stand for all three of the files a board
14
+ * can live in (ruling 5-3): a handle drizzle was given a host app's whole schema
15
+ * satisfies it, and so does one given only the board's own nine tables. The
16
+ * board never reaches for `database.query`, so the relational builder those
17
+ * generics shape is not something this package gives up by asking for less —
18
+ * `src/sqlite/database-type.test.ts` is the probe that says both handles still
19
+ * arrive here.
20
+ */
21
+ type SqliteDatabase = BetterSQLite3Database<Record<string, unknown>>;
22
+ /**
23
+ * How the outer `begin` takes its write lock. `deferred` — the SQLite default —
24
+ * waits for the first write; `immediate` takes the lock up front, so two
25
+ * processes racing for the same file fail fast instead of half-way through.
26
+ * A nested scope is a savepoint and takes no lock of its own, so the mode only
27
+ * reaches the outer statement.
28
+ */
29
+ type SqliteTransactionMode = 'deferred' | 'immediate';
30
+ /**
31
+ * Run `fn` inside one SQLite transaction that is allowed to await.
32
+ *
33
+ * `database.transaction(...)` cannot serve here: it commits the moment its
34
+ * callback returns, and an async callback returns a pending promise, so the
35
+ * transaction would close before the work inside it ran. The statements are
36
+ * issued by hand instead, and the driver's own `inTransaction` flag picks which
37
+ * — the same branch better-sqlite3 takes. With nothing open: `begin`, then
38
+ * `commit`, or `rollback` when `fn` throws. With a transaction already open —
39
+ * another call to this helper, or one a module opened through
40
+ * `database.transaction` — a `savepoint` … `release` pair, undone by
41
+ * `rollback to` followed by its own `release`. A second `begin` would throw,
42
+ * which is why the flag decides and not a private counter. When SQLite has
43
+ * already aborted the transaction itself the undo is skipped: it would throw
44
+ * over the caller's error.
45
+ *
46
+ * **The callback must be the only database-touching async chain in flight —
47
+ * no `Promise.all` sibling, no lock hand-off, no fire-and-forget promise
48
+ * started before it — and inside it, only await operations that resolve
49
+ * without I/O: store methods, synchronous database writes.** Even a resolved
50
+ * promise yields to the microtask queue first, so a sibling chain already
51
+ * queued in the same macrotask still runs inside this open transaction; a
52
+ * chain started in a separate macrotask is unaffected. Awaiting anything that
53
+ * truly suspends — a timer, the filesystem, the network — hands the
54
+ * connection to whatever runs next, and its writes land in this transaction
55
+ * too.
56
+ */
57
+ declare function runSqliteTransaction<T>(database: SqliteDatabase, fn: () => Promise<T>, options?: {
58
+ mode?: SqliteTransactionMode;
59
+ }): Promise<T>;
60
+ //#endregion
61
+ //#region src/sqlite/board-store.sqlite.d.ts
62
+ /**
63
+ * `BoardStore` backed by SQLite: every method resolves immediately, because the
64
+ * core underneath it is synchronous.
65
+ *
66
+ * `database` is a function rather than a handle so the store follows whatever
67
+ * the host currently has open — a server passes its single connection
68
+ * accessor, a standalone reader passes its own.
69
+ */
70
+ declare function createSqliteBoardStore(options: {
71
+ database: () => SqliteDatabase;
72
+ }): BoardStore;
73
+ //#endregion
74
+ //#region src/sqlite/migrate.d.ts
75
+ /**
76
+ * The board's SQLite migrations for the file that is running right now — the
77
+ * ones that build a board *file of this package's own*. The two layouts this
78
+ * has to survive are `src/migrations-path.ts`'s subject.
79
+ */
80
+ declare function getBoardSqliteMigrationsPath(): string;
81
+ /**
82
+ * Create or update a board file this package owns.
83
+ *
84
+ * A host app's own database is not this: there the board is nine tables among
85
+ * the app's own, and the app's migration runner migrates the whole file — which
86
+ * may take two passes, because a migration that rebuilds a table has to drop
87
+ * it with foreign keys off. Nothing here rebuilds anything — `drizzle-sqlite/` starts at the
88
+ * board as it is now and will only ever be appended to — so drizzle's own
89
+ * migrator is the whole of what this needs, and a file that has been migrated
90
+ * before is a no-op by `__drizzle_migrations`.
91
+ *
92
+ * What the file holds afterwards is the board and nothing else: no
93
+ * `workspaces`, no `agents`, no `provider_targets`. Every reference out of the
94
+ * board is a plain text column for exactly that reason (ruling 5-1).
95
+ */
96
+ declare function migrateBoardFile(database: SqliteDatabase): void;
97
+ //#endregion
98
+ //#region src/sqlite/open-database.d.ts
99
+ /** One open board file: the drizzle handle, the driver beneath it, and the way to let go. */
100
+ interface BoardDatabase {
101
+ database: SqliteDatabase;
102
+ connection: Database;
103
+ close: () => void;
104
+ }
105
+ /**
106
+ * Open a board file with the runtime pragmas a long-running server sets on its
107
+ * own database, so a board read from a terminal behaves the same as one read
108
+ * from inside an app. Migrations are not applied here: the file's owner applies
109
+ * them (`kanbo init --file`, `kanbo migrate`, or the app the database belongs to).
110
+ *
111
+ * Asynchronous because the driver beneath it is loaded on demand — see
112
+ * `loadSqliteDriver`. The native module is asked for first, so an install
113
+ * without it hears the sentence above rather than a module-resolution stack
114
+ * from inside drizzle.
115
+ */
116
+ declare function openBoardDatabase(path: string): Promise<BoardDatabase>;
117
+ /**
118
+ * Refuse a board file this build cannot speak for, before any statement runs
119
+ * against it: one with no board in it (`missingTables`), one whose board a
120
+ * later migration has since added a table to (`missingAddedTables`) or a
121
+ * column to (`missingColumns`), and one stamped with another epoch. An app
122
+ * that migrates its own database on start need not call this; it is the guard a
123
+ * standalone reader puts in front of a file it did not create.
124
+ */
125
+ declare function assertBoardSchema(database: SqliteDatabase): void;
126
+ /**
127
+ * Who created this board file's tables from nothing: this package
128
+ * (`kanbo init --file`), or a host app whose own database the board lives in.
129
+ */
130
+ type BoardFileOwner = 'kanbo' | 'host';
131
+ /**
132
+ * Which of the two ever wrote this file's board, going by the `kanban_meta`
133
+ * marker `kanbo init --file` leaves behind (ruling 5-4).
134
+ *
135
+ * Absent reads as a host database — every file this package has never
136
+ * touched, and a file this build cannot make sense of at all: `assertBoardSchema` is what says a board is missing or too old,
137
+ * not this, so a table or a row that is not there yet is read as "not this
138
+ * package's file" rather than an error of its own.
139
+ */
140
+ declare function readBoardFileOwner(database: SqliteDatabase): BoardFileOwner;
141
+ /**
142
+ * Leave the marker that tells every later reader this file is this package's
143
+ * own, not a host app's. `kanbo init --file` calls this once, right after
144
+ * migrating; `insert or ignore` is what makes calling it again on the same
145
+ * file a no-op rather than a conflict.
146
+ */
147
+ declare function markBoardFileOwnedByKanbo(database: SqliteDatabase): void;
148
+ /** What a file already holds, before a board is opened on it or written into it. */
149
+ interface BoardFileContents {
150
+ /** No tables at all — a path nothing has been created in yet, or a zero-byte file. */
151
+ empty: boolean;
152
+ /** Whose board the tables are, by the `file_owner` marker (ruling 5-4). Says nothing about an empty file. */
153
+ owner: BoardFileOwner;
154
+ }
155
+ /**
156
+ * Look at a file on a connection of its own and hand it back closed, so a
157
+ * caller can decide what to do with it before opening it for real.
158
+ *
159
+ * Two callers, two different decisions off the same two facts: the command line
160
+ * asks whose file it is to know whether a host app's `workspaces` row may be
161
+ * looked up in it, and a host app asks before it writes a board into it, because
162
+ * a file with tables that are not this package's is somebody else's database
163
+ * and migrating it would contaminate it (ruling 5-8).
164
+ *
165
+ * A path that is not a SQLite database at all — a README, a half-downloaded
166
+ * file, a directory — throws, and that is deliberately not the same answer as
167
+ * "a database with somebody else's tables in it": one is a mistake about which
168
+ * path to use and the other is a mistake about which file is a board. No pragma
169
+ * is set and nothing is written, so a file that turns out not to be ours is
170
+ * left exactly as it was found, journal mode included.
171
+ */
172
+ declare function readBoardFileContents(path: string): BoardFileContents;
173
+ //#endregion
174
+ export { BOARD_SCHEMA_EPOCH, type BoardDatabase, type BoardFileContents, type BoardFileOwner, type Issue, type IssueComment, type IssueFieldChange, type IssueMilestone, type IssueRelation, type IssueRun, type IssueStatus, type KanbanMeta, type SqliteDatabase, type SqliteTransactionMode, assertBoardSchema, boardSqliteSchema, createSqliteBoardStore, getBoardSqliteMigrationsPath, issueComments, issueFieldChanges, issueMilestones, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta, markBoardFileOwnedByKanbo, migrateBoardFile, openBoardDatabase, readBoardFileContents, readBoardFileOwner, runSqliteTransaction };
175
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,4 @@
1
+ import { r as BOARD_SCHEMA_EPOCH } from "../migrations-path-Ciwan537.mjs";
2
+ import { boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta } from "./schema.mjs";
3
+ import { a as openBoardDatabase, c as createSqliteBoardStore, i as markBoardFileOwnedByKanbo, l as runSqliteTransaction, n as migrateBoardFile, o as readBoardFileContents, r as assertBoardSchema, s as readBoardFileOwner, t as getBoardSqliteMigrationsPath } from "../migrate-BhYi9cXw.mjs";
4
+ export { BOARD_SCHEMA_EPOCH, assertBoardSchema, boardSqliteSchema, createSqliteBoardStore, getBoardSqliteMigrationsPath, issueComments, issueFieldChanges, issueMilestones, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta, markBoardFileOwnedByKanbo, migrateBoardFile, openBoardDatabase, readBoardFileContents, readBoardFileOwner, runSqliteTransaction };
@@ -0,0 +1,266 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let drizzle_orm = require("drizzle-orm");
3
+ let drizzle_orm_sqlite_core = require("drizzle-orm/sqlite-core");
4
+ //#region src/sqlite/schema.ts
5
+ /**
6
+ * The board, as a SQLite file holds it.
7
+ *
8
+ * These nine tables are the board itself, and this package owns them: the same
9
+ * logical schema as `src/postgres/schema.ts`, written for the dialect a file
10
+ * speaks. They live in three different places at runtime — a host app's own
11
+ * database, a board file of a project's own, and neither of those when the
12
+ * board is a Postgres database — and none of those homes owns the shape. A host
13
+ * app re-exports these very objects from its own schema, so its tables and
14
+ * these are the same tables rather than two declarations that have to be kept
15
+ * in step.
16
+ *
17
+ * **Every reference out of the board is a plain text column** (ruling 5-1).
18
+ * `workspace_id`, `delegate_agent_id`, `delegate_provider_target_id` and
19
+ * `source_chat_session_id` name rows in a host app's tables, and a board file of
20
+ * a project's own has no such tables to point at — so they are soft references
21
+ * into whichever app is looking, exactly as they are on Postgres. What an
22
+ * `ON DELETE` would do is done in the open by the app that deletes the row: it
23
+ * empties a removed workspace's board, and clears the delegation off the cards
24
+ * that named a removed agent or provider target. The foreign keys that stay are the
25
+ * ones that point *inside* the board, and they still cascade.
26
+ */
27
+ const textPk = () => (0, drizzle_orm_sqlite_core.text)("id").primaryKey();
28
+ const timestamps = () => ({
29
+ createdAt: (0, drizzle_orm_sqlite_core.int)("created_at").notNull().default(drizzle_orm.sql`(unixepoch())`),
30
+ updatedAt: (0, drizzle_orm_sqlite_core.int)("updated_at").notNull().default(drizzle_orm.sql`(unixepoch())`)
31
+ });
32
+ const createdAt = () => ({ createdAt: (0, drizzle_orm_sqlite_core.int)("created_at").notNull().default(drizzle_orm.sql`(unixepoch())`) });
33
+ const issueStatuses = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_statuses", {
34
+ id: textPk(),
35
+ workspaceId: (0, drizzle_orm_sqlite_core.text)("workspace_id").notNull(),
36
+ name: (0, drizzle_orm_sqlite_core.text)("name").notNull(),
37
+ description: (0, drizzle_orm_sqlite_core.text)("description"),
38
+ color: (0, drizzle_orm_sqlite_core.text)("color"),
39
+ category: (0, drizzle_orm_sqlite_core.text)("category", { enum: [
40
+ "triage",
41
+ "backlog",
42
+ "unstarted",
43
+ "started",
44
+ "completed",
45
+ "canceled"
46
+ ] }).notNull().default("unstarted"),
47
+ order: (0, drizzle_orm_sqlite_core.int)("order").notNull().default(0),
48
+ /**
49
+ * What a card must satisfy before an agent may put it in this column — a JSON
50
+ * array of `ENTRY_RULES` (ruling 6-1); `null` asks for nothing. Read it
51
+ * through `readEntryRules`, never by hand.
52
+ */
53
+ entryRules: (0, drizzle_orm_sqlite_core.text)("entry_rules"),
54
+ ...createdAt()
55
+ }, (table) => ({
56
+ byWorkspace: (0, drizzle_orm_sqlite_core.index)("issue_statuses_workspace_id_idx").on(table.workspaceId),
57
+ byWorkspaceName: (0, drizzle_orm_sqlite_core.uniqueIndex)("issue_statuses_workspace_name_unique").on(table.workspaceId, table.name)
58
+ }));
59
+ const issueMilestones = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_milestones", {
60
+ id: textPk(),
61
+ workspaceId: (0, drizzle_orm_sqlite_core.text)("workspace_id").notNull(),
62
+ title: (0, drizzle_orm_sqlite_core.text)("title").notNull(),
63
+ description: (0, drizzle_orm_sqlite_core.text)("description"),
64
+ /** When the milestone, read as a sprint, begins (unix seconds); null for a plain milestone. */
65
+ startDate: (0, drizzle_orm_sqlite_core.int)("start_date"),
66
+ dueDate: (0, drizzle_orm_sqlite_core.int)("due_date"),
67
+ status: (0, drizzle_orm_sqlite_core.text)("status", { enum: ["open", "closed"] }).notNull().default("open"),
68
+ ...timestamps()
69
+ }, (table) => ({ byWorkspace: (0, drizzle_orm_sqlite_core.index)("issue_milestones_workspace_id_idx").on(table.workspaceId) }));
70
+ const issues = (0, drizzle_orm_sqlite_core.sqliteTable)("issues", {
71
+ id: textPk(),
72
+ workspaceId: (0, drizzle_orm_sqlite_core.text)("workspace_id").notNull(),
73
+ number: (0, drizzle_orm_sqlite_core.int)("number").notNull(),
74
+ statusId: (0, drizzle_orm_sqlite_core.text)("status_id").references(() => issueStatuses.id, { onDelete: "set null" }),
75
+ milestoneId: (0, drizzle_orm_sqlite_core.text)("milestone_id").references(() => issueMilestones.id, { onDelete: "set null" }),
76
+ parentIssueId: (0, drizzle_orm_sqlite_core.text)("parent_issue_id").references(() => issues.id, { onDelete: "set null" }),
77
+ title: (0, drizzle_orm_sqlite_core.text)("title").notNull(),
78
+ description: (0, drizzle_orm_sqlite_core.text)("description"),
79
+ priority: (0, drizzle_orm_sqlite_core.text)("priority", { enum: [
80
+ "none",
81
+ "low",
82
+ "medium",
83
+ "high",
84
+ "urgent"
85
+ ] }).notNull().default("none"),
86
+ labels: (0, drizzle_orm_sqlite_core.text)("labels").notNull().default("[]"),
87
+ assigneeKind: (0, drizzle_orm_sqlite_core.text)("assignee_kind"),
88
+ assigneeId: (0, drizzle_orm_sqlite_core.text)("assignee_id"),
89
+ dueDate: (0, drizzle_orm_sqlite_core.int)("due_date"),
90
+ createdByKind: (0, drizzle_orm_sqlite_core.text)("created_by_kind", { enum: [
91
+ "user",
92
+ "agent",
93
+ "system",
94
+ "provider-target"
95
+ ] }).notNull().default("user"),
96
+ createdById: (0, drizzle_orm_sqlite_core.text)("created_by_id").notNull().default("__self__"),
97
+ sourceChatSessionId: (0, drizzle_orm_sqlite_core.text)("source_chat_session_id"),
98
+ delegateAgentId: (0, drizzle_orm_sqlite_core.text)("delegate_agent_id"),
99
+ delegateProviderTargetId: (0, drizzle_orm_sqlite_core.text)("delegate_provider_target_id"),
100
+ contextRefs: (0, drizzle_orm_sqlite_core.text)("context_refs").notNull().default("[]"),
101
+ statusLine: (0, drizzle_orm_sqlite_core.text)("status_line"),
102
+ waitingFor: (0, drizzle_orm_sqlite_core.text)("waiting_for", { enum: ["human"] }),
103
+ executionMode: (0, drizzle_orm_sqlite_core.text)("execution_mode", { enum: ["worktree", "main"] }).notNull().default("worktree"),
104
+ order: (0, drizzle_orm_sqlite_core.int)("order").notNull().default(0),
105
+ ...timestamps()
106
+ }, (table) => ({
107
+ byWorkspace: (0, drizzle_orm_sqlite_core.index)("issues_workspace_id_idx").on(table.workspaceId),
108
+ byWorkspaceNumber: (0, drizzle_orm_sqlite_core.uniqueIndex)("issues_workspace_number_unique").on(table.workspaceId, table.number),
109
+ byStatus: (0, drizzle_orm_sqlite_core.index)("issues_status_id_idx").on(table.statusId),
110
+ byMilestone: (0, drizzle_orm_sqlite_core.index)("issues_milestone_id_idx").on(table.milestoneId),
111
+ byParent: (0, drizzle_orm_sqlite_core.index)("issues_parent_issue_id_idx").on(table.parentIssueId),
112
+ byDelegateAgent: (0, drizzle_orm_sqlite_core.index)("issues_delegate_agent_id_idx").on(table.delegateAgentId),
113
+ byDelegateProviderTarget: (0, drizzle_orm_sqlite_core.index)("issues_delegate_provider_target_id_idx").on(table.delegateProviderTargetId)
114
+ }));
115
+ const issueComments = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_comments", {
116
+ id: textPk(),
117
+ issueId: (0, drizzle_orm_sqlite_core.text)("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
118
+ content: (0, drizzle_orm_sqlite_core.text)("content").notNull(),
119
+ authorKind: (0, drizzle_orm_sqlite_core.text)("author_kind", { enum: [
120
+ "user",
121
+ "agent",
122
+ "provider-target",
123
+ "system",
124
+ "system.delegated",
125
+ "system.undelegated",
126
+ "system.run",
127
+ "system.approved",
128
+ "system.returned",
129
+ "system.pr"
130
+ ] }).notNull().default("user"),
131
+ authorId: (0, drizzle_orm_sqlite_core.text)("author_id"),
132
+ sourceChatSessionId: (0, drizzle_orm_sqlite_core.text)("source_chat_session_id"),
133
+ agentActivityId: (0, drizzle_orm_sqlite_core.text)("agent_activity_id"),
134
+ dedupeKey: (0, drizzle_orm_sqlite_core.text)("dedupe_key"),
135
+ ...createdAt()
136
+ }, (table) => ({
137
+ byIssue: (0, drizzle_orm_sqlite_core.index)("issue_comments_issue_id_idx").on(table.issueId),
138
+ byIssueDedupeKey: (0, drizzle_orm_sqlite_core.uniqueIndex)("issue_comments_issue_dedupe_idx").on(table.issueId, table.dedupeKey)
139
+ }));
140
+ const issueRuns = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_runs", {
141
+ id: textPk(),
142
+ issueId: (0, drizzle_orm_sqlite_core.text)("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
143
+ launchedByKind: (0, drizzle_orm_sqlite_core.text)("launched_by_kind", { enum: [
144
+ "user",
145
+ "agent",
146
+ "external"
147
+ ] }).notNull().default("user"),
148
+ launchedById: (0, drizzle_orm_sqlite_core.text)("launched_by_id"),
149
+ agentId: (0, drizzle_orm_sqlite_core.text)("agent_id"),
150
+ agentName: (0, drizzle_orm_sqlite_core.text)("agent_name").notNull(),
151
+ host: (0, drizzle_orm_sqlite_core.text)("host"),
152
+ executionMode: (0, drizzle_orm_sqlite_core.text)("execution_mode", { enum: ["worktree", "main"] }).notNull().default("worktree"),
153
+ branch: (0, drizzle_orm_sqlite_core.text)("branch"),
154
+ worktreePath: (0, drizzle_orm_sqlite_core.text)("worktree_path"),
155
+ state: (0, drizzle_orm_sqlite_core.text)("state", { enum: [
156
+ "running",
157
+ "finished",
158
+ "failed",
159
+ "stopped"
160
+ ] }).notNull().default("running"),
161
+ chatSessionId: (0, drizzle_orm_sqlite_core.text)("chat_session_id"),
162
+ /** Where an external agent's own log of this run lives — `claude:<id>` or `codex:<id>` (ruling 7-1), `null` when it never said. */
163
+ externalSessionRef: (0, drizzle_orm_sqlite_core.text)("external_session_ref"),
164
+ startedAt: (0, drizzle_orm_sqlite_core.int)("started_at").notNull().default(drizzle_orm.sql`(unixepoch())`),
165
+ endedAt: (0, drizzle_orm_sqlite_core.int)("ended_at")
166
+ }, (table) => ({
167
+ byIssue: (0, drizzle_orm_sqlite_core.index)("issue_runs_issue_id_idx").on(table.issueId),
168
+ byIssueState: (0, drizzle_orm_sqlite_core.index)("issue_runs_issue_state_idx").on(table.issueId, table.state),
169
+ byChatSession: (0, drizzle_orm_sqlite_core.index)("issue_runs_chat_session_idx").on(table.chatSessionId)
170
+ }));
171
+ const issueRelations = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_relations", {
172
+ id: textPk(),
173
+ sourceIssueId: (0, drizzle_orm_sqlite_core.text)("source_issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
174
+ targetIssueId: (0, drizzle_orm_sqlite_core.text)("target_issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
175
+ type: (0, drizzle_orm_sqlite_core.text)("type", { enum: [
176
+ "blocks",
177
+ "duplicates",
178
+ "relates_to"
179
+ ] }).notNull(),
180
+ ...createdAt()
181
+ }, (table) => ({
182
+ bySource: (0, drizzle_orm_sqlite_core.index)("issue_relations_source_issue_id_idx").on(table.sourceIssueId),
183
+ byTarget: (0, drizzle_orm_sqlite_core.index)("issue_relations_target_issue_id_idx").on(table.targetIssueId),
184
+ byPairType: (0, drizzle_orm_sqlite_core.uniqueIndex)("issue_relations_pair_type_unique").on(table.sourceIssueId, table.targetIssueId, table.type)
185
+ }));
186
+ const issueFieldChanges = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_field_changes", {
187
+ id: textPk(),
188
+ issueId: (0, drizzle_orm_sqlite_core.text)("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
189
+ field: (0, drizzle_orm_sqlite_core.text)("field").notNull(),
190
+ fromValue: (0, drizzle_orm_sqlite_core.text)("from_value"),
191
+ toValue: (0, drizzle_orm_sqlite_core.text)("to_value"),
192
+ actorKind: (0, drizzle_orm_sqlite_core.text)("actor_kind", { enum: [
193
+ "user",
194
+ "agent",
195
+ "provider-target",
196
+ "system"
197
+ ] }).notNull().default("user"),
198
+ actorId: (0, drizzle_orm_sqlite_core.text)("actor_id"),
199
+ sourceChatSessionId: (0, drizzle_orm_sqlite_core.text)("source_chat_session_id"),
200
+ ...createdAt()
201
+ }, (table) => ({ byIssue: (0, drizzle_orm_sqlite_core.index)("issue_field_changes_issue_id_idx").on(table.issueId) }));
202
+ /**
203
+ * A pull request someone said belongs to a card.
204
+ *
205
+ * The link is the board's; what the pull request *is* — open, merged, green —
206
+ * is GitHub's, and the board keeps none of it. Whoever watches GitHub reads the
207
+ * links here and writes what it saw as comments on the card, so this row is a
208
+ * name (`owner/repo#number`, and the URL it came from) and who gave it. One
209
+ * card names one pull request once; the same pull request may belong to several
210
+ * cards, which is why `(owner, repo, number)` is indexed on its own.
211
+ */
212
+ const issuePullRequests = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_pull_requests", {
213
+ id: textPk(),
214
+ issueId: (0, drizzle_orm_sqlite_core.text)("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
215
+ owner: (0, drizzle_orm_sqlite_core.text)("owner").notNull(),
216
+ repo: (0, drizzle_orm_sqlite_core.text)("repo").notNull(),
217
+ number: (0, drizzle_orm_sqlite_core.int)("number").notNull(),
218
+ url: (0, drizzle_orm_sqlite_core.text)("url").notNull(),
219
+ createdByKind: (0, drizzle_orm_sqlite_core.text)("created_by_kind", { enum: [
220
+ "user",
221
+ "agent",
222
+ "provider-target",
223
+ "system"
224
+ ] }).notNull(),
225
+ createdById: (0, drizzle_orm_sqlite_core.text)("created_by_id"),
226
+ ...createdAt()
227
+ }, (table) => ({
228
+ byIssuePullRequest: (0, drizzle_orm_sqlite_core.uniqueIndex)("issue_pull_requests_issue_pr_unique").on(table.issueId, table.owner, table.repo, table.number),
229
+ byPullRequest: (0, drizzle_orm_sqlite_core.index)("issue_pull_requests_pr_idx").on(table.owner, table.repo, table.number)
230
+ }));
231
+ /**
232
+ * Monotonic counters the board keeps for its readers: `board` is bumped by the
233
+ * board operations layer once per write transaction that changed something, so a
234
+ * poller can tell a changed board from an unchanged one, and `schema_epoch`
235
+ * records the board schema generation the file was written with.
236
+ */
237
+ const kanbanMeta = (0, drizzle_orm_sqlite_core.sqliteTable)("kanban_meta", {
238
+ key: (0, drizzle_orm_sqlite_core.text)("key").primaryKey(),
239
+ revision: (0, drizzle_orm_sqlite_core.int)("revision").notNull().default(0),
240
+ updatedAt: (0, drizzle_orm_sqlite_core.int)("updated_at").notNull().default(drizzle_orm.sql`(unixepoch())`)
241
+ });
242
+ /** Every table of the board, in the order a reader of the schema wants them. */
243
+ const boardSqliteSchema = {
244
+ issueStatuses,
245
+ issueMilestones,
246
+ issues,
247
+ issueComments,
248
+ issueRuns,
249
+ issueRelations,
250
+ issueFieldChanges,
251
+ issuePullRequests,
252
+ kanbanMeta
253
+ };
254
+ //#endregion
255
+ exports.boardSqliteSchema = boardSqliteSchema;
256
+ exports.issueComments = issueComments;
257
+ exports.issueFieldChanges = issueFieldChanges;
258
+ exports.issueMilestones = issueMilestones;
259
+ exports.issuePullRequests = issuePullRequests;
260
+ exports.issueRelations = issueRelations;
261
+ exports.issueRuns = issueRuns;
262
+ exports.issueStatuses = issueStatuses;
263
+ exports.issues = issues;
264
+ exports.kanbanMeta = kanbanMeta;
265
+
266
+ //# sourceMappingURL=schema.cjs.map