@jingyi0605/codingns 0.2.0 → 0.2.5

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 (257) hide show
  1. package/README.md +44 -0
  2. package/bin/codingns.mjs +640 -53
  3. package/dist/public/assets/{TerminalPage-BlbQuWi1.js → TerminalPage-BkjqU9NG.js} +19 -19
  4. package/dist/public/assets/index-C6U8-9jg.css +1 -0
  5. package/dist/public/assets/index-CKSumuV2.js +109 -0
  6. package/dist/public/index.html +2 -2
  7. package/dist/server/config/env.d.ts +1 -0
  8. package/dist/server/config/env.js +3 -0
  9. package/dist/server/config/env.js.map +1 -1
  10. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +89 -0
  11. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +138 -0
  12. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -0
  13. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +115 -0
  14. package/dist/server/modules/assistant-capability/assistant-capability-service.js +241 -0
  15. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -0
  16. package/dist/server/modules/butler/butler-control-session-service.js +69 -30
  17. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  18. package/dist/server/modules/butler/butler-follow-up-scheduler.d.ts +9 -0
  19. package/dist/server/modules/butler/butler-follow-up-scheduler.js +47 -11
  20. package/dist/server/modules/butler/butler-follow-up-scheduler.js.map +1 -1
  21. package/dist/server/modules/butler/butler-follow-up-service.d.ts +7 -1
  22. package/dist/server/modules/butler/butler-follow-up-service.js +10 -0
  23. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  24. package/dist/server/modules/butler/butler-session-service.d.ts +2 -1
  25. package/dist/server/modules/butler/butler-session-service.js +10 -1
  26. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  27. package/dist/server/modules/butler/butler-session-summary-service.d.ts +8 -1
  28. package/dist/server/modules/butler/butler-session-summary-service.js +34 -7
  29. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  30. package/dist/server/modules/butler/context-aggregator.js +44 -13
  31. package/dist/server/modules/butler/context-aggregator.js.map +1 -1
  32. package/dist/server/modules/butler/patrol-scheduler.d.ts +9 -0
  33. package/dist/server/modules/butler/patrol-scheduler.js +63 -9
  34. package/dist/server/modules/butler/patrol-scheduler.js.map +1 -1
  35. package/dist/server/modules/butler/session-summary-scheduler.d.ts +9 -0
  36. package/dist/server/modules/butler/session-summary-scheduler.js +47 -11
  37. package/dist/server/modules/butler/session-summary-scheduler.js.map +1 -1
  38. package/dist/server/modules/debug-target/debug-runtime-reconciliation-scheduler.d.ts +38 -0
  39. package/dist/server/modules/debug-target/debug-runtime-reconciliation-scheduler.js +99 -0
  40. package/dist/server/modules/debug-target/debug-runtime-reconciliation-scheduler.js.map +1 -0
  41. package/dist/server/modules/debug-target/debug-target-controller.d.ts +70 -0
  42. package/dist/server/modules/debug-target/debug-target-controller.js +113 -0
  43. package/dist/server/modules/debug-target/debug-target-controller.js.map +1 -0
  44. package/dist/server/modules/debug-target/debug-target-service.d.ts +102 -0
  45. package/dist/server/modules/debug-target/debug-target-service.js +1484 -0
  46. package/dist/server/modules/debug-target/debug-target-service.js.map +1 -0
  47. package/dist/server/modules/debug-target/framework-compatibility-matrix.d.ts +4 -0
  48. package/dist/server/modules/debug-target/framework-compatibility-matrix.js +45 -0
  49. package/dist/server/modules/debug-target/framework-compatibility-matrix.js.map +1 -0
  50. package/dist/server/modules/debug-target/launch-adapter-registry.d.ts +25 -0
  51. package/dist/server/modules/debug-target/launch-adapter-registry.js +445 -0
  52. package/dist/server/modules/debug-target/launch-adapter-registry.js.map +1 -0
  53. package/dist/server/modules/file/file-content-service.d.ts +2 -1
  54. package/dist/server/modules/file/file-content-service.js +53 -0
  55. package/dist/server/modules/file/file-content-service.js.map +1 -1
  56. package/dist/server/modules/git/commit-orchestrator.d.ts +4 -1
  57. package/dist/server/modules/git/commit-orchestrator.js +18 -1
  58. package/dist/server/modules/git/commit-orchestrator.js.map +1 -1
  59. package/dist/server/modules/git/git-auth.d.ts +25 -0
  60. package/dist/server/modules/git/git-auth.js +88 -0
  61. package/dist/server/modules/git/git-auth.js.map +1 -0
  62. package/dist/server/modules/git/git-controller.d.ts +6 -0
  63. package/dist/server/modules/git/git-controller.js +5 -1
  64. package/dist/server/modules/git/git-controller.js.map +1 -1
  65. package/dist/server/modules/git/git-read-service.d.ts +2 -1
  66. package/dist/server/modules/git/git-read-service.js +19 -2
  67. package/dist/server/modules/git/git-read-service.js.map +1 -1
  68. package/dist/server/modules/git/git-remote-credential-service.d.ts +9 -0
  69. package/dist/server/modules/git/git-remote-credential-service.js +76 -0
  70. package/dist/server/modules/git/git-remote-credential-service.js.map +1 -0
  71. package/dist/server/modules/git/git-write-service.d.ts +5 -2
  72. package/dist/server/modules/git/git-write-service.js +33 -17
  73. package/dist/server/modules/git/git-write-service.js.map +1 -1
  74. package/dist/server/modules/git/types.d.ts +3 -0
  75. package/dist/server/modules/git/workspace-repo-guard.js +3 -2
  76. package/dist/server/modules/git/workspace-repo-guard.js.map +1 -1
  77. package/dist/server/modules/provider/codex-model-options.d.ts +3 -1
  78. package/dist/server/modules/provider/codex-model-options.js +4 -1
  79. package/dist/server/modules/provider/codex-model-options.js.map +1 -1
  80. package/dist/server/modules/provider/opencode-model-options.d.ts +3 -1
  81. package/dist/server/modules/provider/opencode-model-options.js +5 -1
  82. package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
  83. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +24 -0
  84. package/dist/server/modules/provider/provider-discovery-helper-client.js +14 -0
  85. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
  86. package/dist/server/modules/provider/provider-discovery-helper-process.js +54 -0
  87. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  88. package/dist/server/modules/sessions/session-controller.d.ts +5 -0
  89. package/dist/server/modules/sessions/session-controller.js +16 -0
  90. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  91. package/dist/server/modules/sessions/session-history-service.d.ts +19 -5
  92. package/dist/server/modules/sessions/session-history-service.js +322 -39
  93. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  94. package/dist/server/modules/tasks/event-loop-monitor.d.ts +21 -0
  95. package/dist/server/modules/tasks/event-loop-monitor.js +64 -0
  96. package/dist/server/modules/tasks/event-loop-monitor.js.map +1 -0
  97. package/dist/server/modules/tasks/observability-controller.d.ts +30 -0
  98. package/dist/server/modules/tasks/observability-controller.js +44 -0
  99. package/dist/server/modules/tasks/observability-controller.js.map +1 -0
  100. package/dist/server/modules/tasks/observability-service.d.ts +32 -0
  101. package/dist/server/modules/tasks/observability-service.js +104 -0
  102. package/dist/server/modules/tasks/observability-service.js.map +1 -0
  103. package/dist/server/modules/tasks/scheduler-metrics.d.ts +41 -0
  104. package/dist/server/modules/tasks/scheduler-metrics.js +92 -0
  105. package/dist/server/modules/tasks/scheduler-metrics.js.map +1 -0
  106. package/dist/server/modules/tasks/task-activity-log.d.ts +39 -0
  107. package/dist/server/modules/tasks/task-activity-log.js +43 -0
  108. package/dist/server/modules/tasks/task-activity-log.js.map +1 -0
  109. package/dist/server/modules/tasks/task-helper-client.d.ts +11 -0
  110. package/dist/server/modules/tasks/task-helper-client.js +132 -0
  111. package/dist/server/modules/tasks/task-helper-client.js.map +1 -0
  112. package/dist/server/modules/tasks/task-helper-process-handlers.d.ts +16 -0
  113. package/dist/server/modules/tasks/task-helper-process-handlers.js +14 -0
  114. package/dist/server/modules/tasks/task-helper-process-handlers.js.map +1 -0
  115. package/dist/server/modules/tasks/task-helper-process.d.ts +1 -0
  116. package/dist/server/modules/tasks/task-helper-process.js +49 -0
  117. package/dist/server/modules/tasks/task-helper-process.js.map +1 -0
  118. package/dist/server/modules/tasks/task-lane-executors.d.ts +2 -0
  119. package/dist/server/modules/tasks/task-lane-executors.js +15 -0
  120. package/dist/server/modules/tasks/task-lane-executors.js.map +1 -0
  121. package/dist/server/modules/tasks/task-manager.d.ts +15 -0
  122. package/dist/server/modules/tasks/task-manager.js +36 -0
  123. package/dist/server/modules/tasks/task-manager.js.map +1 -0
  124. package/dist/server/modules/tasks/task-metrics.d.ts +9 -0
  125. package/dist/server/modules/tasks/task-metrics.js +81 -0
  126. package/dist/server/modules/tasks/task-metrics.js.map +1 -0
  127. package/dist/server/modules/tasks/task-registry.d.ts +7 -0
  128. package/dist/server/modules/tasks/task-registry.js +21 -0
  129. package/dist/server/modules/tasks/task-registry.js.map +1 -0
  130. package/dist/server/modules/tasks/task-scheduler.d.ts +31 -0
  131. package/dist/server/modules/tasks/task-scheduler.js +473 -0
  132. package/dist/server/modules/tasks/task-scheduler.js.map +1 -0
  133. package/dist/server/modules/tasks/task-types.d.ts +106 -0
  134. package/dist/server/modules/tasks/task-types.js +23 -0
  135. package/dist/server/modules/tasks/task-types.js.map +1 -0
  136. package/dist/server/modules/terminal/command-template-service.d.ts +4 -0
  137. package/dist/server/modules/terminal/command-template-service.js +5 -3
  138. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  139. package/dist/server/modules/terminal/runtime/terminal-log-spooler.d.ts +7 -3
  140. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js +95 -15
  141. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js.map +1 -1
  142. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.d.ts +21 -0
  143. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.js +144 -0
  144. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.js.map +1 -0
  145. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.d.ts +1 -0
  146. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.js +187 -0
  147. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.js.map +1 -0
  148. package/dist/server/modules/terminal/terminal-service.d.ts +12 -0
  149. package/dist/server/modules/terminal/terminal-service.js +34 -17
  150. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  151. package/dist/server/modules/workbench/workbench-service.d.ts +23 -2
  152. package/dist/server/modules/workbench/workbench-service.js +126 -15
  153. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  154. package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +5 -1
  155. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +88 -19
  156. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  157. package/dist/server/modules/workspace/workspace-code-composition.d.ts +2 -0
  158. package/dist/server/modules/workspace/workspace-code-composition.js +154 -0
  159. package/dist/server/modules/workspace/workspace-code-composition.js.map +1 -0
  160. package/dist/server/modules/workspace/workspace-controller.d.ts +14 -0
  161. package/dist/server/modules/workspace/workspace-controller.js +19 -0
  162. package/dist/server/modules/workspace/workspace-controller.js.map +1 -1
  163. package/dist/server/modules/workspace/workspace-service.d.ts +21 -14
  164. package/dist/server/modules/workspace/workspace-service.js +183 -234
  165. package/dist/server/modules/workspace/workspace-service.js.map +1 -1
  166. package/dist/server/modules/worktree/worktree-cleanup-service.d.ts +35 -0
  167. package/dist/server/modules/worktree/worktree-cleanup-service.js +210 -0
  168. package/dist/server/modules/worktree/worktree-cleanup-service.js.map +1 -0
  169. package/dist/server/modules/worktree/worktree-controller.d.ts +44 -0
  170. package/dist/server/modules/worktree/worktree-controller.js +40 -0
  171. package/dist/server/modules/worktree/worktree-controller.js.map +1 -0
  172. package/dist/server/modules/worktree/worktree-manager.d.ts +34 -0
  173. package/dist/server/modules/worktree/worktree-manager.js +292 -0
  174. package/dist/server/modules/worktree/worktree-manager.js.map +1 -0
  175. package/dist/server/modules/worktree/worktree-merge-service.d.ts +52 -0
  176. package/dist/server/modules/worktree/worktree-merge-service.js +293 -0
  177. package/dist/server/modules/worktree/worktree-merge-service.js.map +1 -0
  178. package/dist/server/modules/worktree/worktree-sync-service.d.ts +23 -0
  179. package/dist/server/modules/worktree/worktree-sync-service.js +166 -0
  180. package/dist/server/modules/worktree/worktree-sync-service.js.map +1 -0
  181. package/dist/server/routes/assistant.d.ts +3 -0
  182. package/dist/server/routes/assistant.js +15 -0
  183. package/dist/server/routes/assistant.js.map +1 -0
  184. package/dist/server/routes/debug-targets.d.ts +3 -0
  185. package/dist/server/routes/debug-targets.js +15 -0
  186. package/dist/server/routes/debug-targets.js.map +1 -0
  187. package/dist/server/routes/git.js +1 -0
  188. package/dist/server/routes/git.js.map +1 -1
  189. package/dist/server/routes/observability.d.ts +3 -0
  190. package/dist/server/routes/observability.js +7 -0
  191. package/dist/server/routes/observability.js.map +1 -0
  192. package/dist/server/routes/workspaces.js +2 -0
  193. package/dist/server/routes/workspaces.js.map +1 -1
  194. package/dist/server/routes/worktrees.d.ts +3 -0
  195. package/dist/server/routes/worktrees.js +8 -0
  196. package/dist/server/routes/worktrees.js.map +1 -0
  197. package/dist/server/server/create-server.d.ts +34 -0
  198. package/dist/server/server/create-server.js +100 -10
  199. package/dist/server/server/create-server.js.map +1 -1
  200. package/dist/server/shared/utils/secret-box.d.ts +2 -0
  201. package/dist/server/shared/utils/secret-box.js +29 -0
  202. package/dist/server/shared/utils/secret-box.js.map +1 -0
  203. package/dist/server/shared/utils/terminal-debug-log.js +5 -3
  204. package/dist/server/shared/utils/terminal-debug-log.js.map +1 -1
  205. package/dist/server/storage/repositories/ai-fallback-edit-repository.d.ts +11 -0
  206. package/dist/server/storage/repositories/ai-fallback-edit-repository.js +118 -0
  207. package/dist/server/storage/repositories/ai-fallback-edit-repository.js.map +1 -0
  208. package/dist/server/storage/repositories/debug-runtime-session-repository.d.ts +11 -0
  209. package/dist/server/storage/repositories/debug-runtime-session-repository.js +100 -0
  210. package/dist/server/storage/repositories/debug-runtime-session-repository.js.map +1 -0
  211. package/dist/server/storage/repositories/debug-service-repository.d.ts +9 -0
  212. package/dist/server/storage/repositories/debug-service-repository.js +99 -0
  213. package/dist/server/storage/repositories/debug-service-repository.js.map +1 -0
  214. package/dist/server/storage/repositories/debug-target-repository.d.ts +11 -0
  215. package/dist/server/storage/repositories/debug-target-repository.js +100 -0
  216. package/dist/server/storage/repositories/debug-target-repository.js.map +1 -0
  217. package/dist/server/storage/repositories/framework-analysis-result-repository.d.ts +9 -0
  218. package/dist/server/storage/repositories/framework-analysis-result-repository.js +98 -0
  219. package/dist/server/storage/repositories/framework-analysis-result-repository.js.map +1 -0
  220. package/dist/server/storage/repositories/git-remote-credential-repository.d.ts +9 -0
  221. package/dist/server/storage/repositories/git-remote-credential-repository.js +51 -0
  222. package/dist/server/storage/repositories/git-remote-credential-repository.js.map +1 -0
  223. package/dist/server/storage/repositories/port-lease-repository.d.ts +12 -0
  224. package/dist/server/storage/repositories/port-lease-repository.js +124 -0
  225. package/dist/server/storage/repositories/port-lease-repository.js.map +1 -0
  226. package/dist/server/storage/repositories/runtime-binding-repository.d.ts +10 -0
  227. package/dist/server/storage/repositories/runtime-binding-repository.js +89 -0
  228. package/dist/server/storage/repositories/runtime-binding-repository.js.map +1 -0
  229. package/dist/server/storage/repositories/terminal-command-template-repository.js +77 -4
  230. package/dist/server/storage/repositories/terminal-command-template-repository.js.map +1 -1
  231. package/dist/server/storage/repositories/terminal-instance-repository.js +89 -7
  232. package/dist/server/storage/repositories/terminal-instance-repository.js.map +1 -1
  233. package/dist/server/storage/repositories/workspace-navigation-state-repository.d.ts +9 -0
  234. package/dist/server/storage/repositories/workspace-navigation-state-repository.js +49 -0
  235. package/dist/server/storage/repositories/workspace-navigation-state-repository.js.map +1 -0
  236. package/dist/server/storage/repositories/workspace-repository.d.ts +7 -1
  237. package/dist/server/storage/repositories/workspace-repository.js +32 -8
  238. package/dist/server/storage/repositories/workspace-repository.js.map +1 -1
  239. package/dist/server/storage/repositories/workspace-worktree-repository.d.ts +13 -0
  240. package/dist/server/storage/repositories/workspace-worktree-repository.js +158 -0
  241. package/dist/server/storage/repositories/workspace-worktree-repository.js.map +1 -0
  242. package/dist/server/storage/sqlite/client.js +301 -0
  243. package/dist/server/storage/sqlite/client.js.map +1 -1
  244. package/dist/server/storage/sqlite/schema.sql +238 -0
  245. package/dist/server/types/domain.d.ts +231 -0
  246. package/dist/server/ws/workbench-ws-hub.js +33 -9
  247. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  248. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +18 -6
  249. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  250. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +14 -2
  251. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  252. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +25 -1
  253. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  254. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +6 -0
  255. package/package.json +1 -1
  256. package/dist/public/assets/index-1VIm8lVL.css +0 -1
  257. package/dist/public/assets/index-Dti93O2S.js +0 -109
