gobby 0.2.6__py3-none-any.whl → 0.2.7__py3-none-any.whl

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 (146) hide show
  1. gobby/__init__.py +1 -1
  2. gobby/adapters/__init__.py +2 -1
  3. gobby/adapters/codex_impl/__init__.py +28 -0
  4. gobby/adapters/codex_impl/adapter.py +722 -0
  5. gobby/adapters/codex_impl/client.py +679 -0
  6. gobby/adapters/codex_impl/protocol.py +20 -0
  7. gobby/adapters/codex_impl/types.py +68 -0
  8. gobby/agents/definitions.py +11 -1
  9. gobby/agents/isolation.py +395 -0
  10. gobby/agents/sandbox.py +261 -0
  11. gobby/agents/spawn.py +42 -287
  12. gobby/agents/spawn_executor.py +385 -0
  13. gobby/agents/spawners/__init__.py +24 -0
  14. gobby/agents/spawners/command_builder.py +189 -0
  15. gobby/agents/spawners/embedded.py +21 -2
  16. gobby/agents/spawners/headless.py +21 -2
  17. gobby/agents/spawners/prompt_manager.py +125 -0
  18. gobby/cli/install.py +4 -4
  19. gobby/cli/installers/claude.py +6 -0
  20. gobby/cli/installers/gemini.py +6 -0
  21. gobby/cli/installers/shared.py +103 -4
  22. gobby/cli/sessions.py +1 -1
  23. gobby/cli/utils.py +9 -2
  24. gobby/config/__init__.py +12 -97
  25. gobby/config/app.py +10 -94
  26. gobby/config/extensions.py +2 -2
  27. gobby/config/features.py +7 -130
  28. gobby/config/tasks.py +4 -28
  29. gobby/hooks/__init__.py +0 -13
  30. gobby/hooks/event_handlers.py +45 -2
  31. gobby/hooks/hook_manager.py +2 -2
  32. gobby/hooks/plugins.py +1 -1
  33. gobby/hooks/webhooks.py +1 -1
  34. gobby/llm/resolver.py +3 -2
  35. gobby/mcp_proxy/importer.py +62 -4
  36. gobby/mcp_proxy/instructions.py +2 -0
  37. gobby/mcp_proxy/registries.py +1 -4
  38. gobby/mcp_proxy/services/recommendation.py +43 -11
  39. gobby/mcp_proxy/tools/agents.py +31 -731
  40. gobby/mcp_proxy/tools/clones.py +0 -385
  41. gobby/mcp_proxy/tools/memory.py +2 -2
  42. gobby/mcp_proxy/tools/sessions/__init__.py +14 -0
  43. gobby/mcp_proxy/tools/sessions/_commits.py +232 -0
  44. gobby/mcp_proxy/tools/sessions/_crud.py +253 -0
  45. gobby/mcp_proxy/tools/sessions/_factory.py +63 -0
  46. gobby/mcp_proxy/tools/sessions/_handoff.py +499 -0
  47. gobby/mcp_proxy/tools/sessions/_messages.py +138 -0
  48. gobby/mcp_proxy/tools/skills/__init__.py +14 -29
  49. gobby/mcp_proxy/tools/spawn_agent.py +417 -0
  50. gobby/mcp_proxy/tools/tasks/_lifecycle.py +52 -18
  51. gobby/mcp_proxy/tools/tasks/_lifecycle_validation.py +1 -1
  52. gobby/mcp_proxy/tools/worktrees.py +0 -343
  53. gobby/memory/ingestion/__init__.py +5 -0
  54. gobby/memory/ingestion/multimodal.py +221 -0
  55. gobby/memory/manager.py +62 -283
  56. gobby/memory/search/__init__.py +10 -0
  57. gobby/memory/search/coordinator.py +248 -0
  58. gobby/memory/services/__init__.py +5 -0
  59. gobby/memory/services/crossref.py +142 -0
  60. gobby/prompts/loader.py +5 -2
  61. gobby/servers/http.py +1 -4
  62. gobby/servers/routes/admin.py +14 -0
  63. gobby/servers/routes/mcp/endpoints/__init__.py +61 -0
  64. gobby/servers/routes/mcp/endpoints/discovery.py +405 -0
  65. gobby/servers/routes/mcp/endpoints/execution.py +568 -0
  66. gobby/servers/routes/mcp/endpoints/registry.py +378 -0
  67. gobby/servers/routes/mcp/endpoints/server.py +304 -0
  68. gobby/servers/routes/mcp/hooks.py +1 -1
  69. gobby/servers/routes/mcp/tools.py +48 -1506
  70. gobby/sessions/lifecycle.py +1 -1
  71. gobby/sessions/processor.py +10 -0
  72. gobby/sessions/transcripts/base.py +1 -0
  73. gobby/sessions/transcripts/claude.py +15 -5
  74. gobby/skills/parser.py +30 -2
  75. gobby/storage/migrations.py +159 -372
  76. gobby/storage/sessions.py +43 -7
  77. gobby/storage/skills.py +37 -4
  78. gobby/storage/tasks/_lifecycle.py +18 -3
  79. gobby/sync/memories.py +1 -1
  80. gobby/tasks/external_validator.py +1 -1
  81. gobby/tasks/validation.py +22 -20
  82. gobby/tools/summarizer.py +91 -10
  83. gobby/utils/project_context.py +2 -3
  84. gobby/utils/status.py +13 -0
  85. gobby/workflows/actions.py +221 -1217
  86. gobby/workflows/artifact_actions.py +31 -0
  87. gobby/workflows/autonomous_actions.py +11 -0
  88. gobby/workflows/context_actions.py +50 -1
  89. gobby/workflows/enforcement/__init__.py +47 -0
  90. gobby/workflows/enforcement/blocking.py +269 -0
  91. gobby/workflows/enforcement/commit_policy.py +283 -0
  92. gobby/workflows/enforcement/handlers.py +269 -0
  93. gobby/workflows/enforcement/task_policy.py +542 -0
  94. gobby/workflows/git_utils.py +106 -0
  95. gobby/workflows/llm_actions.py +30 -0
  96. gobby/workflows/mcp_actions.py +20 -1
  97. gobby/workflows/memory_actions.py +80 -0
  98. gobby/workflows/safe_evaluator.py +183 -0
  99. gobby/workflows/session_actions.py +44 -0
  100. gobby/workflows/state_actions.py +60 -1
  101. gobby/workflows/stop_signal_actions.py +55 -0
  102. gobby/workflows/summary_actions.py +94 -1
  103. gobby/workflows/task_sync_actions.py +347 -0
  104. gobby/workflows/todo_actions.py +34 -1
  105. gobby/workflows/webhook_actions.py +185 -0
  106. {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/METADATA +6 -1
  107. {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/RECORD +111 -111
  108. {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/WHEEL +1 -1
  109. gobby/adapters/codex.py +0 -1332
  110. gobby/install/claude/commands/gobby/bug.md +0 -51
  111. gobby/install/claude/commands/gobby/chore.md +0 -51
  112. gobby/install/claude/commands/gobby/epic.md +0 -52
  113. gobby/install/claude/commands/gobby/eval.md +0 -235
  114. gobby/install/claude/commands/gobby/feat.md +0 -49
  115. gobby/install/claude/commands/gobby/nit.md +0 -52
  116. gobby/install/claude/commands/gobby/ref.md +0 -52
  117. gobby/mcp_proxy/tools/session_messages.py +0 -1055
  118. gobby/prompts/defaults/expansion/system.md +0 -119
  119. gobby/prompts/defaults/expansion/user.md +0 -48
  120. gobby/prompts/defaults/external_validation/agent.md +0 -72
  121. gobby/prompts/defaults/external_validation/external.md +0 -63
  122. gobby/prompts/defaults/external_validation/spawn.md +0 -83
  123. gobby/prompts/defaults/external_validation/system.md +0 -6
  124. gobby/prompts/defaults/features/import_mcp.md +0 -22
  125. gobby/prompts/defaults/features/import_mcp_github.md +0 -17
  126. gobby/prompts/defaults/features/import_mcp_search.md +0 -16
  127. gobby/prompts/defaults/features/recommend_tools.md +0 -32
  128. gobby/prompts/defaults/features/recommend_tools_hybrid.md +0 -35
  129. gobby/prompts/defaults/features/recommend_tools_llm.md +0 -30
  130. gobby/prompts/defaults/features/server_description.md +0 -20
  131. gobby/prompts/defaults/features/server_description_system.md +0 -6
  132. gobby/prompts/defaults/features/task_description.md +0 -31
  133. gobby/prompts/defaults/features/task_description_system.md +0 -6
  134. gobby/prompts/defaults/features/tool_summary.md +0 -17
  135. gobby/prompts/defaults/features/tool_summary_system.md +0 -6
  136. gobby/prompts/defaults/handoff/compact.md +0 -63
  137. gobby/prompts/defaults/handoff/session_end.md +0 -57
  138. gobby/prompts/defaults/memory/extract.md +0 -61
  139. gobby/prompts/defaults/research/step.md +0 -58
  140. gobby/prompts/defaults/validation/criteria.md +0 -47
  141. gobby/prompts/defaults/validation/validate.md +0 -38
  142. gobby/storage/migrations_legacy.py +0 -1359
  143. gobby/workflows/task_enforcement_actions.py +0 -1343
  144. {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/entry_points.txt +0 -0
  145. {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/licenses/LICENSE.md +0 -0
  146. {gobby-0.2.6.dist-info → gobby-0.2.7.dist-info}/top_level.txt +0 -0
@@ -1,1359 +0,0 @@
1
- """Legacy database migrations (v1-60).
2
-
3
- This file contains the incremental migrations used during development.
4
- It is only imported when upgrading a database from version < 60.
5
- New databases use the baseline schema directly.
6
-
7
- For new migrations, add them to migrations.py starting at version 61.
8
- """
9
-
10
- import logging
11
- import uuid
12
- from collections.abc import Callable
13
- from typing import TYPE_CHECKING
14
-
15
- if TYPE_CHECKING:
16
- from gobby.storage.database import LocalDatabase
17
-
18
- logger = logging.getLogger(__name__)
19
-
20
- # Migration can be SQL string or a callable that takes LocalDatabase
21
- MigrationAction = str | Callable[["LocalDatabase"], None]
22
-
23
-
24
- def _backfill_seq_num(db: "LocalDatabase") -> None:
25
- """
26
- Backfill seq_num values for existing tasks.
27
-
28
- Assigns sequential numbers per project, ordered by created_at.
29
- Tasks within the same project get contiguous seq_num values starting from 1.
30
- """
31
- # Get all projects that have tasks
32
- projects = db.fetchall("SELECT DISTINCT project_id FROM tasks WHERE seq_num IS NULL")
33
-
34
- if not projects:
35
- logger.debug("No tasks need seq_num backfill")
36
- return
37
-
38
- for project in projects:
39
- project_id = project["project_id"]
40
-
41
- # Get tasks for this project, ordered by creation time
42
- tasks = db.fetchall(
43
- """
44
- SELECT id FROM tasks
45
- WHERE project_id = ? AND seq_num IS NULL
46
- ORDER BY created_at ASC, id ASC
47
- """,
48
- (project_id,),
49
- )
50
-
51
- # Find the max existing seq_num for this project (in case of partial migration)
52
- max_seq_row = db.fetchone(
53
- "SELECT MAX(seq_num) as max_seq FROM tasks WHERE project_id = ?",
54
- (project_id,),
55
- )
56
- next_seq = ((max_seq_row["max_seq"] if max_seq_row else None) or 0) + 1
57
-
58
- # Assign sequential numbers
59
- for task in tasks:
60
- db.execute(
61
- "UPDATE tasks SET seq_num = ? WHERE id = ?",
62
- (next_seq, task["id"]),
63
- )
64
- next_seq += 1
65
-
66
- logger.debug(f"Backfilled seq_num for {len(tasks)} tasks in project {project_id}")
67
-
68
-
69
- def _backfill_session_seq_num(db: "LocalDatabase") -> None:
70
- """
71
- Backfill seq_num values for existing sessions.
72
-
73
- Assigns sequential numbers globally, ordered by created_at.
74
- Sessions get contiguous seq_num values starting from 1.
75
- """
76
- # Get all sessions that need seq_num
77
- sessions = db.fetchall(
78
- """
79
- SELECT id FROM sessions
80
- WHERE seq_num IS NULL
81
- ORDER BY created_at ASC, id ASC
82
- """
83
- )
84
-
85
- if not sessions:
86
- logger.debug("No sessions need seq_num backfill")
87
- return
88
-
89
- # Find the max existing seq_num (in case of partial migration)
90
- max_seq_row = db.fetchone("SELECT MAX(seq_num) as max_seq FROM sessions")
91
- next_seq = ((max_seq_row["max_seq"] if max_seq_row else None) or 0) + 1
92
-
93
- # Assign sequential numbers
94
- for session in sessions:
95
- db.execute(
96
- "UPDATE sessions SET seq_num = ? WHERE id = ?",
97
- (next_seq, session["id"]),
98
- )
99
- next_seq += 1
100
-
101
- logger.debug(f"Backfilled seq_num for {len(sessions)} sessions")
102
-
103
-
104
- def _migrate_task_ids_to_uuid(db: "LocalDatabase") -> None:
105
- """
106
- Convert gt-* format task IDs to full UUIDs.
107
-
108
- This migration:
109
- 1. Finds all tasks with gt-* format IDs
110
- 2. Generates a full UUID for each (preserving short hash in last segment)
111
- 3. Updates the task ID and all foreign key references
112
-
113
- Note: This is a data migration that modifies existing data.
114
- Foreign keys must be disabled during the update to avoid constraint violations.
115
- """
116
- # Get all tasks with gt-* format IDs
117
- tasks = db.fetchall("SELECT id FROM tasks WHERE id LIKE 'gt-%'")
118
-
119
- if not tasks:
120
- logger.debug("No gt-* format task IDs found, skipping migration")
121
- return
122
-
123
- logger.debug(f"Converting {len(tasks)} task IDs from gt-* to UUID format")
124
-
125
- # Build ID mapping: old_id -> new_uuid
126
- id_mapping: dict[str, str] = {}
127
- for task in tasks:
128
- old_id = task["id"]
129
- # Generate UUID, embedding old short hash in final segment for traceability
130
- # Format: xxxxxxxx-xxxx-4xxx-yxxx-{old_hash}xxxxxx
131
- short_hash = old_id.replace("gt-", "") # 6 hex chars
132
- new_uuid = str(uuid.uuid4())
133
- # Embed old hash at start of last segment for debugging/traceability
134
- parts = new_uuid.split("-")
135
- # Last segment is 12 chars, replace first 6 with old hash
136
- parts[4] = short_hash + parts[4][6:]
137
- new_id = "-".join(parts)
138
- id_mapping[old_id] = new_id
139
-
140
- # Disable foreign keys for bulk update
141
- db.execute("PRAGMA foreign_keys = OFF")
142
-
143
- try:
144
- # Update tasks table (primary key)
145
- for old_id, new_id in id_mapping.items():
146
- db.execute("UPDATE tasks SET id = ? WHERE id = ?", (new_id, old_id))
147
-
148
- # Update parent_task_id references in tasks table
149
- for old_id, new_id in id_mapping.items():
150
- db.execute(
151
- "UPDATE tasks SET parent_task_id = ? WHERE parent_task_id = ?",
152
- (new_id, old_id),
153
- )
154
-
155
- # Update task_dependencies table (both task_id and depends_on columns)
156
- for old_id, new_id in id_mapping.items():
157
- db.execute(
158
- "UPDATE task_dependencies SET task_id = ? WHERE task_id = ?",
159
- (new_id, old_id),
160
- )
161
- db.execute(
162
- "UPDATE task_dependencies SET depends_on = ? WHERE depends_on = ?",
163
- (new_id, old_id),
164
- )
165
-
166
- # Update session_tasks table
167
- for old_id, new_id in id_mapping.items():
168
- db.execute(
169
- "UPDATE session_tasks SET task_id = ? WHERE task_id = ?",
170
- (new_id, old_id),
171
- )
172
-
173
- # Update task_validation_history table
174
- for old_id, new_id in id_mapping.items():
175
- db.execute(
176
- "UPDATE task_validation_history SET task_id = ? WHERE task_id = ?",
177
- (new_id, old_id),
178
- )
179
-
180
- # Update task_selection_history table
181
- for old_id, new_id in id_mapping.items():
182
- db.execute(
183
- "UPDATE task_selection_history SET task_id = ? WHERE task_id = ?",
184
- (new_id, old_id),
185
- )
186
-
187
- # Update worktrees table (task_id column)
188
- for old_id, new_id in id_mapping.items():
189
- db.execute(
190
- "UPDATE worktrees SET task_id = ? WHERE task_id = ?",
191
- (new_id, old_id),
192
- )
193
-
194
- logger.debug(f"Successfully converted {len(id_mapping)} task IDs to UUID format")
195
-
196
- finally:
197
- # Re-enable foreign keys
198
- db.execute("PRAGMA foreign_keys = ON")
199
-
200
-
201
- def _backfill_path_cache(db: "LocalDatabase") -> None:
202
- """
203
- Backfill path_cache values for existing tasks.
204
-
205
- Computes hierarchical paths by traversing parent chains.
206
- Processes root tasks first, then children to ensure parent paths exist.
207
- """
208
- from gobby.storage.tasks import LocalTaskManager
209
-
210
- task_mgr = LocalTaskManager(db)
211
-
212
- # Get all tasks that have seq_num but no path_cache, ordered by hierarchy depth
213
- # Use a recursive CTE to determine depth and process root tasks first
214
- tasks = db.fetchall(
215
- """
216
- WITH RECURSIVE task_depth AS (
217
- -- Base case: root tasks (no parent)
218
- SELECT id, 0 as depth
219
- FROM tasks
220
- WHERE parent_task_id IS NULL
221
- AND seq_num IS NOT NULL
222
- AND path_cache IS NULL
223
-
224
- UNION ALL
225
-
226
- -- Recursive case: children (only if parent has seq_num)
227
- SELECT t.id, td.depth + 1
228
- FROM tasks t
229
- JOIN task_depth td ON t.parent_task_id = td.id
230
- WHERE t.seq_num IS NOT NULL
231
- AND t.path_cache IS NULL
232
- )
233
- SELECT id FROM task_depth ORDER BY depth ASC
234
- """
235
- )
236
-
237
- if not tasks:
238
- logger.debug("No tasks need path_cache backfill")
239
- return
240
-
241
- # Compute and store path for each task
242
- updated = 0
243
- for task in tasks:
244
- path = task_mgr.update_path_cache(task["id"])
245
- if path:
246
- updated += 1
247
-
248
- logger.debug(f"Backfilled path_cache for {updated} tasks")
249
-
250
-
251
- # Legacy migrations (v1-60)
252
- # These are only run when upgrading a database from version < 60.
253
- LEGACY_MIGRATIONS: list[tuple[int, str, MigrationAction]] = [
254
- (
255
- 1,
256
- "Create schema_version table",
257
- """
258
- CREATE TABLE IF NOT EXISTS schema_version (
259
- version INTEGER PRIMARY KEY,
260
- applied_at TEXT NOT NULL DEFAULT (datetime('now'))
261
- );
262
- """,
263
- ),
264
- (
265
- 2,
266
- "Create projects table",
267
- """
268
- CREATE TABLE IF NOT EXISTS projects (
269
- id TEXT PRIMARY KEY,
270
- name TEXT NOT NULL UNIQUE,
271
- repo_path TEXT,
272
- github_url TEXT,
273
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
274
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
275
- );
276
- CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(name);
277
- """,
278
- ),
279
- (
280
- 3,
281
- "Create sessions table",
282
- """
283
- CREATE TABLE IF NOT EXISTS sessions (
284
- id TEXT PRIMARY KEY,
285
- cli_key TEXT NOT NULL,
286
- machine_id TEXT NOT NULL,
287
- source TEXT NOT NULL,
288
- project_id TEXT REFERENCES projects(id),
289
- title TEXT,
290
- status TEXT DEFAULT 'active',
291
- jsonl_path TEXT,
292
- summary_path TEXT,
293
- summary_markdown TEXT,
294
- cwd TEXT,
295
- git_branch TEXT,
296
- parent_session_id TEXT REFERENCES sessions(id),
297
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
298
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
299
- );
300
- CREATE INDEX IF NOT EXISTS idx_sessions_cli_key ON sessions(cli_key);
301
- CREATE INDEX IF NOT EXISTS idx_sessions_machine_id ON sessions(machine_id);
302
- CREATE INDEX IF NOT EXISTS idx_sessions_source ON sessions(source);
303
- CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
304
- CREATE INDEX IF NOT EXISTS idx_sessions_project_id ON sessions(project_id);
305
- CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_unique
306
- ON sessions(cli_key, machine_id, source);
307
- """,
308
- ),
309
- (
310
- 4,
311
- "Create mcp_servers table",
312
- """
313
- CREATE TABLE IF NOT EXISTS mcp_servers (
314
- id TEXT PRIMARY KEY,
315
- name TEXT NOT NULL UNIQUE,
316
- transport TEXT NOT NULL,
317
- url TEXT,
318
- command TEXT,
319
- args TEXT,
320
- env TEXT,
321
- headers TEXT,
322
- enabled INTEGER DEFAULT 1,
323
- description TEXT,
324
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
325
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
326
- );
327
- CREATE INDEX IF NOT EXISTS idx_mcp_servers_name ON mcp_servers(name);
328
- CREATE INDEX IF NOT EXISTS idx_mcp_servers_enabled ON mcp_servers(enabled);
329
- """,
330
- ),
331
- (
332
- 5,
333
- "Create tools table",
334
- """
335
- CREATE TABLE IF NOT EXISTS tools (
336
- id TEXT PRIMARY KEY,
337
- mcp_server_id TEXT NOT NULL REFERENCES mcp_servers(id) ON DELETE CASCADE,
338
- name TEXT NOT NULL,
339
- description TEXT,
340
- input_schema TEXT,
341
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
342
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
343
- UNIQUE(mcp_server_id, name)
344
- );
345
- CREATE INDEX IF NOT EXISTS idx_tools_server_id ON tools(mcp_server_id);
346
- CREATE INDEX IF NOT EXISTS idx_tools_name ON tools(name);
347
- """,
348
- ),
349
- (
350
- 6,
351
- "Remove cwd column from sessions (use project_id instead)",
352
- """
353
- PRAGMA foreign_keys = OFF;
354
- INSERT OR IGNORE INTO projects (id, name, repo_path, created_at, updated_at)
355
- VALUES ('00000000-0000-0000-0000-000000000000', '_orphaned', NULL, datetime('now'), datetime('now'));
356
- CREATE TABLE sessions_new (
357
- id TEXT PRIMARY KEY,
358
- cli_key TEXT NOT NULL,
359
- machine_id TEXT NOT NULL,
360
- source TEXT NOT NULL,
361
- project_id TEXT NOT NULL REFERENCES projects(id),
362
- title TEXT,
363
- status TEXT DEFAULT 'active',
364
- jsonl_path TEXT,
365
- summary_path TEXT,
366
- summary_markdown TEXT,
367
- git_branch TEXT,
368
- parent_session_id TEXT REFERENCES sessions(id),
369
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
370
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
371
- );
372
- INSERT INTO sessions_new (id, cli_key, machine_id, source, project_id, title, status, jsonl_path, summary_path, summary_markdown, git_branch, parent_session_id, created_at, updated_at)
373
- SELECT id, cli_key, machine_id, source, COALESCE(project_id, '00000000-0000-0000-0000-000000000000'), title, status, jsonl_path, summary_path, summary_markdown, git_branch, parent_session_id, created_at, updated_at FROM sessions;
374
- DROP TABLE sessions;
375
- ALTER TABLE sessions_new RENAME TO sessions;
376
- CREATE INDEX IF NOT EXISTS idx_sessions_cli_key ON sessions(cli_key);
377
- CREATE INDEX IF NOT EXISTS idx_sessions_machine_id ON sessions(machine_id);
378
- CREATE INDEX IF NOT EXISTS idx_sessions_source ON sessions(source);
379
- CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
380
- CREATE INDEX IF NOT EXISTS idx_sessions_project_id ON sessions(project_id);
381
- CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_unique ON sessions(cli_key, machine_id, source);
382
- PRAGMA foreign_keys = ON;
383
- """,
384
- ),
385
- (
386
- 7,
387
- "Add project_id to mcp_servers (required, no global servers)",
388
- """
389
- PRAGMA foreign_keys = OFF;
390
- CREATE TABLE mcp_servers_new (
391
- id TEXT PRIMARY KEY,
392
- name TEXT NOT NULL,
393
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
394
- transport TEXT NOT NULL,
395
- url TEXT,
396
- command TEXT,
397
- args TEXT,
398
- env TEXT,
399
- headers TEXT,
400
- enabled INTEGER DEFAULT 1,
401
- description TEXT,
402
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
403
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
404
- );
405
- INSERT OR IGNORE INTO projects (id, name, repo_path, created_at, updated_at)
406
- VALUES ('00000000-0000-0000-0000-000000000001', '_migrated', NULL, datetime('now'), datetime('now'));
407
- INSERT INTO mcp_servers_new (id, name, project_id, transport, url, command, args, env, headers, enabled, description, created_at, updated_at)
408
- SELECT id, name, '00000000-0000-0000-0000-000000000001', transport, url, command, args, env, headers, enabled, description, created_at, updated_at FROM mcp_servers;
409
- DROP TABLE mcp_servers;
410
- ALTER TABLE mcp_servers_new RENAME TO mcp_servers;
411
- CREATE INDEX IF NOT EXISTS idx_mcp_servers_name ON mcp_servers(name);
412
- CREATE INDEX IF NOT EXISTS idx_mcp_servers_project_id ON mcp_servers(project_id);
413
- CREATE INDEX IF NOT EXISTS idx_mcp_servers_enabled ON mcp_servers(enabled);
414
- CREATE UNIQUE INDEX IF NOT EXISTS idx_mcp_servers_name_project
415
- ON mcp_servers(name, project_id);
416
- PRAGMA foreign_keys = ON;
417
- """,
418
- ),
419
- (
420
- 8,
421
- "Rename cli_key to external_id in sessions table",
422
- """
423
- PRAGMA foreign_keys = OFF;
424
- CREATE TABLE sessions_new (
425
- id TEXT PRIMARY KEY,
426
- external_id TEXT NOT NULL,
427
- machine_id TEXT NOT NULL,
428
- source TEXT NOT NULL,
429
- project_id TEXT NOT NULL REFERENCES projects(id),
430
- title TEXT,
431
- status TEXT DEFAULT 'active',
432
- jsonl_path TEXT,
433
- summary_path TEXT,
434
- summary_markdown TEXT,
435
- git_branch TEXT,
436
- parent_session_id TEXT REFERENCES sessions(id),
437
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
438
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
439
- );
440
- INSERT INTO sessions_new (id, external_id, machine_id, source, project_id, title, status, jsonl_path, summary_path, summary_markdown, git_branch, parent_session_id, created_at, updated_at)
441
- SELECT id, cli_key, machine_id, source, project_id, title, status, jsonl_path, summary_path, summary_markdown, git_branch, parent_session_id, created_at, updated_at FROM sessions;
442
- DROP TABLE sessions;
443
- ALTER TABLE sessions_new RENAME TO sessions;
444
- CREATE INDEX IF NOT EXISTS idx_sessions_external_id ON sessions(external_id);
445
- CREATE INDEX IF NOT EXISTS idx_sessions_machine_id ON sessions(machine_id);
446
- CREATE INDEX IF NOT EXISTS idx_sessions_source ON sessions(source);
447
- CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
448
- CREATE INDEX IF NOT EXISTS idx_sessions_project_id ON sessions(project_id);
449
- CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_unique ON sessions(external_id, machine_id, source);
450
- PRAGMA foreign_keys = ON;
451
- """,
452
- ),
453
- (
454
- 9,
455
- "Create task system tables (tasks, dependencies, session linkages)",
456
- """
457
- CREATE TABLE IF NOT EXISTS tasks (
458
- id TEXT PRIMARY KEY,
459
- project_id TEXT NOT NULL REFERENCES projects(id),
460
- parent_task_id TEXT REFERENCES tasks(id),
461
- discovered_in_session_id TEXT REFERENCES sessions(id),
462
- title TEXT NOT NULL,
463
- description TEXT,
464
- status TEXT DEFAULT 'open',
465
- priority INTEGER DEFAULT 2,
466
- type TEXT DEFAULT 'task',
467
- assignee TEXT,
468
- labels TEXT,
469
- closed_reason TEXT,
470
- created_at TEXT NOT NULL,
471
- updated_at TEXT NOT NULL
472
- );
473
- CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id);
474
- CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
475
- CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_task_id);
476
-
477
- CREATE TABLE IF NOT EXISTS task_dependencies (
478
- id INTEGER PRIMARY KEY AUTOINCREMENT,
479
- task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
480
- depends_on TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
481
- dep_type TEXT NOT NULL,
482
- created_at TEXT NOT NULL,
483
- UNIQUE(task_id, depends_on, dep_type)
484
- );
485
- CREATE INDEX IF NOT EXISTS idx_deps_task ON task_dependencies(task_id);
486
- CREATE INDEX IF NOT EXISTS idx_deps_depends_on ON task_dependencies(depends_on);
487
-
488
- CREATE TABLE IF NOT EXISTS session_tasks (
489
- id INTEGER PRIMARY KEY AUTOINCREMENT,
490
- session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
491
- task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
492
- action TEXT NOT NULL,
493
- created_at TEXT NOT NULL,
494
- UNIQUE(session_id, task_id, action)
495
- );
496
- CREATE INDEX IF NOT EXISTS idx_session_tasks_session ON session_tasks(session_id);
497
- CREATE INDEX IF NOT EXISTS idx_session_tasks_task ON session_tasks(task_id);
498
- """,
499
- ),
500
- (
501
- 10,
502
- "Add platform_id column to tasks for future fleet sync",
503
- """
504
- ALTER TABLE tasks ADD COLUMN platform_id TEXT;
505
- CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_platform_id
506
- ON tasks(platform_id) WHERE platform_id IS NOT NULL;
507
- """,
508
- ),
509
- (
510
- 11,
511
- "Add compaction columns to tasks",
512
- """
513
- ALTER TABLE tasks ADD COLUMN compacted_at TEXT;
514
- ALTER TABLE tasks ADD COLUMN summary TEXT;
515
- """,
516
- ),
517
- (
518
- 12,
519
- "Create workflow state and handoff tables",
520
- """
521
- CREATE TABLE IF NOT EXISTS workflow_states (
522
- session_id TEXT PRIMARY KEY,
523
- workflow_name TEXT NOT NULL,
524
- phase TEXT NOT NULL,
525
- phase_entered_at TEXT,
526
- phase_action_count INTEGER DEFAULT 0,
527
- total_action_count INTEGER DEFAULT 0,
528
- artifacts TEXT,
529
- observations TEXT,
530
- reflection_pending INTEGER DEFAULT 0,
531
- context_injected INTEGER DEFAULT 0,
532
- variables TEXT,
533
- task_list TEXT,
534
- current_task_index INTEGER DEFAULT 0,
535
- files_modified_this_task INTEGER DEFAULT 0,
536
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
537
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
538
- FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
539
- );
540
-
541
- CREATE TABLE IF NOT EXISTS workflow_handoffs (
542
- id INTEGER PRIMARY KEY AUTOINCREMENT,
543
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
544
- workflow_name TEXT NOT NULL,
545
- from_session_id TEXT REFERENCES sessions(id),
546
- phase TEXT,
547
- artifacts TEXT,
548
- pending_tasks TEXT,
549
- notes TEXT,
550
- consumed_at TEXT,
551
- consumed_by_session TEXT REFERENCES sessions(id),
552
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
553
- );
554
- CREATE INDEX IF NOT EXISTS idx_workflow_handoffs_project ON workflow_handoffs(project_id);
555
- CREATE INDEX IF NOT EXISTS idx_workflow_handoffs_consumed ON workflow_handoffs(consumed_at);
556
- """,
557
- ),
558
- (
559
- 13,
560
- "Drop workflow_handoffs table (replaced by sessions.summary_markdown)",
561
- """
562
- DROP TABLE IF EXISTS workflow_handoffs;
563
- """,
564
- ),
565
- (
566
- 14,
567
- "Add task validation columns",
568
- """
569
- ALTER TABLE tasks ADD COLUMN validation_status TEXT CHECK(validation_status IN ('pending', 'valid', 'invalid'));
570
- ALTER TABLE tasks ADD COLUMN validation_feedback TEXT;
571
- ALTER TABLE tasks ADD COLUMN original_instruction TEXT;
572
- """,
573
- ),
574
- (
575
- 15,
576
- "Create session messages tables",
577
- """
578
- CREATE TABLE IF NOT EXISTS session_messages (
579
- id INTEGER PRIMARY KEY AUTOINCREMENT,
580
- session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
581
- message_index INTEGER NOT NULL,
582
- role TEXT NOT NULL,
583
- content TEXT NOT NULL,
584
- content_type TEXT DEFAULT 'text',
585
- tool_name TEXT,
586
- tool_input TEXT,
587
- tool_result TEXT,
588
- timestamp TEXT NOT NULL,
589
- raw_json TEXT,
590
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
591
- UNIQUE(session_id, message_index)
592
- );
593
-
594
- CREATE INDEX IF NOT EXISTS idx_session_messages_session ON session_messages(session_id);
595
- CREATE INDEX IF NOT EXISTS idx_session_messages_role ON session_messages(role);
596
- CREATE INDEX IF NOT EXISTS idx_session_messages_timestamp ON session_messages(timestamp);
597
- CREATE INDEX IF NOT EXISTS idx_session_messages_tool ON session_messages(tool_name);
598
-
599
- CREATE TABLE IF NOT EXISTS session_message_state (
600
- session_id TEXT PRIMARY KEY REFERENCES sessions(id) ON DELETE CASCADE,
601
- last_byte_offset INTEGER DEFAULT 0,
602
- last_message_index INTEGER DEFAULT 0,
603
- last_processed_at TEXT,
604
- processing_errors INTEGER DEFAULT 0,
605
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
606
- );
607
- """,
608
- ),
609
- (
610
- 16,
611
- "Add transcript_processed column to sessions",
612
- """
613
- ALTER TABLE sessions ADD COLUMN transcript_processed BOOLEAN DEFAULT FALSE;
614
-
615
- CREATE INDEX IF NOT EXISTS idx_sessions_pending_transcript
616
- ON sessions(status, transcript_processed)
617
- WHERE status = 'expired' AND transcript_processed = FALSE;
618
- """,
619
- ),
620
- (
621
- 17,
622
- "Create memory system tables (memories, skills, session_memories)",
623
- """
624
- CREATE TABLE IF NOT EXISTS memories (
625
- id TEXT PRIMARY KEY,
626
- project_id TEXT REFERENCES projects(id),
627
- memory_type TEXT NOT NULL,
628
- content TEXT NOT NULL,
629
- source_type TEXT,
630
- source_session_id TEXT REFERENCES sessions(id),
631
- importance REAL DEFAULT 0.5,
632
- access_count INTEGER DEFAULT 0,
633
- last_accessed_at TEXT,
634
- embedding BLOB,
635
- tags TEXT,
636
- created_at TEXT NOT NULL,
637
- updated_at TEXT NOT NULL
638
- );
639
- CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project_id);
640
- CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type);
641
- CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance DESC);
642
-
643
- CREATE TABLE IF NOT EXISTS skills (
644
- id TEXT PRIMARY KEY,
645
- project_id TEXT REFERENCES projects(id),
646
- name TEXT NOT NULL,
647
- description TEXT,
648
- trigger_pattern TEXT,
649
- instructions TEXT NOT NULL,
650
- source_session_id TEXT REFERENCES sessions(id),
651
- tags TEXT,
652
- created_at TEXT NOT NULL,
653
- updated_at TEXT NOT NULL
654
- );
655
- CREATE INDEX IF NOT EXISTS idx_skills_project ON skills(project_id);
656
- CREATE INDEX IF NOT EXISTS idx_skills_name ON skills(name);
657
-
658
- CREATE TABLE IF NOT EXISTS session_memories (
659
- id INTEGER PRIMARY KEY AUTOINCREMENT,
660
- session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
661
- memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
662
- action TEXT NOT NULL,
663
- created_at TEXT NOT NULL,
664
- UNIQUE(session_id, memory_id, action)
665
- );
666
- CREATE INDEX IF NOT EXISTS idx_session_memories_session ON session_memories(session_id);
667
- CREATE INDEX IF NOT EXISTS idx_session_memories_memory ON session_memories(memory_id);
668
- """,
669
- ),
670
- (
671
- 18,
672
- "Add expansion fields to tasks table",
673
- """
674
- ALTER TABLE tasks ADD COLUMN details TEXT;
675
- ALTER TABLE tasks ADD COLUMN test_strategy TEXT;
676
- ALTER TABLE tasks ADD COLUMN complexity_score INTEGER;
677
- ALTER TABLE tasks ADD COLUMN estimated_subtasks INTEGER;
678
- ALTER TABLE tasks ADD COLUMN expansion_context TEXT;
679
- """,
680
- ),
681
- (
682
- 19,
683
- "Add enhanced validation fields",
684
- """
685
- ALTER TABLE tasks ADD COLUMN validation_criteria TEXT;
686
- ALTER TABLE tasks ADD COLUMN use_external_validator INTEGER DEFAULT 0;
687
- ALTER TABLE tasks ADD COLUMN validation_fail_count INTEGER DEFAULT 0;
688
- """,
689
- ),
690
- (
691
- 20,
692
- "Add compact_markdown column to sessions for compaction handoff",
693
- """
694
- ALTER TABLE sessions ADD COLUMN compact_markdown TEXT;
695
- """,
696
- ),
697
- (
698
- 21,
699
- "Create tool_embeddings table for semantic search",
700
- """
701
- CREATE TABLE IF NOT EXISTS tool_embeddings (
702
- id INTEGER PRIMARY KEY AUTOINCREMENT,
703
- tool_id TEXT NOT NULL REFERENCES tools(id) ON DELETE CASCADE,
704
- server_name TEXT NOT NULL,
705
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
706
- embedding BLOB NOT NULL,
707
- embedding_model TEXT NOT NULL,
708
- embedding_dim INTEGER NOT NULL,
709
- text_hash TEXT NOT NULL,
710
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
711
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
712
- UNIQUE(tool_id)
713
- );
714
- CREATE INDEX IF NOT EXISTS idx_tool_embeddings_tool ON tool_embeddings(tool_id);
715
- CREATE INDEX IF NOT EXISTS idx_tool_embeddings_server ON tool_embeddings(server_name);
716
- CREATE INDEX IF NOT EXISTS idx_tool_embeddings_project ON tool_embeddings(project_id);
717
- CREATE INDEX IF NOT EXISTS idx_tool_embeddings_hash ON tool_embeddings(text_hash);
718
- """,
719
- ),
720
- (
721
- 22,
722
- "Add workflow integration columns to tasks table",
723
- """
724
- ALTER TABLE tasks ADD COLUMN workflow_name TEXT;
725
- ALTER TABLE tasks ADD COLUMN verification TEXT;
726
- ALTER TABLE tasks ADD COLUMN sequence_order INTEGER;
727
- CREATE INDEX IF NOT EXISTS idx_tasks_workflow ON tasks(workflow_name);
728
- CREATE INDEX IF NOT EXISTS idx_tasks_sequence ON tasks(workflow_name, sequence_order);
729
- """,
730
- ),
731
- (
732
- 23,
733
- "Rename discovered_in_session_id to created_in_session_id and add close tracking columns",
734
- """
735
- PRAGMA foreign_keys = OFF;
736
-
737
- CREATE TABLE tasks_new (
738
- id TEXT PRIMARY KEY,
739
- project_id TEXT NOT NULL REFERENCES projects(id),
740
- parent_task_id TEXT REFERENCES tasks(id),
741
- created_in_session_id TEXT REFERENCES sessions(id),
742
- closed_in_session_id TEXT REFERENCES sessions(id),
743
- closed_commit_sha TEXT,
744
- closed_at TEXT,
745
- title TEXT NOT NULL,
746
- description TEXT,
747
- status TEXT DEFAULT 'open',
748
- priority INTEGER DEFAULT 2,
749
- type TEXT DEFAULT 'task',
750
- assignee TEXT,
751
- labels TEXT,
752
- closed_reason TEXT,
753
- created_at TEXT NOT NULL,
754
- updated_at TEXT NOT NULL,
755
- platform_id TEXT,
756
- compacted_at TEXT,
757
- summary TEXT,
758
- validation_status TEXT CHECK(validation_status IN ('pending', 'valid', 'invalid')),
759
- validation_feedback TEXT,
760
- original_instruction TEXT,
761
- details TEXT,
762
- test_strategy TEXT,
763
- complexity_score INTEGER,
764
- estimated_subtasks INTEGER,
765
- expansion_context TEXT,
766
- validation_criteria TEXT,
767
- use_external_validator INTEGER DEFAULT 0,
768
- validation_fail_count INTEGER DEFAULT 0,
769
- workflow_name TEXT,
770
- verification TEXT,
771
- sequence_order INTEGER
772
- );
773
-
774
- INSERT INTO tasks_new (
775
- id, project_id, parent_task_id, created_in_session_id,
776
- closed_in_session_id, closed_commit_sha, closed_at,
777
- title, description, status, priority, type, assignee, labels,
778
- closed_reason, created_at, updated_at, platform_id,
779
- compacted_at, summary, validation_status, validation_feedback,
780
- original_instruction, details, test_strategy, complexity_score,
781
- estimated_subtasks, expansion_context, validation_criteria,
782
- use_external_validator, validation_fail_count,
783
- workflow_name, verification, sequence_order
784
- )
785
- SELECT
786
- id, project_id, parent_task_id, discovered_in_session_id,
787
- NULL, NULL, NULL,
788
- title, description, status, priority, type, assignee, labels,
789
- closed_reason, created_at, updated_at, platform_id,
790
- compacted_at, summary, validation_status, validation_feedback,
791
- original_instruction, details, test_strategy, complexity_score,
792
- estimated_subtasks, expansion_context, validation_criteria,
793
- use_external_validator, validation_fail_count,
794
- workflow_name, verification, sequence_order
795
- FROM tasks;
796
-
797
- DROP TABLE tasks;
798
- ALTER TABLE tasks_new RENAME TO tasks;
799
-
800
- CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id);
801
- CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
802
- CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_task_id);
803
- CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_platform_id
804
- ON tasks(platform_id) WHERE platform_id IS NOT NULL;
805
- CREATE INDEX IF NOT EXISTS idx_tasks_workflow ON tasks(workflow_name);
806
- CREATE INDEX IF NOT EXISTS idx_tasks_sequence ON tasks(workflow_name, sequence_order);
807
- CREATE INDEX IF NOT EXISTS idx_tasks_created_session ON tasks(created_in_session_id);
808
- CREATE INDEX IF NOT EXISTS idx_tasks_closed_session ON tasks(closed_in_session_id);
809
-
810
- PRAGMA foreign_keys = ON;
811
- """,
812
- ),
813
- (
814
- 24,
815
- "Create workflow_audit_log table for workflow explainability",
816
- """
817
- CREATE TABLE IF NOT EXISTS workflow_audit_log (
818
- id INTEGER PRIMARY KEY AUTOINCREMENT,
819
- session_id TEXT NOT NULL,
820
- timestamp TEXT NOT NULL DEFAULT (datetime('now')),
821
- phase TEXT NOT NULL,
822
- event_type TEXT NOT NULL,
823
- tool_name TEXT,
824
- rule_id TEXT,
825
- condition TEXT,
826
- result TEXT NOT NULL,
827
- reason TEXT,
828
- context TEXT,
829
- FOREIGN KEY (session_id) REFERENCES sessions(id)
830
- );
831
-
832
- CREATE INDEX IF NOT EXISTS idx_audit_session ON workflow_audit_log(session_id);
833
- CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON workflow_audit_log(timestamp);
834
- CREATE INDEX IF NOT EXISTS idx_audit_event_type ON workflow_audit_log(event_type);
835
- CREATE INDEX IF NOT EXISTS idx_audit_result ON workflow_audit_log(result);
836
- """,
837
- ),
838
- (
839
- 25,
840
- "Add validation_override_reason column to tasks",
841
- """
842
- ALTER TABLE tasks ADD COLUMN validation_override_reason TEXT;
843
- """,
844
- ),
845
- (
846
- 26,
847
- "Rename phase columns to step in workflow tables",
848
- """
849
- PRAGMA foreign_keys = OFF;
850
-
851
- CREATE TABLE workflow_states_new (
852
- session_id TEXT PRIMARY KEY,
853
- workflow_name TEXT NOT NULL,
854
- step TEXT NOT NULL,
855
- step_entered_at TEXT,
856
- step_action_count INTEGER DEFAULT 0,
857
- total_action_count INTEGER DEFAULT 0,
858
- artifacts TEXT,
859
- observations TEXT,
860
- reflection_pending INTEGER DEFAULT 0,
861
- context_injected INTEGER DEFAULT 0,
862
- variables TEXT,
863
- task_list TEXT,
864
- current_task_index INTEGER DEFAULT 0,
865
- files_modified_this_task INTEGER DEFAULT 0,
866
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
867
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
868
- FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
869
- );
870
-
871
- INSERT INTO workflow_states_new (
872
- session_id, workflow_name, step, step_entered_at, step_action_count,
873
- total_action_count, artifacts, observations, reflection_pending,
874
- context_injected, variables, task_list, current_task_index,
875
- files_modified_this_task, created_at, updated_at
876
- )
877
- SELECT
878
- session_id, workflow_name, phase, phase_entered_at, phase_action_count,
879
- total_action_count, artifacts, observations, reflection_pending,
880
- context_injected, variables, task_list, current_task_index,
881
- files_modified_this_task, created_at, updated_at
882
- FROM workflow_states;
883
-
884
- DROP TABLE workflow_states;
885
- ALTER TABLE workflow_states_new RENAME TO workflow_states;
886
-
887
- CREATE TABLE workflow_audit_log_new (
888
- id INTEGER PRIMARY KEY AUTOINCREMENT,
889
- session_id TEXT NOT NULL,
890
- timestamp TEXT NOT NULL DEFAULT (datetime('now')),
891
- step TEXT NOT NULL,
892
- event_type TEXT NOT NULL,
893
- tool_name TEXT,
894
- rule_id TEXT,
895
- condition TEXT,
896
- result TEXT NOT NULL,
897
- reason TEXT,
898
- context TEXT,
899
- FOREIGN KEY (session_id) REFERENCES sessions(id)
900
- );
901
-
902
- INSERT INTO workflow_audit_log_new (
903
- id, session_id, timestamp, step, event_type, tool_name,
904
- rule_id, condition, result, reason, context
905
- )
906
- SELECT
907
- id, session_id, timestamp, phase, event_type, tool_name,
908
- rule_id, condition, result, reason, context
909
- FROM workflow_audit_log;
910
-
911
- DROP TABLE workflow_audit_log;
912
- ALTER TABLE workflow_audit_log_new RENAME TO workflow_audit_log;
913
-
914
- CREATE INDEX IF NOT EXISTS idx_audit_session ON workflow_audit_log(session_id);
915
- CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON workflow_audit_log(timestamp);
916
- CREATE INDEX IF NOT EXISTS idx_audit_event_type ON workflow_audit_log(event_type);
917
- CREATE INDEX IF NOT EXISTS idx_audit_result ON workflow_audit_log(result);
918
-
919
- PRAGMA foreign_keys = ON;
920
- """,
921
- ),
922
- (
923
- 27,
924
- "Remove platform_id column from tasks table",
925
- """
926
- DROP INDEX IF EXISTS idx_tasks_platform_id;
927
- ALTER TABLE tasks DROP COLUMN platform_id;
928
- """,
929
- ),
930
- (
931
- 28,
932
- "Create tool_metrics table for tracking tool call statistics",
933
- """
934
- CREATE TABLE IF NOT EXISTS tool_metrics (
935
- id TEXT PRIMARY KEY,
936
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
937
- server_name TEXT NOT NULL,
938
- tool_name TEXT NOT NULL,
939
- call_count INTEGER NOT NULL DEFAULT 0,
940
- success_count INTEGER NOT NULL DEFAULT 0,
941
- failure_count INTEGER NOT NULL DEFAULT 0,
942
- total_latency_ms REAL NOT NULL DEFAULT 0,
943
- avg_latency_ms REAL,
944
- last_called_at TEXT,
945
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
946
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
947
- UNIQUE(project_id, server_name, tool_name)
948
- );
949
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_project ON tool_metrics(project_id);
950
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_server ON tool_metrics(server_name);
951
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_tool ON tool_metrics(tool_name);
952
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_call_count ON tool_metrics(call_count DESC);
953
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_last_called ON tool_metrics(last_called_at);
954
- """,
955
- ),
956
- (
957
- 29,
958
- "Create tool_schema_hashes table for incremental tool re-indexing",
959
- """
960
- CREATE TABLE IF NOT EXISTS tool_schema_hashes (
961
- id INTEGER PRIMARY KEY AUTOINCREMENT,
962
- server_name TEXT NOT NULL,
963
- tool_name TEXT NOT NULL,
964
- project_id TEXT NOT NULL,
965
- schema_hash TEXT NOT NULL,
966
- last_verified_at TEXT NOT NULL DEFAULT (datetime('now')),
967
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
968
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
969
- UNIQUE(project_id, server_name, tool_name)
970
- );
971
- CREATE INDEX IF NOT EXISTS idx_schema_hashes_server ON tool_schema_hashes(server_name);
972
- CREATE INDEX IF NOT EXISTS idx_schema_hashes_project ON tool_schema_hashes(project_id);
973
- CREATE INDEX IF NOT EXISTS idx_schema_hashes_verified ON tool_schema_hashes(last_verified_at);
974
- """,
975
- ),
976
- (
977
- 30,
978
- "Add commits column to tasks table for commit linking",
979
- """
980
- ALTER TABLE tasks ADD COLUMN commits TEXT;
981
- """,
982
- ),
983
- (
984
- 31,
985
- "Create task_validation_history table and add escalation columns to tasks",
986
- """
987
- CREATE TABLE IF NOT EXISTS task_validation_history (
988
- id INTEGER PRIMARY KEY AUTOINCREMENT,
989
- task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
990
- iteration INTEGER NOT NULL,
991
- status TEXT NOT NULL,
992
- feedback TEXT,
993
- issues TEXT,
994
- context_type TEXT,
995
- context_summary TEXT,
996
- validator_type TEXT,
997
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
998
- );
999
- CREATE INDEX IF NOT EXISTS idx_validation_history_task ON task_validation_history(task_id);
1000
-
1001
- ALTER TABLE tasks ADD COLUMN escalated_at TEXT;
1002
- ALTER TABLE tasks ADD COLUMN escalation_reason TEXT;
1003
- """,
1004
- ),
1005
- (
1006
- 32,
1007
- "Create tool_metrics_daily table for aggregated historical metrics",
1008
- """
1009
- CREATE TABLE IF NOT EXISTS tool_metrics_daily (
1010
- id INTEGER PRIMARY KEY AUTOINCREMENT,
1011
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
1012
- server_name TEXT NOT NULL,
1013
- tool_name TEXT NOT NULL,
1014
- date TEXT NOT NULL,
1015
- call_count INTEGER NOT NULL DEFAULT 0,
1016
- success_count INTEGER NOT NULL DEFAULT 0,
1017
- failure_count INTEGER NOT NULL DEFAULT 0,
1018
- total_latency_ms REAL NOT NULL DEFAULT 0,
1019
- avg_latency_ms REAL,
1020
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
1021
- UNIQUE(project_id, server_name, tool_name, date)
1022
- );
1023
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_daily_project ON tool_metrics_daily(project_id);
1024
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_daily_date ON tool_metrics_daily(date);
1025
- CREATE INDEX IF NOT EXISTS idx_tool_metrics_daily_server ON tool_metrics_daily(server_name);
1026
- """,
1027
- ),
1028
- (
1029
- 33,
1030
- "Add agent_depth and spawned_by_agent_id columns to sessions table",
1031
- """
1032
- ALTER TABLE sessions ADD COLUMN agent_depth INTEGER DEFAULT 0;
1033
- ALTER TABLE sessions ADD COLUMN spawned_by_agent_id TEXT;
1034
- CREATE INDEX IF NOT EXISTS idx_sessions_agent_depth ON sessions(agent_depth);
1035
- CREATE INDEX IF NOT EXISTS idx_sessions_spawned_by ON sessions(spawned_by_agent_id);
1036
- """,
1037
- ),
1038
- (
1039
- 34,
1040
- "Create agent_runs table for tracking spawned agent executions",
1041
- """
1042
- CREATE TABLE IF NOT EXISTS agent_runs (
1043
- id TEXT PRIMARY KEY,
1044
- parent_session_id TEXT NOT NULL REFERENCES sessions(id),
1045
- child_session_id TEXT REFERENCES sessions(id),
1046
- workflow_name TEXT,
1047
- provider TEXT NOT NULL,
1048
- model TEXT,
1049
- status TEXT NOT NULL DEFAULT 'pending',
1050
- prompt TEXT NOT NULL,
1051
- result TEXT,
1052
- error TEXT,
1053
- tool_calls_count INTEGER DEFAULT 0,
1054
- turns_used INTEGER DEFAULT 0,
1055
- started_at TEXT,
1056
- completed_at TEXT,
1057
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
1058
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
1059
- );
1060
- CREATE INDEX IF NOT EXISTS idx_agent_runs_parent_session ON agent_runs(parent_session_id);
1061
- CREATE INDEX IF NOT EXISTS idx_agent_runs_child_session ON agent_runs(child_session_id);
1062
- CREATE INDEX IF NOT EXISTS idx_agent_runs_status ON agent_runs(status);
1063
- CREATE INDEX IF NOT EXISTS idx_agent_runs_provider ON agent_runs(provider);
1064
- """,
1065
- ),
1066
- (
1067
- 35,
1068
- "Add terminal pickup metadata fields to sessions table",
1069
- """
1070
- ALTER TABLE sessions ADD COLUMN workflow_name TEXT;
1071
- ALTER TABLE sessions ADD COLUMN agent_run_id TEXT REFERENCES agent_runs(id) ON DELETE SET NULL;
1072
- ALTER TABLE sessions ADD COLUMN context_injected INTEGER DEFAULT 0;
1073
- ALTER TABLE sessions ADD COLUMN original_prompt TEXT;
1074
- CREATE INDEX IF NOT EXISTS idx_sessions_workflow ON sessions(workflow_name);
1075
- CREATE INDEX IF NOT EXISTS idx_sessions_agent_run ON sessions(agent_run_id);
1076
- """,
1077
- ),
1078
- (
1079
- 36,
1080
- "Create worktrees table for git worktree management",
1081
- """
1082
- CREATE TABLE IF NOT EXISTS worktrees (
1083
- id TEXT PRIMARY KEY,
1084
- project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
1085
- task_id TEXT REFERENCES tasks(id) ON DELETE SET NULL,
1086
- branch_name TEXT NOT NULL,
1087
- worktree_path TEXT NOT NULL,
1088
- base_branch TEXT DEFAULT 'main',
1089
- agent_session_id TEXT REFERENCES sessions(id) ON DELETE SET NULL,
1090
- status TEXT DEFAULT 'active',
1091
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
1092
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
1093
- merged_at TEXT
1094
- );
1095
- CREATE INDEX IF NOT EXISTS idx_worktrees_project ON worktrees(project_id);
1096
- CREATE INDEX IF NOT EXISTS idx_worktrees_status ON worktrees(status);
1097
- CREATE INDEX IF NOT EXISTS idx_worktrees_task ON worktrees(task_id);
1098
- CREATE INDEX IF NOT EXISTS idx_worktrees_session ON worktrees(agent_session_id);
1099
- CREATE UNIQUE INDEX IF NOT EXISTS idx_worktrees_branch ON worktrees(project_id, branch_name);
1100
- CREATE UNIQUE INDEX IF NOT EXISTS idx_worktrees_path ON worktrees(worktree_path);
1101
- """,
1102
- ),
1103
- (
1104
- 37,
1105
- "Create session_stop_signals table for autonomous stop infrastructure",
1106
- """
1107
- CREATE TABLE IF NOT EXISTS session_stop_signals (
1108
- session_id TEXT PRIMARY KEY REFERENCES sessions(id) ON DELETE CASCADE,
1109
- source TEXT NOT NULL,
1110
- reason TEXT,
1111
- requested_at TEXT NOT NULL,
1112
- acknowledged_at TEXT
1113
- );
1114
- CREATE INDEX IF NOT EXISTS idx_stop_signals_pending
1115
- ON session_stop_signals(acknowledged_at)
1116
- WHERE acknowledged_at IS NULL;
1117
- """,
1118
- ),
1119
- (
1120
- 38,
1121
- "Create loop_progress table for autonomous progress tracking",
1122
- """
1123
- CREATE TABLE IF NOT EXISTS loop_progress (
1124
- id INTEGER PRIMARY KEY AUTOINCREMENT,
1125
- session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
1126
- progress_type TEXT NOT NULL,
1127
- tool_name TEXT,
1128
- details TEXT,
1129
- recorded_at TEXT NOT NULL,
1130
- is_high_value INTEGER NOT NULL DEFAULT 0
1131
- );
1132
- CREATE INDEX IF NOT EXISTS idx_loop_progress_session
1133
- ON loop_progress(session_id, recorded_at DESC);
1134
- CREATE INDEX IF NOT EXISTS idx_loop_progress_high_value
1135
- ON loop_progress(session_id, is_high_value, recorded_at DESC)
1136
- WHERE is_high_value = 1;
1137
- """,
1138
- ),
1139
- (
1140
- 39,
1141
- "Create task_selection_history table for stuck detection",
1142
- """
1143
- CREATE TABLE IF NOT EXISTS task_selection_history (
1144
- id INTEGER PRIMARY KEY AUTOINCREMENT,
1145
- session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
1146
- task_id TEXT NOT NULL,
1147
- selected_at TEXT NOT NULL,
1148
- context TEXT
1149
- );
1150
- CREATE INDEX IF NOT EXISTS idx_task_selection_session
1151
- ON task_selection_history(session_id, selected_at DESC);
1152
- CREATE INDEX IF NOT EXISTS idx_task_selection_task
1153
- ON task_selection_history(session_id, task_id, selected_at DESC);
1154
- """,
1155
- ),
1156
- (
1157
- 40,
1158
- "Rename type column to task_type in tasks table",
1159
- """
1160
- ALTER TABLE tasks RENAME COLUMN type TO task_type;
1161
- """,
1162
- ),
1163
- (
1164
- 41,
1165
- "Create session_artifacts table with FTS5 for full-text search",
1166
- """
1167
- CREATE TABLE IF NOT EXISTS session_artifacts (
1168
- id TEXT PRIMARY KEY,
1169
- session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
1170
- artifact_type TEXT NOT NULL,
1171
- content TEXT NOT NULL,
1172
- metadata_json TEXT,
1173
- source_file TEXT,
1174
- line_start INTEGER,
1175
- line_end INTEGER,
1176
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
1177
- );
1178
- CREATE INDEX IF NOT EXISTS idx_session_artifacts_session ON session_artifacts(session_id);
1179
- CREATE INDEX IF NOT EXISTS idx_session_artifacts_type ON session_artifacts(artifact_type);
1180
- CREATE INDEX IF NOT EXISTS idx_session_artifacts_created ON session_artifacts(created_at);
1181
- CREATE VIRTUAL TABLE IF NOT EXISTS session_artifacts_fts USING fts5(content);
1182
- """,
1183
- ),
1184
- (
1185
- 42,
1186
- "Add id column to session_artifacts_fts for JOIN support",
1187
- """
1188
- DROP TABLE IF EXISTS session_artifacts_fts;
1189
- CREATE VIRTUAL TABLE IF NOT EXISTS session_artifacts_fts USING fts5(id UNINDEXED, content);
1190
- """,
1191
- ),
1192
- (
1193
- 43,
1194
- "Create merge_resolutions and merge_conflicts tables",
1195
- """
1196
- CREATE TABLE IF NOT EXISTS merge_resolutions (
1197
- id TEXT PRIMARY KEY,
1198
- worktree_id TEXT NOT NULL REFERENCES worktrees(id) ON DELETE CASCADE,
1199
- source_branch TEXT NOT NULL,
1200
- target_branch TEXT NOT NULL,
1201
- status TEXT NOT NULL DEFAULT 'pending',
1202
- tier_used TEXT,
1203
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
1204
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
1205
- );
1206
- CREATE INDEX IF NOT EXISTS idx_merge_resolutions_worktree ON merge_resolutions(worktree_id);
1207
- CREATE INDEX IF NOT EXISTS idx_merge_resolutions_status ON merge_resolutions(status);
1208
- CREATE INDEX IF NOT EXISTS idx_merge_resolutions_source_branch ON merge_resolutions(source_branch);
1209
- CREATE INDEX IF NOT EXISTS idx_merge_resolutions_target_branch ON merge_resolutions(target_branch);
1210
- CREATE TABLE IF NOT EXISTS merge_conflicts (
1211
- id TEXT PRIMARY KEY,
1212
- resolution_id TEXT NOT NULL REFERENCES merge_resolutions(id) ON DELETE CASCADE,
1213
- file_path TEXT NOT NULL,
1214
- status TEXT NOT NULL DEFAULT 'pending',
1215
- ours_content TEXT,
1216
- theirs_content TEXT,
1217
- resolved_content TEXT,
1218
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
1219
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
1220
- );
1221
- CREATE INDEX IF NOT EXISTS idx_merge_conflicts_resolution ON merge_conflicts(resolution_id);
1222
- CREATE INDEX IF NOT EXISTS idx_merge_conflicts_file_path ON merge_conflicts(file_path);
1223
- CREATE INDEX IF NOT EXISTS idx_merge_conflicts_status ON merge_conflicts(status);
1224
- """,
1225
- ),
1226
- (
1227
- 44,
1228
- "Add token usage columns to sessions table",
1229
- """
1230
- ALTER TABLE sessions ADD COLUMN usage_input_tokens INTEGER DEFAULT 0;
1231
- ALTER TABLE sessions ADD COLUMN usage_output_tokens INTEGER DEFAULT 0;
1232
- ALTER TABLE sessions ADD COLUMN usage_cache_creation_tokens INTEGER DEFAULT 0;
1233
- ALTER TABLE sessions ADD COLUMN usage_cache_read_tokens INTEGER DEFAULT 0;
1234
- ALTER TABLE sessions ADD COLUMN usage_total_cost_usd REAL DEFAULT 0.0;
1235
- """,
1236
- ),
1237
- (
1238
- 45,
1239
- "Add terminal_context column to sessions table",
1240
- """
1241
- ALTER TABLE sessions ADD COLUMN terminal_context TEXT;
1242
- """,
1243
- ),
1244
- (
1245
- 46,
1246
- "Drop skills table",
1247
- """
1248
- DROP TABLE IF EXISTS skills;
1249
- """,
1250
- ),
1251
- (
1252
- 47,
1253
- "Create memory_crossrefs table for linking related memories",
1254
- """
1255
- CREATE TABLE IF NOT EXISTS memory_crossrefs (
1256
- source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
1257
- target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
1258
- similarity REAL NOT NULL,
1259
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
1260
- PRIMARY KEY (source_id, target_id)
1261
- );
1262
- CREATE INDEX IF NOT EXISTS idx_crossrefs_source ON memory_crossrefs(source_id);
1263
- CREATE INDEX IF NOT EXISTS idx_crossrefs_target ON memory_crossrefs(target_id);
1264
- CREATE INDEX IF NOT EXISTS idx_crossrefs_similarity ON memory_crossrefs(similarity DESC);
1265
- """,
1266
- ),
1267
- (
1268
- 48,
1269
- "Add GitHub integration columns to tasks table",
1270
- """
1271
- ALTER TABLE tasks ADD COLUMN github_issue_number INTEGER;
1272
- ALTER TABLE tasks ADD COLUMN github_pr_number INTEGER;
1273
- ALTER TABLE tasks ADD COLUMN github_repo TEXT;
1274
- """,
1275
- ),
1276
- (
1277
- 49,
1278
- "Add github_repo column to projects table",
1279
- """
1280
- ALTER TABLE projects ADD COLUMN github_repo TEXT;
1281
- """,
1282
- ),
1283
- (
1284
- 50,
1285
- "Add Linear integration columns to tasks table",
1286
- """
1287
- ALTER TABLE tasks ADD COLUMN linear_issue_id TEXT;
1288
- ALTER TABLE tasks ADD COLUMN linear_team_id TEXT;
1289
- """,
1290
- ),
1291
- (
1292
- 51,
1293
- "Add linear_team_id column to projects table",
1294
- """
1295
- ALTER TABLE projects ADD COLUMN linear_team_id TEXT;
1296
- """,
1297
- ),
1298
- (
1299
- 52,
1300
- "Add seq_num and path_cache columns to tasks table for human-friendly IDs",
1301
- """
1302
- ALTER TABLE tasks ADD COLUMN seq_num INTEGER;
1303
- ALTER TABLE tasks ADD COLUMN path_cache TEXT;
1304
- CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_seq_num ON tasks(project_id, seq_num);
1305
- CREATE INDEX IF NOT EXISTS idx_tasks_path_cache ON tasks(path_cache);
1306
- """,
1307
- ),
1308
- (
1309
- 53,
1310
- "Convert gt-* task IDs to full UUIDs",
1311
- _migrate_task_ids_to_uuid,
1312
- ),
1313
- (
1314
- 54,
1315
- "Backfill seq_num for existing tasks",
1316
- _backfill_seq_num,
1317
- ),
1318
- (
1319
- 55,
1320
- "Backfill path_cache for existing tasks",
1321
- _backfill_path_cache,
1322
- ),
1323
- (
1324
- 56,
1325
- "Add merge_state column to worktrees table",
1326
- """
1327
- ALTER TABLE worktrees ADD COLUMN merge_state TEXT;
1328
- """,
1329
- ),
1330
- (
1331
- 57,
1332
- "Remove embedding column from memories",
1333
- """
1334
- ALTER TABLE memories DROP COLUMN embedding;
1335
- """,
1336
- ),
1337
- (
1338
- 58,
1339
- "Add seq_num column to sessions table for human-friendly IDs (#N)",
1340
- """
1341
- ALTER TABLE sessions ADD COLUMN seq_num INTEGER;
1342
- CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_seq_num ON sessions(seq_num);
1343
- """,
1344
- ),
1345
- (
1346
- 59,
1347
- "Backfill seq_num for existing sessions",
1348
- _backfill_session_seq_num,
1349
- ),
1350
- (
1351
- 60,
1352
- "Add project_id to sessions unique index for safer lookups",
1353
- """
1354
- DROP INDEX IF EXISTS idx_sessions_unique;
1355
- CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_unique
1356
- ON sessions(external_id, machine_id, source, project_id);
1357
- """,
1358
- ),
1359
- ]