agor-live 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/commands/db/migrate.d.ts +13 -0
  3. package/dist/cli/commands/db/migrate.js +26 -0
  4. package/dist/cli/commands/db/status.d.ts +13 -0
  5. package/dist/cli/commands/db/status.js +52 -0
  6. package/dist/cli/commands/init.js +1 -1
  7. package/dist/cli/commands/session/load-claude.js +3 -1
  8. package/dist/core/api/index.d.cts +8 -5
  9. package/dist/core/api/index.d.ts +8 -5
  10. package/dist/core/board-Oa2OJ-K3.d.cts +134 -0
  11. package/dist/core/board-ava4cdq5.d.ts +134 -0
  12. package/dist/core/claude/index.cjs +40 -10
  13. package/dist/core/claude/index.d.cts +3 -2
  14. package/dist/core/claude/index.d.ts +3 -2
  15. package/dist/core/claude/index.js +51 -21
  16. package/dist/core/{worktrees-BnZ6TnB3.d.cts → client-B7p2_7Ut.d.cts} +211 -365
  17. package/dist/core/{worktrees-BGyg0_jA.d.ts → client-CklMhh5V.d.ts} +211 -365
  18. package/dist/core/config/browser.d.cts +5 -3
  19. package/dist/core/config/browser.d.ts +5 -3
  20. package/dist/core/config/index.cjs +754 -17
  21. package/dist/core/config/index.d.cts +154 -3
  22. package/dist/core/config/index.d.ts +154 -3
  23. package/dist/core/config/index.js +738 -14
  24. package/dist/core/context-ByxGjp5l.d.cts +36 -0
  25. package/dist/core/context-ByxGjp5l.d.ts +36 -0
  26. package/dist/core/db/index.cjs +187 -441
  27. package/dist/core/db/index.d.cts +79 -124
  28. package/dist/core/db/index.d.ts +79 -124
  29. package/dist/core/db/index.js +282 -541
  30. package/dist/core/environment/variable-resolver.d.cts +1 -1
  31. package/dist/core/environment/variable-resolver.d.ts +1 -1
  32. package/dist/core/feathers/index.cjs +7 -0
  33. package/dist/core/feathers/index.d.cts +2 -1
  34. package/dist/core/feathers/index.d.ts +2 -1
  35. package/dist/core/feathers/index.js +5 -0
  36. package/dist/core/git/index.cjs +6 -2
  37. package/dist/core/git/index.js +6 -2
  38. package/dist/core/index.cjs +731 -716
  39. package/dist/core/index.d.cts +12 -8
  40. package/dist/core/index.d.ts +12 -8
  41. package/dist/core/index.js +675 -679
  42. package/dist/core/mcp-BJoCdfzv.d.ts +189 -0
  43. package/dist/core/mcp-DpJnAKie.d.cts +189 -0
  44. package/dist/core/{message-BoxZISHg.d.cts → message-B1tv5qyO.d.cts} +8 -1
  45. package/dist/core/{message-DvBzHu7V.d.ts → message-Wm1fS7rs.d.ts} +8 -1
  46. package/dist/core/permissions/index.d.cts +1 -1
  47. package/dist/core/permissions/index.d.ts +1 -1
  48. package/dist/core/{repo-BoA8D6Uf.d.ts → repo-DU_q1nOJ.d.ts} +141 -1
  49. package/dist/core/{repo-Dr--T0wp.d.cts → repo-Da9KZn56.d.cts} +141 -1
  50. package/dist/core/session-BiQr29HO.d.cts +187 -0
  51. package/dist/core/session-CxdFDTYb.d.ts +187 -0
  52. package/dist/core/{task-DuIfiUbW.d.ts → task-C4bogx9k.d.ts} +2 -36
  53. package/dist/core/{task-BIEgT1DK.d.cts → task-sTuyYLoN.d.cts} +2 -36
  54. package/dist/core/tools/claude/models.cjs +6 -6
  55. package/dist/core/tools/claude/models.js +6 -6
  56. package/dist/core/tools/index.cjs +1100 -174
  57. package/dist/core/tools/index.d.cts +48 -18
  58. package/dist/core/tools/index.d.ts +48 -18
  59. package/dist/core/tools/index.js +1099 -172
  60. package/dist/core/tools/models.cjs +6 -6
  61. package/dist/core/tools/models.js +6 -6
  62. package/dist/core/types/index.d.cts +9 -6
  63. package/dist/core/types/index.d.ts +9 -6
  64. package/dist/core/{user-BmL3kFol.d.ts → user-CS2VnSS6.d.ts} +12 -0
  65. package/dist/core/{user-eUuKj7yM.d.cts → user-iMPpW1iA.d.cts} +12 -0
  66. package/dist/core/utils/cron.cjs +167 -0
  67. package/dist/core/utils/cron.d.cts +121 -0
  68. package/dist/core/utils/cron.d.ts +121 -0
  69. package/dist/core/utils/cron.js +124 -0
  70. package/dist/core/utils/permission-mode-mapper.cjs +107 -0
  71. package/dist/core/utils/permission-mode-mapper.d.cts +44 -0
  72. package/dist/core/utils/permission-mode-mapper.d.ts +44 -0
  73. package/dist/core/utils/permission-mode-mapper.js +81 -0
  74. package/dist/core/worktrees-DCLpNeje.d.ts +416 -0
  75. package/dist/core/worktrees-Df_shHCZ.d.cts +416 -0
  76. package/dist/daemon/declarations.d.ts +6 -0
  77. package/dist/daemon/index.js +2235 -127
  78. package/dist/daemon/mcp/routes.js +1005 -2
  79. package/dist/daemon/services/context.d.ts +4 -0
  80. package/dist/daemon/services/context.js +61 -5
  81. package/dist/daemon/services/health-monitor.js +0 -1
  82. package/dist/daemon/services/mcp-servers.d.ts +7 -2
  83. package/dist/daemon/services/messages.d.ts +5 -1
  84. package/dist/daemon/services/messages.js +34 -0
  85. package/dist/daemon/services/scheduler.d.ts +123 -0
  86. package/dist/daemon/services/scheduler.js +381 -0
  87. package/dist/daemon/services/sessions.js +2 -1
  88. package/dist/daemon/services/terminals.d.ts +5 -1
  89. package/dist/daemon/services/terminals.js +14 -2
  90. package/dist/daemon/services/users.d.ts +16 -0
  91. package/dist/daemon/services/users.js +110 -5
  92. package/dist/daemon/services/worktrees.d.ts +23 -3
  93. package/dist/daemon/services/worktrees.js +115 -8
  94. package/dist/daemon/strategies/anonymous.js +1 -1
  95. package/dist/daemon/utils/authorization.d.ts +19 -0
  96. package/dist/daemon/utils/authorization.js +38 -0
  97. package/dist/ui/assets/index-B_3eFhE9.js +612 -0
  98. package/dist/ui/assets/{index-CkISoKn2.css → index-BmuYUAWn.css} +1 -1
  99. package/dist/ui/index.html +2 -2
  100. package/package.json +3 -3
  101. package/dist/core/session-De4TwIM_.d.ts +0 -433
  102. package/dist/core/session-Dl5E0CV3.d.cts +0 -433
  103. package/dist/ui/assets/index-DLp8CGmD.js +0 -578
