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.
- package/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/better-sqlite3-fU3G4xnX.cjs +2254 -0
- package/dist/better-sqlite3-fU3G4xnX.cjs.map +1 -0
- package/dist/cli.cjs +42949 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/dist-Cd6wg8pp.cjs +942 -0
- package/dist/dist-Cd6wg8pp.cjs.map +1 -0
- package/dist/drizzle-postgres/0000_board.sql +135 -0
- package/dist/drizzle-postgres/0001_history_order.sql +2 -0
- package/dist/drizzle-postgres/0002_issue_pull_requests.sql +16 -0
- package/dist/drizzle-postgres/0003_milestone_start_date.sql +1 -0
- package/dist/drizzle-postgres/0004_status_entry_rules.sql +1 -0
- package/dist/drizzle-postgres/0005_run_external_session_ref.sql +1 -0
- package/dist/drizzle-postgres/README.md +61 -0
- package/dist/drizzle-postgres/meta/0000_snapshot.json +1078 -0
- package/dist/drizzle-postgres/meta/0001_snapshot.json +1090 -0
- package/dist/drizzle-postgres/meta/0002_snapshot.json +1239 -0
- package/dist/drizzle-postgres/meta/0003_snapshot.json +1245 -0
- package/dist/drizzle-postgres/meta/0004_snapshot.json +1251 -0
- package/dist/drizzle-postgres/meta/0005_snapshot.json +1257 -0
- package/dist/drizzle-postgres/meta/_journal.json +48 -0
- package/dist/drizzle-sqlite/0000_board.sql +133 -0
- package/dist/drizzle-sqlite/0001_issue_pull_requests.sql +15 -0
- package/dist/drizzle-sqlite/0002_milestone_start_date.sql +1 -0
- package/dist/drizzle-sqlite/0003_status_entry_rules.sql +1 -0
- package/dist/drizzle-sqlite/0004_run_external_session_ref.sql +1 -0
- package/dist/drizzle-sqlite/README.md +67 -0
- package/dist/drizzle-sqlite/meta/0000_snapshot.json +946 -0
- package/dist/drizzle-sqlite/meta/0001_snapshot.json +1054 -0
- package/dist/drizzle-sqlite/meta/0002_snapshot.json +1061 -0
- package/dist/drizzle-sqlite/meta/0003_snapshot.json +1068 -0
- package/dist/drizzle-sqlite/meta/0004_snapshot.json +1075 -0
- package/dist/drizzle-sqlite/meta/_journal.json +41 -0
- package/dist/lib/board-store-B16YarvX.d.mts +281 -0
- package/dist/lib/board-store-BHHo_ZlR.d.cts +281 -0
- package/dist/lib/index.cjs +340 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.d.cts +1608 -0
- package/dist/lib/index.d.mts +1608 -0
- package/dist/lib/index.mjs +284 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/manifest-C0EcwwgO.mjs +7866 -0
- package/dist/lib/manifest-C0EcwwgO.mjs.map +1 -0
- package/dist/lib/manifest-CpZOcB_6.cjs +8272 -0
- package/dist/lib/manifest-CpZOcB_6.cjs.map +1 -0
- package/dist/lib/mcp/index.cjs +184 -0
- package/dist/lib/mcp/index.cjs.map +1 -0
- package/dist/lib/mcp/index.d.cts +346 -0
- package/dist/lib/mcp/index.d.mts +346 -0
- package/dist/lib/mcp/index.mjs +173 -0
- package/dist/lib/mcp/index.mjs.map +1 -0
- package/dist/lib/migrate-BhYi9cXw.mjs +656 -0
- package/dist/lib/migrate-BhYi9cXw.mjs.map +1 -0
- package/dist/lib/migrate-DnMjTCvu.cjs +709 -0
- package/dist/lib/migrate-DnMjTCvu.cjs.map +1 -0
- package/dist/lib/migrations-path-CZxVOgeD.cjs +109 -0
- package/dist/lib/migrations-path-CZxVOgeD.cjs.map +1 -0
- package/dist/lib/migrations-path-Ciwan537.mjs +80 -0
- package/dist/lib/migrations-path-Ciwan537.mjs.map +1 -0
- package/dist/lib/postgres/index.cjs +56 -0
- package/dist/lib/postgres/index.cjs.map +1 -0
- package/dist/lib/postgres/index.d.cts +3403 -0
- package/dist/lib/postgres/index.d.mts +3403 -0
- package/dist/lib/postgres/index.mjs +35 -0
- package/dist/lib/postgres/index.mjs.map +1 -0
- package/dist/lib/roles.sql-B9rt-x4o.cjs +1033 -0
- package/dist/lib/roles.sql-B9rt-x4o.cjs.map +1 -0
- package/dist/lib/roles.sql-CvyCGt38.mjs +920 -0
- package/dist/lib/roles.sql-CvyCGt38.mjs.map +1 -0
- package/dist/lib/schema-epoch-ZyumVL_A.d.cts +16 -0
- package/dist/lib/schema-epoch-ZyumVL_A.d.mts +16 -0
- package/dist/lib/schema-fsHqNAip.d.cts +3612 -0
- package/dist/lib/schema-fsHqNAip.d.mts +3612 -0
- package/dist/lib/sqlite/index.cjs +23 -0
- package/dist/lib/sqlite/index.d.cts +175 -0
- package/dist/lib/sqlite/index.d.mts +175 -0
- package/dist/lib/sqlite/index.mjs +4 -0
- package/dist/lib/sqlite/schema.cjs +266 -0
- package/dist/lib/sqlite/schema.cjs.map +1 -0
- package/dist/lib/sqlite/schema.d.cts +2 -0
- package/dist/lib/sqlite/schema.d.mts +2 -0
- package/dist/lib/sqlite/schema.mjs +256 -0
- package/dist/lib/sqlite/schema.mjs.map +1 -0
- package/dist/lib/tool-names-9cmCn0gP.d.cts +112 -0
- package/dist/lib/tool-names-Dxg1UTUl.d.mts +112 -0
- package/dist/page/board.css +477 -0
- package/dist/page/board.js +2 -0
- package/drizzle-postgres/0000_board.sql +135 -0
- package/drizzle-postgres/0001_history_order.sql +2 -0
- package/drizzle-postgres/0002_issue_pull_requests.sql +16 -0
- package/drizzle-postgres/0003_milestone_start_date.sql +1 -0
- package/drizzle-postgres/0004_status_entry_rules.sql +1 -0
- package/drizzle-postgres/0005_run_external_session_ref.sql +1 -0
- package/drizzle-postgres/README.md +61 -0
- package/drizzle-postgres/meta/0000_snapshot.json +1078 -0
- package/drizzle-postgres/meta/0001_snapshot.json +1090 -0
- package/drizzle-postgres/meta/0002_snapshot.json +1239 -0
- package/drizzle-postgres/meta/0003_snapshot.json +1245 -0
- package/drizzle-postgres/meta/0004_snapshot.json +1251 -0
- package/drizzle-postgres/meta/0005_snapshot.json +1257 -0
- package/drizzle-postgres/meta/_journal.json +48 -0
- package/drizzle-sqlite/0000_board.sql +133 -0
- package/drizzle-sqlite/0001_issue_pull_requests.sql +15 -0
- package/drizzle-sqlite/0002_milestone_start_date.sql +1 -0
- package/drizzle-sqlite/0003_status_entry_rules.sql +1 -0
- package/drizzle-sqlite/0004_run_external_session_ref.sql +1 -0
- package/drizzle-sqlite/README.md +67 -0
- package/drizzle-sqlite/meta/0000_snapshot.json +946 -0
- package/drizzle-sqlite/meta/0001_snapshot.json +1054 -0
- package/drizzle-sqlite/meta/0002_snapshot.json +1061 -0
- package/drizzle-sqlite/meta/0003_snapshot.json +1068 -0
- package/drizzle-sqlite/meta/0004_snapshot.json +1075 -0
- package/drizzle-sqlite/meta/_journal.json +41 -0
- package/package.json +147 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.cjs","names":["text","int","sqliteTable","index","uniqueIndex"],"sources":["../../../src/sqlite/schema.ts"],"sourcesContent":["import { sql } from 'drizzle-orm'\nimport type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core'\nimport { index, int, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core'\n\n/**\n * The board, as a SQLite file holds it.\n *\n * These nine tables are the board itself, and this package owns them: the same\n * logical schema as `src/postgres/schema.ts`, written for the dialect a file\n * speaks. They live in three different places at runtime — a host app's own\n * database, a board file of a project's own, and neither of those when the\n * board is a Postgres database — and none of those homes owns the shape. A host\n * app re-exports these very objects from its own schema, so its tables and\n * these are the same tables rather than two declarations that have to be kept\n * in step.\n *\n * **Every reference out of the board is a plain text column** (ruling 5-1).\n * `workspace_id`, `delegate_agent_id`, `delegate_provider_target_id` and\n * `source_chat_session_id` name rows in a host app's tables, and a board file of\n * a project's own has no such tables to point at — so they are soft references\n * into whichever app is looking, exactly as they are on Postgres. What an\n * `ON DELETE` would do is done in the open by the app that deletes the row: it\n * empties a removed workspace's board, and clears the delegation off the cards\n * that named a removed agent or provider target. The foreign keys that stay are the\n * ones that point *inside* the board, and they still cascade.\n */\n\nconst textPk = () => text('id').primaryKey()\n\nconst timestamps = () => ({\n createdAt: int('created_at').notNull().default(sql`(unixepoch())`),\n updatedAt: int('updated_at').notNull().default(sql`(unixepoch())`),\n})\n\nconst createdAt = () => ({\n createdAt: int('created_at').notNull().default(sql`(unixepoch())`),\n})\n\nexport const issueStatuses = sqliteTable('issue_statuses', {\n id: textPk(),\n workspaceId: text('workspace_id').notNull(),\n name: text('name').notNull(),\n description: text('description'),\n color: text('color'),\n category: text('category', { enum: ['triage', 'backlog', 'unstarted', 'started', 'completed', 'canceled'] }).notNull().default('unstarted'),\n order: int('order').notNull().default(0),\n /**\n * What a card must satisfy before an agent may put it in this column — a JSON\n * array of `ENTRY_RULES` (ruling 6-1); `null` asks for nothing. Read it\n * through `readEntryRules`, never by hand.\n */\n entryRules: text('entry_rules'),\n ...createdAt(),\n}, table => ({\n byWorkspace: index('issue_statuses_workspace_id_idx').on(table.workspaceId),\n byWorkspaceName: uniqueIndex('issue_statuses_workspace_name_unique').on(table.workspaceId, table.name),\n}))\n\nexport const issueMilestones = sqliteTable('issue_milestones', {\n id: textPk(),\n workspaceId: text('workspace_id').notNull(),\n title: text('title').notNull(),\n description: text('description'),\n /** When the milestone, read as a sprint, begins (unix seconds); null for a plain milestone. */\n startDate: int('start_date'),\n dueDate: int('due_date'),\n status: text('status', { enum: ['open', 'closed'] }).notNull().default('open'),\n ...timestamps(),\n}, table => ({\n byWorkspace: index('issue_milestones_workspace_id_idx').on(table.workspaceId),\n}))\n\nexport const issues = sqliteTable('issues', {\n id: textPk(),\n workspaceId: text('workspace_id').notNull(),\n number: int('number').notNull(),\n statusId: text('status_id').references(() => issueStatuses.id, { onDelete: 'set null' }),\n milestoneId: text('milestone_id').references(() => issueMilestones.id, { onDelete: 'set null' }),\n parentIssueId: text('parent_issue_id')\n .references((): AnySQLiteColumn => issues.id, { onDelete: 'set null' }),\n title: text('title').notNull(),\n description: text('description'),\n priority: text('priority', {\n enum: ['none', 'low', 'medium', 'high', 'urgent'],\n }).notNull().default('none'),\n labels: text('labels').notNull().default('[]'),\n assigneeKind: text('assignee_kind'),\n assigneeId: text('assignee_id'),\n dueDate: int('due_date'),\n createdByKind: text('created_by_kind', { enum: ['user', 'agent', 'system', 'provider-target'] }).notNull().default('user'),\n createdById: text('created_by_id').notNull().default('__self__'),\n sourceChatSessionId: text('source_chat_session_id'),\n delegateAgentId: text('delegate_agent_id'),\n delegateProviderTargetId: text('delegate_provider_target_id'),\n contextRefs: text('context_refs').notNull().default('[]'),\n statusLine: text('status_line'),\n waitingFor: text('waiting_for', { enum: ['human'] }),\n executionMode: text('execution_mode', { enum: ['worktree', 'main'] }).notNull().default('worktree'),\n order: int('order').notNull().default(0),\n ...timestamps(),\n}, table => ({\n byWorkspace: index('issues_workspace_id_idx').on(table.workspaceId),\n byWorkspaceNumber: uniqueIndex('issues_workspace_number_unique').on(table.workspaceId, table.number),\n byStatus: index('issues_status_id_idx').on(table.statusId),\n byMilestone: index('issues_milestone_id_idx').on(table.milestoneId),\n byParent: index('issues_parent_issue_id_idx').on(table.parentIssueId),\n byDelegateAgent: index('issues_delegate_agent_id_idx').on(table.delegateAgentId),\n byDelegateProviderTarget: index('issues_delegate_provider_target_id_idx').on(table.delegateProviderTargetId),\n}))\n\nexport const issueComments = sqliteTable('issue_comments', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n content: text('content').notNull(),\n authorKind: text('author_kind', {\n enum: [\n 'user',\n 'agent',\n 'provider-target',\n 'system',\n 'system.delegated',\n 'system.undelegated',\n 'system.run',\n 'system.approved',\n 'system.returned',\n 'system.pr',\n ],\n }).notNull().default('user'),\n authorId: text('author_id'),\n sourceChatSessionId: text('source_chat_session_id'),\n agentActivityId: text('agent_activity_id'),\n dedupeKey: text('dedupe_key'),\n ...createdAt(),\n}, table => ({\n byIssue: index('issue_comments_issue_id_idx').on(table.issueId),\n byIssueDedupeKey: uniqueIndex('issue_comments_issue_dedupe_idx').on(table.issueId, table.dedupeKey),\n}))\n\nexport const issueRuns = sqliteTable('issue_runs', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n launchedByKind: text('launched_by_kind', { enum: ['user', 'agent', 'external'] }).notNull().default('user'),\n launchedById: text('launched_by_id'),\n agentId: text('agent_id'),\n agentName: text('agent_name').notNull(),\n host: text('host'),\n executionMode: text('execution_mode', { enum: ['worktree', 'main'] }).notNull().default('worktree'),\n branch: text('branch'),\n worktreePath: text('worktree_path'),\n state: text('state', { enum: ['running', 'finished', 'failed', 'stopped'] }).notNull().default('running'),\n chatSessionId: text('chat_session_id'),\n /** Where an external agent's own log of this run lives — `claude:<id>` or `codex:<id>` (ruling 7-1), `null` when it never said. */\n externalSessionRef: text('external_session_ref'),\n startedAt: int('started_at').notNull().default(sql`(unixepoch())`),\n endedAt: int('ended_at'),\n}, table => ({\n byIssue: index('issue_runs_issue_id_idx').on(table.issueId),\n byIssueState: index('issue_runs_issue_state_idx').on(table.issueId, table.state),\n byChatSession: index('issue_runs_chat_session_idx').on(table.chatSessionId),\n}))\n\nexport const issueRelations = sqliteTable('issue_relations', {\n id: textPk(),\n sourceIssueId: text('source_issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n targetIssueId: text('target_issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n type: text('type', { enum: ['blocks', 'duplicates', 'relates_to'] }).notNull(),\n ...createdAt(),\n}, table => ({\n bySource: index('issue_relations_source_issue_id_idx').on(table.sourceIssueId),\n byTarget: index('issue_relations_target_issue_id_idx').on(table.targetIssueId),\n byPairType: uniqueIndex('issue_relations_pair_type_unique')\n .on(table.sourceIssueId, table.targetIssueId, table.type),\n}))\n\nexport const issueFieldChanges = sqliteTable('issue_field_changes', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n field: text('field').notNull(),\n fromValue: text('from_value'),\n toValue: text('to_value'),\n actorKind: text('actor_kind', { enum: ['user', 'agent', 'provider-target', 'system'] }).notNull().default('user'),\n actorId: text('actor_id'),\n sourceChatSessionId: text('source_chat_session_id'),\n ...createdAt(),\n}, table => ({\n byIssue: index('issue_field_changes_issue_id_idx').on(table.issueId),\n}))\n\n/**\n * A pull request someone said belongs to a card.\n *\n * The link is the board's; what the pull request *is* — open, merged, green —\n * is GitHub's, and the board keeps none of it. Whoever watches GitHub reads the\n * links here and writes what it saw as comments on the card, so this row is a\n * name (`owner/repo#number`, and the URL it came from) and who gave it. One\n * card names one pull request once; the same pull request may belong to several\n * cards, which is why `(owner, repo, number)` is indexed on its own.\n */\nexport const issuePullRequests = sqliteTable('issue_pull_requests', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n owner: text('owner').notNull(),\n repo: text('repo').notNull(),\n number: int('number').notNull(),\n url: text('url').notNull(),\n createdByKind: text('created_by_kind', { enum: ['user', 'agent', 'provider-target', 'system'] }).notNull(),\n createdById: text('created_by_id'),\n ...createdAt(),\n}, table => ({\n byIssuePullRequest: uniqueIndex('issue_pull_requests_issue_pr_unique')\n .on(table.issueId, table.owner, table.repo, table.number),\n byPullRequest: index('issue_pull_requests_pr_idx').on(table.owner, table.repo, table.number),\n}))\n\n/**\n * Monotonic counters the board keeps for its readers: `board` is bumped by the\n * board operations layer once per write transaction that changed something, so a\n * poller can tell a changed board from an unchanged one, and `schema_epoch`\n * records the board schema generation the file was written with.\n */\nexport const kanbanMeta = sqliteTable('kanban_meta', {\n key: text('key').primaryKey(),\n revision: int('revision').notNull().default(0),\n updatedAt: int('updated_at').notNull().default(sql`(unixepoch())`),\n})\n\nexport type IssueStatus = typeof issueStatuses.$inferSelect\nexport type IssueMilestone = typeof issueMilestones.$inferSelect\nexport type Issue = typeof issues.$inferSelect\nexport type IssueComment = typeof issueComments.$inferSelect\nexport type IssueRun = typeof issueRuns.$inferSelect\nexport type IssueRelation = typeof issueRelations.$inferSelect\nexport type IssueFieldChange = typeof issueFieldChanges.$inferSelect\nexport type IssuePullRequest = typeof issuePullRequests.$inferSelect\nexport type KanbanMeta = typeof kanbanMeta.$inferSelect\n\n/** Every table of the board, in the order a reader of the schema wants them. */\nexport const boardSqliteSchema = {\n issueStatuses,\n issueMilestones,\n issues,\n issueComments,\n issueRuns,\n issueRelations,\n issueFieldChanges,\n issuePullRequests,\n kanbanMeta,\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +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-fsHqNAip.cjs";
|
|
2
|
+
export { Issue, IssueComment, IssueFieldChange, IssueMilestone, IssuePullRequest, IssueRelation, IssueRun, IssueStatus, KanbanMeta, boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issuePullRequests, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta };
|
|
@@ -0,0 +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-fsHqNAip.mjs";
|
|
2
|
+
export { Issue, IssueComment, IssueFieldChange, IssueMilestone, IssuePullRequest, IssueRelation, IssueRun, IssueStatus, KanbanMeta, boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issuePullRequests, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta };
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { index, int, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
3
|
+
//#region src/sqlite/schema.ts
|
|
4
|
+
/**
|
|
5
|
+
* The board, as a SQLite file holds it.
|
|
6
|
+
*
|
|
7
|
+
* These nine tables are the board itself, and this package owns them: the same
|
|
8
|
+
* logical schema as `src/postgres/schema.ts`, written for the dialect a file
|
|
9
|
+
* speaks. They live in three different places at runtime — a host app's own
|
|
10
|
+
* database, a board file of a project's own, and neither of those when the
|
|
11
|
+
* board is a Postgres database — and none of those homes owns the shape. A host
|
|
12
|
+
* app re-exports these very objects from its own schema, so its tables and
|
|
13
|
+
* these are the same tables rather than two declarations that have to be kept
|
|
14
|
+
* in step.
|
|
15
|
+
*
|
|
16
|
+
* **Every reference out of the board is a plain text column** (ruling 5-1).
|
|
17
|
+
* `workspace_id`, `delegate_agent_id`, `delegate_provider_target_id` and
|
|
18
|
+
* `source_chat_session_id` name rows in a host app's tables, and a board file of
|
|
19
|
+
* a project's own has no such tables to point at — so they are soft references
|
|
20
|
+
* into whichever app is looking, exactly as they are on Postgres. What an
|
|
21
|
+
* `ON DELETE` would do is done in the open by the app that deletes the row: it
|
|
22
|
+
* empties a removed workspace's board, and clears the delegation off the cards
|
|
23
|
+
* that named a removed agent or provider target. The foreign keys that stay are the
|
|
24
|
+
* ones that point *inside* the board, and they still cascade.
|
|
25
|
+
*/
|
|
26
|
+
const textPk = () => text("id").primaryKey();
|
|
27
|
+
const timestamps = () => ({
|
|
28
|
+
createdAt: int("created_at").notNull().default(sql`(unixepoch())`),
|
|
29
|
+
updatedAt: int("updated_at").notNull().default(sql`(unixepoch())`)
|
|
30
|
+
});
|
|
31
|
+
const createdAt = () => ({ createdAt: int("created_at").notNull().default(sql`(unixepoch())`) });
|
|
32
|
+
const issueStatuses = sqliteTable("issue_statuses", {
|
|
33
|
+
id: textPk(),
|
|
34
|
+
workspaceId: text("workspace_id").notNull(),
|
|
35
|
+
name: text("name").notNull(),
|
|
36
|
+
description: text("description"),
|
|
37
|
+
color: text("color"),
|
|
38
|
+
category: text("category", { enum: [
|
|
39
|
+
"triage",
|
|
40
|
+
"backlog",
|
|
41
|
+
"unstarted",
|
|
42
|
+
"started",
|
|
43
|
+
"completed",
|
|
44
|
+
"canceled"
|
|
45
|
+
] }).notNull().default("unstarted"),
|
|
46
|
+
order: int("order").notNull().default(0),
|
|
47
|
+
/**
|
|
48
|
+
* What a card must satisfy before an agent may put it in this column — a JSON
|
|
49
|
+
* array of `ENTRY_RULES` (ruling 6-1); `null` asks for nothing. Read it
|
|
50
|
+
* through `readEntryRules`, never by hand.
|
|
51
|
+
*/
|
|
52
|
+
entryRules: text("entry_rules"),
|
|
53
|
+
...createdAt()
|
|
54
|
+
}, (table) => ({
|
|
55
|
+
byWorkspace: index("issue_statuses_workspace_id_idx").on(table.workspaceId),
|
|
56
|
+
byWorkspaceName: uniqueIndex("issue_statuses_workspace_name_unique").on(table.workspaceId, table.name)
|
|
57
|
+
}));
|
|
58
|
+
const issueMilestones = sqliteTable("issue_milestones", {
|
|
59
|
+
id: textPk(),
|
|
60
|
+
workspaceId: text("workspace_id").notNull(),
|
|
61
|
+
title: text("title").notNull(),
|
|
62
|
+
description: text("description"),
|
|
63
|
+
/** When the milestone, read as a sprint, begins (unix seconds); null for a plain milestone. */
|
|
64
|
+
startDate: int("start_date"),
|
|
65
|
+
dueDate: int("due_date"),
|
|
66
|
+
status: text("status", { enum: ["open", "closed"] }).notNull().default("open"),
|
|
67
|
+
...timestamps()
|
|
68
|
+
}, (table) => ({ byWorkspace: index("issue_milestones_workspace_id_idx").on(table.workspaceId) }));
|
|
69
|
+
const issues = sqliteTable("issues", {
|
|
70
|
+
id: textPk(),
|
|
71
|
+
workspaceId: text("workspace_id").notNull(),
|
|
72
|
+
number: int("number").notNull(),
|
|
73
|
+
statusId: text("status_id").references(() => issueStatuses.id, { onDelete: "set null" }),
|
|
74
|
+
milestoneId: text("milestone_id").references(() => issueMilestones.id, { onDelete: "set null" }),
|
|
75
|
+
parentIssueId: text("parent_issue_id").references(() => issues.id, { onDelete: "set null" }),
|
|
76
|
+
title: text("title").notNull(),
|
|
77
|
+
description: text("description"),
|
|
78
|
+
priority: text("priority", { enum: [
|
|
79
|
+
"none",
|
|
80
|
+
"low",
|
|
81
|
+
"medium",
|
|
82
|
+
"high",
|
|
83
|
+
"urgent"
|
|
84
|
+
] }).notNull().default("none"),
|
|
85
|
+
labels: text("labels").notNull().default("[]"),
|
|
86
|
+
assigneeKind: text("assignee_kind"),
|
|
87
|
+
assigneeId: text("assignee_id"),
|
|
88
|
+
dueDate: int("due_date"),
|
|
89
|
+
createdByKind: text("created_by_kind", { enum: [
|
|
90
|
+
"user",
|
|
91
|
+
"agent",
|
|
92
|
+
"system",
|
|
93
|
+
"provider-target"
|
|
94
|
+
] }).notNull().default("user"),
|
|
95
|
+
createdById: text("created_by_id").notNull().default("__self__"),
|
|
96
|
+
sourceChatSessionId: text("source_chat_session_id"),
|
|
97
|
+
delegateAgentId: text("delegate_agent_id"),
|
|
98
|
+
delegateProviderTargetId: text("delegate_provider_target_id"),
|
|
99
|
+
contextRefs: text("context_refs").notNull().default("[]"),
|
|
100
|
+
statusLine: text("status_line"),
|
|
101
|
+
waitingFor: text("waiting_for", { enum: ["human"] }),
|
|
102
|
+
executionMode: text("execution_mode", { enum: ["worktree", "main"] }).notNull().default("worktree"),
|
|
103
|
+
order: int("order").notNull().default(0),
|
|
104
|
+
...timestamps()
|
|
105
|
+
}, (table) => ({
|
|
106
|
+
byWorkspace: index("issues_workspace_id_idx").on(table.workspaceId),
|
|
107
|
+
byWorkspaceNumber: uniqueIndex("issues_workspace_number_unique").on(table.workspaceId, table.number),
|
|
108
|
+
byStatus: index("issues_status_id_idx").on(table.statusId),
|
|
109
|
+
byMilestone: index("issues_milestone_id_idx").on(table.milestoneId),
|
|
110
|
+
byParent: index("issues_parent_issue_id_idx").on(table.parentIssueId),
|
|
111
|
+
byDelegateAgent: index("issues_delegate_agent_id_idx").on(table.delegateAgentId),
|
|
112
|
+
byDelegateProviderTarget: index("issues_delegate_provider_target_id_idx").on(table.delegateProviderTargetId)
|
|
113
|
+
}));
|
|
114
|
+
const issueComments = sqliteTable("issue_comments", {
|
|
115
|
+
id: textPk(),
|
|
116
|
+
issueId: text("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
|
117
|
+
content: text("content").notNull(),
|
|
118
|
+
authorKind: text("author_kind", { enum: [
|
|
119
|
+
"user",
|
|
120
|
+
"agent",
|
|
121
|
+
"provider-target",
|
|
122
|
+
"system",
|
|
123
|
+
"system.delegated",
|
|
124
|
+
"system.undelegated",
|
|
125
|
+
"system.run",
|
|
126
|
+
"system.approved",
|
|
127
|
+
"system.returned",
|
|
128
|
+
"system.pr"
|
|
129
|
+
] }).notNull().default("user"),
|
|
130
|
+
authorId: text("author_id"),
|
|
131
|
+
sourceChatSessionId: text("source_chat_session_id"),
|
|
132
|
+
agentActivityId: text("agent_activity_id"),
|
|
133
|
+
dedupeKey: text("dedupe_key"),
|
|
134
|
+
...createdAt()
|
|
135
|
+
}, (table) => ({
|
|
136
|
+
byIssue: index("issue_comments_issue_id_idx").on(table.issueId),
|
|
137
|
+
byIssueDedupeKey: uniqueIndex("issue_comments_issue_dedupe_idx").on(table.issueId, table.dedupeKey)
|
|
138
|
+
}));
|
|
139
|
+
const issueRuns = sqliteTable("issue_runs", {
|
|
140
|
+
id: textPk(),
|
|
141
|
+
issueId: text("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
|
142
|
+
launchedByKind: text("launched_by_kind", { enum: [
|
|
143
|
+
"user",
|
|
144
|
+
"agent",
|
|
145
|
+
"external"
|
|
146
|
+
] }).notNull().default("user"),
|
|
147
|
+
launchedById: text("launched_by_id"),
|
|
148
|
+
agentId: text("agent_id"),
|
|
149
|
+
agentName: text("agent_name").notNull(),
|
|
150
|
+
host: text("host"),
|
|
151
|
+
executionMode: text("execution_mode", { enum: ["worktree", "main"] }).notNull().default("worktree"),
|
|
152
|
+
branch: text("branch"),
|
|
153
|
+
worktreePath: text("worktree_path"),
|
|
154
|
+
state: text("state", { enum: [
|
|
155
|
+
"running",
|
|
156
|
+
"finished",
|
|
157
|
+
"failed",
|
|
158
|
+
"stopped"
|
|
159
|
+
] }).notNull().default("running"),
|
|
160
|
+
chatSessionId: text("chat_session_id"),
|
|
161
|
+
/** Where an external agent's own log of this run lives — `claude:<id>` or `codex:<id>` (ruling 7-1), `null` when it never said. */
|
|
162
|
+
externalSessionRef: text("external_session_ref"),
|
|
163
|
+
startedAt: int("started_at").notNull().default(sql`(unixepoch())`),
|
|
164
|
+
endedAt: int("ended_at")
|
|
165
|
+
}, (table) => ({
|
|
166
|
+
byIssue: index("issue_runs_issue_id_idx").on(table.issueId),
|
|
167
|
+
byIssueState: index("issue_runs_issue_state_idx").on(table.issueId, table.state),
|
|
168
|
+
byChatSession: index("issue_runs_chat_session_idx").on(table.chatSessionId)
|
|
169
|
+
}));
|
|
170
|
+
const issueRelations = sqliteTable("issue_relations", {
|
|
171
|
+
id: textPk(),
|
|
172
|
+
sourceIssueId: text("source_issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
|
173
|
+
targetIssueId: text("target_issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
|
174
|
+
type: text("type", { enum: [
|
|
175
|
+
"blocks",
|
|
176
|
+
"duplicates",
|
|
177
|
+
"relates_to"
|
|
178
|
+
] }).notNull(),
|
|
179
|
+
...createdAt()
|
|
180
|
+
}, (table) => ({
|
|
181
|
+
bySource: index("issue_relations_source_issue_id_idx").on(table.sourceIssueId),
|
|
182
|
+
byTarget: index("issue_relations_target_issue_id_idx").on(table.targetIssueId),
|
|
183
|
+
byPairType: uniqueIndex("issue_relations_pair_type_unique").on(table.sourceIssueId, table.targetIssueId, table.type)
|
|
184
|
+
}));
|
|
185
|
+
const issueFieldChanges = sqliteTable("issue_field_changes", {
|
|
186
|
+
id: textPk(),
|
|
187
|
+
issueId: text("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
|
188
|
+
field: text("field").notNull(),
|
|
189
|
+
fromValue: text("from_value"),
|
|
190
|
+
toValue: text("to_value"),
|
|
191
|
+
actorKind: text("actor_kind", { enum: [
|
|
192
|
+
"user",
|
|
193
|
+
"agent",
|
|
194
|
+
"provider-target",
|
|
195
|
+
"system"
|
|
196
|
+
] }).notNull().default("user"),
|
|
197
|
+
actorId: text("actor_id"),
|
|
198
|
+
sourceChatSessionId: text("source_chat_session_id"),
|
|
199
|
+
...createdAt()
|
|
200
|
+
}, (table) => ({ byIssue: index("issue_field_changes_issue_id_idx").on(table.issueId) }));
|
|
201
|
+
/**
|
|
202
|
+
* A pull request someone said belongs to a card.
|
|
203
|
+
*
|
|
204
|
+
* The link is the board's; what the pull request *is* — open, merged, green —
|
|
205
|
+
* is GitHub's, and the board keeps none of it. Whoever watches GitHub reads the
|
|
206
|
+
* links here and writes what it saw as comments on the card, so this row is a
|
|
207
|
+
* name (`owner/repo#number`, and the URL it came from) and who gave it. One
|
|
208
|
+
* card names one pull request once; the same pull request may belong to several
|
|
209
|
+
* cards, which is why `(owner, repo, number)` is indexed on its own.
|
|
210
|
+
*/
|
|
211
|
+
const issuePullRequests = sqliteTable("issue_pull_requests", {
|
|
212
|
+
id: textPk(),
|
|
213
|
+
issueId: text("issue_id").notNull().references(() => issues.id, { onDelete: "cascade" }),
|
|
214
|
+
owner: text("owner").notNull(),
|
|
215
|
+
repo: text("repo").notNull(),
|
|
216
|
+
number: int("number").notNull(),
|
|
217
|
+
url: text("url").notNull(),
|
|
218
|
+
createdByKind: text("created_by_kind", { enum: [
|
|
219
|
+
"user",
|
|
220
|
+
"agent",
|
|
221
|
+
"provider-target",
|
|
222
|
+
"system"
|
|
223
|
+
] }).notNull(),
|
|
224
|
+
createdById: text("created_by_id"),
|
|
225
|
+
...createdAt()
|
|
226
|
+
}, (table) => ({
|
|
227
|
+
byIssuePullRequest: uniqueIndex("issue_pull_requests_issue_pr_unique").on(table.issueId, table.owner, table.repo, table.number),
|
|
228
|
+
byPullRequest: index("issue_pull_requests_pr_idx").on(table.owner, table.repo, table.number)
|
|
229
|
+
}));
|
|
230
|
+
/**
|
|
231
|
+
* Monotonic counters the board keeps for its readers: `board` is bumped by the
|
|
232
|
+
* board operations layer once per write transaction that changed something, so a
|
|
233
|
+
* poller can tell a changed board from an unchanged one, and `schema_epoch`
|
|
234
|
+
* records the board schema generation the file was written with.
|
|
235
|
+
*/
|
|
236
|
+
const kanbanMeta = sqliteTable("kanban_meta", {
|
|
237
|
+
key: text("key").primaryKey(),
|
|
238
|
+
revision: int("revision").notNull().default(0),
|
|
239
|
+
updatedAt: int("updated_at").notNull().default(sql`(unixepoch())`)
|
|
240
|
+
});
|
|
241
|
+
/** Every table of the board, in the order a reader of the schema wants them. */
|
|
242
|
+
const boardSqliteSchema = {
|
|
243
|
+
issueStatuses,
|
|
244
|
+
issueMilestones,
|
|
245
|
+
issues,
|
|
246
|
+
issueComments,
|
|
247
|
+
issueRuns,
|
|
248
|
+
issueRelations,
|
|
249
|
+
issueFieldChanges,
|
|
250
|
+
issuePullRequests,
|
|
251
|
+
kanbanMeta
|
|
252
|
+
};
|
|
253
|
+
//#endregion
|
|
254
|
+
export { boardSqliteSchema, issueComments, issueFieldChanges, issueMilestones, issuePullRequests, issueRelations, issueRuns, issueStatuses, issues, kanbanMeta };
|
|
255
|
+
|
|
256
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":[],"sources":["../../../src/sqlite/schema.ts"],"sourcesContent":["import { sql } from 'drizzle-orm'\nimport type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core'\nimport { index, int, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core'\n\n/**\n * The board, as a SQLite file holds it.\n *\n * These nine tables are the board itself, and this package owns them: the same\n * logical schema as `src/postgres/schema.ts`, written for the dialect a file\n * speaks. They live in three different places at runtime — a host app's own\n * database, a board file of a project's own, and neither of those when the\n * board is a Postgres database — and none of those homes owns the shape. A host\n * app re-exports these very objects from its own schema, so its tables and\n * these are the same tables rather than two declarations that have to be kept\n * in step.\n *\n * **Every reference out of the board is a plain text column** (ruling 5-1).\n * `workspace_id`, `delegate_agent_id`, `delegate_provider_target_id` and\n * `source_chat_session_id` name rows in a host app's tables, and a board file of\n * a project's own has no such tables to point at — so they are soft references\n * into whichever app is looking, exactly as they are on Postgres. What an\n * `ON DELETE` would do is done in the open by the app that deletes the row: it\n * empties a removed workspace's board, and clears the delegation off the cards\n * that named a removed agent or provider target. The foreign keys that stay are the\n * ones that point *inside* the board, and they still cascade.\n */\n\nconst textPk = () => text('id').primaryKey()\n\nconst timestamps = () => ({\n createdAt: int('created_at').notNull().default(sql`(unixepoch())`),\n updatedAt: int('updated_at').notNull().default(sql`(unixepoch())`),\n})\n\nconst createdAt = () => ({\n createdAt: int('created_at').notNull().default(sql`(unixepoch())`),\n})\n\nexport const issueStatuses = sqliteTable('issue_statuses', {\n id: textPk(),\n workspaceId: text('workspace_id').notNull(),\n name: text('name').notNull(),\n description: text('description'),\n color: text('color'),\n category: text('category', { enum: ['triage', 'backlog', 'unstarted', 'started', 'completed', 'canceled'] }).notNull().default('unstarted'),\n order: int('order').notNull().default(0),\n /**\n * What a card must satisfy before an agent may put it in this column — a JSON\n * array of `ENTRY_RULES` (ruling 6-1); `null` asks for nothing. Read it\n * through `readEntryRules`, never by hand.\n */\n entryRules: text('entry_rules'),\n ...createdAt(),\n}, table => ({\n byWorkspace: index('issue_statuses_workspace_id_idx').on(table.workspaceId),\n byWorkspaceName: uniqueIndex('issue_statuses_workspace_name_unique').on(table.workspaceId, table.name),\n}))\n\nexport const issueMilestones = sqliteTable('issue_milestones', {\n id: textPk(),\n workspaceId: text('workspace_id').notNull(),\n title: text('title').notNull(),\n description: text('description'),\n /** When the milestone, read as a sprint, begins (unix seconds); null for a plain milestone. */\n startDate: int('start_date'),\n dueDate: int('due_date'),\n status: text('status', { enum: ['open', 'closed'] }).notNull().default('open'),\n ...timestamps(),\n}, table => ({\n byWorkspace: index('issue_milestones_workspace_id_idx').on(table.workspaceId),\n}))\n\nexport const issues = sqliteTable('issues', {\n id: textPk(),\n workspaceId: text('workspace_id').notNull(),\n number: int('number').notNull(),\n statusId: text('status_id').references(() => issueStatuses.id, { onDelete: 'set null' }),\n milestoneId: text('milestone_id').references(() => issueMilestones.id, { onDelete: 'set null' }),\n parentIssueId: text('parent_issue_id')\n .references((): AnySQLiteColumn => issues.id, { onDelete: 'set null' }),\n title: text('title').notNull(),\n description: text('description'),\n priority: text('priority', {\n enum: ['none', 'low', 'medium', 'high', 'urgent'],\n }).notNull().default('none'),\n labels: text('labels').notNull().default('[]'),\n assigneeKind: text('assignee_kind'),\n assigneeId: text('assignee_id'),\n dueDate: int('due_date'),\n createdByKind: text('created_by_kind', { enum: ['user', 'agent', 'system', 'provider-target'] }).notNull().default('user'),\n createdById: text('created_by_id').notNull().default('__self__'),\n sourceChatSessionId: text('source_chat_session_id'),\n delegateAgentId: text('delegate_agent_id'),\n delegateProviderTargetId: text('delegate_provider_target_id'),\n contextRefs: text('context_refs').notNull().default('[]'),\n statusLine: text('status_line'),\n waitingFor: text('waiting_for', { enum: ['human'] }),\n executionMode: text('execution_mode', { enum: ['worktree', 'main'] }).notNull().default('worktree'),\n order: int('order').notNull().default(0),\n ...timestamps(),\n}, table => ({\n byWorkspace: index('issues_workspace_id_idx').on(table.workspaceId),\n byWorkspaceNumber: uniqueIndex('issues_workspace_number_unique').on(table.workspaceId, table.number),\n byStatus: index('issues_status_id_idx').on(table.statusId),\n byMilestone: index('issues_milestone_id_idx').on(table.milestoneId),\n byParent: index('issues_parent_issue_id_idx').on(table.parentIssueId),\n byDelegateAgent: index('issues_delegate_agent_id_idx').on(table.delegateAgentId),\n byDelegateProviderTarget: index('issues_delegate_provider_target_id_idx').on(table.delegateProviderTargetId),\n}))\n\nexport const issueComments = sqliteTable('issue_comments', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n content: text('content').notNull(),\n authorKind: text('author_kind', {\n enum: [\n 'user',\n 'agent',\n 'provider-target',\n 'system',\n 'system.delegated',\n 'system.undelegated',\n 'system.run',\n 'system.approved',\n 'system.returned',\n 'system.pr',\n ],\n }).notNull().default('user'),\n authorId: text('author_id'),\n sourceChatSessionId: text('source_chat_session_id'),\n agentActivityId: text('agent_activity_id'),\n dedupeKey: text('dedupe_key'),\n ...createdAt(),\n}, table => ({\n byIssue: index('issue_comments_issue_id_idx').on(table.issueId),\n byIssueDedupeKey: uniqueIndex('issue_comments_issue_dedupe_idx').on(table.issueId, table.dedupeKey),\n}))\n\nexport const issueRuns = sqliteTable('issue_runs', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n launchedByKind: text('launched_by_kind', { enum: ['user', 'agent', 'external'] }).notNull().default('user'),\n launchedById: text('launched_by_id'),\n agentId: text('agent_id'),\n agentName: text('agent_name').notNull(),\n host: text('host'),\n executionMode: text('execution_mode', { enum: ['worktree', 'main'] }).notNull().default('worktree'),\n branch: text('branch'),\n worktreePath: text('worktree_path'),\n state: text('state', { enum: ['running', 'finished', 'failed', 'stopped'] }).notNull().default('running'),\n chatSessionId: text('chat_session_id'),\n /** Where an external agent's own log of this run lives — `claude:<id>` or `codex:<id>` (ruling 7-1), `null` when it never said. */\n externalSessionRef: text('external_session_ref'),\n startedAt: int('started_at').notNull().default(sql`(unixepoch())`),\n endedAt: int('ended_at'),\n}, table => ({\n byIssue: index('issue_runs_issue_id_idx').on(table.issueId),\n byIssueState: index('issue_runs_issue_state_idx').on(table.issueId, table.state),\n byChatSession: index('issue_runs_chat_session_idx').on(table.chatSessionId),\n}))\n\nexport const issueRelations = sqliteTable('issue_relations', {\n id: textPk(),\n sourceIssueId: text('source_issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n targetIssueId: text('target_issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n type: text('type', { enum: ['blocks', 'duplicates', 'relates_to'] }).notNull(),\n ...createdAt(),\n}, table => ({\n bySource: index('issue_relations_source_issue_id_idx').on(table.sourceIssueId),\n byTarget: index('issue_relations_target_issue_id_idx').on(table.targetIssueId),\n byPairType: uniqueIndex('issue_relations_pair_type_unique')\n .on(table.sourceIssueId, table.targetIssueId, table.type),\n}))\n\nexport const issueFieldChanges = sqliteTable('issue_field_changes', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n field: text('field').notNull(),\n fromValue: text('from_value'),\n toValue: text('to_value'),\n actorKind: text('actor_kind', { enum: ['user', 'agent', 'provider-target', 'system'] }).notNull().default('user'),\n actorId: text('actor_id'),\n sourceChatSessionId: text('source_chat_session_id'),\n ...createdAt(),\n}, table => ({\n byIssue: index('issue_field_changes_issue_id_idx').on(table.issueId),\n}))\n\n/**\n * A pull request someone said belongs to a card.\n *\n * The link is the board's; what the pull request *is* — open, merged, green —\n * is GitHub's, and the board keeps none of it. Whoever watches GitHub reads the\n * links here and writes what it saw as comments on the card, so this row is a\n * name (`owner/repo#number`, and the URL it came from) and who gave it. One\n * card names one pull request once; the same pull request may belong to several\n * cards, which is why `(owner, repo, number)` is indexed on its own.\n */\nexport const issuePullRequests = sqliteTable('issue_pull_requests', {\n id: textPk(),\n issueId: text('issue_id')\n .notNull()\n .references(() => issues.id, { onDelete: 'cascade' }),\n owner: text('owner').notNull(),\n repo: text('repo').notNull(),\n number: int('number').notNull(),\n url: text('url').notNull(),\n createdByKind: text('created_by_kind', { enum: ['user', 'agent', 'provider-target', 'system'] }).notNull(),\n createdById: text('created_by_id'),\n ...createdAt(),\n}, table => ({\n byIssuePullRequest: uniqueIndex('issue_pull_requests_issue_pr_unique')\n .on(table.issueId, table.owner, table.repo, table.number),\n byPullRequest: index('issue_pull_requests_pr_idx').on(table.owner, table.repo, table.number),\n}))\n\n/**\n * Monotonic counters the board keeps for its readers: `board` is bumped by the\n * board operations layer once per write transaction that changed something, so a\n * poller can tell a changed board from an unchanged one, and `schema_epoch`\n * records the board schema generation the file was written with.\n */\nexport const kanbanMeta = sqliteTable('kanban_meta', {\n key: text('key').primaryKey(),\n revision: int('revision').notNull().default(0),\n updatedAt: int('updated_at').notNull().default(sql`(unixepoch())`),\n})\n\nexport type IssueStatus = typeof issueStatuses.$inferSelect\nexport type IssueMilestone = typeof issueMilestones.$inferSelect\nexport type Issue = typeof issues.$inferSelect\nexport type IssueComment = typeof issueComments.$inferSelect\nexport type IssueRun = typeof issueRuns.$inferSelect\nexport type IssueRelation = typeof issueRelations.$inferSelect\nexport type IssueFieldChange = typeof issueFieldChanges.$inferSelect\nexport type IssuePullRequest = typeof issuePullRequests.$inferSelect\nexport type KanbanMeta = typeof kanbanMeta.$inferSelect\n\n/** Every table of the board, in the order a reader of the schema wants them. */\nexport const boardSqliteSchema = {\n issueStatuses,\n issueMilestones,\n issues,\n issueComments,\n issueRuns,\n issueRelations,\n issueFieldChanges,\n issuePullRequests,\n kanbanMeta,\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { c as IssueStatus } from "./schema-fsHqNAip.cjs";
|
|
2
|
+
//#region src/domain/entry-rules.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* What a column may ask of a card before an agent puts the card in it (ruling
|
|
5
|
+
* 6-1). The set is fixed: each rule is one fact the board can check on its own.
|
|
6
|
+
*
|
|
7
|
+
* - `checklist_complete` — the description holds at least one markdown task
|
|
8
|
+
* item, and every one of them is checked.
|
|
9
|
+
* - `pull_request_linked` — the card names at least one pull request.
|
|
10
|
+
* - `ci_green` — the newest CI verdict across the card's linked pull requests
|
|
11
|
+
* is green.
|
|
12
|
+
* - `approved` — a person's last decision on the card was to approve it.
|
|
13
|
+
*/
|
|
14
|
+
declare const ENTRY_RULES: readonly ["checklist_complete", "pull_request_linked", "ci_green", "approved"];
|
|
15
|
+
type EntryRule = typeof ENTRY_RULES[number];
|
|
16
|
+
/** Why a rule is unmet, as a key a translated surface can name in its own words. */
|
|
17
|
+
declare const UNMET_ENTRY_RULE_REASONS: readonly ["no_checklist", "unchecked", "no_pull_request", "no_ci", "ci_red", "approval_pending", "returned", "not_approved"];
|
|
18
|
+
type UnmetEntryRuleReason = typeof UNMET_ENTRY_RULE_REASONS[number];
|
|
19
|
+
/**
|
|
20
|
+
* One rule a card does not meet yet: `detail` says what is missing in English
|
|
21
|
+
* words the command line and MCP print; `reason` (with `checked` and `total`
|
|
22
|
+
* for `unchecked`) says the same for a surface that translates it.
|
|
23
|
+
*/
|
|
24
|
+
interface UnmetEntryRule {
|
|
25
|
+
rule: EntryRule;
|
|
26
|
+
reason: UnmetEntryRuleReason;
|
|
27
|
+
detail: string;
|
|
28
|
+
checked?: number;
|
|
29
|
+
total?: number;
|
|
30
|
+
}
|
|
31
|
+
/** What `evaluateEntryRules` needs to know beyond the card's own fields. */
|
|
32
|
+
interface EntryRuleFacts {
|
|
33
|
+
/** How many pull requests the card names. */
|
|
34
|
+
pullRequestCount: number;
|
|
35
|
+
/** The newest CI verdict across those pull requests, or `null` while none has arrived. */
|
|
36
|
+
latestCi: 'green' | 'red' | null;
|
|
37
|
+
/** Where the card stands with the person who approves it (`BoardApproval['state']`). */
|
|
38
|
+
approval: 'none' | 'pending' | 'approved' | 'returned';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The rules a caller asked for, as the column stores them: known rules only,
|
|
42
|
+
* each once, in `ENTRY_RULES` order, and `null` for none — an empty list and no
|
|
43
|
+
* list are the same column. An unknown rule is `board_entry_rule_invalid`,
|
|
44
|
+
* before anything is written.
|
|
45
|
+
*/
|
|
46
|
+
declare function serializeEntryRules(rules: readonly string[] | null): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* The rules a column asks for. A rule this build does not know — written by a
|
|
49
|
+
* newer one — is left out rather than failing the read: the column still
|
|
50
|
+
* enforces everything this build can check.
|
|
51
|
+
*/
|
|
52
|
+
declare function readEntryRules(column: Pick<IssueStatus, 'entryRules'>): EntryRule[];
|
|
53
|
+
/** How many markdown task items a description holds, and how many are checked. */
|
|
54
|
+
interface ChecklistProgress {
|
|
55
|
+
total: number;
|
|
56
|
+
checked: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Count the task items of a markdown description.
|
|
60
|
+
*
|
|
61
|
+
* Every list item that starts with `[ ]` or `[x]` (either case) counts,
|
|
62
|
+
* nested ones included — a sub-task is still a task. Lines inside a fenced code
|
|
63
|
+
* block (```` ``` ```` or `~~~`) do not: a `- [ ]` there is an example someone
|
|
64
|
+
* quoted, not a box anyone can tick. An indented code block cannot be told
|
|
65
|
+
* apart from a nested list without a full markdown parser, so it counts; fence
|
|
66
|
+
* the example to keep it out.
|
|
67
|
+
*/
|
|
68
|
+
declare function readChecklist(description: string | null): ChecklistProgress;
|
|
69
|
+
/**
|
|
70
|
+
* The rules a card does not meet, in the order the column lists them (ruling
|
|
71
|
+
* 6-2). Pure: everything beyond the card's own description arrives in `facts`.
|
|
72
|
+
*/
|
|
73
|
+
declare function evaluateEntryRules(card: {
|
|
74
|
+
description: string | null;
|
|
75
|
+
}, rules: readonly EntryRule[], facts: EntryRuleFacts): {
|
|
76
|
+
unmet: UnmetEntryRule[];
|
|
77
|
+
};
|
|
78
|
+
/** What `ENTRY_RULES` each mean, in the words the prime text and the manifest use. */
|
|
79
|
+
declare const ENTRY_RULE_DESCRIPTIONS: Record<EntryRule, string>;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/mcp/tool-names.d.ts
|
|
82
|
+
/**
|
|
83
|
+
* The board's tools, named once.
|
|
84
|
+
*
|
|
85
|
+
* An agent reaches this board through an MCP server, through a command line, or
|
|
86
|
+
* through an HTTP API (`kanbo serve`, or an app that serves the same routes),
|
|
87
|
+
* and the three must agree on what the board can be asked to do. The names live
|
|
88
|
+
* here rather than in the MCP server so that a prompt built for an agent and the
|
|
89
|
+
* tools that agent actually holds cannot drift apart: both read this list.
|
|
90
|
+
*
|
|
91
|
+
* Nothing here executes anything. These are names and the commands that mean
|
|
92
|
+
* the same thing, for a prompt and for documentation.
|
|
93
|
+
*/
|
|
94
|
+
declare const KANBO_TOOL_NAMES: readonly ["kanbo_prime", "kanbo_ready", "kanbo_columns", "kanbo_sprints", "kanbo_card_get", "kanbo_card_list", "kanbo_card_create", "kanbo_card_update", "kanbo_card_move", "kanbo_card_comment", "kanbo_card_link_pr", "kanbo_card_pull_requests", "kanbo_status_line", "kanbo_wait_approval", "kanbo_run_start", "kanbo_run_finish"];
|
|
95
|
+
/** One of the board's tools. */
|
|
96
|
+
type KanboToolName = typeof KANBO_TOOL_NAMES[number];
|
|
97
|
+
/** The command line that does what a tool does. */
|
|
98
|
+
interface KanboToolCliEquivalent {
|
|
99
|
+
/** The `kanbo` command, which needs no server. */
|
|
100
|
+
kanbo: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* What to type instead of calling the tool.
|
|
104
|
+
*
|
|
105
|
+
* An agent without MCP tools is not shut out of the board: every tool has a
|
|
106
|
+
* command that does the same thing, and the card ends up saying the same
|
|
107
|
+
* either way, because both call the same operations.
|
|
108
|
+
*/
|
|
109
|
+
declare const KANBO_TOOL_CLI_EQUIVALENTS: Record<KanboToolName, KanboToolCliEquivalent>;
|
|
110
|
+
//#endregion
|
|
111
|
+
export { ENTRY_RULES as a, EntryRuleFacts as c, evaluateEntryRules as d, readChecklist as f, KanboToolName as i, UNMET_ENTRY_RULE_REASONS as l, serializeEntryRules as m, KANBO_TOOL_NAMES as n, ENTRY_RULE_DESCRIPTIONS as o, readEntryRules as p, KanboToolCliEquivalent as r, EntryRule as s, KANBO_TOOL_CLI_EQUIVALENTS as t, UnmetEntryRule as u };
|
|
112
|
+
//# sourceMappingURL=tool-names-9cmCn0gP.d.cts.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { c as IssueStatus } from "./schema-fsHqNAip.mjs";
|
|
2
|
+
//#region src/domain/entry-rules.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* What a column may ask of a card before an agent puts the card in it (ruling
|
|
5
|
+
* 6-1). The set is fixed: each rule is one fact the board can check on its own.
|
|
6
|
+
*
|
|
7
|
+
* - `checklist_complete` — the description holds at least one markdown task
|
|
8
|
+
* item, and every one of them is checked.
|
|
9
|
+
* - `pull_request_linked` — the card names at least one pull request.
|
|
10
|
+
* - `ci_green` — the newest CI verdict across the card's linked pull requests
|
|
11
|
+
* is green.
|
|
12
|
+
* - `approved` — a person's last decision on the card was to approve it.
|
|
13
|
+
*/
|
|
14
|
+
declare const ENTRY_RULES: readonly ["checklist_complete", "pull_request_linked", "ci_green", "approved"];
|
|
15
|
+
type EntryRule = typeof ENTRY_RULES[number];
|
|
16
|
+
/** Why a rule is unmet, as a key a translated surface can name in its own words. */
|
|
17
|
+
declare const UNMET_ENTRY_RULE_REASONS: readonly ["no_checklist", "unchecked", "no_pull_request", "no_ci", "ci_red", "approval_pending", "returned", "not_approved"];
|
|
18
|
+
type UnmetEntryRuleReason = typeof UNMET_ENTRY_RULE_REASONS[number];
|
|
19
|
+
/**
|
|
20
|
+
* One rule a card does not meet yet: `detail` says what is missing in English
|
|
21
|
+
* words the command line and MCP print; `reason` (with `checked` and `total`
|
|
22
|
+
* for `unchecked`) says the same for a surface that translates it.
|
|
23
|
+
*/
|
|
24
|
+
interface UnmetEntryRule {
|
|
25
|
+
rule: EntryRule;
|
|
26
|
+
reason: UnmetEntryRuleReason;
|
|
27
|
+
detail: string;
|
|
28
|
+
checked?: number;
|
|
29
|
+
total?: number;
|
|
30
|
+
}
|
|
31
|
+
/** What `evaluateEntryRules` needs to know beyond the card's own fields. */
|
|
32
|
+
interface EntryRuleFacts {
|
|
33
|
+
/** How many pull requests the card names. */
|
|
34
|
+
pullRequestCount: number;
|
|
35
|
+
/** The newest CI verdict across those pull requests, or `null` while none has arrived. */
|
|
36
|
+
latestCi: 'green' | 'red' | null;
|
|
37
|
+
/** Where the card stands with the person who approves it (`BoardApproval['state']`). */
|
|
38
|
+
approval: 'none' | 'pending' | 'approved' | 'returned';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The rules a caller asked for, as the column stores them: known rules only,
|
|
42
|
+
* each once, in `ENTRY_RULES` order, and `null` for none — an empty list and no
|
|
43
|
+
* list are the same column. An unknown rule is `board_entry_rule_invalid`,
|
|
44
|
+
* before anything is written.
|
|
45
|
+
*/
|
|
46
|
+
declare function serializeEntryRules(rules: readonly string[] | null): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* The rules a column asks for. A rule this build does not know — written by a
|
|
49
|
+
* newer one — is left out rather than failing the read: the column still
|
|
50
|
+
* enforces everything this build can check.
|
|
51
|
+
*/
|
|
52
|
+
declare function readEntryRules(column: Pick<IssueStatus, 'entryRules'>): EntryRule[];
|
|
53
|
+
/** How many markdown task items a description holds, and how many are checked. */
|
|
54
|
+
interface ChecklistProgress {
|
|
55
|
+
total: number;
|
|
56
|
+
checked: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Count the task items of a markdown description.
|
|
60
|
+
*
|
|
61
|
+
* Every list item that starts with `[ ]` or `[x]` (either case) counts,
|
|
62
|
+
* nested ones included — a sub-task is still a task. Lines inside a fenced code
|
|
63
|
+
* block (```` ``` ```` or `~~~`) do not: a `- [ ]` there is an example someone
|
|
64
|
+
* quoted, not a box anyone can tick. An indented code block cannot be told
|
|
65
|
+
* apart from a nested list without a full markdown parser, so it counts; fence
|
|
66
|
+
* the example to keep it out.
|
|
67
|
+
*/
|
|
68
|
+
declare function readChecklist(description: string | null): ChecklistProgress;
|
|
69
|
+
/**
|
|
70
|
+
* The rules a card does not meet, in the order the column lists them (ruling
|
|
71
|
+
* 6-2). Pure: everything beyond the card's own description arrives in `facts`.
|
|
72
|
+
*/
|
|
73
|
+
declare function evaluateEntryRules(card: {
|
|
74
|
+
description: string | null;
|
|
75
|
+
}, rules: readonly EntryRule[], facts: EntryRuleFacts): {
|
|
76
|
+
unmet: UnmetEntryRule[];
|
|
77
|
+
};
|
|
78
|
+
/** What `ENTRY_RULES` each mean, in the words the prime text and the manifest use. */
|
|
79
|
+
declare const ENTRY_RULE_DESCRIPTIONS: Record<EntryRule, string>;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/mcp/tool-names.d.ts
|
|
82
|
+
/**
|
|
83
|
+
* The board's tools, named once.
|
|
84
|
+
*
|
|
85
|
+
* An agent reaches this board through an MCP server, through a command line, or
|
|
86
|
+
* through an HTTP API (`kanbo serve`, or an app that serves the same routes),
|
|
87
|
+
* and the three must agree on what the board can be asked to do. The names live
|
|
88
|
+
* here rather than in the MCP server so that a prompt built for an agent and the
|
|
89
|
+
* tools that agent actually holds cannot drift apart: both read this list.
|
|
90
|
+
*
|
|
91
|
+
* Nothing here executes anything. These are names and the commands that mean
|
|
92
|
+
* the same thing, for a prompt and for documentation.
|
|
93
|
+
*/
|
|
94
|
+
declare const KANBO_TOOL_NAMES: readonly ["kanbo_prime", "kanbo_ready", "kanbo_columns", "kanbo_sprints", "kanbo_card_get", "kanbo_card_list", "kanbo_card_create", "kanbo_card_update", "kanbo_card_move", "kanbo_card_comment", "kanbo_card_link_pr", "kanbo_card_pull_requests", "kanbo_status_line", "kanbo_wait_approval", "kanbo_run_start", "kanbo_run_finish"];
|
|
95
|
+
/** One of the board's tools. */
|
|
96
|
+
type KanboToolName = typeof KANBO_TOOL_NAMES[number];
|
|
97
|
+
/** The command line that does what a tool does. */
|
|
98
|
+
interface KanboToolCliEquivalent {
|
|
99
|
+
/** The `kanbo` command, which needs no server. */
|
|
100
|
+
kanbo: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* What to type instead of calling the tool.
|
|
104
|
+
*
|
|
105
|
+
* An agent without MCP tools is not shut out of the board: every tool has a
|
|
106
|
+
* command that does the same thing, and the card ends up saying the same
|
|
107
|
+
* either way, because both call the same operations.
|
|
108
|
+
*/
|
|
109
|
+
declare const KANBO_TOOL_CLI_EQUIVALENTS: Record<KanboToolName, KanboToolCliEquivalent>;
|
|
110
|
+
//#endregion
|
|
111
|
+
export { ENTRY_RULES as a, EntryRuleFacts as c, evaluateEntryRules as d, readChecklist as f, KanboToolName as i, UNMET_ENTRY_RULE_REASONS as l, serializeEntryRules as m, KANBO_TOOL_NAMES as n, ENTRY_RULE_DESCRIPTIONS as o, readEntryRules as p, KanboToolCliEquivalent as r, EntryRule as s, KANBO_TOOL_CLI_EQUIVALENTS as t, UnmetEntryRule as u };
|
|
112
|
+
//# sourceMappingURL=tool-names-Dxg1UTUl.d.mts.map
|