@saadnvd1/agent-os 0.3.596 → 0.3.597

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 (106) hide show
  1. package/lib/db/migration-types.ts +15 -0
  2. package/lib/db/migrations/0001_add_group_path_to_sessions.ts +11 -0
  3. package/lib/db/migrations/0002_add_agent_type_to_sessions.ts +11 -0
  4. package/lib/db/migrations/0003_add_worktree_columns_to_sessions.ts +12 -0
  5. package/lib/db/migrations/0004_add_pr_tracking_to_sessions.ts +11 -0
  6. package/lib/db/migrations/0005_add_group_path_index.ts +11 -0
  7. package/lib/db/migrations/0006_add_orchestration_columns_to_sessions.ts +16 -0
  8. package/lib/db/migrations/0007_add_auto_approve_to_sessions.ts +11 -0
  9. package/lib/db/migrations/0008_add_dev_server_columns.ts +19 -0
  10. package/lib/db/migrations/0009_add_project_id_to_sessions.ts +17 -0
  11. package/lib/db/migrations/0010_add_project_id_to_dev_servers.ts +36 -0
  12. package/lib/db/migrations/0011_add_tmux_name_to_sessions.ts +13 -0
  13. package/lib/db/migrations/0012_add_initial_prompt_to_projects.ts +9 -0
  14. package/lib/db/migrations/0013_add_project_repositories_table.ts +22 -0
  15. package/lib/db/migrations/0014_add_hosts.ts +23 -0
  16. package/lib/db/migrations/0015_add_workspaces.ts +18 -0
  17. package/lib/db/migrations/0016_add_task_columns_to_sessions.ts +13 -0
  18. package/lib/db/migrations/0017_add_bus_messages.ts +24 -0
  19. package/lib/db/migrations/0018_add_chat.ts +23 -0
  20. package/lib/db/migrations/0019_add_lumifyhub.ts +36 -0
  21. package/lib/db/migrations/0020_add_lumifyhub_published_docs.ts +18 -0
  22. package/lib/db/migrations/0021_add_chat_access.ts +14 -0
  23. package/lib/db/migrations/0022_add_last_seen.ts +10 -0
  24. package/lib/db/migrations/0023_mark_existing_sessions_seen.ts +12 -0
  25. package/lib/db/migrations/0024_add_stacks.ts +49 -0
  26. package/lib/db/migrations/0025_add_stack_item_attempts.ts +16 -0
  27. package/lib/db/migrations/0026_add_workspace_orchestrator.ts +47 -0
  28. package/lib/db/migrations/0027_add_devices_and_settings.ts +28 -0
  29. package/lib/db/migrations/0028_add_orchestrator_acting.ts +70 -0
  30. package/lib/db/migrations/0029_add_orchestrator_asks_and_pause.ts +81 -0
  31. package/lib/db/migrations/0030_add_sessions_archived_at.ts +14 -0
  32. package/lib/db/migrations/0031_add_stack_item_restacked_heads.ts +22 -0
  33. package/lib/db/migrations/0032_add_sessions_pinned.ts +12 -0
  34. package/lib/db/migrations/0033_add_program_status.ts +18 -0
  35. package/lib/db/migrations/0034_add_session_names.ts +21 -0
  36. package/lib/db/migrations/0035_add_artifacts.ts +23 -0
  37. package/lib/db/migrations/0036_add_chat_queue.ts +26 -0
  38. package/lib/db/migrations/0037_add_chat_plan_and_turns.ts +39 -0
  39. package/lib/db/migrations/0038_add_schedules.ts +56 -0
  40. package/lib/db/migrations/0039_add_session_name_source.ts +21 -0
  41. package/lib/db/migrations/0040_add_schedule_targets_and_phone_notify.ts +41 -0
  42. package/lib/db/migrations/0041_add_task_setup.ts +17 -0
  43. package/lib/db/migrations/0042_add_host_links_and_moved_tasks.ts +29 -0
  44. package/lib/db/migrations/0043_scratch_project.ts +14 -0
  45. package/lib/db/migrations/0044_chat_item_kind.ts +21 -0
  46. package/lib/db/migrations/0045_change_versions.ts +13 -0
  47. package/lib/db/migrations/0046_session_port_slots.ts +21 -0
  48. package/lib/db/migrations/0047_pin_orchestrators.ts +12 -0
  49. package/lib/db/migrations/0048_session_database.ts +15 -0
  50. package/lib/db/migrations/0049_peer_mirror.ts +14 -0
  51. package/lib/db/migrations/0050_task_queue.ts +44 -0
  52. package/lib/db/migrations/0051_chat_queue_sent_by.ts +16 -0
  53. package/lib/db/migrations/0052_sessions_chat_restarted.ts +17 -0
  54. package/lib/db/migrations/0053_brief_amendments_failure_sha_ask_raised_by.ts +37 -0
  55. package/lib/db/migrations/0054_sessions_chat_tools_digest.ts +15 -0
  56. package/lib/db/migrations/0055_sessions_merge_armed_and_rebase.ts +25 -0
  57. package/lib/db/migrations/0056_orchestrator_rules.ts +39 -0
  58. package/lib/db/migrations/0057_task_pr_wakes.ts +34 -0
  59. package/lib/db/migrations/0058_away_mode.ts +71 -0
  60. package/lib/db/migrations/0059_gate_failure_commits.ts +33 -0
  61. package/lib/db/migrations/0060_check_runs_and_compactions.ts +44 -0
  62. package/lib/db/migrations/0061_model_routing.ts +30 -0
  63. package/lib/db/migrations/0062_sessions_quick_of.ts +19 -0
  64. package/lib/db/migrations/0063_one_off_schedules.ts +16 -0
  65. package/lib/db/migrations/0064_chat_compactions_phase.ts +15 -0
  66. package/lib/db/migrations/0065_orchestrator_triage.ts +23 -0
  67. package/lib/db/migrations/0066_workspace_orch_mcp_servers.ts +16 -0
  68. package/lib/db/migrations/0067_orchestrator_event_log_suppressed.ts +14 -0
  69. package/lib/db/migrations/0068_usage_calls_and_rollups.ts +74 -0
  70. package/lib/db/migrations/0069_session_logs.ts +26 -0
  71. package/lib/db/migrations/0070_chat_items_running.ts +15 -0
  72. package/lib/db/migrations/0071_devices_push.ts +29 -0
  73. package/lib/db/migrations/0072_push_outbox.ts +33 -0
  74. package/lib/db/migrations/0073_orchestrated_task_moves.ts +27 -0
  75. package/lib/db/migrations/0074_held_task_replies.ts +27 -0
  76. package/lib/db/migrations/0075_plan_only_tasks.ts +17 -0
  77. package/lib/db/migrations/0076_welcome_backfill.ts +16 -0
  78. package/lib/db/migrations/0077_simulator_leases.ts +21 -0
  79. package/lib/db/migrations/0078_orchestrator_questions.ts +34 -0
  80. package/lib/db/migrations/0079_task_queue_agent.ts +13 -0
  81. package/lib/db/migrations/0080_recipes.ts +129 -0
  82. package/lib/db/migrations/0081_schedules_into_recipes.ts +18 -0
  83. package/lib/db/migrations/0082_session_shelf_times.ts +23 -0
  84. package/lib/db/migrations/0083_native_devices_can_approve.ts +18 -0
  85. package/lib/db/migrations/0084_approval_audit.ts +20 -0
  86. package/lib/db/migrations/0085_experiment_usage.ts +35 -0
  87. package/lib/db/migrations/0086_learning_cards.ts +28 -0
  88. package/lib/db/migrations/0087_plan_pieces_reconcile.ts +29 -0
  89. package/lib/db/migrations/0088_shared_links.ts +25 -0
  90. package/lib/db/migrations/0089_passkeys_device_keys.ts +23 -0
  91. package/lib/db/migrations/20261014T0900_task_scheduling.ts +57 -0
  92. package/lib/db/migrations/20261014T1235_placed_mirror_started_by.ts +19 -0
  93. package/lib/db/migrations/20261014T1600_queued_task_messages.ts +21 -0
  94. package/lib/db/migrations/20261014T1800_task_starter_device.ts +20 -0
  95. package/lib/db/migrations/20261014T1900_pause_note.ts +13 -0
  96. package/lib/db/migrations/20261014T2000_chat_bookmarks.ts +33 -0
  97. package/lib/db/migrations/20261014T2100_gate_failure_ask_held.ts +18 -0
  98. package/lib/db/migrations/README.md +35 -0
  99. package/lib/db/migrations-legacy-checksums.json +9 -8
  100. package/lib/db/migrations-split-snapshot.json +1759 -0
  101. package/lib/db/migrations.ts +76 -2337
  102. package/package.json +6 -3
  103. package/scripts/check +1 -0
  104. package/scripts/gen-migrations-index.mjs +44 -0
  105. package/scripts/screenshots/demo.ts +5 -1
  106. package/scripts/screenshots/run.ts +5 -1