package/README.md CHANGED
@@ -34,7 +34,7 @@ agor ui open
34
34
 
35
35
  ## Documentation
36
36
 
37
- - **GitHub**: https://github.com/agorapp/agor
37
+ - **GitHub**: https://github.com/preset-io/agor
38
38
  - **Docs**: https://agor.live
39
39
 
40
40
  ## License
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+
3
+ /**
4
+ * `agor db migrate` - Run pending database migrations
5
+ */
6
+
7
+ declare class DbMigrate extends Command {
8
+ static description: string;
9
+ static examples: string[];
10
+ run(): Promise<void>;
11
+ }
12
+
13
+ export { DbMigrate as default };
@@ -0,0 +1,26 @@
1
+ // src/commands/db/migrate.ts
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { createDatabase, runMigrations } from "@agor/core/db";
5
+ import { Command } from "@oclif/core";
6
+ import chalk from "chalk";
7
+ var DbMigrate = class extends Command {
8
+ static description = "Run pending database migrations";
9
+ static examples = ["<%= config.bin %> <%= command.id %>"];
10
+ async run() {
11
+ try {
12
+ const dbPath = process.env.AGOR_DB_PATH || `file:${join(homedir(), ".agor", "agor.db")}`;
13
+ this.log("Running database migrations...");
14
+ const db = createDatabase({ url: dbPath });
15
+ await runMigrations(db);
16
+ this.log(`${chalk.green("\u2713")} Database is up to date`);
17
+ } catch (error) {
18
+ this.error(
19
+ `Failed to run migrations: ${error instanceof Error ? error.message : String(error)}`
20
+ );
21
+ }
22
+ }
23
+ };
24
+ export {
25
+ DbMigrate as default
26
+ };
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+
3
+ /**
4
+ * `agor db status` - Show applied database migrations
5
+ */
6
+
7
+ declare class DbStatus extends Command {
8
+ static description: string;
9
+ static examples: string[];
10
+ run(): Promise<void>;
11
+ }
12
+
13
+ export { DbStatus as default };
@@ -0,0 +1,52 @@
1
+ // src/commands/db/status.ts
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { createDatabase, sql } from "@agor/core/db";
5
+ import { Command } from "@oclif/core";
6
+ import chalk from "chalk";
7
+ var DbStatus = class extends Command {
8
+ static description = "Show applied database migrations";
9
+ static examples = ["<%= config.bin %> <%= command.id %>"];
10
+ async run() {
11
+ try {
12
+ const dbPath = process.env.AGOR_DB_PATH || `file:${join(homedir(), ".agor", "agor.db")}`;
13
+ const db = createDatabase({ url: dbPath });
14
+ const tableCheck = await db.run(sql`
15
+ SELECT name FROM sqlite_master
16
+ WHERE type='table' AND name='__drizzle_migrations'
17
+ `);
18
+ if (tableCheck.rows.length === 0) {
19
+ this.log(
20
+ `${chalk.yellow("\u26A0")} No migrations table found. Run ${chalk.cyan("agor db migrate")} to initialize.`
21
+ );
22
+ return;
23
+ }
24
+ const result = await db.run(sql`
25
+ SELECT hash, created_at FROM __drizzle_migrations
26
+ ORDER BY created_at ASC
27
+ `);
28
+ if (result.rows.length === 0) {
29
+ this.log("No migrations applied yet");
30
+ return;
31
+ }
32
+ this.log(chalk.bold("\nApplied migrations:\n"));
33
+ result.rows.forEach((row) => {
34
+ const migration = row;
35
+ const date = new Date(migration.created_at);
36
+ const formattedDate = date.toLocaleString();
37
+ this.log(
38
+ ` ${chalk.green("\u2713")} ${chalk.cyan(migration.hash)} ${chalk.dim(`(${formattedDate})`)}`
39
+ );
40
+ });
41
+ this.log(`
42
+ ${chalk.bold(`Total: ${result.rows.length} migration(s)`)}`);
43
+ } catch (error) {
44
+ this.error(
45
+ `Failed to get migration status: ${error instanceof Error ? error.message : String(error)}`
46
+ );
47
+ }
48
+ }
49
+ };
50
+ export {
51
+ DbStatus as default
52
+ };
@@ -95,7 +95,7 @@ var Init = class _Init extends Command {
95
95
  this.log(" - Stopped Codespaces retain data for 30 days");
96
96
  this.log(" - Rebuilt Codespaces lose all data\n");
97
97
  this.log(chalk.dim("For production use, install Agor locally:"));
98
- this.log(chalk.dim(" https://github.com/mistercrunch/agor#installation\n"));
98
+ this.log(chalk.dim(" https://github.com/preset-io/agor#installation\n"));
99
99
  }
