kanbo-cli 0.4.0 → 0.6.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 (43) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/cli-main.cjs +1322 -154
  3. package/dist/drizzle-postgres/0006_flow_rules_and_column_entries.sql +3 -0
  4. package/dist/drizzle-postgres/README.md +8 -0
  5. package/dist/drizzle-postgres/meta/0006_snapshot.json +1290 -0
  6. package/dist/drizzle-postgres/meta/_journal.json +7 -0
  7. package/dist/drizzle-sqlite/0005_flow_rules_and_column_entries.sql +3 -0
  8. package/dist/drizzle-sqlite/README.md +8 -0
  9. package/dist/drizzle-sqlite/meta/0005_snapshot.json +1097 -0
  10. package/dist/drizzle-sqlite/meta/_journal.json +7 -0
  11. package/dist/lib/{approval-BsBk2xVr.d.cts → approval-CnJJfwfi.d.mts} +30 -6
  12. package/dist/lib/{approval-LRZ6ontC.d.mts → approval-DNfUhYD5.d.cts} +30 -6
  13. package/dist/lib/{board-store-D_Mpfb84.d.mts → board-store-BjhiH9TZ.d.mts} +38 -2
  14. package/dist/lib/{board-store-Dx-mw2I6.d.cts → board-store-CsyBXBwH.d.cts} +38 -2
  15. package/dist/lib/index.cjs +9 -1
  16. package/dist/lib/index.d.cts +302 -6
  17. package/dist/lib/index.d.mts +302 -6
  18. package/dist/lib/index.mjs +2 -2
  19. package/dist/lib/{manifest-DcIMYvWk.cjs → manifest-BFI4HGPh.cjs} +1410 -225
  20. package/dist/lib/{manifest-Dmo6IlWk.mjs → manifest-DHI1fkoW.mjs} +1395 -258
  21. package/dist/lib/mcp/index.cjs +24 -4
  22. package/dist/lib/mcp/index.d.cts +19 -4
  23. package/dist/lib/mcp/index.d.mts +19 -4
  24. package/dist/lib/mcp/index.mjs +24 -4
  25. package/dist/lib/{migrate-Dca5WdYd.cjs → migrate-36aT0rV0.cjs} +17 -0
  26. package/dist/lib/{migrate-DtBeW3Fs.mjs → migrate-Bgj_aABY.mjs} +18 -1
  27. package/dist/lib/postgres/index.cjs +1 -1
  28. package/dist/lib/postgres/index.d.cts +69 -1
  29. package/dist/lib/postgres/index.d.mts +69 -1
  30. package/dist/lib/postgres/index.mjs +1 -1
  31. package/dist/lib/{roles.sql-BoOZSkBp.mjs → roles.sql-9OkYvsNM.mjs} +26 -2
  32. package/dist/lib/{roles.sql-E58x7mLS.cjs → roles.sql-BC7k_zPh.cjs} +25 -1
  33. package/dist/lib/{schema-D0MyXcej.d.cts → schema-Cwx3HosC.d.cts} +72 -0
  34. package/dist/lib/{schema-D0MyXcej.d.mts → schema-Cwx3HosC.d.mts} +72 -0
  35. package/dist/lib/sqlite/index.cjs +1 -1
  36. package/dist/lib/sqlite/index.d.cts +2 -2
  37. package/dist/lib/sqlite/index.d.mts +2 -2
  38. package/dist/lib/sqlite/index.mjs +1 -1
  39. package/dist/lib/sqlite/schema.cjs +13 -1
  40. package/dist/lib/sqlite/schema.d.cts +1 -1
  41. package/dist/lib/sqlite/schema.d.mts +1 -1
  42. package/dist/lib/sqlite/schema.mjs +13 -1
  43. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { a as BoardError, i as BOARD_TABLES_ADDED_WITHIN_EPOCH, n as resolveBoardMigrationsPath, t as hasMigrationJournal } from "./migrations-path-ClaYRNwk.mjs";