@@ -0,0 +1,15 @@
1
+ import type Database from "better-sqlite3";
2
+
3
+ export interface LegacyMigration {
4
+ id: number;
5
+ key?: undefined;
6
+ name: string;
7
+ up: (db: Database.Database) => void;
8
+ }
9
+ export interface KeyedMigration {
10
+ key: string;
11
+ id?: undefined;
12
+ name?: undefined;
13
+ up: (db: Database.Database) => void;
14
+ }
15
+ export type Migration = LegacyMigration | KeyedMigration;
@@ -0,0 +1,11 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 1,
5
+ name: "add_group_path_to_sessions",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE sessions ADD COLUMN group_path TEXT NOT NULL DEFAULT 'sessions'`
9
+ );
10
+ },
11
+ } satisfies Migration;
@@ -0,0 +1,11 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 2,
5
+ name: "add_agent_type_to_sessions",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE sessions ADD COLUMN agent_type TEXT NOT NULL DEFAULT 'claude'`
9
+ );
10
+ },
11
+ } satisfies Migration;
@@ -0,0 +1,12 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 3,
5
+ name: "add_worktree_columns_to_sessions",
6
+ up: (db) => {
7
+ db.exec(`ALTER TABLE sessions ADD COLUMN worktree_path TEXT`);
8
+ db.exec(`ALTER TABLE sessions ADD COLUMN branch_name TEXT`);
9
+ db.exec(`ALTER TABLE sessions ADD COLUMN base_branch TEXT`);
10
+ db.exec(`ALTER TABLE sessions ADD COLUMN dev_server_port INTEGER`);
11
+ },
12
+ } satisfies Migration;
@@ -0,0 +1,11 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 4,
5
+ name: "add_pr_tracking_to_sessions",
6
+ up: (db) => {
7
+ db.exec(`ALTER TABLE sessions ADD COLUMN pr_url TEXT`);
8
+ db.exec(`ALTER TABLE sessions ADD COLUMN pr_number INTEGER`);
9
+ db.exec(`ALTER TABLE sessions ADD COLUMN pr_status TEXT`);
10
+ },
11
+ } satisfies Migration;
@@ -0,0 +1,11 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 5,
5
+ name: "add_group_path_index",
6
+ up: (db) => {
7
+ db.exec(
8
+ `CREATE INDEX IF NOT EXISTS idx_sessions_group ON sessions(group_path)`
9
+ );
10
+ },
11
+ } satisfies Migration;
@@ -0,0 +1,16 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 6,
5
+ name: "add_orchestration_columns_to_sessions",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE sessions ADD COLUMN conductor_session_id TEXT REFERENCES sessions(id)`
9
+ );
10
+ db.exec(`ALTER TABLE sessions ADD COLUMN worker_task TEXT`);
11
+ db.exec(`ALTER TABLE sessions ADD COLUMN worker_status TEXT`);
12
+ db.exec(
13
+ `CREATE INDEX IF NOT EXISTS idx_sessions_conductor ON sessions(conductor_session_id)`
14
+ );
15
+ },
16
+ } satisfies Migration;
@@ -0,0 +1,11 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 7,
5
+ name: "add_auto_approve_to_sessions",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE sessions ADD COLUMN auto_approve INTEGER NOT NULL DEFAULT 0`
9
+ );
10
+ },
11
+ } satisfies Migration;
@@ -0,0 +1,19 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 8,
5
+ name: "add_dev_server_columns",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE dev_servers ADD COLUMN type TEXT NOT NULL DEFAULT 'node'`
9
+ );
10
+ db.exec(`ALTER TABLE dev_servers ADD COLUMN name TEXT NOT NULL DEFAULT ''`);
11
+ db.exec(
12
+ `ALTER TABLE dev_servers ADD COLUMN command TEXT NOT NULL DEFAULT ''`
13
+ );
14
+ db.exec(`ALTER TABLE dev_servers ADD COLUMN pid INTEGER`);
15
+ db.exec(
16
+ `ALTER TABLE dev_servers ADD COLUMN working_directory TEXT NOT NULL DEFAULT ''`
17
+ );
18
+ },
19
+ } satisfies Migration;
@@ -0,0 +1,17 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 9,
5
+ name: "add_project_id_to_sessions",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE sessions ADD COLUMN project_id TEXT REFERENCES projects(id)`
9
+ );
10
+ db.exec(
11
+ `UPDATE sessions SET project_id = 'uncategorized' WHERE project_id IS NULL`
12
+ );
13
+ db.exec(
14
+ `CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id)`
15
+ );
16
+ },
17
+ } satisfies Migration;
@@ -0,0 +1,36 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 10,
5
+ name: "add_project_id_to_dev_servers",
6
+ up: (db) => {
7
+ // Check if column exists first
8
+ const cols = db.prepare(`PRAGMA table_info(dev_servers)`).all() as {
9
+ name: string;
10
+ }[];
11
+ if (cols.some((c) => c.name === "project_id")) return;
12
+
13
+ db.exec(
14
+ `ALTER TABLE dev_servers ADD COLUMN project_id TEXT REFERENCES projects(id)`
15
+ );
16
+ // Migrate from session_id if it exists
17
+ const hasSessionId = cols.some((c) => c.name === "session_id");
18
+ if (hasSessionId) {
19
+ db.exec(`
20
+ UPDATE dev_servers
21
+ SET project_id = (
22
+ SELECT COALESCE(s.project_id, 'uncategorized')
23
+ FROM sessions s
24
+ WHERE s.id = dev_servers.session_id
25
+ )
26
+ WHERE project_id IS NULL
27
+ `);
28
+ }
29
+ db.exec(
30
+ `UPDATE dev_servers SET project_id = 'uncategorized' WHERE project_id IS NULL`
31
+ );
32
+ db.exec(
33
+ `CREATE INDEX IF NOT EXISTS idx_dev_servers_project ON dev_servers(project_id)`
34
+ );
35
+ },
36
+ } satisfies Migration;
@@ -0,0 +1,13 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 11,
5
+ name: "add_tmux_name_to_sessions",
6
+ up: (db) => {
7
+ db.exec(`ALTER TABLE sessions ADD COLUMN tmux_name TEXT`);
8
+ // Backfill existing sessions with computed tmux name
9
+ db.exec(
10
+ `UPDATE sessions SET tmux_name = agent_type || '-' || id WHERE tmux_name IS NULL`
11
+ );
12
+ },
13
+ } satisfies Migration;
@@ -0,0 +1,9 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 12,
5
+ name: "add_initial_prompt_to_projects",
6
+ up: (db) => {
7
+ db.exec(`ALTER TABLE projects ADD COLUMN initial_prompt TEXT`);
8
+ },
9
+ } satisfies Migration;
@@ -0,0 +1,22 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 13,
5
+ name: "add_project_repositories_table",
6
+ up: (db) => {
7
+ db.exec(`
8
+ CREATE TABLE IF NOT EXISTS project_repositories (
9
+ id TEXT PRIMARY KEY,
10
+ project_id TEXT NOT NULL,
11
+ name TEXT NOT NULL,
12
+ path TEXT NOT NULL,
13
+ is_primary INTEGER NOT NULL DEFAULT 0,
14
+ sort_order INTEGER NOT NULL DEFAULT 0,
15
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
16
+ )
17
+ `);
18
+ db.exec(
19
+ `CREATE INDEX IF NOT EXISTS idx_project_repositories_project ON project_repositories(project_id)`
20
+ );
21
+ },
22
+ } satisfies Migration;
@@ -0,0 +1,23 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 14,
5
+ name: "add_hosts",
6
+ up: (db) => {
7
+ db.exec(`
8
+ CREATE TABLE IF NOT EXISTS hosts (
9
+ id TEXT PRIMARY KEY,
10
+ name TEXT NOT NULL,
11
+ ssh_target TEXT NOT NULL,
12
+ sort_order INTEGER NOT NULL DEFAULT 0,
13
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
14
+ )
15
+ `);
16
+ db.exec(
17
+ `ALTER TABLE projects ADD COLUMN host_id TEXT NOT NULL DEFAULT 'local'`
18
+ );
19
+ db.exec(
20
+ `ALTER TABLE sessions ADD COLUMN host_id TEXT NOT NULL DEFAULT 'local'`
21
+ );
22
+ },
23
+ } satisfies Migration;
@@ -0,0 +1,18 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 15,
5
+ name: "add_workspaces",
6
+ up: (db) => {
7
+ db.exec(`
8
+ CREATE TABLE IF NOT EXISTS workspaces (
9
+ id TEXT PRIMARY KEY,
10
+ name TEXT NOT NULL,
11
+ sort_order INTEGER NOT NULL DEFAULT 0,
12
+ collapsed INTEGER NOT NULL DEFAULT 0,
13
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
14
+ )
15
+ `);
16
+ db.exec(`ALTER TABLE projects ADD COLUMN workspace_id TEXT`);
17
+ },
18
+ } satisfies Migration;
@@ -0,0 +1,13 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 16,
5
+ name: "add_task_columns_to_sessions",
6
+ up: (db) => {
7
+ db.exec(`ALTER TABLE sessions ADD COLUMN task_prompt TEXT`);
8
+ db.exec(`ALTER TABLE sessions ADD COLUMN task_status TEXT`);
9
+ db.exec(
10
+ `CREATE INDEX IF NOT EXISTS idx_sessions_task_status ON sessions(task_status)`
11
+ );
12
+ },
13
+ } satisfies Migration;
@@ -0,0 +1,24 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 17,
5
+ name: "add_bus_messages",
6
+ up: (db) => {
7
+ db.exec(`
8
+ CREATE TABLE IF NOT EXISTS bus_messages (
9
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
10
+ from_id TEXT,
11
+ from_name TEXT NOT NULL,
12
+ to_id TEXT NOT NULL,
13
+ to_name TEXT NOT NULL,
14
+ body TEXT NOT NULL,
15
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
16
+ delivered_at TEXT,
17
+ read_at TEXT
18
+ )
19
+ `);
20
+ db.exec(
21
+ `CREATE INDEX IF NOT EXISTS idx_bus_to ON bus_messages(to_id, read_at)`
22
+ );
23
+ },
24
+ } satisfies Migration;
@@ -0,0 +1,23 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 18,
5
+ name: "add_chat",
6
+ up: (db) => {
7
+ db.exec(
8
+ `ALTER TABLE sessions ADD COLUMN view TEXT NOT NULL DEFAULT 'terminal'`
9
+ );
10
+ db.exec(`
11
+ CREATE TABLE IF NOT EXISTS chat_items (
12
+ session_id TEXT NOT NULL,
13
+ item_id TEXT NOT NULL,
14
+ seq INTEGER NOT NULL,
15
+ data TEXT NOT NULL,
16
+ PRIMARY KEY (session_id, item_id)
17
+ )
18
+ `);
19
+ db.exec(
20
+ `CREATE INDEX IF NOT EXISTS idx_chat_items_seq ON chat_items(session_id, seq)`
21
+ );
22
+ },
23
+ } satisfies Migration;
@@ -0,0 +1,36 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 19,
5
+ name: "add_lumifyhub",
6
+ up: (db) => {
7
+ db.exec(`
8
+ CREATE TABLE IF NOT EXISTS lumifyhub_connection (
9
+ id INTEGER PRIMARY KEY CHECK (id = 1),
10
+ base_url TEXT NOT NULL,
11
+ token TEXT NOT NULL,
12
+ user_id TEXT,
13
+ user_email TEXT,
14
+ user_name TEXT,
15
+ connected_at TEXT NOT NULL DEFAULT (datetime('now'))
16
+ )
17
+ `);
18
+ db.exec(`
19
+ CREATE TABLE IF NOT EXISTS lumifyhub_connect_attempts (
20
+ state TEXT PRIMARY KEY,
21
+ verifier TEXT NOT NULL,
22
+ redirect_uri TEXT NOT NULL,
23
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
24
+ )
25
+ `);
26
+ db.exec(`ALTER TABLE workspaces ADD COLUMN lh_workspace_id TEXT`);
27
+ db.exec(`ALTER TABLE workspaces ADD COLUMN lh_workspace_slug TEXT`);
28
+ db.exec(`ALTER TABLE workspaces ADD COLUMN lh_workspace_name TEXT`);
29
+ db.exec(`ALTER TABLE projects ADD COLUMN lh_board_id TEXT`);
30
+ db.exec(`ALTER TABLE projects ADD COLUMN lh_board_name TEXT`);
31
+ db.exec(`ALTER TABLE projects ADD COLUMN lh_board_page_id TEXT`);
32
+ db.exec(`ALTER TABLE sessions ADD COLUMN lh_card_id TEXT`);
33
+ db.exec(`ALTER TABLE sessions ADD COLUMN lh_board_id TEXT`);
34
+ db.exec(`ALTER TABLE sessions ADD COLUMN lh_card_list TEXT`);
35
+ },
36
+ } satisfies Migration;
@@ -0,0 +1,18 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 20,
5
+ name: "add_lumifyhub_published_docs",
6
+ up: (db) => {
7
+ db.exec(`
8
+ CREATE TABLE IF NOT EXISTS lumifyhub_published_docs (
9
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
10
+ repo_path TEXT NOT NULL,
11
+ page_id TEXT NOT NULL,
12
+ content_hash TEXT NOT NULL,
13
+ published_at TEXT NOT NULL DEFAULT (datetime('now')),
14
+ PRIMARY KEY (project_id, repo_path)
15
+ )
16
+ `);
17
+ },
18
+ } satisfies Migration;
@@ -0,0 +1,14 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 21,
5
+ name: "add_chat_access",
6
+ up: (db) => {
7
+ // What a chat agent may do without asking; full is the old behavior.
8
+ db.exec(
9
+ `ALTER TABLE sessions ADD COLUMN chat_access TEXT NOT NULL DEFAULT 'full'`
10
+ );
11
+ // After an undo, where the next start resumes the conversation from.
12
+ db.exec(`ALTER TABLE sessions ADD COLUMN chat_resume_at TEXT`);
13
+ },
14
+ } satisfies Migration;
@@ -0,0 +1,10 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 22,
5
+ name: "add_last_seen",
6
+ up: (db) => {
7
+ // When the reader last looked, so "needs you" means something new.
8
+ db.exec(`ALTER TABLE sessions ADD COLUMN last_seen_at TEXT`);
9
+ },
10
+ } satisfies Migration;
@@ -0,0 +1,12 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 23,
5
+ name: "mark_existing_sessions_seen",
6
+ up: (db) => {
7
+ // Start quiet: what finished before "needs you" meant news is old news.
8
+ db.exec(
9
+ `UPDATE sessions SET last_seen_at = datetime('now') WHERE last_seen_at IS NULL`
10
+ );
11
+ },
12
+ } satisfies Migration;
@@ -0,0 +1,49 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 24,
5
+ name: "add_stacks",
6
+ up: (db) => {
7
+ // A LumifyHub board's cards run as stacked tasks (lib/stacks).
8
+ db.exec(`
9
+ CREATE TABLE IF NOT EXISTS stacks (
10
+ id TEXT PRIMARY KEY,
11
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
12
+ lh_board_id TEXT NOT NULL,
13
+ name TEXT NOT NULL,
14
+ status TEXT NOT NULL DEFAULT 'running',
15
+ max_parallel INTEGER NOT NULL DEFAULT 3,
16
+ progress TEXT,
17
+ error TEXT,
18
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
19
+ landed_at TEXT
20
+ )
21
+ `);
22
+ db.exec(`
23
+ CREATE TABLE IF NOT EXISTS stack_items (
24
+ id TEXT PRIMARY KEY,
25
+ stack_id TEXT NOT NULL REFERENCES stacks(id) ON DELETE CASCADE,
26
+ position INTEGER NOT NULL,
27
+ lh_card_id TEXT NOT NULL,
28
+ ticket TEXT,
29
+ title TEXT NOT NULL,
30
+ parent_item_id TEXT,
31
+ also_item_ids TEXT NOT NULL DEFAULT '[]',
32
+ blocker_item_ids TEXT NOT NULL DEFAULT '[]',
33
+ status TEXT NOT NULL DEFAULT 'planned',
34
+ session_id TEXT,
35
+ base_branch TEXT,
36
+ base_tip TEXT,
37
+ pr_number INTEGER,
38
+ note TEXT,
39
+ error TEXT
40
+ )
41
+ `);
42
+ db.exec(
43
+ `CREATE INDEX IF NOT EXISTS idx_stack_items_stack ON stack_items(stack_id, position)`
44
+ );
45
+ db.exec(
46
+ `CREATE INDEX IF NOT EXISTS idx_stack_items_session ON stack_items(session_id)`
47
+ );
48
+ },
49
+ } satisfies Migration;
@@ -0,0 +1,16 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 25,
5
+ name: "add_stack_item_attempts",
6
+ up: (db) => {
7
+ // Starts retried after a transient failure, and holds the plan made
8
+ // (an open blocker outside the stack) that a retry must not undo.
9
+ db.exec(
10
+ `ALTER TABLE stack_items ADD COLUMN attempts INTEGER NOT NULL DEFAULT 0`
11
+ );
12
+ db.exec(
13
+ `ALTER TABLE stack_items ADD COLUMN held_outside INTEGER NOT NULL DEFAULT 0`
14
+ );
15
+ },
16
+ } satisfies Migration;
@@ -0,0 +1,47 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 26,
5
+ name: "add_workspace_orchestrator",
6
+ up: (db) => {
7
+ // One standing orchestrator chat per workspace. Its events are kept
8
+ // by key: a key present means that event is known, delivered or
9
+ // queued. An event is sent once seen on two diffs in a row (hits);
10
+ // a passing one that cleared is remembered (cleared_at) so it can't
11
+ // fire again too soon. The log counts deliveries per subject.
12
+ db.exec(`ALTER TABLE sessions ADD COLUMN role TEXT`);
13
+ db.exec(`ALTER TABLE sessions ADD COLUMN workspace_id TEXT`);
14
+ db.exec(
15
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_orchestrator
16
+ ON sessions(workspace_id) WHERE role = 'orchestrator'`
17
+ );
18
+ db.exec(`
19
+ CREATE TABLE IF NOT EXISTS orchestrator_events (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ workspace_id TEXT NOT NULL,
22
+ key TEXT NOT NULL,
23
+ subject TEXT,
24
+ line TEXT NOT NULL,
25
+ sticky INTEGER NOT NULL DEFAULT 1,
26
+ low INTEGER NOT NULL DEFAULT 0,
27
+ hits INTEGER NOT NULL DEFAULT 1,
28
+ created_at TEXT NOT NULL,
29
+ delivered_at TEXT,
30
+ cleared_at TEXT,
31
+ UNIQUE (workspace_id, key)
32
+ )
33
+ `);
34
+ db.exec(`
35
+ CREATE TABLE IF NOT EXISTS orchestrator_event_log (
36
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
37
+ workspace_id TEXT NOT NULL,
38
+ subject TEXT,
39
+ delivered_at TEXT NOT NULL
40
+ )
41
+ `);
42
+ db.exec(
43
+ `CREATE INDEX IF NOT EXISTS idx_orchestrator_event_log
44
+ ON orchestrator_event_log(workspace_id, delivered_at)`
45
+ );
46
+ },
47
+ } satisfies Migration;
@@ -0,0 +1,28 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 27,
5
+ name: "add_devices_and_settings",
6
+ up: (db) => {
7
+ // Paired phones, tablets and laptops. Only a hash of each token is kept.
8
+ db.exec(`
9
+ CREATE TABLE IF NOT EXISTS devices (
10
+ id TEXT PRIMARY KEY,
11
+ name TEXT NOT NULL,
12
+ token_hash TEXT NOT NULL UNIQUE,
13
+ user_agent TEXT,
14
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
15
+ last_seen_at TEXT,
16
+ last_address TEXT,
17
+ revoked_at TEXT
18
+ )
19
+ `);
20
+ // Small app-wide switches (Wi-Fi access, pairing on the tailnet).
21
+ db.exec(`
22
+ CREATE TABLE IF NOT EXISTS settings (
23
+ key TEXT PRIMARY KEY,
24
+ value TEXT NOT NULL
25
+ )
26
+ `);
27
+ },
28
+ } satisfies Migration;
@@ -0,0 +1,70 @@
1
+ import type { Migration } from "../migration-types";
2
+
3
+ export default {
4
+ id: 28,
5
+ name: "add_orchestrator_acting",
6
+ up: (db) => {
7
+ // The orchestrator's brakes (settings per workspace, and the brake in
8
+ // force so it's noted once), its starts, its decision log, the reviews
9
+ // and scope checks it ran per commit, and gate failures per task.
10
+ db.exec(
11
+ `ALTER TABLE workspaces ADD COLUMN orch_max_running INTEGER NOT NULL DEFAULT 4`
12
+ );
13
+ db.exec(
14
+ `ALTER TABLE workspaces ADD COLUMN orch_max_starts_per_hour INTEGER NOT NULL DEFAULT 6`
15
+ );
16
+ db.exec(`ALTER TABLE workspaces ADD COLUMN orch_brake TEXT`);
17
+ // The secret an orchestrator's worker sends with each tool call.
18
+ db.exec(`ALTER TABLE sessions ADD COLUMN orch_token TEXT`);
19
+ db.exec(`
20
+ CREATE TABLE IF NOT EXISTS orchestrator_starts (
21
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
22
+ workspace_id TEXT NOT NULL,
23
+ kind TEXT NOT NULL,
24
+ target TEXT,
25
+ created_at TEXT NOT NULL
26
+ )
27
+ `);
28
+ db.exec(
29
+ `CREATE INDEX IF NOT EXISTS idx_orchestrator_starts
30
+ ON orchestrator_starts(workspace_id, created_at)`
31
+ );
32
+ db.exec(`
33
+ CREATE TABLE IF NOT EXISTS orchestrator_notes (
34
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
35
+ workspace_id TEXT NOT NULL,
36
+ kind TEXT NOT NULL DEFAULT 'note',
37
+ text TEXT NOT NULL,
38
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
39
+ )
40
+ `);
41
+ db.exec(
42
+ `CREATE INDEX IF NOT EXISTS idx_orchestrator_notes
43
+ ON orchestrator_notes(workspace_id, id)`
44
+ );
45
+ db.exec(`
46
+ CREATE TABLE IF NOT EXISTS orchestrator_checks (
47
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
48
+ workspace_id TEXT NOT NULL,
49
+ session_id TEXT NOT NULL,
50
+ sha TEXT NOT NULL,
51
+ kind TEXT NOT NULL,
52
+ status TEXT NOT NULL,
53
+ detail TEXT,
54
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
55
+ UNIQUE (session_id, sha, kind)
56
+ )
57
+ `);
58
+ db.exec(`
59
+ CREATE TABLE IF NOT EXISTS orchestrator_gate_failures (
60
+ session_id TEXT NOT NULL,
61
+ gate TEXT NOT NULL,
62
+ workspace_id TEXT NOT NULL,
63
+ count INTEGER NOT NULL DEFAULT 0,
64
+ last_reason TEXT,
65
+ escalated_at TEXT,
66
+ PRIMARY KEY (session_id, gate)
67
+ )
68
+ `);
69
+ },
70
+ } satisfies Migration;