100
100
  try {
101
101
  const baseDir = flags.local ? join(process.cwd(), ".agor") : join(homedir(), ".agor");
@@ -176,7 +176,9 @@ ${chalk.blue("\u25CF")} Loading Claude Code session: ${chalk.cyan(sessionId)}
176
176
  for (let i = 0; i < messageLinkUpdates.length; i += batchSize2) {
177
177
  const batch = messageLinkUpdates.slice(i, i + batchSize2);
178
178
  await Promise.all(
179
- batch.map((update) => messagesService.patch(update.messageId, { task_id: update.taskId }))
179
+ batch.map(
180
+ (update) => messagesService.patch(update.messageId, { task_id: update.taskId })
181
+ )
180
182
  );
181
183
  this.log(
182
184
  `${chalk.blue("\u25CF")} Linked ${Math.min(i + batchSize2, messageLinkUpdates.length)}/${messageLinkUpdates.length} messages...`
@@ -1,9 +1,12 @@
1
- import { d as Message } from '../message-BoxZISHg.cjs';
2
- import { v as Session, e as Board, o as MCPServer } from '../session-Dl5E0CV3.cjs';
3
- import { e as Task, a as ContextFileListItem, b as ContextFileDetail } from '../task-BIEgT1DK.cjs';
1
+ import { d as Message } from '../message-B1tv5qyO.cjs';
2
+ import { e as Board } from '../board-Oa2OJ-K3.cjs';
3
+ import { a as ContextFileListItem, b as ContextFileDetail } from '../context-ByxGjp5l.cjs';
4
4
  import { b as AuthenticationResult } from '../feathers-BzHEPnpl.cjs';
5
- import { a as User } from '../user-eUuKj7yM.cjs';
6
- import { a as Repo, c as Worktree } from '../repo-Dr--T0wp.cjs';
5
+ import { h as MCPServer } from '../mcp-DpJnAKie.cjs';
6
+ import { a as User } from '../user-iMPpW1iA.cjs';
7
+ import { a as Repo, c as Worktree } from '../repo-Da9KZn56.cjs';
8
+ import { a as Session } from '../session-BiQr29HO.cjs';
9
+ import { c as Task } from '../task-sTuyYLoN.cjs';
7
10
  import { Params, Paginated, Application } from '@feathersjs/feathers';
8
11
  import { Socket } from 'socket.io-client';
9
12
  import '../id-DMqyogFB.cjs';
@@ -1,9 +1,12 @@
1
- import { d as Message } from '../message-DvBzHu7V.js';
2
- import { v as Session, e as Board, o as MCPServer } from '../session-De4TwIM_.js';
3
- import { e as Task, a as ContextFileListItem, b as ContextFileDetail } from '../task-DuIfiUbW.js';
1
+ import { d as Message } from '../message-Wm1fS7rs.js';
2
+ import { e as Board } from '../board-ava4cdq5.js';
3
+ import { a as ContextFileListItem, b as ContextFileDetail } from '../context-ByxGjp5l.js';
4
4
  import { b as AuthenticationResult } from '../feathers-BzHEPnpl.js';
5
- import { a as User } from '../user-BmL3kFol.js';
6
- import { a as Repo, c as Worktree } from '../repo-BoA8D6Uf.js';
5
+ import { h as MCPServer } from '../mcp-BJoCdfzv.js';
6
+ import { a as User } from '../user-CS2VnSS6.js';
7
+ import { a as Repo, c as Worktree } from '../repo-DU_q1nOJ.js';
8
+ import { a as Session } from '../session-CxdFDTYb.js';
9
+ import { c as Task } from '../task-C4bogx9k.js';
7
10
  import { Params, Paginated, Application } from '@feathersjs/feathers';
8
11
  import { Socket } from 'socket.io-client';
9
12
  import '../id-DMqyogFB.js';
@@ -0,0 +1,134 @@
1
+ import { B as BoardID, W as WorktreeID } from './id-DMqyogFB.cjs';
2
+
3
+ /**
4
+ * Board object types for canvas annotations
5
+ */
6
+ type BoardObjectType = 'text' | 'zone';
7
+ /**
8
+ * Positioned worktree card on a board
9
+ *
10
+ * Boards display worktrees as primary units. Sessions are accessed
11
+ * through the worktree card's session tree.
12
+ */
13
+ interface BoardEntityObject {
14
+ /** Unique object identifier */
15
+ object_id: string;
16
+ /** Board this entity belongs to */
17
+ board_id: BoardID;
18
+ /** Worktree reference */
19
+ worktree_id: WorktreeID;
20
+ /** Position on canvas */
21
+ position: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ /** Zone this worktree is pinned to (optional) */
26
+ zone_id?: string;
27
+ /** When this entity was added to the board */
28
+ created_at: string;
29
+ }
30
+ /**
31
+ * Text annotation object
32
+ */
33
+ interface TextBoardObject {
34
+ type: 'text';
35
+ x: number;
36
+ y: number;
37
+ width?: number;
38
+ height?: number;
39
+ content: string;
40
+ fontSize?: number;
41
+ color?: string;
42
+ background?: string;
43
+ }
44
+ /**
45
+ * Zone trigger behavior modes for worktree drops
46
+ */
47
+ type ZoneTriggerBehavior = 'always_new' | 'show_picker';
48
+ /**
49
+ * Zone trigger configuration for worktree drops
50
+ *
51
+ * When a worktree is dropped on a zone with a trigger:
52
+ * - 'always_new': Automatically create new root session and apply trigger
53
+ * - 'show_picker': Open modal to select existing session or create new one
54
+ */
55
+ interface ZoneTrigger {
56
+ /** Handlebars template for the prompt */
57
+ template: string;
58
+ /** Trigger behavior mode (default: 'show_picker') */
59
+ behavior: ZoneTriggerBehavior;
60
+ }
61
+ /**
62
+ * Zone rectangle object (for organizing sessions visually)
63
+ */
64
+ interface ZoneBoardObject {
65
+ type: 'zone';
66
+ x: number;
67
+ y: number;
68
+ width: number;
69
+ height: number;
70
+ label: string;
71
+ color?: string;
72
+ status?: string;
73
+ /** Trigger configuration for sessions dropped into this zone */
74
+ trigger?: ZoneTrigger;
75
+ }
76
+ /**
77
+ * Union type for all board objects
78
+ */
79
+ type BoardObject = TextBoardObject | ZoneBoardObject;
80
+ interface Board {
81
+ /** Unique board identifier (UUIDv7) */
82
+ board_id: BoardID;
83
+ name: string;
84
+ /**
85
+ * Optional URL-friendly slug for board
86
+ *
87
+ * Examples: "main", "experiments", "bug-fixes"
88
+ *
89
+ * Allows CLI commands like:
90
+ * agor session list --board experiments
91
+ * instead of:
92
+ * agor session list --board 01933e4a
93
+ */
94
+ slug?: string;
95
+ description?: string;
96
+ /**
97
+ * DEPRECATED: Sessions and layout are now tracked in board_objects table
98
+ *
99
+ * Query board entities via:
100
+ * - boardObjectsService.find({ query: { board_id } })
101
+ *
102
+ * Old fields removed:
103
+ * - sessions: SessionID[]
104
+ * - layout: { [sessionId: string]: { x, y, parentId? } }
105
+ */
106
+ /**
107
+ * Canvas annotation objects (text labels, zones, etc.)
108
+ *
109
+ * Keys are object IDs (e.g., "text-123", "zone-456")
110
+ * Use atomic backend methods: upsertBoardObject(), removeBoardObject()
111
+ *
112
+ * IMPORTANT: Do NOT directly replace this entire object from client.
113
+ * Use atomic operations to prevent concurrent write conflicts.
114
+ */
115
+ objects?: {
116
+ [objectId: string]: BoardObject;
117
+ };
118
+ created_at: string;
119
+ last_updated: string;
120
+ /** User ID of the user who created this board */
121
+ created_by: string;
122
+ /** Hex color for visual distinction */
123
+ color?: string;
124
+ /** Optional emoji/icon */
125
+ icon?: string;
126
+ /**
127
+ * Custom context for Handlebars templates (board-level)
128
+ * Example: { "team": "Backend", "sprint": 42, "deadline": "2025-03-15" }
129
+ * Access in templates: {{ board.context.team }}
130
+ */
131
+ custom_context?: Record<string, unknown>;
132
+ }
133
+
134
+ export type { BoardObjectType as B, TextBoardObject as T, ZoneTriggerBehavior as Z, BoardEntityObject as a, ZoneTrigger as b, ZoneBoardObject as c, BoardObject as d, Board as e };
@@ -0,0 +1,134 @@
1
+ import { B as BoardID, W as WorktreeID } from './id-DMqyogFB.js';
2
+
3
+ /**
4
+ * Board object types for canvas annotations
5
+ */
6
+ type BoardObjectType = 'text' | 'zone';
7
+ /**
8
+ * Positioned worktree card on a board
9
+ *
10
+ * Boards display worktrees as primary units. Sessions are accessed
11
+ * through the worktree card's session tree.
12
+ */
13
+ interface BoardEntityObject {
14
+ /** Unique object identifier */
15
+ object_id: string;
16
+ /** Board this entity belongs to */
17
+ board_id: BoardID;
18
+ /** Worktree reference */
19
+ worktree_id: WorktreeID;
20
+ /** Position on canvas */
21
+ position: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ /** Zone this worktree is pinned to (optional) */
26
+ zone_id?: string;
27
+ /** When this entity was added to the board */
28
+ created_at: string;
29
+ }
30
+ /**
31
+ * Text annotation object
32
+ */
33
+ interface TextBoardObject {
34
+ type: 'text';
35
+ x: number;
36
+ y: number;
37
+ width?: number;
38
+ height?: number;
39
+ content: string;
40
+ fontSize?: number;
41
+ color?: string;
42
+ background?: string;
43
+ }
44
+ /**
45
+ * Zone trigger behavior modes for worktree drops
46
+ */
47
+ type ZoneTriggerBehavior = 'always_new' | 'show_picker';
48
+ /**
49
+ * Zone trigger configuration for worktree drops
50
+ *
51
+ * When a worktree is dropped on a zone with a trigger:
52
+ * - 'always_new': Automatically create new root session and apply trigger
53
+ * - 'show_picker': Open modal to select existing session or create new one
54
+ */
55
+ interface ZoneTrigger {
56
+ /** Handlebars template for the prompt */
57
+ template: string;
58
+ /** Trigger behavior mode (default: 'show_picker') */
59
+ behavior: ZoneTriggerBehavior;
60
+ }
61
+ /**
62
+ * Zone rectangle object (for organizing sessions visually)
63
+ */
64
+ interface ZoneBoardObject {
65
+ type: 'zone';
66
+ x: number;
67
+ y: number;
68
+ width: number;
69
+ height: number;
70
+ label: string;
71
+ color?: string;
72
+ status?: string;
73
+ /** Trigger configuration for sessions dropped into this zone */
74
+ trigger?: ZoneTrigger;
75
+ }
76
+ /**
77
+ * Union type for all board objects
78
+ */
79
+ type BoardObject = TextBoardObject | ZoneBoardObject;
80
+ interface Board {
81
+ /** Unique board identifier (UUIDv7) */
82
+ board_id: BoardID;
83
+ name: string;
84
+ /**
85
+ * Optional URL-friendly slug for board
86
+ *
87
+ * Examples: "main", "experiments", "bug-fixes"
88
+ *
89
+ * Allows CLI commands like:
90
+ * agor session list --board experiments
91
+ * instead of:
92
+ * agor session list --board 01933e4a
93
+ */
94
+ slug?: string;
95
+ description?: string;
96
+ /**
97
+ * DEPRECATED: Sessions and layout are now tracked in board_objects table
98
+ *
99
+ * Query board entities via:
100
+ * - boardObjectsService.find({ query: { board_id } })
101
+ *
102
+ * Old fields removed:
103
+ * - sessions: SessionID[]
104
+ * - layout: { [sessionId: string]: { x, y, parentId? } }
105
+ */
106
+ /**
107
+ * Canvas annotation objects (text labels, zones, etc.)
108
+ *
109
+ * Keys are object IDs (e.g., "text-123", "zone-456")
110
+ * Use atomic backend methods: upsertBoardObject(), removeBoardObject()
111
+ *
112
+ * IMPORTANT: Do NOT directly replace this entire object from client.
113
+ * Use atomic operations to prevent concurrent write conflicts.
114
+ */
115
+ objects?: {
116
+ [objectId: string]: BoardObject;
117
+ };
118
+ created_at: string;
119
+ last_updated: string;
120
+ /** User ID of the user who created this board */
121
+ created_by: string;
122
+ /** Hex color for visual distinction */
123
+ color?: string;
124
+ /** Optional emoji/icon */
125
+ icon?: string;
126
+ /**
127
+ * Custom context for Handlebars templates (board-level)
128
+ * Example: { "team": "Backend", "sprint": 42, "deadline": "2025-03-15" }
129
+ * Access in templates: {{ board.context.team }}
130
+ */
131
+ custom_context?: Record<string, unknown>;
132
+ }
133
+
134
+ export type { BoardObjectType as B, TextBoardObject as T, ZoneTriggerBehavior as Z, BoardEntityObject as a, ZoneTrigger as b, ZoneBoardObject as c, BoardObject as d, Board as e };
@@ -32,13 +32,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
 
33
33
  // src/lib/ids.ts
34
34
  function generateId() {
35
- return (0, import_uuidv7.uuidv7)();
35
+ return (0, import_uuid.v4)();
36
36
  }
37
- var import_uuidv7;
37
+ var import_uuid;
38
38
  var init_ids = __esm({
39
39
  "src/lib/ids.ts"() {
40
40
  "use strict";
41
- import_uuidv7 = require("uuidv7");
41
+ import_uuid = require("uuid");
42
42
  }
43
43
  });
44
44
 
@@ -164,7 +164,7 @@ async function loadClaudeSession(sessionId, projectDir) {
164
164
 
165
165
  // src/db/index.ts
166
166
  var import_drizzle_orm14 = require("drizzle-orm");
167
- var import_bcryptjs2 = __toESM(require("bcryptjs"), 1);
167
+ var import_bcryptjs3 = __toESM(require("bcryptjs"), 1);
168
168
  init_ids();
169
169
 
170
170
  // src/db/client.ts
@@ -200,6 +200,10 @@ var sessions = (0, import_sqlite_core.sqliteTable)(
200
200
  onDelete: "cascade"
201
201
  // Cascade delete sessions when worktree is deleted
202
202
  }),
203
+ // Scheduler tracking (materialized for deduplication and retention cleanup)
204
+ scheduled_run_at: (0, import_sqlite_core.integer)("scheduled_run_at"),
205
+ // Unix timestamp (ms) - authoritative run ID
206
+ scheduled_from_worktree: (0, import_sqlite_core.integer)("scheduled_from_worktree", { mode: "boolean" }).notNull().default(false),
203
207
  // JSON blob for everything else (cross-DB via json() type)
204
208
  data: (0, import_sqlite_core.text)("data", { mode: "json" }).$type().notNull()
205
209
  },
@@ -210,7 +214,11 @@ var sessions = (0, import_sqlite_core.sqliteTable)(
210
214
  worktreeIdx: (0, import_sqlite_core.index)("sessions_worktree_idx").on(table.worktree_id),
211
215
  createdIdx: (0, import_sqlite_core.index)("sessions_created_idx").on(table.created_at),
212
216
  parentIdx: (0, import_sqlite_core.index)("sessions_parent_idx").on(table.parent_session_id),
213
- forkedIdx: (0, import_sqlite_core.index)("sessions_forked_idx").on(table.forked_from_session_id)
217
+ forkedIdx: (0, import_sqlite_core.index)("sessions_forked_idx").on(table.forked_from_session_id),
218
+ // Scheduler indexes (note: partial indexes defined in migration, not here)
219
+ scheduledFromWorktreeIdx: (0, import_sqlite_core.index)("sessions_scheduled_flag_idx").on(
220
+ table.scheduled_from_worktree
221
+ )
214
222
  })
215
223
  );