2
- import { and, asc, desc, eq, getTableColumns, gte, inArray, isNotNull, isNull, or, sql } from "drizzle-orm";
2
+ import { and, asc, desc, eq, getTableColumns, gte, inArray, isNotNull, isNull, lte, or, sql } from "drizzle-orm";
3
3
  import { bigint, bigserial, getTableConfig, index, integer, pgSchema, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
4
4
  import { dirname } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -73,6 +73,10 @@ const issueStatuses = pgTable("issue_statuses", {
73
73
  order: integer("order").notNull().default(0),
74
74
  /** A JSON array of `ENTRY_RULES`, or `null` for none — see the SQLite schema. */
75
75
  entryRules: text("entry_rules"),
76
+ /** A JSON array of the status ids a card may enter from, or `null` for any — see the SQLite schema. */
77
+ allowedFrom: text("allowed_from"),
78
+ /** The most cards the column holds, or `null` — see the SQLite schema. */
79
+ wipLimit: integer("wip_limit"),
76
80
  ...createdAt()
77
81
  }, (table) => [index("issue_statuses_workspace_id_idx").on(table.workspaceId), uniqueIndex("issue_statuses_workspace_name_unique").on(table.workspaceId, table.name)]);
78
82
  const issueMilestones = pgTable("issue_milestones", {
@@ -220,7 +224,7 @@ const issueFieldChanges = pgTable("issue_field_changes", {
220
224
  ...createdAt(),
221
225
  /** Insertion order, standing in for the `rowid` the SQLite board orders changes by. */
222
226
  seq: bigserial("seq", { mode: "number" }).notNull()
223
- }, (table) => [index("issue_field_changes_issue_id_idx").on(table.issueId)]);
227
+ }, (table) => [index("issue_field_changes_issue_id_idx").on(table.issueId), index("issue_field_changes_field_created_at_idx").on(table.field, table.createdAt)]);
224
228
  /** A pull request someone said belongs to a card — see the SQLite twin for what the row is and is not. */
225
229
  const issuePullRequests = pgTable("issue_pull_requests", {
226
230
  id: textPk(),
@@ -296,6 +300,10 @@ function toIssueComment({ seq: _seq, ...comment }) {
296
300
  function toIssueFieldChange({ seq: _seq, ...change }) {
297
301
  return change;
298
302
  }
303
+ /** A field change with its card's workspace, without `seq`, for the same reason. */
304
+ function toWorkspaceFieldChange({ seq: _seq, ...change }) {
305
+ return change;
306
+ }
299
307
  /** The pull-request link without `seq`, for the same reason. */
300
308
  function toIssuePullRequest({ seq: _seq, ...link }) {
301
309
  return link;
@@ -502,6 +510,10 @@ function createStoreOver(database) {
502
510
  const [row] = await database.select().from(issues).where(eq(issues.id, issueId)).limit(1);
503
511
  return row ?? null;
504
512
  },
513
+ lockById: async (issueId) => {
514
+ const [row] = await database.select().from(issues).where(eq(issues.id, issueId)).limit(1).for("update");
515
+ return row ?? null;
516
+ },
505
517
  findInWorkspace: async (workspaceId, issueId) => {
506
518
  const [row] = await database.select().from(issues).where(and(eq(issues.id, issueId), eq(issues.workspaceId, workspaceId))).limit(1);
507
519
  return row ?? null;
@@ -566,6 +578,10 @@ function createStoreOver(database) {
566
578
  },
567
579
  comments: {
568
580
  listByIssue: async (issueId) => (await database.select().from(issueComments).where(eq(issueComments.issueId, issueId)).orderBy(asc(issueComments.createdAt), asc(issueComments.seq))).map(toIssueComment),
581
+ listByWorkspaces: async (workspaceIds, authorKinds) => {
582
+ if (workspaceIds.length === 0 || authorKinds.length === 0) return [];
583
+ return (await database.select(getTableColumns(issueComments)).from(issueComments).innerJoin(issues, eq(issues.id, issueComments.issueId)).where(and(inArray(issues.workspaceId, [...workspaceIds]), inArray(issueComments.authorKind, [...authorKinds]))).orderBy(asc(issueComments.createdAt), asc(issueComments.seq))).map(toIssueComment);
584
+ },
569
585
  listLatestByIssues: async (issueIds, authorKinds) => {
570
586
  if (issueIds.length === 0 || authorKinds?.length === 0) return [];
571
587
  const ranked = database.select({
@@ -602,6 +618,10 @@ function createStoreOver(database) {
602
618
  listByIssue: async (issueId) => (await database.select().from(issueRuns).where(eq(issueRuns.issueId, issueId)).orderBy(asc(issueRuns.startedAt), asc(issueRuns.seq))).map(toIssueRun),
603
619
  listRunning: async (issueId) => (await database.select().from(issueRuns).where(and(eq(issueRuns.issueId, issueId), eq(issueRuns.state, "running"))).orderBy(asc(issueRuns.startedAt), asc(issueRuns.seq))).map(toIssueRun),
604
620
  listRunningWithSession: async () => (await database.select().from(issueRuns).where(and(eq(issueRuns.state, "running"), isNotNull(issueRuns.chatSessionId))).orderBy(asc(issueRuns.startedAt), asc(issueRuns.seq))).map(toIssueRun),
621
+ listByWorkspaces: async (workspaceIds) => {
622
+ if (workspaceIds.length === 0) return [];
623
+ return (await database.select(getTableColumns(issueRuns)).from(issueRuns).innerJoin(issues, eq(issues.id, issueRuns.issueId)).where(inArray(issues.workspaceId, [...workspaceIds])).orderBy(asc(issueRuns.startedAt), asc(issueRuns.seq))).map(toIssueRun);
624
+ },
605
625
  findById: async (runId) => {
606
626
  const [row] = await database.select().from(issueRuns).where(eq(issueRuns.id, runId)).limit(1);
607
627
  return row ? toIssueRun(row) : null;
@@ -653,6 +673,10 @@ function createStoreOver(database) {
653
673
  fieldChanges: {
654
674
  listByIssue: async (issueId) => (await database.select().from(issueFieldChanges).where(eq(issueFieldChanges.issueId, issueId)).orderBy(asc(issueFieldChanges.createdAt), asc(issueFieldChanges.seq))).map(toIssueFieldChange),
655
675
  listByIssueField: async (issueId, field) => (await database.select().from(issueFieldChanges).where(and(eq(issueFieldChanges.issueId, issueId), eq(issueFieldChanges.field, field))).orderBy(asc(issueFieldChanges.createdAt), asc(issueFieldChanges.seq))).map(toIssueFieldChange),
676
+ listByFieldSince: async (field, query) => query.workspaceIds.length === 0 ? [] : (await database.select({
677
+ ...getTableColumns(issueFieldChanges),
678
+ workspaceId: issues.workspaceId
679
+ }).from(issueFieldChanges).innerJoin(issues, eq(issues.id, issueFieldChanges.issueId)).where(and(eq(issueFieldChanges.field, field), isNotNull(issueFieldChanges.toValue), gte(issueFieldChanges.createdAt, query.since), query.until === void 0 ? void 0 : lte(issueFieldChanges.createdAt, query.until), inArray(issues.workspaceId, [...query.workspaceIds]))).orderBy(asc(issueFieldChanges.createdAt), asc(issueFieldChanges.id)).limit(query.limit ?? Number.MAX_SAFE_INTEGER)).map(toWorkspaceFieldChange),
656
680
  create: async (values) => {
657
681
  await database.insert(issueFieldChanges).values(values);
658
682
  }
@@ -73,6 +73,10 @@ const issueStatuses = (0, drizzle_orm_pg_core.pgTable)("issue_statuses", {
73
73
  order: (0, drizzle_orm_pg_core.integer)("order").notNull().default(0),
74
74
  /** A JSON array of `ENTRY_RULES`, or `null` for none — see the SQLite schema. */
75
75
  entryRules: (0, drizzle_orm_pg_core.text)("entry_rules"),
76
+ /** A JSON array of the status ids a card may enter from, or `null` for any — see the SQLite schema. */
77
+ allowedFrom: (0, drizzle_orm_pg_core.text)("allowed_from"),
78
+ /** The most cards the column holds, or `null` — see the SQLite schema. */
79
+ wipLimit: (0, drizzle_orm_pg_core.integer)("wip_limit"),
76
80
  ...createdAt()
77
81
  }, (table) => [(0, drizzle_orm_pg_core.index)("issue_statuses_workspace_id_idx").on(table.workspaceId), (0, drizzle_orm_pg_core.uniqueIndex)("issue_statuses_workspace_name_unique").on(table.workspaceId, table.name)]);
78
82
  const issueMilestones = (0, drizzle_orm_pg_core.pgTable)("issue_milestones", {
@@ -220,7 +224,7 @@ const issueFieldChanges = (0, drizzle_orm_pg_core.pgTable)("issue_field_changes"
220
224
  ...createdAt(),
221
225
  /** Insertion order, standing in for the `rowid` the SQLite board orders changes by. */
222
226
  seq: (0, drizzle_orm_pg_core.bigserial)("seq", { mode: "number" }).notNull()
223
- }, (table) => [(0, drizzle_orm_pg_core.index)("issue_field_changes_issue_id_idx").on(table.issueId)]);
227
+ }, (table) => [(0, drizzle_orm_pg_core.index)("issue_field_changes_issue_id_idx").on(table.issueId), (0, drizzle_orm_pg_core.index)("issue_field_changes_field_created_at_idx").on(table.field, table.createdAt)]);
224
228
  /** A pull request someone said belongs to a card — see the SQLite twin for what the row is and is not. */
225
229
  const issuePullRequests = (0, drizzle_orm_pg_core.pgTable)("issue_pull_requests", {
226
230
  id: textPk(),
@@ -296,6 +300,10 @@ function toIssueComment({ seq: _seq, ...comment }) {
296
300
  function toIssueFieldChange({ seq: _seq, ...change }) {
297
301
  return change;
298
302
  }
303
+ /** A field change with its card's workspace, without `seq`, for the same reason. */
304
+ function toWorkspaceFieldChange({ seq: _seq, ...change }) {
305
+ return change;
306
+ }
299
307
  /** The pull-request link without `seq`, for the same reason. */
300
308
  function toIssuePullRequest({ seq: _seq, ...link }) {
301
309
  return link;
@@ -502,6 +510,10 @@ function createStoreOver(database) {
502
510
  const [row] = await database.select().from(issues).where((0, drizzle_orm.eq)(issues.id, issueId)).limit(1);
503
511
  return row ?? null;
504
512
  },
513
+ lockById: async (issueId) => {
514
+ const [row] = await database.select().from(issues).where((0, drizzle_orm.eq)(issues.id, issueId)).limit(1).for("update");
515
+ return row ?? null;
516
+ },
505
517
  findInWorkspace: async (workspaceId, issueId) => {
506
518
  const [row] = await database.select().from(issues).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(issues.id, issueId), (0, drizzle_orm.eq)(issues.workspaceId, workspaceId))).limit(1);
507
519
  return row ?? null;
@@ -566,6 +578,10 @@ function createStoreOver(database) {
566
578
  },
567
579
  comments: {
568
580
  listByIssue: async (issueId) => (await database.select().from(issueComments).where((0, drizzle_orm.eq)(issueComments.issueId, issueId)).orderBy((0, drizzle_orm.asc)(issueComments.createdAt), (0, drizzle_orm.asc)(issueComments.seq))).map(toIssueComment),
581
+ listByWorkspaces: async (workspaceIds, authorKinds) => {
582
+ if (workspaceIds.length === 0 || authorKinds.length === 0) return [];
583
+ return (await database.select((0, drizzle_orm.getTableColumns)(issueComments)).from(issueComments).innerJoin(issues, (0, drizzle_orm.eq)(issues.id, issueComments.issueId)).where((0, drizzle_orm.and)((0, drizzle_orm.inArray)(issues.workspaceId, [...workspaceIds]), (0, drizzle_orm.inArray)(issueComments.authorKind, [...authorKinds]))).orderBy((0, drizzle_orm.asc)(issueComments.createdAt), (0, drizzle_orm.asc)(issueComments.seq))).map(toIssueComment);
584
+ },
569
585
  listLatestByIssues: async (issueIds, authorKinds) => {
570
586
  if (issueIds.length === 0 || authorKinds?.length === 0) return [];
571
587
  const ranked = database.select({
@@ -602,6 +618,10 @@ function createStoreOver(database) {
602
618
  listByIssue: async (issueId) => (await database.select().from(issueRuns).where((0, drizzle_orm.eq)(issueRuns.issueId, issueId)).orderBy((0, drizzle_orm.asc)(issueRuns.startedAt), (0, drizzle_orm.asc)(issueRuns.seq))).map(toIssueRun),
603
619
  listRunning: async (issueId) => (await database.select().from(issueRuns).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(issueRuns.issueId, issueId), (0, drizzle_orm.eq)(issueRuns.state, "running"))).orderBy((0, drizzle_orm.asc)(issueRuns.startedAt), (0, drizzle_orm.asc)(issueRuns.seq))).map(toIssueRun),
604
620
  listRunningWithSession: async () => (await database.select().from(issueRuns).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(issueRuns.state, "running"), (0, drizzle_orm.isNotNull)(issueRuns.chatSessionId))).orderBy((0, drizzle_orm.asc)(issueRuns.startedAt), (0, drizzle_orm.asc)(issueRuns.seq))).map(toIssueRun),
621
+ listByWorkspaces: async (workspaceIds) => {
622
+ if (workspaceIds.length === 0) return [];
623
+ return (await database.select((0, drizzle_orm.getTableColumns)(issueRuns)).from(issueRuns).innerJoin(issues, (0, drizzle_orm.eq)(issues.id, issueRuns.issueId)).where((0, drizzle_orm.inArray)(issues.workspaceId, [...workspaceIds])).orderBy((0, drizzle_orm.asc)(issueRuns.startedAt), (0, drizzle_orm.asc)(issueRuns.seq))).map(toIssueRun);
624
+ },
605
625
  findById: async (runId) => {
606
626
  const [row] = await database.select().from(issueRuns).where((0, drizzle_orm.eq)(issueRuns.id, runId)).limit(1);
607
627
  return row ? toIssueRun(row) : null;
@@ -653,6 +673,10 @@ function createStoreOver(database) {
653
673
  fieldChanges: {
654
674
  listByIssue: async (issueId) => (await database.select().from(issueFieldChanges).where((0, drizzle_orm.eq)(issueFieldChanges.issueId, issueId)).orderBy((0, drizzle_orm.asc)(issueFieldChanges.createdAt), (0, drizzle_orm.asc)(issueFieldChanges.seq))).map(toIssueFieldChange),
655
675
  listByIssueField: async (issueId, field) => (await database.select().from(issueFieldChanges).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(issueFieldChanges.issueId, issueId), (0, drizzle_orm.eq)(issueFieldChanges.field, field))).orderBy((0, drizzle_orm.asc)(issueFieldChanges.createdAt), (0, drizzle_orm.asc)(issueFieldChanges.seq))).map(toIssueFieldChange),
676
+ listByFieldSince: async (field, query) => query.workspaceIds.length === 0 ? [] : (await database.select({
677
+ ...(0, drizzle_orm.getTableColumns)(issueFieldChanges),
678
+ workspaceId: issues.workspaceId
679
+ }).from(issueFieldChanges).innerJoin(issues, (0, drizzle_orm.eq)(issues.id, issueFieldChanges.issueId)).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(issueFieldChanges.field, field), (0, drizzle_orm.isNotNull)(issueFieldChanges.toValue), (0, drizzle_orm.gte)(issueFieldChanges.createdAt, query.since), query.until === void 0 ? void 0 : (0, drizzle_orm.lte)(issueFieldChanges.createdAt, query.until), (0, drizzle_orm.inArray)(issues.workspaceId, [...query.workspaceIds]))).orderBy((0, drizzle_orm.asc)(issueFieldChanges.createdAt), (0, drizzle_orm.asc)(issueFieldChanges.id)).limit(query.limit ?? Number.MAX_SAFE_INTEGER)).map(toWorkspaceFieldChange),
656
680
  create: async (values) => {
657
681
  await database.insert(issueFieldChanges).values(values);
658
682
  }
@@ -170,6 +170,42 @@ declare const issueStatuses: import("drizzle-orm/sqlite-core").SQLiteTableWithCo
170
170
  }, {}, {
171
171
  length: number | undefined;
172
172
  }>;
173
+ allowedFrom: import("drizzle-orm/sqlite-core").SQLiteColumn<{
174
+ name: "allowed_from";
175
+ tableName: "issue_statuses";
176
+ dataType: "string";
177
+ columnType: "SQLiteText";
178
+ data: string;
179
+ driverParam: string;
180
+ notNull: false;
181
+ hasDefault: false;
182
+ isPrimaryKey: false;
183
+ isAutoincrement: false;
184
+ hasRuntimeDefault: false;
185
+ enumValues: [string, ...string[]];
186
+ baseColumn: never;
187
+ identity: undefined;
188
+ generated: undefined;
189
+ }, {}, {
190
+ length: number | undefined;
191
+ }>;
192
+ wipLimit: import("drizzle-orm/sqlite-core").SQLiteColumn<{
193
+ name: "wip_limit";
194
+ tableName: "issue_statuses";
195
+ dataType: "number";
196
+ columnType: "SQLiteInteger";
197
+ data: number;
198
+ driverParam: number;
199
+ notNull: false;
200
+ hasDefault: false;
201
+ isPrimaryKey: false;
202
+ isAutoincrement: false;
203
+ hasRuntimeDefault: false;
204
+ enumValues: undefined;
205
+ baseColumn: never;
206
+ identity: undefined;
207
+ generated: undefined;
208
+ }, {}, {}>;
173
209
  };
174
210
  dialect: 'sqlite';
175
211
  }>;
@@ -1987,6 +2023,42 @@ declare const boardSqliteSchema: {
1987
2023
  }, {}, {
1988
2024
  length: number | undefined;
1989
2025
  }>;
2026
+ allowedFrom: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2027
+ name: "allowed_from";
2028
+ tableName: "issue_statuses";
2029
+ dataType: "string";
2030
+ columnType: "SQLiteText";
2031
+ data: string;
2032
+ driverParam: string;
2033
+ notNull: false;
2034
+ hasDefault: false;
2035
+ isPrimaryKey: false;
2036
+ isAutoincrement: false;
2037
+ hasRuntimeDefault: false;
2038
+ enumValues: [string, ...string[]];
2039
+ baseColumn: never;
2040
+ identity: undefined;
2041
+ generated: undefined;
2042
+ }, {}, {
2043
+ length: number | undefined;
2044
+ }>;
2045
+ wipLimit: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2046
+ name: "wip_limit";
2047
+ tableName: "issue_statuses";
2048
+ dataType: "number";
2049
+ columnType: "SQLiteInteger";
2050
+ data: number;
2051
+ driverParam: number;
2052
+ notNull: false;
2053
+ hasDefault: false;
2054
+ isPrimaryKey: false;
2055
+ isAutoincrement: false;
2056
+ hasRuntimeDefault: false;
2057
+ enumValues: undefined;
2058
+ baseColumn: never;
2059
+ identity: undefined;
2060
+ generated: undefined;
2061
+ }, {}, {}>;
1990
2062
  };
1991
2063
  dialect: 'sqlite';
1992
2064
  }>;
@@ -170,6 +170,42 @@ declare const issueStatuses: import("drizzle-orm/sqlite-core").SQLiteTableWithCo
170
170
  }, {}, {
171
171
  length: number | undefined;
172
172
  }>;
173
+ allowedFrom: import("drizzle-orm/sqlite-core").SQLiteColumn<{
174
+ name: "allowed_from";
175
+ tableName: "issue_statuses";
176
+ dataType: "string";
177
+ columnType: "SQLiteText";
178
+ data: string;
179
+ driverParam: string;
180
+ notNull: false;
181
+ hasDefault: false;
182
+ isPrimaryKey: false;
183
+ isAutoincrement: false;
184
+ hasRuntimeDefault: false;
185
+ enumValues: [string, ...string[]];
186
+ baseColumn: never;
187
+ identity: undefined;
188
+ generated: undefined;
189
+ }, {}, {
190
+ length: number | undefined;
191
+ }>;
192
+ wipLimit: import("drizzle-orm/sqlite-core").SQLiteColumn<{
193
+ name: "wip_limit";
194
+ tableName: "issue_statuses";
195
+ dataType: "number";
196
+ columnType: "SQLiteInteger";
197
+ data: number;
198
+ driverParam: number;
199
+ notNull: false;
200
+ hasDefault: false;
201
+ isPrimaryKey: false;
202
+ isAutoincrement: false;
203
+ hasRuntimeDefault: false;
204
+ enumValues: undefined;
205
+ baseColumn: never;
206
+ identity: undefined;
207
+ generated: undefined;
208
+ }, {}, {}>;
173
209
  };
174
210
  dialect: 'sqlite';
175
211
  }>;
@@ -1987,6 +2023,42 @@ declare const boardSqliteSchema: {
1987
2023
  }, {}, {
1988
2024
  length: number | undefined;
1989
2025
  }>;
2026
+ allowedFrom: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2027
+ name: "allowed_from";
2028
+ tableName: "issue_statuses";
2029
+ dataType: "string";
2030
+ columnType: "SQLiteText";
2031
+ data: string;
2032
+ driverParam: string;
2033
+ notNull: false;
2034
+ hasDefault: false;
2035
+ isPrimaryKey: false;
2036
+ isAutoincrement: false;
2037
+ hasRuntimeDefault: false;
2038
+ enumValues: [string, ...string[]];
2039
+ baseColumn: never;
2040
+ identity: undefined;
2041
+ generated: undefined;
2042
+ }, {}, {
2043
+ length: number | undefined;
2044
+ }>;
2045
+ wipLimit: import("drizzle-orm/sqlite-core").SQLiteColumn<{
2046
+ name: "wip_limit";
2047
+ tableName: "issue_statuses";
2048
+ dataType: "number";
2049
+ columnType: "SQLiteInteger";
2050
+ data: number;
2051
+ driverParam: number;
2052
+ notNull: false;
2053
+ hasDefault: false;
2054
+ isPrimaryKey: false;
2055
+ isAutoincrement: false;
2056
+ hasRuntimeDefault: false;
2057
+ enumValues: undefined;
2058
+ baseColumn: never;
2059
+ identity: undefined;
2060
+ generated: undefined;
2061
+ }, {}, {}>;
1990
2062
  };
1991
2063
  dialect: 'sqlite';
1992
2064
  }>;
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_migrations_path = require("../migrations-path-DBCE17dT.cjs");
3
- const require_migrate = require("../migrate-Dca5WdYd.cjs");
3
+ const require_migrate = require("../migrate-36aT0rV0.cjs");
4
4
  const require_sqlite_schema = require("./schema.cjs");
5
5
  exports.BOARD_SCHEMA_EPOCH = require_migrations_path.BOARD_SCHEMA_EPOCH;
6
6
  exports.assertBoardSchema = require_migrate.assertBoardSchema;
@@ -1,5 +1,5 @@
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-D0MyXcej.cjs";
2
- import { c as BoardStore } from "../board-store-Dx-mw2I6.cjs";
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-Cwx3HosC.cjs";
2
+ import { l as BoardStore } from "../board-store-CsyBXBwH.cjs";
3
3
  import { t as BOARD_SCHEMA_EPOCH } from "../schema-epoch-ZyumVL_A.cjs";
4
4
  import { Database } from "better-sqlite3";
5
5
  import { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
@@ -1,5 +1,5 @@
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-D0MyXcej.mjs";
2
- import { c as BoardStore } from "../board-store-D_Mpfb84.mjs";
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-Cwx3HosC.mjs";
2
+ import { l as BoardStore } from "../board-store-BjhiH9TZ.mjs";
3
3
  import { t as BOARD_SCHEMA_EPOCH } from "../schema-epoch-ZyumVL_A.mjs";
4
4
  import { Database } from "better-sqlite3";
5
5
  import { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
@@ -1,4 +1,4 @@
1
1
  import { r as BOARD_SCHEMA_EPOCH } from "../migrations-path-ClaYRNwk.mjs";
2
- import { a as openBoardDatabase, i as markBoardFileOwnedByKanbo, l as createSqliteBoardStore, n as migrateBoardFile, o as readBoardFileContents, r as assertBoardSchema, s as readBoardFileOwner, t as getBoardSqliteMigrationsPath, u as runSqliteTransaction } from "../migrate-DtBeW3Fs.mjs";
2
+ import { a as openBoardDatabase, i as markBoardFileOwnedByKanbo, l as createSqliteBoardStore, n as migrateBoardFile, o as readBoardFileContents, r as assertBoardSchema, s as readBoardFileOwner, t as getBoardSqliteMigrationsPath, u as runSqliteTransaction } from "../migrate-Bgj_aABY.mjs";
3
3
  import { boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta } from "./schema.mjs";
4
4
  export { BOARD_SCHEMA_EPOCH, assertBoardSchema, boardSqliteSchema, createSqliteBoardStore, getBoardSqliteMigrationsPath, issueComments, issueFieldChanges, issueMilestones, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta, markBoardFileOwnedByKanbo, migrateBoardFile, openBoardDatabase, readBoardFileContents, readBoardFileOwner, runSqliteTransaction };
@@ -51,6 +51,14 @@ const issueStatuses = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_statuses",
51
51
  * through `readEntryRules`, never by hand.
52
52
  */
53
53
  entryRules: (0, drizzle_orm_sqlite_core.text)("entry_rules"),
54
+ /**
55
+ * The columns a card may enter this one from — a JSON array of status ids;
56
+ * `null` for any column, `[]` for none (only a person puts a card here). Read
57
+ * it through `readFlowRules`, never by hand.
58
+ */
59
+ allowedFrom: (0, drizzle_orm_sqlite_core.text)("allowed_from"),
60
+ /** The most cards this column holds, 1 or more; `null` for no limit. */
61
+ wipLimit: (0, drizzle_orm_sqlite_core.int)("wip_limit"),
54
62
  ...createdAt()
55
63
  }, (table) => ({
56
64
  byWorkspace: (0, drizzle_orm_sqlite_core.index)("issue_statuses_workspace_id_idx").on(table.workspaceId),
@@ -198,7 +206,11 @@ const issueFieldChanges = (0, drizzle_orm_sqlite_core.sqliteTable)("issue_field_
198
206
  actorId: (0, drizzle_orm_sqlite_core.text)("actor_id"),
199
207
  sourceChatSessionId: (0, drizzle_orm_sqlite_core.text)("source_chat_session_id"),
200
208
  ...createdAt()
201
- }, (table) => ({ byIssue: (0, drizzle_orm_sqlite_core.index)("issue_field_changes_issue_id_idx").on(table.issueId) }));
209
+ }, (table) => ({
210
+ byIssue: (0, drizzle_orm_sqlite_core.index)("issue_field_changes_issue_id_idx").on(table.issueId),
211
+ /** The column-entry feed reads one field across a board by time. */
212
+ byFieldCreatedAt: (0, drizzle_orm_sqlite_core.index)("issue_field_changes_field_created_at_idx").on(table.field, table.createdAt)
213
+ }));
202
214
  /**
203
215
  * A pull request someone said belongs to a card.
204
216
  *
@@ -1,2 +1,2 @@
1
- import { _ as issueStatuses, a as IssuePullRequest, c as IssueStatus, d as issueComments, f as issueFieldChanges, g as issueRuns, h as issueRelations, i as IssueMilestone, l as KanbanMeta, m as issuePullRequests, 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-D0MyXcej.cjs";
1
+ import { _ as issueStatuses, a as IssuePullRequest, c as IssueStatus, d as issueComments, f as issueFieldChanges, g as issueRuns, h as issueRelations, i as IssueMilestone, l as KanbanMeta, m as issuePullRequests, 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-Cwx3HosC.cjs";
2
2
  export { Issue, IssueComment, IssueFieldChange, IssueMilestone, IssuePullRequest, IssueRelation, IssueRun, IssueStatus, KanbanMeta, boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issuePullRequests, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta };
@@ -1,2 +1,2 @@
1
- import { _ as issueStatuses, a as IssuePullRequest, c as IssueStatus, d as issueComments, f as issueFieldChanges, g as issueRuns, h as issueRelations, i as IssueMilestone, l as KanbanMeta, m as issuePullRequests, 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-D0MyXcej.mjs";
1
+ import { _ as issueStatuses, a as IssuePullRequest, c as IssueStatus, d as issueComments, f as issueFieldChanges, g as issueRuns, h as issueRelations, i as IssueMilestone, l as KanbanMeta, m as issuePullRequests, 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-Cwx3HosC.mjs";
2
2
  export { Issue, IssueComment, IssueFieldChange, IssueMilestone, IssuePullRequest, IssueRelation, IssueRun, IssueStatus, KanbanMeta, boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issuePullRequests, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta };
@@ -50,6 +50,14 @@ const issueStatuses = sqliteTable("issue_statuses", {
50
50
  * through `readEntryRules`, never by hand.
51
51
  */
52
52
  entryRules: text("entry_rules"),
53
+ /**
54
+ * The columns a card may enter this one from — a JSON array of status ids;
55
+ * `null` for any column, `[]` for none (only a person puts a card here). Read
56
+ * it through `readFlowRules`, never by hand.
57
+ */
58
+ allowedFrom: text("allowed_from"),
59
+ /** The most cards this column holds, 1 or more; `null` for no limit. */
60
+ wipLimit: int("wip_limit"),
53
61
  ...createdAt()
54
62
  }, (table) => ({
55
63
  byWorkspace: index("issue_statuses_workspace_id_idx").on(table.workspaceId),
@@ -197,7 +205,11 @@ const issueFieldChanges = sqliteTable("issue_field_changes", {
197
205
  actorId: text("actor_id"),
198
206
  sourceChatSessionId: text("source_chat_session_id"),
199
207
  ...createdAt()
200
- }, (table) => ({ byIssue: index("issue_field_changes_issue_id_idx").on(table.issueId) }));
208
+ }, (table) => ({
209
+ byIssue: index("issue_field_changes_issue_id_idx").on(table.issueId),
210
+ /** The column-entry feed reads one field across a board by time. */
211
+ byFieldCreatedAt: index("issue_field_changes_field_created_at_idx").on(table.field, table.createdAt)
212
+ }));
201
213
  /**
202
214
  * A pull request someone said belongs to a card.
203
215
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kanbo-cli",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "A Kanban board your AI agents drive through a CLI and an MCP server, and you watch and approve.",
5
5
  "keywords": [
6
6
  "kanban",