@@ -0,0 +1,49 @@
1
+ export class WorkspaceNavigationStateRepository {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ listByUserId(userId) {
7
+ return this.db
8
+ .prepare(`SELECT workspace_id, user_id, collapsed, background_color, updated_at
9
+ FROM workspace_navigation_states
10
+ WHERE user_id = ?`)
11
+ .all(userId)
12
+ .map((row) => mapWorkspaceNavigationStateRow(row));
13
+ }
14
+ findByWorkspaceIdAndUserId(workspaceId, userId) {
15
+ const row = this.db
16
+ .prepare(`SELECT workspace_id, user_id, collapsed, background_color, updated_at
17
+ FROM workspace_navigation_states
18
+ WHERE workspace_id = ?
19
+ AND user_id = ?`)
20
+ .get(workspaceId, userId);
21
+ return row ? mapWorkspaceNavigationStateRow(row) : null;
22
+ }
23
+ upsert(record) {
24
+ this.db
25
+ .prepare(`INSERT INTO workspace_navigation_states (
26
+ workspace_id,
27
+ user_id,
28
+ collapsed,
29
+ background_color,
30
+ updated_at
31
+ ) VALUES (?, ?, ?, ?, ?)
32
+ ON CONFLICT(workspace_id, user_id) DO UPDATE SET
33
+ collapsed = excluded.collapsed,
34
+ background_color = excluded.background_color,
35
+ updated_at = excluded.updated_at`)
36
+ .run(record.workspaceId, record.userId, record.collapsed ? 1 : 0, record.backgroundColor, record.updatedAt);
37
+ return record;
38
+ }
39
+ }
40
+ function mapWorkspaceNavigationStateRow(row) {
41
+ return {
42
+ workspaceId: row.workspace_id,
43
+ userId: row.user_id,
44
+ collapsed: row.collapsed === 1,
45
+ backgroundColor: row.background_color,
46
+ updatedAt: row.updated_at
47
+ };
48
+ }
49
+ //# sourceMappingURL=workspace-navigation-state-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-navigation-state-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/workspace-navigation-state-repository.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,kCAAkC;IAChB;IAA7B,YAA6B,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;IAAG,CAAC;IAEtD,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,EAAE;aACX,OAAO,CACN;;2BAEmB,CACpB;aACA,GAAG,CAAC,MAAM,CAAC;aACX,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,8BAA8B,CAAC,GAAkC,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,0BAA0B,CAAC,WAAmB,EAAE,MAAc;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN;;;2BAGmB,CACpB;aACA,GAAG,CAAC,WAAW,EAAE,MAAM,CAA4C,CAAC;QAEvE,OAAO,GAAG,CAAC,CAAC,CAAC,8BAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,MAAsC;QAC3C,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;;;;;;;;;;4CAUoC,CACrC;aACA,GAAG,CACF,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACxB,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,SAAS,CACjB,CAAC;QAEJ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAUD,SAAS,8BAA8B,CAAC,GAAgC;IACtE,OAAO;QACL,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,MAAM,EAAE,GAAG,CAAC,OAAO;QACnB,SAAS,EAAE,GAAG,CAAC,SAAS,KAAK,CAAC;QAC9B,eAAe,EAAE,GAAG,CAAC,gBAAgB;QACrC,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
@@ -1,12 +1,17 @@
1
1
  import type Database from "better-sqlite3";