216
224
  var tasks = (0, import_sqlite_core.sqliteTable)(
@@ -264,6 +272,8 @@ var messages = (0, import_sqlite_core.sqliteTable)(
264
272
  timestamp: (0, import_sqlite_core.integer)("timestamp", { mode: "timestamp_ms" }).notNull(),
265
273
  content_preview: (0, import_sqlite_core.text)("content_preview"),
266
274
  // First 200 chars for list views
275
+ // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
276
+ parent_tool_use_id: (0, import_sqlite_core.text)("parent_tool_use_id"),
267
277
  // Full data (JSON blob)
268
278
  data: (0, import_sqlite_core.text)("data", { mode: "json" }).$type().notNull()
269
279
  },
@@ -329,6 +339,14 @@ var worktrees = (0, import_sqlite_core.sqliteTable)(
329
339
  onDelete: "set null"
330
340
  // If board is deleted, worktree remains but loses board association
331
341
  }),
342
+ // Scheduler config (materialized for efficient queries)
343
+ schedule_enabled: (0, import_sqlite_core.integer)("schedule_enabled", { mode: "boolean" }).notNull().default(false),
344
+ schedule_cron: (0, import_sqlite_core.text)("schedule_cron"),
345
+ // Cron expression (e.g., "0 9 * * 1-5")
346
+ schedule_last_triggered_at: (0, import_sqlite_core.integer)("schedule_last_triggered_at"),
347
+ // Unix timestamp (ms)
348
+ schedule_next_run_at: (0, import_sqlite_core.integer)("schedule_next_run_at"),
349
+ // Unix timestamp (ms)
332
350
  // JSON blob for everything else
