agor-live 0.7.2 → 0.7.4

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 (86) hide show
  1. package/dist/cli/commands/db/migrate.js +55 -3
  2. package/dist/cli/commands/repo/add.js +15 -2
  3. package/dist/core/{agentic-tool-BkgiidIe.d.cts → agentic-tool-Beqe459E.d.cts} +11 -2
  4. package/dist/core/{agentic-tool-hY49SjX4.d.ts → agentic-tool-DQc61m9k.d.ts} +11 -2
  5. package/dist/core/api/index.d.cts +6 -10
  6. package/dist/core/api/index.d.ts +6 -10
  7. package/dist/core/claude/index.cjs +19 -2
  8. package/dist/core/claude/index.d.cts +2 -2
  9. package/dist/core/claude/index.d.ts +2 -2
  10. package/dist/core/claude/index.js +19 -2
  11. package/dist/core/{client-BeMnWEfJ.d.cts → client-C9LJu52s.d.cts} +163 -16
  12. package/dist/core/{client-WZqLuIZg.d.ts → client-CBvzDnJx.d.ts} +163 -16
  13. package/dist/core/config/browser.cjs +8 -1
  14. package/dist/core/config/browser.d.cts +26 -3
  15. package/dist/core/config/browser.d.ts +26 -3
  16. package/dist/core/config/browser.js +7 -1
  17. package/dist/core/config/index.cjs +27 -3
  18. package/dist/core/config/index.d.cts +7 -7
  19. package/dist/core/config/index.d.ts +7 -7
  20. package/dist/core/config/index.js +26 -3
  21. package/dist/core/db/index.cjs +181 -8
  22. package/dist/core/db/index.d.cts +59 -12
  23. package/dist/core/db/index.d.ts +59 -12
  24. package/dist/core/db/index.js +178 -8
  25. package/dist/core/drizzle/0004_add_static_urls.sql +5 -0
  26. package/dist/core/drizzle/0005_clammy_mole_man.sql +3 -0
  27. package/dist/core/drizzle/meta/0004_snapshot.json +1344 -0
  28. package/dist/core/drizzle/meta/0005_snapshot.json +1363 -0
  29. package/dist/core/drizzle/meta/_journal.json +14 -0
  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/index.cjs +191 -10
  33. package/dist/core/index.d.cts +10 -10
  34. package/dist/core/index.d.ts +10 -10
  35. package/dist/core/index.js +187 -10
  36. package/dist/core/{message-B1tv5qyO.d.cts → message-2XWJyHm9.d.cts} +14 -4
  37. package/dist/core/{message-Wm1fS7rs.d.ts → message-CvkDJT8d.d.ts} +14 -4
  38. package/dist/core/package.json +10 -0
  39. package/dist/core/permissions/index.d.cts +1 -1
  40. package/dist/core/permissions/index.d.ts +1 -1
  41. package/dist/core/{repo-Cb002or9.d.cts → repo-Dg2-wav9.d.cts} +11 -11
  42. package/dist/core/{repo-mJfbv6xB.d.ts → repo-zsilYRNq.d.ts} +11 -11
  43. package/dist/core/seed/index.cjs +1497 -0
  44. package/dist/core/seed/index.d.cts +60 -0
  45. package/dist/core/seed/index.d.ts +60 -0
  46. package/dist/core/seed/index.js +1465 -0
  47. package/dist/core/{session-j-skJz_m.d.cts → session-BasJ-_Qb.d.cts} +35 -3
  48. package/dist/core/{session-EYs7DP3G.d.ts → session-Bw1plufc.d.ts} +35 -3
  49. package/dist/core/{task-sTuyYLoN.d.cts → task-2w6W9cra.d.cts} +7 -0
  50. package/dist/core/{task-C4bogx9k.d.ts → task-o367fWBe.d.ts} +7 -0
  51. package/dist/core/tools/index.cjs +842 -298
  52. package/dist/core/tools/index.d.cts +227 -13
  53. package/dist/core/tools/index.d.ts +227 -13
  54. package/dist/core/tools/index.js +841 -299
  55. package/dist/core/types/index.cjs +2 -1
  56. package/dist/core/types/index.d.cts +7 -7
  57. package/dist/core/types/index.d.ts +7 -7
  58. package/dist/core/types/index.js +2 -1
  59. package/dist/core/{user-DB3ViAaB.d.ts → user-C0513NmD.d.ts} +3 -2
  60. package/dist/core/{user-DBq-aJq5.d.cts → user-C78ebiEP.d.cts} +3 -2
  61. package/dist/core/utils/context-window.cjs +94 -0
  62. package/dist/core/utils/context-window.d.cts +149 -0
  63. package/dist/core/utils/context-window.d.ts +149 -0
  64. package/dist/core/utils/context-window.js +65 -0
  65. package/dist/core/utils/permission-mode-mapper.d.cts +2 -2
  66. package/dist/core/utils/permission-mode-mapper.d.ts +2 -2
  67. package/dist/core/utils/pricing.cjs +8 -0
  68. package/dist/core/utils/pricing.d.cts +1 -1
  69. package/dist/core/utils/pricing.d.ts +1 -1
  70. package/dist/core/utils/pricing.js +8 -0
  71. package/dist/core/{worktrees-_SyzlCFc.d.ts → worktrees-BNlkflxB.d.ts} +22 -4
  72. package/dist/core/{worktrees-BmxS9Cbv.d.cts → worktrees-CMGq2xZ_.d.cts} +22 -4
  73. package/dist/daemon/index.js +503 -140
  74. package/dist/daemon/services/config.d.ts +1 -1
  75. package/dist/daemon/services/config.js +14 -1
  76. package/dist/daemon/services/repos.d.ts +0 -4
  77. package/dist/daemon/services/repos.js +39 -26
  78. package/dist/daemon/services/sessions.d.ts +8 -2
  79. package/dist/daemon/services/sessions.js +52 -5
  80. package/dist/daemon/services/worktrees.d.ts +0 -6
  81. package/dist/daemon/services/worktrees.js +11 -53
  82. package/dist/ui/assets/index-D-C5QSdw.js +631 -0
  83. package/dist/ui/index.html +1 -1
  84. package/package.json +1 -1
  85. package/dist/core/drizzle/0001_complex_the_call.sql +0 -10
  86. package/dist/ui/assets/index-Dmo92jKC.js +0 -623