2
2
  import type { Workspace } from "../../types/domain.js";
3
+ type WorkspaceCreateInput = Omit<Workspace, "sortOrder"> & {
4
+ sortOrder?: number;
5
+ };
3
6
  export declare class WorkspaceRepository {
4
7
  private readonly db;
5
8
  constructor(db: Database.Database);
6
- create(record: Workspace): Workspace;
9
+ create(record: WorkspaceCreateInput): Workspace;
7
10
  findById(id: string): Workspace | null;
8
11
  findByPath(workspacePath: string): Workspace | null;
9
12
  list(): Workspace[];
13
+ getNextSortOrder(): number;
14
+ reorderVisible(workspaceIds: readonly string[]): void;
10
15
  restore(id: string, input: {
11
16
  name?: string;
12
17
  repoRoot?: string | null;
@@ -14,3 +19,4 @@ export declare class WorkspaceRepository {
14
19
  }): Workspace | null;
15
20
  markRemoved(id: string, removedAt: string, updatedAt: string): Workspace | null;
16
21
  }
22
+ export {};
@@ -4,15 +4,20 @@ export class WorkspaceRepository {
4
4
  this.db = db;
5
5
  }
6
6
  create(record) {
7
+ const sortOrder = record.sortOrder ?? this.getNextSortOrder();
7
8
  this.db
8
- .prepare(`INSERT INTO workspaces (id, name, path, repo_root, favorite, created_at, updated_at, removed_at)
9
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
10
- .run(record.id, record.name, record.path, record.repoRoot, record.favorite ? 1 : 0, record.createdAt, record.updatedAt, record.removedAt ?? null);
11
- return record;
9
+ .prepare(`INSERT INTO workspaces (id, name, path, repo_root, favorite, sort_order, created_at, updated_at, removed_at)
10
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
11
+ .run(record.id, record.name, record.path, record.repoRoot, record.favorite ? 1 : 0, sortOrder, record.createdAt, record.updatedAt, record.removedAt ?? null);
12
+ return {
13
+ ...record,
14
+ sortOrder,
15
+ removedAt: record.removedAt ?? null
16
+ };
12
17
  }
13
18
  findById(id) {
14
19
  const row = this.db
15
- .prepare(`SELECT id, name, path, repo_root, favorite, created_at, updated_at, removed_at
20
+ .prepare(`SELECT id, name, path, repo_root, favorite, sort_order, created_at, updated_at, removed_at
16
21
  FROM workspaces
17
22
  WHERE id = ?`)
18
23
  .get(id);
@@ -20,7 +25,7 @@ export class WorkspaceRepository {
20
25
  }
21
26
  findByPath(workspacePath) {
22
27
  const row = this.db
23
- .prepare(`SELECT id, name, path, repo_root, favorite, created_at, updated_at, removed_at
28
+ .prepare(`SELECT id, name, path, repo_root, favorite, sort_order, created_at, updated_at, removed_at
24
29
  FROM workspaces
25
30
  WHERE path = ?`)
26
31
  .get(workspacePath);
@@ -28,13 +33,31 @@ export class WorkspaceRepository {
28
33
  }
29
34
  list() {
30
35
  return this.db
31
- .prepare(`SELECT id, name, path, repo_root, favorite, created_at, updated_at, removed_at
36
+ .prepare(`SELECT id, name, path, repo_root, favorite, sort_order, created_at, updated_at, removed_at
32
37
  FROM workspaces
33
38
  WHERE removed_at IS NULL
34
- ORDER BY updated_at DESC, created_at DESC`)
39
+ ORDER BY sort_order ASC, updated_at DESC, created_at DESC`)
35
40
  .all()
36
41
  .map((row) => mapWorkspaceRow(row));
37
42
  }
43
+ getNextSortOrder() {
44
+ const row = this.db
45
+ .prepare(`SELECT COALESCE(MAX(sort_order), -1) AS max_sort_order
46
+ FROM workspaces`)
47
+ .get();
48
+ return (row?.max_sort_order ?? -1) + 1;
49
+ }
50
+ reorderVisible(workspaceIds) {
51
+ const update = this.db.prepare(`UPDATE workspaces
52
+ SET sort_order = ?
53
+ WHERE id = ? AND removed_at IS NULL`);
54
+ const runInTransaction = this.db.transaction((orderedIds) => {
55
+ orderedIds.forEach((workspaceId, index) => {
56
+ update.run(index, workspaceId);
57
+ });
58
+ });
59
+ runInTransaction(workspaceIds);
60
+ }
38
61
  restore(id, input) {
39
62
  this.db
40
63
  .prepare(`UPDATE workspaces
@@ -63,6 +86,7 @@ function mapWorkspaceRow(row) {
63
86
  path: row.path,
64
87
  repoRoot: row.repo_root,
65
88
  favorite: row.favorite === 1,
89
+ sortOrder: row.sort_order,
66
90
  createdAt: row.created_at,
67
91
  updatedAt: row.updated_at,
68
92
  removedAt: row.removed_at
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/workspace-repository.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,EAAqB;QAArB,OAAE,GAAF,EAAE,CAAmB;IAAG,CAAC;IAEtD,MAAM,CAAC,MAAiB;QACtB,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;yCACiC,CAClC;aACA,GAAG,CACF,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACvB,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,SAAS,IAAI,IAAI,CACzB,CAAC;QAEJ,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,QAAQ,CAAC,EAAU;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN;;sBAEc,CACf;aACA,GAAG,CAAC,EAAE,CAA6B,CAAC;QAEvC,OAAO,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAED,UAAU,CAAC,aAAqB;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN;;wBAEgB,CACjB;aACA,GAAG,CAAC,aAAa,CAA6B,CAAC;QAElD,OAAO,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,EAAE;aACX,OAAO,CACN;;;mDAG2C,CAC5C;aACA,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAmB,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CACL,EAAU,EACV,KAIC;QAED,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;;;;;sBAKc,CACf;aACA,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEhF,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,WAAW,CAAC,EAAU,EAAE,SAAiB,EAAE,SAAiB;QAC1D,IAAI,CAAC,EAAE;aACJ,OAAO,CACN;;;sBAGc,CACf;aACA,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAEjC,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;CACF;AAaD,SAAS,eAAe,CAAC,GAAiB;IACxC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,QAAQ,EAAE,GAAG,CAAC,QAAQ,KAAK,CAAC;QAC5B,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"workspace-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/workspace-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { WorkspaceWorktreeRecord } from "../../types/domain.js";
3
+ export declare class WorkspaceWorktreeRepository {
4
+ private readonly db;
5
+ constructor(db: Database.Database);
6
+ create(record: WorkspaceWorktreeRecord): WorkspaceWorktreeRecord;
7
+ findByWorkspaceId(workspaceId: string): WorkspaceWorktreeRecord | null;
8
+ listWorkspaceIds(): string[];
9
+ listByRootWorkspaceId(rootWorkspaceId: string): WorkspaceWorktreeRecord[];
10
+ listByParentWorkspaceId(parentWorkspaceId: string): WorkspaceWorktreeRecord[];
11
+ update(record: WorkspaceWorktreeRecord): WorkspaceWorktreeRecord | null;
12
+ deleteByWorkspaceId(workspaceId: string): void;
13
+ }
@@ -0,0 +1,158 @@
1
+ export class WorkspaceWorktreeRepository {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ create(record) {
7
+ this.db
8
+ .prepare(`INSERT INTO workspace_worktrees (
9
+ workspace_id,
10
+ root_workspace_id,
11
+ parent_workspace_id,
12
+ source_workspace_id,
13
+ merge_target_workspace_id,
14
+ branch_name,
15
+ base_ref,
16
+ base_commit,
17
+ head_commit,
18
+ display_name,
19
+ depth,
20
+ lifecycle_status,
21
+ merged_at,
22
+ removed_at,
23
+ created_at,
24
+ updated_at
25
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
26
+ .run(record.workspaceId, record.rootWorkspaceId, record.parentWorkspaceId, record.sourceWorkspaceId, record.mergeTargetWorkspaceId, record.branchName, record.baseRef, record.baseCommit, record.headCommit, record.displayName, record.depth, record.lifecycleStatus, record.mergedAt, record.removedAt, record.createdAt, record.updatedAt);
27
+ return record;
28
+ }
29
+ findByWorkspaceId(workspaceId) {
30
+ const row = this.db
31
+ .prepare(`SELECT
32
+ workspace_id,
33
+ root_workspace_id,
34
+ parent_workspace_id,
35
+ source_workspace_id,
36
+ merge_target_workspace_id,
37
+ branch_name,
38
+ base_ref,
39
+ base_commit,
40
+ head_commit,
41
+ display_name,
42
+ depth,
43
+ lifecycle_status,
44
+ merged_at,
45
+ removed_at,
46
+ created_at,
47
+ updated_at
48
+ FROM workspace_worktrees
49
+ WHERE workspace_id = ?`)
50
+ .get(workspaceId);
51
+ return row ? mapWorkspaceWorktreeRow(row) : null;
52
+ }
53
+ listWorkspaceIds() {
54
+ return this.db
55
+ .prepare(`SELECT workspace_id
56
+ FROM workspace_worktrees`)
57
+ .all()
58
+ .map((row) => row.workspace_id);
59
+ }
60
+ listByRootWorkspaceId(rootWorkspaceId) {
61
+ return this.db
62
+ .prepare(`SELECT
63
+ workspace_id,
64
+ root_workspace_id,
65
+ parent_workspace_id,
66
+ source_workspace_id,
67
+ merge_target_workspace_id,
68
+ branch_name,
69
+ base_ref,
70
+ base_commit,
71
+ head_commit,
72
+ display_name,
73
+ depth,
74
+ lifecycle_status,
75
+ merged_at,
76
+ removed_at,
77
+ created_at,
78
+ updated_at
79
+ FROM workspace_worktrees
80
+ WHERE root_workspace_id = ?
81
+ ORDER BY depth ASC, updated_at DESC, created_at DESC`)
82
+ .all(rootWorkspaceId)
83
+ .map((row) => mapWorkspaceWorktreeRow(row));
84
+ }
85
+ listByParentWorkspaceId(parentWorkspaceId) {
86
+ return this.db
87
+ .prepare(`SELECT
88
+ workspace_id,
89
+ root_workspace_id,
90
+ parent_workspace_id,
91
+ source_workspace_id,
92
+ merge_target_workspace_id,
93
+ branch_name,
94
+ base_ref,
95
+ base_commit,
96
+ head_commit,
97
+ display_name,
98
+ depth,
99
+ lifecycle_status,
100
+ merged_at,
101
+ removed_at,
102
+ created_at,
103
+ updated_at
104
+ FROM workspace_worktrees
105
+ WHERE parent_workspace_id = ?
106
+ ORDER BY updated_at DESC, created_at DESC`)
107
+ .all(parentWorkspaceId)
108
+ .map((row) => mapWorkspaceWorktreeRow(row));
109
+ }
110
+ update(record) {
111
+ this.db
112
+ .prepare(`UPDATE workspace_worktrees
113
+ SET root_workspace_id = ?,
114
+ parent_workspace_id = ?,
115
+ source_workspace_id = ?,
116
+ merge_target_workspace_id = ?,
117
+ branch_name = ?,
118
+ base_ref = ?,
119
+ base_commit = ?,
120
+ head_commit = ?,
121
+ display_name = ?,
122
+ depth = ?,
123
+ lifecycle_status = ?,
124
+ merged_at = ?,
125
+ removed_at = ?,
126
+ updated_at = ?
127
+ WHERE workspace_id = ?`)
128
+ .run(record.rootWorkspaceId, record.parentWorkspaceId, record.sourceWorkspaceId, record.mergeTargetWorkspaceId, record.branchName, record.baseRef, record.baseCommit, record.headCommit, record.displayName, record.depth, record.lifecycleStatus, record.mergedAt, record.removedAt, record.updatedAt, record.workspaceId);
129
+ return this.findByWorkspaceId(record.workspaceId);
130
+ }
131
+ deleteByWorkspaceId(workspaceId) {
132
+ this.db
133
+ .prepare(`DELETE FROM workspace_worktrees
134
+ WHERE workspace_id = ?`)
135
+ .run(workspaceId);
136
+ }
137
+ }
138
+ function mapWorkspaceWorktreeRow(row) {
139
+ return {
140
+ workspaceId: row.workspace_id,
141
+ rootWorkspaceId: row.root_workspace_id,
142
+ parentWorkspaceId: row.parent_workspace_id,
143
+ sourceWorkspaceId: row.source_workspace_id,
144
+ mergeTargetWorkspaceId: row.merge_target_workspace_id,
145
+ branchName: row.branch_name,
146
+ baseRef: row.base_ref,
147
+ baseCommit: row.base_commit,
148
+ headCommit: row.head_commit,
149
+ displayName: row.display_name,
150
+ depth: row.depth,
151
+ lifecycleStatus: row.lifecycle_status,
152
+ mergedAt: row.merged_at,
153
+ removedAt: row.removed_at,
154
+ createdAt: row.created_at,
155
+ updatedAt: row.updated_at
156
+ };
157
+ }
158
+ //# sourceMappingURL=workspace-worktree-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-worktree-repository.js","sourceRoot":"","sources":["../../../../src/storage/repositories/workspace-worktree-repository.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ export function createDatabaseClient(databasePath) {
10
10
  const schema = fs.readFileSync(schemaPath, "utf8");
11
11
  db.exec(schema);
12
12
  ensureWorkspaceRemovalColumn(db);
13
+ ensureWorkspaceSortOrderColumn(db);
14
+ ensureWorkspaceNavigationBackgroundColorColumn(db);
13
15
  ensureSessionProviderSchema(db);
14
16
  ensureSessionStateSchema(db);
15
17
  ensureSessionIndexArchiveColumn(db);
@@ -22,6 +24,14 @@ export function createDatabaseClient(databasePath) {
22
24
  ensureTerminalCommandTemplatePortColumn(db);
23
25
  ensureTerminalCommandTemplateRuntimeTypeColumn(db);
24
26
  ensureTerminalCommandTemplateProxySchema(db);
27
+ ensureDebugTargetSchema(db);
28
+ ensureFrameworkAnalysisSchema(db);
29
+ ensureDebugRuntimeSchema(db);
30
+ ensurePortLeaseSchema(db);
31
+ ensureRuntimeBindingSchema(db);
32
+ ensureAiFallbackEditSchema(db);
33
+ ensureTerminalCommandTemplateDebugSchema(db);
34
+ ensureTerminalInstanceDebugSchema(db);
25
35
  ensureButlerProfileSchema(db);
26
36
  ensureButlerFollowUpTaskSchema(db);
27
37
  ensureButlerSessionSummarySchema(db);
@@ -39,6 +49,49 @@ function ensureWorkspaceRemovalColumn(db) {
39
49
  }
40
50
  db.exec("ALTER TABLE workspaces ADD COLUMN removed_at TEXT");
41
51
  }
52
+ function ensureWorkspaceSortOrderColumn(db) {
53
+ const columns = db
54
+ .prepare("PRAGMA table_info(workspaces)")
55
+ .all();
56
+ const columnNames = new Set(columns.map((column) => column.name));
57
+ if (columnNames.has("sort_order")) {
58
+ return;
59
+ }
60
+ db.exec("ALTER TABLE workspaces ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0");
61
+ const orderByClauses = [];
62
+ if (columnNames.has("updated_at")) {
63
+ orderByClauses.push("updated_at DESC");
64
+ }
65
+ if (columnNames.has("created_at")) {
66
+ orderByClauses.push("created_at DESC");
67
+ }
68
+ if (orderByClauses.length === 0) {
69
+ orderByClauses.push("id ASC");
70
+ }
71
+ const workspaces = db
72
+ .prepare(`SELECT id
73
+ FROM workspaces
74
+ ORDER BY ${orderByClauses.join(", ")}`)
75
+ .all();
76
+ const update = db.prepare(`UPDATE workspaces
77
+ SET sort_order = ?
78
+ WHERE id = ?`);
79
+ const runInTransaction = db.transaction((items) => {
80
+ items.forEach((item, index) => {
81
+ update.run(index, item.id);
82
+ });
83
+ });
84
+ runInTransaction(workspaces);
85
+ }
86
+ function ensureWorkspaceNavigationBackgroundColorColumn(db) {
87
+ const columns = db
88
+ .prepare("PRAGMA table_info(workspace_navigation_states)")
89
+ .all();
90
+ if (columns.length === 0 || columns.some((column) => column.name === "background_color")) {
91
+ return;
92
+ }
93
+ db.exec("ALTER TABLE workspace_navigation_states ADD COLUMN background_color TEXT");
94
+ }
42
95
  function ensureButlerProfileSchema(db) {
43
96
  const columns = db
44
97
  .prepare("PRAGMA table_info(butler_profiles)")
@@ -606,6 +659,254 @@ function ensureTerminalLogSchema(db) {
606
659
  ON terminal_log_segments(file_id, start_offset ASC);
607
660
  `);
608
661
  }
662
+ function ensureDebugTargetSchema(db) {
663
+ db.exec(`
664
+ CREATE TABLE IF NOT EXISTS debug_targets (
665
+ id TEXT PRIMARY KEY,
666
+ workspace_id TEXT NOT NULL,
667
+ root_path TEXT NOT NULL,
668
+ display_name TEXT NOT NULL,
669
+ stack_hint TEXT,
670
+ source_type TEXT NOT NULL CHECK (source_type IN ('repo', 'worktree')),
671
+ root_workspace_id TEXT,
672
+ created_at TEXT NOT NULL,
673
+ updated_at TEXT NOT NULL,
674
+ FOREIGN KEY (workspace_id) REFERENCES workspaces(id),
675
+ FOREIGN KEY (root_workspace_id) REFERENCES workspaces(id),
676
+ UNIQUE (workspace_id, root_path)
677
+ );
678
+
679
+ CREATE INDEX IF NOT EXISTS idx_debug_targets_workspace_id
680
+ ON debug_targets(workspace_id, updated_at DESC, created_at DESC);
681
+
682
+ CREATE TABLE IF NOT EXISTS debug_services (
683
+ id TEXT PRIMARY KEY,
684
+ target_id TEXT NOT NULL,
685
+ role TEXT NOT NULL CHECK (role IN ('frontend', 'backend', 'worker', 'mock', 'custom')),
686
+ name TEXT NOT NULL,
687
+ cwd TEXT NOT NULL,
688
+ command TEXT NOT NULL,
689
+ args_json TEXT NOT NULL,
690
+ env_json TEXT NOT NULL,
691
+ default_port_hint INTEGER,
692
+ protocol TEXT CHECK (protocol IS NULL OR protocol IN ('http', 'ws', 'tcp')),
693
+ health_path TEXT,
694
+ adapter_kind TEXT CHECK (
695
+ adapter_kind IS NULL OR adapter_kind IN ('cli', 'env', 'override', 'ai_fallback')
696
+ ),
697
+ framework_analysis_id TEXT,
698
+ created_at TEXT NOT NULL,
699
+ updated_at TEXT NOT NULL,
700
+ FOREIGN KEY (target_id) REFERENCES debug_targets(id) ON DELETE CASCADE
701
+ );
702
+
703
+ CREATE INDEX IF NOT EXISTS idx_debug_services_target_id
704
+ ON debug_services(target_id, updated_at DESC, created_at DESC);
705
+ `);
706
+ }
707
+ function ensureFrameworkAnalysisSchema(db) {
708
+ db.exec(`
709
+ CREATE TABLE IF NOT EXISTS framework_analysis_results (
710
+ id TEXT PRIMARY KEY,
711
+ target_id TEXT NOT NULL,
712
+ service_id TEXT,
713
+ primary_framework TEXT,
714
+ confidence TEXT NOT NULL CHECK (confidence IN ('high', 'medium', 'low')),
715
+ compatibility_level TEXT NOT NULL CHECK (
716
+ compatibility_level IN ('supported', 'conditional', 'unsupported', 'unknown')
717
+ ),
718
+ recommended_injection_mode TEXT CHECK (
719
+ recommended_injection_mode IS NULL OR recommended_injection_mode IN ('cli', 'env', 'override', 'none')
720
+ ),
721
+ requires_service_discovery_handling INTEGER NOT NULL CHECK (
722
+ requires_service_discovery_handling IN (0, 1)
723
+ ),
724
+ requires_hmr_handling INTEGER NOT NULL CHECK (requires_hmr_handling IN (0, 1)),
725
+ requires_callback_handling INTEGER NOT NULL CHECK (requires_callback_handling IN (0, 1)),
726
+ ai_fallback_policy TEXT NOT NULL CHECK (ai_fallback_policy IN ('never', 'conditional', 'allowed')),
727
+ reasons_json TEXT NOT NULL,
728
+ detected_files_json TEXT NOT NULL DEFAULT '[]',
729
+ raw_evidence_json TEXT NOT NULL DEFAULT '{}',
730
+ created_at TEXT NOT NULL,
731
+ FOREIGN KEY (target_id) REFERENCES debug_targets(id) ON DELETE CASCADE,
732
+ FOREIGN KEY (service_id) REFERENCES debug_services(id) ON DELETE CASCADE
733
+ );
734
+
735
+ CREATE INDEX IF NOT EXISTS idx_framework_analysis_results_target_id
736
+ ON framework_analysis_results(target_id, created_at DESC);
737
+
738
+ CREATE INDEX IF NOT EXISTS idx_framework_analysis_results_service_id
739
+ ON framework_analysis_results(service_id, created_at DESC);
740
+ `);
741
+ }
742
+ function ensureDebugRuntimeSchema(db) {
743
+ db.exec(`
744
+ CREATE TABLE IF NOT EXISTS debug_runtime_sessions (
745
+ id TEXT PRIMARY KEY,
746
+ target_id TEXT NOT NULL,
747
+ status TEXT NOT NULL CHECK (status IN ('PREPARING', 'RUNNING', 'FAILED', 'STOPPED')),
748
+ failure_stage TEXT,
749
+ started_at TEXT,
750
+ stopped_at TEXT,
751
+ created_at TEXT NOT NULL,
752
+ updated_at TEXT NOT NULL,
753
+ FOREIGN KEY (target_id) REFERENCES debug_targets(id) ON DELETE CASCADE
754
+ );
755
+
756
+ CREATE INDEX IF NOT EXISTS idx_debug_runtime_sessions_target_id
757
+ ON debug_runtime_sessions(target_id, updated_at DESC, created_at DESC);
758
+ `);
759
+ }
760
+ function ensurePortLeaseSchema(db) {
761
+ db.exec(`
762
+ CREATE TABLE IF NOT EXISTS port_leases (
763
+ id TEXT PRIMARY KEY,
764
+ runtime_id TEXT NOT NULL,
765
+ service_id TEXT NOT NULL,
766
+ port INTEGER NOT NULL,
767
+ protocol TEXT NOT NULL CHECK (protocol IN ('tcp', 'udp')),
768
+ status TEXT NOT NULL CHECK (status IN ('LEASED', 'RELEASING', 'RELEASED', 'STALE')),
769
+ leased_at TEXT NOT NULL,
770
+ expires_at TEXT,
771
+ released_at TEXT,
772
+ FOREIGN KEY (runtime_id) REFERENCES debug_runtime_sessions(id) ON DELETE CASCADE,
773
+ FOREIGN KEY (service_id) REFERENCES debug_services(id) ON DELETE CASCADE
774
+ );
775
+
776
+ CREATE INDEX IF NOT EXISTS idx_port_leases_runtime_id
777
+ ON port_leases(runtime_id, leased_at DESC);
778
+
779
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_port_leases_active_port
780
+ ON port_leases(port, protocol)
781
+ WHERE status IN ('LEASED', 'RELEASING');
782
+ `);
783
+ }
784
+ function ensureRuntimeBindingSchema(db) {
785
+ db.exec(`
786
+ CREATE TABLE IF NOT EXISTS runtime_bindings (
787
+ id TEXT PRIMARY KEY,
788
+ runtime_id TEXT NOT NULL,
789
+ service_id TEXT NOT NULL,
790
+ process_instance_id TEXT,
791
+ expected_port INTEGER,
792
+ leased_port INTEGER,
793
+ observed_port INTEGER,
794
+ proxy_path TEXT,
795
+ status TEXT NOT NULL CHECK (status IN ('ALLOCATED', 'LISTENING', 'FAILED', 'RELEASED')),
796
+ updated_at TEXT NOT NULL,
797
+ FOREIGN KEY (runtime_id) REFERENCES debug_runtime_sessions(id) ON DELETE CASCADE,
798
+ FOREIGN KEY (service_id) REFERENCES debug_services(id) ON DELETE CASCADE
799
+ );
800
+
801
+ CREATE INDEX IF NOT EXISTS idx_runtime_bindings_runtime_id
802
+ ON runtime_bindings(runtime_id, updated_at DESC);
803
+ `);
804
+ }
805
+ function ensureAiFallbackEditSchema(db) {
806
+ db.exec(`
807
+ CREATE TABLE IF NOT EXISTS ai_fallback_edits (
808
+ id TEXT PRIMARY KEY,
809
+ runtime_id TEXT NOT NULL,
810
+ service_id TEXT NOT NULL,
811
+ reason TEXT NOT NULL,
812
+ allowed_files_json TEXT NOT NULL,
813
+ target_port INTEGER NOT NULL,
814
+ patch_ref TEXT,
815
+ rollback_ref TEXT,
816
+ status TEXT NOT NULL CHECK (status IN ('PENDING', 'APPLIED', 'ROLLED_BACK', 'REJECTED')),
817
+ created_at TEXT NOT NULL,
818
+ FOREIGN KEY (runtime_id) REFERENCES debug_runtime_sessions(id) ON DELETE CASCADE,
819
+ FOREIGN KEY (service_id) REFERENCES debug_services(id) ON DELETE CASCADE
820
+ );
821
+
822
+ CREATE INDEX IF NOT EXISTS idx_ai_fallback_edits_runtime_id
823
+ ON ai_fallback_edits(runtime_id, created_at DESC);
824
+ `);
825
+ }
826
+ function ensureTerminalCommandTemplateDebugSchema(db) {
827
+ const columns = db
828
+ .prepare("PRAGMA table_info(terminal_command_templates)")
829
+ .all();
830
+ const columnNames = new Set(columns.map((column) => column.name));
831
+ if (!columnNames.has("source_type")) {
832
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN source_type TEXT");
833
+ }
834
+ if (!columnNames.has("debug_target_id")) {
835
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN debug_target_id TEXT");
836
+ }
837
+ if (!columnNames.has("debug_service_id")) {
838
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN debug_service_id TEXT");
839
+ }
840
+ if (!columnNames.has("framework_analysis_id")) {
841
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN framework_analysis_id TEXT");
842
+ }
843
+ if (!columnNames.has("adapter_kind")) {
844
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN adapter_kind TEXT");
845
+ }
846
+ if (!columnNames.has("injection_mode")) {
847
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN injection_mode TEXT");
848
+ }
849
+ if (!columnNames.has("generated_artifact_ref")) {
850
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN generated_artifact_ref TEXT");
851
+ }
852
+ if (!columnNames.has("service_discovery_mode")) {
853
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN service_discovery_mode TEXT");
854
+ }
855
+ if (!columnNames.has("managed_by_system")) {
856
+ db.exec("ALTER TABLE terminal_command_templates ADD COLUMN managed_by_system INTEGER NOT NULL DEFAULT 0");
857
+ }
858
+ db.exec(`
859
+ UPDATE terminal_command_templates
860
+ SET managed_by_system = 0
861
+ WHERE managed_by_system IS NULL OR managed_by_system NOT IN (0, 1);
862
+
863
+ CREATE INDEX IF NOT EXISTS idx_terminal_templates_debug_target_id
864
+ ON terminal_command_templates(debug_target_id);
865
+ `);
866
+ }
867
+ function ensureTerminalInstanceDebugSchema(db) {
868
+ const columns = db
869
+ .prepare("PRAGMA table_info(terminal_instances)")
870
+ .all();
871
+ const columnNames = new Set(columns.map((column) => column.name));
872
+ if (!columnNames.has("debug_runtime_session_id")) {
873
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN debug_runtime_session_id TEXT");
874
+ }
875
+ if (!columnNames.has("debug_target_id")) {
876
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN debug_target_id TEXT");
877
+ }
878
+ if (!columnNames.has("debug_service_id")) {
879
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN debug_service_id TEXT");
880
+ }
881
+ if (!columnNames.has("framework_analysis_id")) {
882
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN framework_analysis_id TEXT");
883
+ }
884
+ if (!columnNames.has("launcher_source_type")) {
885
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN launcher_source_type TEXT");
886
+ }
887
+ if (!columnNames.has("launch_stage")) {
888
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN launch_stage TEXT");
889
+ }
890
+ if (!columnNames.has("failure_stage")) {
891
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN failure_stage TEXT");
892
+ }
893
+ if (!columnNames.has("adapter_kind")) {
894
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN adapter_kind TEXT");
895
+ }
896
+ if (!columnNames.has("env_patch_summary_json")) {
897
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN env_patch_summary_json TEXT");
898
+ }
899
+ if (!columnNames.has("artifact_ref")) {
900
+ db.exec("ALTER TABLE terminal_instances ADD COLUMN artifact_ref TEXT");
901
+ }
902
+ db.exec(`
903
+ CREATE INDEX IF NOT EXISTS idx_terminal_instances_debug_runtime_session_id
904
+ ON terminal_instances(debug_runtime_session_id);
905
+
906
+ CREATE INDEX IF NOT EXISTS idx_terminal_instances_debug_target_id
907
+ ON terminal_instances(debug_target_id);
908
+ `);
909
+ }
609
910
  function readTableSql(db, tableName) {
610
911
  const row = db
611
912
  .prepare(`