333
351
  data: (0, import_sqlite_core.text)("data", { mode: "json" }).$type().notNull()
334
352
  },
@@ -340,7 +358,13 @@ var worktrees = (0, import_sqlite_core.sqliteTable)(
340
358
  createdIdx: (0, import_sqlite_core.index)("worktrees_created_idx").on(table.created_at),
341
359
  updatedIdx: (0, import_sqlite_core.index)("worktrees_updated_idx").on(table.updated_at),
342
360
  // Composite unique constraint (repo + name)
343
- uniqueRepoName: (0, import_sqlite_core.index)("worktrees_repo_name_unique").on(table.repo_id, table.name)
361
+ uniqueRepoName: (0, import_sqlite_core.index)("worktrees_repo_name_unique").on(table.repo_id, table.name),
362
+ // Scheduler indexes (note: partial indexes with WHERE clauses defined in migration)
363
+ scheduleEnabledIdx: (0, import_sqlite_core.index)("worktrees_schedule_enabled_idx").on(table.schedule_enabled),
364
+ boardScheduleIdx: (0, import_sqlite_core.index)("worktrees_board_schedule_idx").on(
365
+ table.board_id,
366
+ table.schedule_enabled
367
+ )
344
368
  })
345
369
  );
346
370
  var users = (0, import_sqlite_core.sqliteTable)(
@@ -472,7 +496,7 @@ var boardComments = (0, import_sqlite_core.sqliteTable)(
472
496
  onDelete: "set null"
473
497
  }),