@@ -1,7 +1,7 @@
1
1
  // src/commands/db/migrate.ts
2
2
  import { homedir } from "os";
3
3
  import { join } from "path";
4
- import { createDatabase, runMigrations } from "@agor/core/db";
4
+ import { checkMigrationStatus, createDatabase, runMigrations } from "@agor/core/db";
5
5
  import { Command } from "@oclif/core";
6
6
  import chalk from "chalk";
7
7
  var DbMigrate = class extends Command {
@@ -10,10 +10,62 @@ var DbMigrate = class extends Command {
10
10
  async run() {
11
11
  try {
12
12
  const dbPath = process.env.AGOR_DB_PATH || `file:${join(homedir(), ".agor", "agor.db")}`;
13
- this.log("Running database migrations...");
13
+ const dbFilePath = dbPath.replace("file:", "");
14
+ this.log(chalk.bold("\u{1F50D} Checking database migration status..."));
15
+ this.log("");
14
16
  const db = createDatabase({ url: dbPath });
17
+ const status = await checkMigrationStatus(db);
18
+ if (!status.hasPending) {
19
+ this.log(chalk.green("\u2713") + " Database is already up to date!");
20
+ this.log("");
21
+ this.log(`Applied migrations (${status.applied.length}):`);
22
+ status.applied.forEach((tag) => {
23
+ this.log(` ${chalk.dim("\u2022")} ${tag}`);
24
+ });
25
+ return;
26
+ }
27
+ this.log(chalk.yellow("\u26A0\uFE0F Found pending migrations:"));
28
+ this.log("");
29
+ status.pending.forEach((tag) => {
30
+ this.log(` ${chalk.yellow("+")} ${tag}`);
31
+ });
32
+ this.log("");
33
+ this.log(chalk.bold("\u26A0\uFE0F IMPORTANT: Backup your database before proceeding!"));
34
+ this.log("");
35
+ this.log(`Run this command to create a backup:`);
36
+ this.log(chalk.cyan(` cp ${dbFilePath} ${dbFilePath}.backup-$(date +%s)`));
37
+ this.log("");
38
+ this.log("Press Ctrl+C to cancel, or any key to continue...");
39
+ this.log("");
40
+ if (process.stdin.isTTY) {
41
+ await new Promise((resolve) => {
42
+ process.stdin.once("data", () => resolve());
43
+ process.stdin.setRawMode(true);
44
+ process.stdin.resume();
45
+ });
46
+ process.stdin.setRawMode(false);
47
+ process.stdin.pause();
48
+ } else {
49
+ await new Promise((resolve) => {
50
+ process.stdin.once("data", () => resolve());
51
+ process.stdin.resume();
52
+ });
53
+ process.stdin.pause();
54
+ }
55
+ this.log(chalk.bold("\u{1F504} Running migrations..."));
56
+ this.log("");
15
57
  await runMigrations(db);
16
- this.log(`${chalk.green("\u2713")} Database is up to date`);
58
+ const afterStatus = await checkMigrationStatus(db);
59
+ if (afterStatus.hasPending) {
60
+ this.error(
61
+ `Migration verification failed! Still have ${afterStatus.pending.length} pending migration(s): ${afterStatus.pending.join(", ")}`
62
+ );
63
+ }
64
+ this.log("");
65
+ this.log(chalk.green("\u2713") + " All migrations completed successfully!");
66
+ this.log("");
67
+ this.log("You can now start the daemon with:");
68
+ this.log(chalk.cyan(" agor daemon start"));
17
69
  } catch (error) {
18
70
  this.error(
19
71
  `Failed to run migrations: ${error instanceof Error ? error.message : String(error)}`
@@ -54,7 +54,7 @@ var init_auth = __esm({
54
54
  });
55
55
 
56
56
  // src/commands/repo/add.ts
57
- import { extractSlugFromUrl, isValidSlug } from "@agor/core/config";
57
+ import { extractSlugFromUrl, isValidGitUrl, isValidSlug } from "@agor/core/config";
58
58
  import { Args, Flags } from "@oclif/core";
59
59
  import chalk2 from "chalk";
60
60
 
@@ -160,6 +160,18 @@ var RepoAdd = class _RepoAdd extends BaseCommand {
160
160
  const { args, flags } = await this.parse(_RepoAdd);
161
161
  const client = await this.connectToDaemon();
162
162
  try {
163
+ if (!isValidGitUrl(args.url)) {
164
+ await this.cleanupClient(client);
165
+ this.error(
166
+ `Invalid git URL: ${args.url}
167
+
168
+ Please provide a valid git repository URL:
169
+ SSH: ${chalk2.cyan("git@github.com:apache/superset.git")}
170
+ HTTPS: ${chalk2.cyan("https://github.com/apache/superset.git")}
171
+
172
+ Note: Web page URLs like ${chalk2.dim("github.com/org/repo")} are not valid.`
173
+ );
174
+ }
163
175
  let slug = flags.slug;
164
176
  if (!slug) {
165
177
  slug = extractSlugFromUrl(args.url);
@@ -170,7 +182,8 @@ var RepoAdd = class _RepoAdd extends BaseCommand {
170
182
  await this.cleanupClient(client);
171
183
  this.error(
172
184
  `Invalid slug format: ${slug}
173
- Slug must be in format "org/name" (e.g., "apache/superset")
185
+ Slug must be in format "org/name" with alphanumeric characters, dots, hyphens, or underscores
186
+ Examples: ${chalk2.cyan("apache/superset")}, ${chalk2.cyan("my-org/my.repo")}
174
187
  Use --slug to specify a custom slug.`
175
188
  );
176
189
  }
@@ -7,11 +7,12 @@ import { A as AgenticToolID } from './id-DMqyogFB.cjs';
7
7
  * - claude-code: Anthropic's Claude Code CLI
8
8
  * - codex: OpenAI's Codex CLI
9
9
  * - gemini: Google's Gemini Code Assist
10
+ * - opencode: Open-source terminal-based AI assistant with 75+ LLM providers
10
11
  *
11
12
  * Not to be confused with "execution tools" (Bash, Write, Read, etc.)
12
13
  * which are the primitives that agentic tools use to perform work.
13
14
  */
14
- type AgenticToolName = 'claude-code' | 'codex' | 'gemini';
15
+ type AgenticToolName = 'claude-code' | 'codex' | 'gemini' | 'opencode';
15
16
  /**
16
17
  * Agentic tool metadata for UI display
17
18
  *
@@ -40,6 +41,14 @@ type ClaudeCodePermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions'
40
41
  * Unified permission model - single mode controls tool approval behavior.
41
42
  */
42
43
  type GeminiPermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions';
44
+ /**
45
+ * OpenCode permission modes (via OpenCode server SDK)
46
+ *
47
+ * Unified permission model - single mode controls tool approval behavior.
48
+ * OpenCode auto-approves permissions during automation, so modes primarily affect
49
+ * interactive prompting when user is present.
50
+ */
51
+ type OpenCodePermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions';
43
52
  /**
44
53
  * Codex permission modes (legacy - now split into sandboxMode + approvalPolicy)
45
54
  *
@@ -84,4 +93,4 @@ type CodexApprovalPolicy = 'untrusted' | 'on-request' | 'on-failure' | 'never';
84
93
  */
85
94
  type CodexNetworkAccess = boolean;
86
95
 
87
- export type { AgenticToolName as A, ClaudeCodePermissionMode as C, GeminiPermissionMode as G, CodexPermissionMode as a, AgenticTool as b, CodexSandboxMode as c, CodexApprovalPolicy as d, CodexNetworkAccess as e };
96
+ export type { AgenticToolName as A, ClaudeCodePermissionMode as C, GeminiPermissionMode as G, OpenCodePermissionMode as O, CodexPermissionMode as a, AgenticTool as b, CodexSandboxMode as c, CodexApprovalPolicy as d, CodexNetworkAccess as e };
@@ -7,11 +7,12 @@ import { A as AgenticToolID } from './id-DMqyogFB.js';
7
7
  * - claude-code: Anthropic's Claude Code CLI
8
8
  * - codex: OpenAI's Codex CLI
9
9
  * - gemini: Google's Gemini Code Assist
10
+ * - opencode: Open-source terminal-based AI assistant with 75+ LLM providers
10
11
  *
11
12
  * Not to be confused with "execution tools" (Bash, Write, Read, etc.)
12
13
  * which are the primitives that agentic tools use to perform work.
13
14
  */
14
- type AgenticToolName = 'claude-code' | 'codex' | 'gemini';
15
+ type AgenticToolName = 'claude-code' | 'codex' | 'gemini' | 'opencode';
15
16
  /**
16
17
  * Agentic tool metadata for UI display
17
18
  *
@@ -40,6 +41,14 @@ type ClaudeCodePermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions'
40
41
  * Unified permission model - single mode controls tool approval behavior.
41
42
  */
42
43
  type GeminiPermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions';
44
+ /**
45
+ * OpenCode permission modes (via OpenCode server SDK)
46
+ *
47
+ * Unified permission model - single mode controls tool approval behavior.
48
+ * OpenCode auto-approves permissions during automation, so modes primarily affect
49
+ * interactive prompting when user is present.
50
+ */
51
+ type OpenCodePermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions';
43
52
  /**
44
53
  * Codex permission modes (legacy - now split into sandboxMode + approvalPolicy)
45
54
  *
@@ -84,4 +93,4 @@ type CodexApprovalPolicy = 'untrusted' | 'on-request' | 'on-failure' | 'never';
84
93
  */
85
94
  type CodexNetworkAccess = boolean;
86
95
 
87
- export type { AgenticToolName as A, ClaudeCodePermissionMode as C, GeminiPermissionMode as G, CodexPermissionMode as a, AgenticTool as b, CodexSandboxMode as c, CodexApprovalPolicy as d, CodexNetworkAccess as e };
96
+ export type { AgenticToolName as A, ClaudeCodePermissionMode as C, GeminiPermissionMode as G, OpenCodePermissionMode as O, CodexPermissionMode as a, AgenticTool as b, CodexSandboxMode as c, CodexApprovalPolicy as d, CodexNetworkAccess as e };
@@ -1,16 +1,16 @@
1
- import { d as Message } from '../message-B1tv5qyO.cjs';
1
+ import { e as Message } from '../message-2XWJyHm9.cjs';
2
2
  import { e as Board } from '../board-Oa2OJ-K3.cjs';
3
3
  import { a as ContextFileListItem, b as ContextFileDetail } from '../context-ByxGjp5l.cjs';
4
4
  import { b as AuthenticationResult } from '../feathers-BzHEPnpl.cjs';
5
5
  import { h as MCPServer } from '../mcp-DpJnAKie.cjs';
6
- import { c as User } from '../user-DBq-aJq5.cjs';
7
- import { a as Repo, c as Worktree } from '../repo-Cb002or9.cjs';
8
- import { a as Session } from '../session-j-skJz_m.cjs';
9
- import { c as Task } from '../task-sTuyYLoN.cjs';
6
+ import { c as User } from '../user-C78ebiEP.cjs';
7
+ import { a as Repo, c as Worktree } from '../repo-Dg2-wav9.cjs';
8
+ import { a as Session } from '../session-BasJ-_Qb.cjs';
9
+ import { c as Task } from '../task-2w6W9cra.cjs';
10
10
  import { Params, Paginated, Application } from '@feathersjs/feathers';
11
11
  import { Socket } from 'socket.io-client';
12
12
  import '../id-DMqyogFB.cjs';
13
- import '../agentic-tool-BkgiidIe.cjs';
13
+ import '../agentic-tool-Beqe459E.cjs';
14
14
 
15
15
  /**
16
16
  * Feathers Client for Agor
@@ -173,10 +173,6 @@ interface WorktreesService extends AgorService<Worktree> {
173
173
  * Check environment health
174
174
  */
175
175
  checkHealth(id: string, params?: Params): Promise<Worktree>;
176
- /**
177
- * Recompute access URLs
178
- */
179
- recomputeAccessUrls(id: string, params?: Params): Promise<Worktree>;
180
176
  }
181
177
  /**
182
178
  * Agor client with socket.io connection exposed for lifecycle management
@@ -1,16 +1,16 @@
1
- import { d as Message } from '../message-Wm1fS7rs.js';
1
+ import { e as Message } from '../message-CvkDJT8d.js';
2
2
  import { e as Board } from '../board-ava4cdq5.js';
3
3
  import { a as ContextFileListItem, b as ContextFileDetail } from '../context-ByxGjp5l.js';
4
4
  import { b as AuthenticationResult } from '../feathers-BzHEPnpl.js';
5
5
  import { h as MCPServer } from '../mcp-BJoCdfzv.js';
6
- import { c as User } from '../user-DB3ViAaB.js';
7
- import { a as Repo, c as Worktree } from '../repo-mJfbv6xB.js';
8
- import { a as Session } from '../session-EYs7DP3G.js';
9
- import { c as Task } from '../task-C4bogx9k.js';
6
+ import { c as User } from '../user-C0513NmD.js';
7
+ import { a as Repo, c as Worktree } from '../repo-zsilYRNq.js';
8
+ import { a as Session } from '../session-Bw1plufc.js';
9
+ import { c as Task } from '../task-o367fWBe.js';
10
10
  import { Params, Paginated, Application } from '@feathersjs/feathers';
11
11
  import { Socket } from 'socket.io-client';
12
12
  import '../id-DMqyogFB.js';
13
- import '../agentic-tool-hY49SjX4.js';
13
+ import '../agentic-tool-DQc61m9k.js';
14
14
 
15
15
  /**
16
16
  * Feathers Client for Agor
@@ -173,10 +173,6 @@ interface WorktreesService extends AgorService<Worktree> {
173
173
  * Check environment health
174
174
  */
175
175
  checkHealth(id: string, params?: Params): Promise<Worktree>;
176
- /**
177
- * Recompute access URLs
178
- */
179
- recomputeAccessUrls(id: string, params?: Params): Promise<Worktree>;
180
176
  }
181
177
  /**
182
178
  * Agor client with socket.io connection exposed for lifecycle management
@@ -188,7 +188,7 @@ var sessions = (0, import_sqlite_core.sqliteTable)(
188
188
  enum: ["idle", "running", "awaiting_permission", "completed", "failed"]
189
189
  }).notNull(),
190
190
  agentic_tool: (0, import_sqlite_core.text)("agentic_tool", {
191
- enum: ["claude-code", "codex", "gemini"]
191
+ enum: ["claude-code", "codex", "gemini", "opencode"]
192
192
  }).notNull(),
193
193
  board_id: (0, import_sqlite_core.text)("board_id", { length: 36 }),
194
194
  // NULL = no board
@@ -274,6 +274,11 @@ var messages = (0, import_sqlite_core.sqliteTable)(
274
274
  // First 200 chars for list views
275
275
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
276
276
  parent_tool_use_id: (0, import_sqlite_core.text)("parent_tool_use_id"),
277
+ // Message queueing fields
278
+ status: (0, import_sqlite_core.text)("status", { enum: ["queued"] }),
279
+ // 'queued' or null (normal message)
280
+ queue_position: (0, import_sqlite_core.integer)("queue_position"),
281
+ // Position in queue (1, 2, 3, ...)
277
282
  // Full data (JSON blob)
278
283
  data: (0, import_sqlite_core.text)("data", { mode: "json" }).$type().notNull()
279
284
  },
@@ -281,7 +286,8 @@ var messages = (0, import_sqlite_core.sqliteTable)(
281
286
  // Indexes for efficient lookups
282
287
  sessionIdx: (0, import_sqlite_core.index)("messages_session_id_idx").on(table.session_id),
283
288
  taskIdx: (0, import_sqlite_core.index)("messages_task_id_idx").on(table.task_id),
284
- sessionIndexIdx: (0, import_sqlite_core.index)("messages_session_index_idx").on(table.session_id, table.index)
289
+ sessionIndexIdx: (0, import_sqlite_core.index)("messages_session_index_idx").on(table.session_id, table.index),
290
+ queueIdx: (0, import_sqlite_core.index)("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
285
291
  })
286
292
  );
287
293
  var boards = (0, import_sqlite_core.sqliteTable)(
@@ -334,6 +340,17 @@ var worktrees = (0, import_sqlite_core.sqliteTable)(
334
340
  // Current branch/tag/commit
335
341
  worktree_unique_id: (0, import_sqlite_core.integer)("worktree_unique_id").notNull(),
336
342
  // Auto-assigned sequential ID for templates
343
+ // Environment configuration (static, initialized from templates, then user-editable)
344
+ start_command: (0, import_sqlite_core.text)("start_command"),
345
+ // Start command (initialized from repo's up_command template)
346
+ stop_command: (0, import_sqlite_core.text)("stop_command"),
347
+ // Stop command (initialized from repo's down_command template)
348
+ health_check_url: (0, import_sqlite_core.text)("health_check_url"),
349
+ // Health check URL (initialized from repo's health_check.url_template)
350
+ app_url: (0, import_sqlite_core.text)("app_url"),
351
+ // Application URL (initialized from repo's app_url_template)
352
+ logs_command: (0, import_sqlite_core.text)("logs_command"),
353
+ // Logs command (initialized from repo's logs_command template)
337
354
  // Board relationship (nullable - worktrees can exist without boards)
338
355
  board_id: (0, import_sqlite_core.text)("board_id", { length: 36 }).references(() => boards.board_id, {
339
356
  onDelete: "set null"
@@ -1,6 +1,6 @@
1
- import { d as Message } from '../message-B1tv5qyO.cjs';
1
+ import { e as Message } from '../message-2XWJyHm9.cjs';
2
2
  import { a as SessionID } from '../id-DMqyogFB.cjs';
3
- import { T as TaskStatus, c as Task } from '../task-sTuyYLoN.cjs';
3
+ import { T as TaskStatus, c as Task } from '../task-2w6W9cra.cjs';
4
4
  import '../context-ByxGjp5l.cjs';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
- import { d as Message } from '../message-Wm1fS7rs.js';
1
+ import { e as Message } from '../message-CvkDJT8d.js';
2
2
  import { a as SessionID } from '../id-DMqyogFB.js';
3
- import { T as TaskStatus, c as Task } from '../task-C4bogx9k.js';
3
+ import { T as TaskStatus, c as Task } from '../task-o367fWBe.js';
4
4
  import '../context-ByxGjp5l.js';
5
5
 
6
6
  /**
@@ -145,7 +145,7 @@ var sessions = sqliteTable(
145
145
  enum: ["idle", "running", "awaiting_permission", "completed", "failed"]
146
146
  }).notNull(),
147
147
  agentic_tool: text("agentic_tool", {
148
- enum: ["claude-code", "codex", "gemini"]
148
+ enum: ["claude-code", "codex", "gemini", "opencode"]
149
149
  }).notNull(),
150
150
  board_id: text("board_id", { length: 36 }),
151
151
  // NULL = no board
@@ -231,6 +231,11 @@ var messages = sqliteTable(
231
231
  // First 200 chars for list views
232
232
  // Parent tool use ID (for nested tool calls - e.g., Task tool spawning Read/Grep)
233
233
  parent_tool_use_id: text("parent_tool_use_id"),
234
+ // Message queueing fields
235
+ status: text("status", { enum: ["queued"] }),
236
+ // 'queued' or null (normal message)
237
+ queue_position: integer("queue_position"),
238
+ // Position in queue (1, 2, 3, ...)
234
239
  // Full data (JSON blob)
235
240
  data: text("data", { mode: "json" }).$type().notNull()
236
241
  },
@@ -238,7 +243,8 @@ var messages = sqliteTable(
238
243
  // Indexes for efficient lookups
239
244
  sessionIdx: index("messages_session_id_idx").on(table.session_id),
240
245
  taskIdx: index("messages_task_id_idx").on(table.task_id),
241
- sessionIndexIdx: index("messages_session_index_idx").on(table.session_id, table.index)
246
+ sessionIndexIdx: index("messages_session_index_idx").on(table.session_id, table.index),
247
+ queueIdx: index("messages_queue_idx").on(table.session_id, table.status, table.queue_position)
242
248
  })
243
249
  );
244
250
  var boards = sqliteTable(
@@ -291,6 +297,17 @@ var worktrees = sqliteTable(
291
297
  // Current branch/tag/commit
292
298
  worktree_unique_id: integer("worktree_unique_id").notNull(),
293
299
  // Auto-assigned sequential ID for templates
300
+ // Environment configuration (static, initialized from templates, then user-editable)
301
+ start_command: text("start_command"),
302
+ // Start command (initialized from repo's up_command template)
303
+ stop_command: text("stop_command"),
304
+ // Stop command (initialized from repo's down_command template)
305
+ health_check_url: text("health_check_url"),
306
+ // Health check URL (initialized from repo's health_check.url_template)
307
+ app_url: text("app_url"),
308
+ // Application URL (initialized from repo's app_url_template)
309
+ logs_command: text("logs_command"),
310
+ // Logs command (initialized from repo's logs_command template)
294
311
  // Board relationship (nullable - worktrees can exist without boards)
295
312
  board_id: text("board_id", { length: 36 }).references(() => boards.board_id, {
296
313
  onDelete: "set null"
@@ -1,9 +1,9 @@
1
1
  import { LibSQLDatabase } from 'drizzle-orm/libsql';
2
- import { d as Message } from './message-B1tv5qyO.cjs';
3
- import { c as CodexSandboxMode, d as CodexApprovalPolicy } from './agentic-tool-BkgiidIe.cjs';
2
+ import { e as Message } from './message-2XWJyHm9.cjs';
3
+ import { c as CodexSandboxMode, d as CodexApprovalPolicy } from './agentic-tool-Beqe459E.cjs';
4
4
  import { d as BoardObject } from './board-Oa2OJ-K3.cjs';
5
- import { a as Session, P as PermissionMode } from './session-j-skJz_m.cjs';
6
- import { c as Task } from './task-sTuyYLoN.cjs';
5
+ import { a as Session, P as PermissionMode } from './session-BasJ-_Qb.cjs';
6
+ import { c as Task } from './task-2w6W9cra.cjs';
7
7
  import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
8
8
 
9
9
  /**
@@ -113,14 +113,14 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
113
113
  tableName: "sessions";
114
114
  dataType: "string";
115
115
  columnType: "SQLiteText";
116
- data: "claude-code" | "codex" | "gemini";
116
+ data: "claude-code" | "codex" | "gemini" | "opencode";
117
117
  driverParam: string;
118
118
  notNull: true;
119
119
  hasDefault: false;
120
120
  isPrimaryKey: false;
121
121
  isAutoincrement: false;
122
122
  hasRuntimeDefault: false;
123
- enumValues: ["claude-code", "codex", "gemini"];
123
+ enumValues: ["claude-code", "codex", "gemini", "opencode"];
124
124
  baseColumn: never;
125
125
  identity: undefined;
126
126
  generated: undefined;
@@ -260,7 +260,6 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
260
260
  tasks: string[];
261
261
  message_count: number;
262
262
  permission_config?: {
263
- allowedTools?: string[];
264
263
  mode?: PermissionMode;
265
264
  codex?: {
266
265
  sandboxMode: CodexSandboxMode;
@@ -268,6 +267,9 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
268
267
  };
269
268
  };
270
269
  model_config?: Session["model_config"];
270
+ current_context_usage?: number;
271
+ context_window_limit?: number;
272
+ last_context_update_at?: string;
271
273
  custom_context?: Record<string, unknown> & {
272
274
  scheduled_run?: {
273
275
  rendered_prompt: string;
@@ -309,7 +311,6 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
309
311
  tasks: string[];
310
312
  message_count: number;
311
313
  permission_config?: {
312
- allowedTools?: string[];
313
314
  mode?: PermissionMode;
314
315
  codex?: {
315
316
  sandboxMode: CodexSandboxMode;
@@ -317,6 +318,9 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
317
318
  };
318
319
  };
319
320
  model_config?: Session["model_config"];
321
+ current_context_usage?: number;
322
+ context_window_limit?: number;
323
+ last_context_update_at?: string;
320
324
  custom_context?: Record<string, unknown> & {
321
325
  scheduled_run?: {
322
326
  rendered_prompt: string;
@@ -467,6 +471,7 @@ declare const tasks: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
467
471
  agent_session_id?: string;
468
472
  context_window?: number;
469
473
  context_window_limit?: number;
474
+ model_usage?: Task["model_usage"];
470
475
  report?: Task["report"];
471
476
  permission_request?: Task["permission_request"];
472
477
  };
@@ -493,6 +498,7 @@ declare const tasks: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
493
498
  agent_session_id?: string;
494
499
  context_window?: number;
495
500
  context_window_limit?: number;
501
+ model_usage?: Task["model_usage"];
496
502
  report?: Task["report"];
497
503
  permission_request?: Task["permission_request"];
498
504
  };
@@ -694,6 +700,42 @@ declare const messages: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
694
700
  }, {}, {
695
701
  length: number | undefined;
696
702
  }>;
703
+ status: drizzle_orm_sqlite_core.SQLiteColumn<{
704
+ name: "status";
705
+ tableName: "messages";
706
+ dataType: "string";
707
+ columnType: "SQLiteText";
708
+ data: "queued";
709
+ driverParam: string;
710
+ notNull: false;
711
+ hasDefault: false;
712
+ isPrimaryKey: false;
713
+ isAutoincrement: false;
714
+ hasRuntimeDefault: false;
715
+ enumValues: ["queued"];
716
+ baseColumn: never;
717
+ identity: undefined;
718
+ generated: undefined;
719
+ }, {}, {
720
+ length: number | undefined;
721
+ }>;
722
+ queue_position: drizzle_orm_sqlite_core.SQLiteColumn<{
723
+ name: "queue_position";
724
+ tableName: "messages";
725
+ dataType: "number";
726
+ columnType: "SQLiteInteger";
727
+ data: number;
728
+ driverParam: number;
729
+ notNull: false;
730
+ hasDefault: false;
731
+ isPrimaryKey: false;
732
+ isAutoincrement: false;
733
+ hasRuntimeDefault: false;
734
+ enumValues: undefined;
735
+ baseColumn: never;
736
+ identity: undefined;
737
+ generated: undefined;
738
+ }, {}, {}>;
697
739
  data: drizzle_orm_sqlite_core.SQLiteColumn<{
698
740
  name: "data";
699
741
  tableName: "messages";
@@ -974,9 +1016,6 @@ declare const repos: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
974
1016
  url_template?: string;
975
1017
  };
976
1018
  };
977
- permission_config?: {
978
- allowedTools?: string[];
979
- };
980
1019
  };
981
1020
  driverParam: string;
982
1021
  notNull: true;
@@ -1002,9 +1041,6 @@ declare const repos: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1002
1041
  url_template?: string;
1003
1042
  };
1004
1043
  };
1005
- permission_config?: {
1006
- allowedTools?: string[];
1007
- };
1008
1044
  };
1009
1045
  }>;
1010
1046
  };
@@ -1167,6 +1203,101 @@ declare const worktrees: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1167
1203
  identity: undefined;
1168
1204
  generated: undefined;
1169
1205
  }, {}, {}>;
1206
+ start_command: drizzle_orm_sqlite_core.SQLiteColumn<{
1207
+ name: "start_command";
1208
+ tableName: "worktrees";
1209
+ dataType: "string";
1210
+ columnType: "SQLiteText";
1211
+ data: string;
1212
+ driverParam: string;
1213
+ notNull: false;
1214
+ hasDefault: false;
1215
+ isPrimaryKey: false;
1216
+ isAutoincrement: false;
1217
+ hasRuntimeDefault: false;
1218
+ enumValues: [string, ...string[]];
1219
+ baseColumn: never;
1220
+ identity: undefined;
1221
+ generated: undefined;
1222
+ }, {}, {
1223
+ length: number | undefined;
1224
+ }>;
1225
+ stop_command: drizzle_orm_sqlite_core.SQLiteColumn<{
1226
+ name: "stop_command";
1227
+ tableName: "worktrees";
1228
+ dataType: "string";
1229
+ columnType: "SQLiteText";
1230
+ data: string;
1231
+ driverParam: string;
1232
+ notNull: false;
1233
+ hasDefault: false;
1234
+ isPrimaryKey: false;
1235
+ isAutoincrement: false;
1236
+ hasRuntimeDefault: false;
1237
+ enumValues: [string, ...string[]];
1238
+ baseColumn: never;
1239
+ identity: undefined;
1240
+ generated: undefined;
1241
+ }, {}, {
1242
+ length: number | undefined;
1243
+ }>;
1244
+ health_check_url: drizzle_orm_sqlite_core.SQLiteColumn<{
1245
+ name: "health_check_url";
1246
+ tableName: "worktrees";
1247
+ dataType: "string";
1248
+ columnType: "SQLiteText";
1249
+ data: string;
1250
+ driverParam: string;
1251
+ notNull: false;
1252
+ hasDefault: false;
1253
+ isPrimaryKey: false;
1254
+ isAutoincrement: false;
1255
+ hasRuntimeDefault: false;
1256
+ enumValues: [string, ...string[]];
1257
+ baseColumn: never;
1258
+ identity: undefined;
1259
+ generated: undefined;
1260
+ }, {}, {
1261
+ length: number | undefined;
1262
+ }>;
1263
+ app_url: drizzle_orm_sqlite_core.SQLiteColumn<{
1264
+ name: "app_url";
1265
+ tableName: "worktrees";
1266
+ dataType: "string";
1267
+ columnType: "SQLiteText";
1268
+ data: string;
1269
+ driverParam: string;
1270
+ notNull: false;
1271
+ hasDefault: false;
1272
+ isPrimaryKey: false;
1273
+ isAutoincrement: false;
1274
+ hasRuntimeDefault: false;
1275
+ enumValues: [string, ...string[]];
1276
+ baseColumn: never;
1277
+ identity: undefined;
1278
+ generated: undefined;
1279
+ }, {}, {
1280
+ length: number | undefined;
1281
+ }>;
1282
+ logs_command: drizzle_orm_sqlite_core.SQLiteColumn<{
1283
+ name: "logs_command";
1284
+ tableName: "worktrees";
1285
+ dataType: "string";
1286
+ columnType: "SQLiteText";
1287
+ data: string;
1288
+ driverParam: string;
1289
+ notNull: false;
1290
+ hasDefault: false;
1291
+ isPrimaryKey: false;
1292
+ isAutoincrement: false;
1293
+ hasRuntimeDefault: false;
1294
+ enumValues: [string, ...string[]];
1295
+ baseColumn: never;
1296
+ identity: undefined;
1297
+ generated: undefined;
1298
+ }, {}, {
1299
+ length: number | undefined;
1300
+ }>;
1170
1301
  board_id: drizzle_orm_sqlite_core.SQLiteColumn<{
1171
1302
  name: "board_id";
1172
1303
  tableName: "worktrees";
@@ -1294,7 +1425,7 @@ declare const worktrees: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1294
1425
  schedule?: {
1295
1426
  timezone: string;
1296
1427
  prompt_template: string;
1297
- agentic_tool: "claude-code" | "codex" | "gemini";
1428
+ agentic_tool: "claude-code" | "codex" | "gemini" | "opencode";
1298
1429
  retention: number;
1299
1430
  permission_mode?: string;
1300
1431
  model_config?: {
@@ -1351,7 +1482,7 @@ declare const worktrees: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1351
1482
  schedule?: {
1352
1483
  timezone: string;
1353
1484
  prompt_template: string;
1354
- agentic_tool: "claude-code" | "codex" | "gemini";
1485
+ agentic_tool: "claude-code" | "codex" | "gemini" | "opencode";
1355
1486
  retention: number;
1356
1487
  permission_mode?: string;
1357
1488
  model_config?: {
@@ -1591,6 +1722,14 @@ declare const users: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1591
1722
  permissionMode?: string;
1592
1723
  mcpServerIds?: string[];
1593
1724
  };
1725
+ opencode?: {
1726
+ modelConfig?: {
1727
+ mode?: "alias" | "exact";
1728
+ model?: string;
1729
+ };
1730
+ permissionMode?: string;
1731
+ serverUrl?: string;
1732
+ };
1594
1733
  };
1595
1734
  };
1596
1735
  driverParam: string;
@@ -1647,6 +1786,14 @@ declare const users: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1647
1786
  permissionMode?: string;
1648
1787
  mcpServerIds?: string[];
1649
1788
  };
1789
+ opencode?: {
1790
+ modelConfig?: {
1791
+ mode?: "alias" | "exact";
1792
+ model?: string;
1793
+ };
1794
+ permissionMode?: string;
1795
+ serverUrl?: string;
1796
+ };
1650
1797
  };
1651
1798
  };
1652
1799
  }>;