474
498
  worktree_id: (0, import_sqlite_core.text)("worktree_id", { length: 36 }).references(() => worktrees.worktree_id, {
475
- onDelete: "set null"
499
+ onDelete: "cascade"
476
500
  }),
477
501
  // Content (materialized for display)
478
502
  content: (0, import_sqlite_core.text)("content").notNull(),
@@ -504,7 +528,13 @@ var boardComments = (0, import_sqlite_core.sqliteTable)(
504
528
  })
505
529
  );
506
530
 
531
+ // src/db/encryption.ts
532
+ var import_node_crypto = require("crypto");
533
+
507
534
  // src/db/migrate.ts
535
+ var import_node_path2 = require("path");
536
+ var import_node_url = require("url");
537
+ var import_bcryptjs = __toESM(require("bcryptjs"), 1);
508
538
  var import_drizzle_orm2 = require("drizzle-orm");
509
539
  var import_migrator = require("drizzle-orm/libsql/migrator");
510
540
 
@@ -560,13 +590,13 @@ var import_drizzle_orm12 = require("drizzle-orm");
560
590
  init_ids();
561
591
 
562
592
  // src/db/user-utils.ts
563
- var import_bcryptjs = __toESM(require("bcryptjs"), 1);
593
+ var import_bcryptjs2 = __toESM(require("bcryptjs"), 1);
564
594
  var import_drizzle_orm13 = require("drizzle-orm");
565
595
  init_ids();
566
596
 
567
597
  // src/db/index.ts
568
- var compare = import_bcryptjs2.default.compare;
569
- var hash = import_bcryptjs2.default.hash;
598
+ var compare = import_bcryptjs3.default.compare;
599
+ var hash = import_bcryptjs3.default.hash;
570
600
 
571
601
  // src/claude/message-converter.ts
572
602
  function transcriptToMessage(transcript, sessionId, index2) {
@@ -1,6 +1,7 @@
1
- import { d as Message } from '../message-BoxZISHg.cjs';
1
+ import { d as Message } from '../message-B1tv5qyO.cjs';
2
2
  import { a as SessionID } from '../id-DMqyogFB.cjs';
3
- import { T as TaskStatus, e as Task } from '../task-BIEgT1DK.cjs';
3
+ import { T as TaskStatus, c as Task } from '../task-sTuyYLoN.cjs';
4
+ import '../context-ByxGjp5l.cjs';
4
5
 
5
6
  /**
6
7
  * Claude Code transcript parser
@@ -1,6 +1,7 @@
1
- import { d as Message } from '../message-DvBzHu7V.js';
1
+ import { d as Message } from '../message-Wm1fS7rs.js';
2
2
  import { a as SessionID } from '../id-DMqyogFB.js';
3
- import { T as TaskStatus, e as Task } from '../task-DuIfiUbW.js';
3
+ import { T as TaskStatus, c as Task } from '../task-C4bogx9k.js';
4
+ import '../context-ByxGjp5l.js';
4
5
 
5
6
  /**
6
7
  * Claude Code transcript parser