adam-agent-server 1.14.0 → 1.15.1

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 (208) hide show
  1. package/dist/App-6TRGTNZ7.js +13 -0
  2. package/dist/approval-handler-ZWZZ3FKR.js +1 -0
  3. package/dist/audit-diagnostics-MASYIEGZ.js +1 -0
  4. package/dist/audit-manager-3YOVBIFV.js +1 -0
  5. package/dist/bree-engine-Y6WEQCC4.js +1 -0
  6. package/dist/channels-2DFKJ33W.js +1 -0
  7. package/dist/{channels-PXLE7JHU.js → channels-2IL6USWL.js} +1 -1
  8. package/dist/chat-tool-calls-KARPW7PE.js +1 -0
  9. package/dist/chunk-245WE5AF.js +1 -0
  10. package/dist/chunk-27C637GL.js +9 -0
  11. package/dist/{chunk-IUASV43X.js → chunk-2N4EOZZ4.js} +4 -4
  12. package/dist/chunk-2Q6XLYCC.js +25 -0
  13. package/dist/chunk-3BRHWRZ5.js +2 -0
  14. package/dist/chunk-ASPPM7TQ.js +1 -0
  15. package/dist/chunk-BKNXRSJU.js +4 -0
  16. package/dist/{chunk-RLNMJ2QY.js → chunk-BLCNUT53.js} +1 -1
  17. package/dist/chunk-BPXS4QEO.js +1006 -0
  18. package/dist/chunk-CLNYHWZ6.js +5 -0
  19. package/dist/chunk-D3SPXZZY.js +6 -0
  20. package/dist/chunk-DMDZ3QW7.js +1 -0
  21. package/dist/{chunk-UIMIXDAF.js → chunk-DRO3DG7X.js} +1 -1
  22. package/dist/chunk-F6U5TMM3.js +5 -0
  23. package/dist/chunk-ICAM2GUU.js +1 -0
  24. package/dist/{chunk-WYALKFT7.js → chunk-IRUR4DVD.js} +1 -1
  25. package/dist/chunk-ISKCTUI7.js +9 -0
  26. package/dist/{chunk-5ZP5TJJA.js → chunk-J3VYLSJI.js} +1 -1
  27. package/dist/chunk-JUVQWLWM.js +14 -0
  28. package/dist/chunk-JYJWNUGH.js +1 -0
  29. package/dist/chunk-KJNAORKM.js +15 -0
  30. package/dist/chunk-L47LZYVG.js +21 -0
  31. package/dist/{chunk-WGRTN6TX.js → chunk-L7JP7DUO.js} +1 -1
  32. package/dist/{chunk-4UCIJKQS.js → chunk-LBINDAPE.js} +11 -11
  33. package/dist/chunk-LZDO4PXK.js +34 -0
  34. package/dist/chunk-MFFJ5HFI.js +178 -0
  35. package/dist/{chunk-OMLONR4N.js → chunk-N2OLEUAQ.js} +1 -1
  36. package/dist/{chunk-S2WZL5CT.js → chunk-NLTYJUQG.js} +1 -1
  37. package/dist/chunk-NPGZRSGL.js +5 -0
  38. package/dist/{chunk-SKN4VSLW.js → chunk-NUJSTEV4.js} +1 -1
  39. package/dist/{chunk-E4NFVJ7F.js → chunk-NWGRLNUM.js} +1 -1
  40. package/dist/{chunk-HGRL5ZKG.js → chunk-OW3HDZV5.js} +1 -1
  41. package/dist/chunk-QZ34KQ76.js +3 -0
  42. package/dist/chunk-RBJPQYV3.js +6 -0
  43. package/dist/chunk-RX274IH7.js +5 -0
  44. package/dist/{chunk-TU643PPA.js → chunk-TZCMK3UG.js} +6 -6
  45. package/dist/{chunk-KSFVBI2D.js → chunk-VKKDSXMR.js} +1 -1
  46. package/dist/chunk-VLS3BPCG.js +1 -0
  47. package/dist/chunk-VNXTBIPI.js +31 -0
  48. package/dist/chunk-VVPRB2JU.js +114 -0
  49. package/dist/chunk-XA3MZOWU.js +61 -0
  50. package/dist/chunk-XF7YHFVR.js +15 -0
  51. package/dist/{chunk-FP42MZDK.js → chunk-XIVFVKMB.js} +2 -2
  52. package/dist/chunk-XYZVMTNN.js +1 -0
  53. package/dist/chunk-Z6LHGA27.js +1 -0
  54. package/dist/cli.js +2 -2
  55. package/dist/config-VHWLMFIN.js +1 -0
  56. package/dist/{config-NUQGVGQE.js → config-XO7TGH27.js} +1 -1
  57. package/dist/db-WCTOLFAZ.js +1 -0
  58. package/dist/delivery-log-ML4RJOBM.js +1 -0
  59. package/dist/dist-HCSYRPJU.js +1 -0
  60. package/dist/engine-IZRMVJRH.js +1 -0
  61. package/dist/evolution-audit-HLU7LQL6.js +1 -0
  62. package/dist/execution-tools-3UATAFUL.js +1 -0
  63. package/dist/{external-api-DQX7ZGRF.js → external-api-YMEFVZGG.js} +1 -1
  64. package/dist/index.js +194 -23
  65. package/dist/learner-NJXX2RUL.js +1 -0
  66. package/dist/{logger-4IUSEDG4.js → logger-PAMNFWI3.js} +1 -1
  67. package/dist/memories-JDTQM3UN.js +1 -0
  68. package/dist/memory-extractor-X2HTMKCV.js +1 -0
  69. package/dist/memory-gc-BCHTOSXK.js +1 -0
  70. package/dist/memory-service-66EMRJXO.js +1 -0
  71. package/dist/onnxruntime_binding-2BPLI7ZQ.node +0 -0
  72. package/dist/onnxruntime_binding-5J67DTMJ.node +0 -0
  73. package/dist/onnxruntime_binding-7ZZLEQ2F.node +0 -0
  74. package/dist/onnxruntime_binding-KDCXAPN5.node +0 -0
  75. package/dist/onnxruntime_binding-R73P2IQW.node +0 -0
  76. package/dist/outbound-gateway-R6EVRWHP.js +1 -0
  77. package/dist/presets-ZZVLCPB2.js +1 -0
  78. package/dist/reflection-job-BHX3BWAG.js +23 -0
  79. package/dist/role-presets-JJI7532O.js +1 -0
  80. package/dist/role-workspace-SIHNI6HO.js +1 -0
  81. package/dist/roles-F6AEM6B5.js +1 -0
  82. package/dist/{runtime-WDAYGKY6.js → runtime-TWLGJSL6.js} +1 -1
  83. package/dist/server-bus-GEGVMSCA.js +1 -0
  84. package/dist/session-manager-6MUWHQYF.js +1 -0
  85. package/dist/skill-registry-4JT62GEF.js +1 -0
  86. package/dist/target-resolution-PSSBM4LX.js +1 -0
  87. package/dist/task-templates-6G46OVYT.js +1 -0
  88. package/dist/template-dispatch-NDQH6S2P.js +1 -0
  89. package/dist/template-execution-artifacts-NEPSVD2B.js +1 -0
  90. package/dist/trace-context-UR7DI5ME.js +1 -0
  91. package/package.json +30 -19
  92. package/web/dist/assets/{Button-Dr7ksRu4.js → Button-fLMsJd5o.js} +1 -1
  93. package/web/dist/assets/{Card-B4oFZ8tK.js → Card-cy-gHU0O.js} +1 -1
  94. package/web/dist/assets/{ChannelDetail-eIcfA57N.js → ChannelDetail-CsKBPHkT.js} +1 -1
  95. package/web/dist/assets/{Channels-mwF1UKzb.js → Channels-DMutLV9r.js} +2 -2
  96. package/web/dist/assets/Chat-DWTs-iOw.js +2 -0
  97. package/web/dist/assets/Dashboard-CoatfhW8.js +1 -0
  98. package/web/dist/assets/{EmptyState-CDrBzXK-.js → EmptyState-C5kVDHc7.js} +1 -1
  99. package/web/dist/assets/{EnvVarEditor-Bray2ESp.js → EnvVarEditor-BvRsHayG.js} +1 -1
  100. package/web/dist/assets/{EventDefDetail-CfNFbtRL.js → EventDefDetail-zuJydp12.js} +1 -1
  101. package/web/dist/assets/Events-nCImjXyr.js +1 -0
  102. package/web/dist/assets/{Evolution-CQZZH9YR.js → Evolution-Br41g99g.js} +1 -1
  103. package/web/dist/assets/ExtensionDetail-BXlphIkn.js +1 -0
  104. package/web/dist/assets/Extensions-3lhbw0A2.js +1 -0
  105. package/web/dist/assets/{FeatureRequests-Chu9p9jf.js → FeatureRequests-oaXQNu43.js} +1 -1
  106. package/web/dist/assets/{GoalDetail-D6YA6oj3.js → GoalDetail-DRDg1JDv.js} +1 -1
  107. package/web/dist/assets/Goals-DGmKvtGA.js +1 -0
  108. package/web/dist/assets/{Logs-B05A1bGU.js → Logs-BZKxhdnb.js} +1 -1
  109. package/web/dist/assets/{Memories-CeNngSKF.js → Memories-DhJJk-KB.js} +1 -1
  110. package/web/dist/assets/{Mistakes-SOFsb4IS.js → Mistakes-DxThj9as.js} +1 -1
  111. package/web/dist/assets/{NotFound-Csw1BuG3.js → NotFound-buXr2gl7.js} +1 -1
  112. package/web/dist/assets/{PageHeader-z6FDKzfu.js → PageHeader-BgNbz3JV.js} +1 -1
  113. package/web/dist/assets/Plugins-BXrsGsXs.js +1 -0
  114. package/web/dist/assets/RoleDetail-rClUsHwS.js +35 -0
  115. package/web/dist/assets/Roles-DH9cRv8h.js +1 -0
  116. package/web/dist/assets/{SectionHeader-SRCKtVA-.js → SectionHeader-CwX6m1f6.js} +1 -1
  117. package/web/dist/assets/{Settings-44MJsbkf.js → Settings-My2lOEWv.js} +1 -1
  118. package/web/dist/assets/{Strategies-Ck28Clr5.js → Strategies-YLMryJlG.js} +1 -1
  119. package/web/dist/assets/{Switch-BmTw_pcA.js → Switch-PNpjNoGn.js} +1 -1
  120. package/web/dist/assets/{Table-B0PI8kT6.js → Table-BrERwl-F.js} +1 -1
  121. package/web/dist/assets/{Tabs-BZ6DxWAE.js → Tabs-CGHmpUAD.js} +1 -1
  122. package/web/dist/assets/TaskDetail-Bkaq0NwW.js +2 -0
  123. package/web/dist/assets/Work-4OcGMu_a.js +1 -0
  124. package/web/dist/assets/api-BkdixMz9.js +1 -0
  125. package/web/dist/assets/{es2015-BIlLl5hi.js → es2015-JqLIWAgH.js} +1 -1
  126. package/web/dist/assets/index-C-e-qpXc.js +12 -0
  127. package/web/dist/assets/index-DGTVc0qD.css +2 -0
  128. package/web/dist/assets/{useIsMobileLayout-luhqwSbU.js → useIsMobileLayout-Blj4Mk4K.js} +1 -1
  129. package/web/dist/assets/{usePluginsWithUsage-8a-Ed6EY.js → usePluginsWithUsage-Ch9WCFTb.js} +1 -1
  130. package/web/dist/assets/vendor-icons-U4igmrUq.js +1 -0
  131. package/web/dist/assets/{vendor-react-Kuc9eqr3.js → vendor-react-Bp_V-Hsf.js} +1 -1
  132. package/web/dist/assets/{vendor-state-CcqA6KbS.js → vendor-state-Zjl_6-V3.js} +1 -1
  133. package/web/dist/index.html +8 -8
  134. package/dist/App-DAFKLTGC.js +0 -13
  135. package/dist/adam-tools-NTUOJ42F.js +0 -1
  136. package/dist/approval-handler-D4EXPO2F.js +0 -1
  137. package/dist/audit-manager-FHYCOJZM.js +0 -1
  138. package/dist/bree-engine-XKEGOG7I.js +0 -1
  139. package/dist/channels-LV5F7LUJ.js +0 -1
  140. package/dist/chunk-34WPSSKK.js +0 -7
  141. package/dist/chunk-37TV7A5A.js +0 -740
  142. package/dist/chunk-43JFJEUT.js +0 -1
  143. package/dist/chunk-44DK2I4J.js +0 -47
  144. package/dist/chunk-45I2IYIE.js +0 -10
  145. package/dist/chunk-6JBSBSCL.js +0 -1
  146. package/dist/chunk-7B2DHDUD.js +0 -10
  147. package/dist/chunk-7QELXWKT.js +0 -3
  148. package/dist/chunk-7ZCMGQLK.js +0 -1
  149. package/dist/chunk-CNKUMQ37.js +0 -12
  150. package/dist/chunk-DAD4PSIZ.js +0 -13
  151. package/dist/chunk-EEU56CTK.js +0 -5
  152. package/dist/chunk-ENHE6VOF.js +0 -1
  153. package/dist/chunk-EP26G2WS.js +0 -5
  154. package/dist/chunk-F44QHTMI.js +0 -6
  155. package/dist/chunk-FG72WBDO.js +0 -5
  156. package/dist/chunk-FNHW2CRA.js +0 -5
  157. package/dist/chunk-KZKDPY53.js +0 -1
  158. package/dist/chunk-LLGJEDNK.js +0 -3
  159. package/dist/chunk-MC2R5WMN.js +0 -21
  160. package/dist/chunk-NNNDVFEY.js +0 -1
  161. package/dist/chunk-OPCPSPZ2.js +0 -8
  162. package/dist/chunk-S6HEPXYU.js +0 -80
  163. package/dist/chunk-UEYKBU5K.js +0 -1
  164. package/dist/chunk-UMCM25ZR.js +0 -1
  165. package/dist/chunk-VOO3FHMD.js +0 -14
  166. package/dist/chunk-XMFTVHCC.js +0 -128
  167. package/dist/chunk-YLM6QTFR.js +0 -40
  168. package/dist/chunk-ZYAK567W.js +0 -5
  169. package/dist/config-25UDTFBM.js +0 -1
  170. package/dist/db-GKWPRABQ.js +0 -1
  171. package/dist/delivery-log-XEZBBSRW.js +0 -1
  172. package/dist/dist-CDWBOTZS.js +0 -1
  173. package/dist/engine-P7IWX6CX.js +0 -1
  174. package/dist/evolution-audit-JJOFW6YU.js +0 -1
  175. package/dist/learner-BP3UDHN7.js +0 -1
  176. package/dist/memories-KPMHJLNT.js +0 -1
  177. package/dist/memory-extractor-QAS5ANET.js +0 -6
  178. package/dist/memory-service-YDBU7L54.js +0 -1
  179. package/dist/onnxruntime_binding-6Q6HXASN.node +0 -0
  180. package/dist/onnxruntime_binding-EKZT2NRK.node +0 -0
  181. package/dist/onnxruntime_binding-P6S7V3CI.node +0 -0
  182. package/dist/onnxruntime_binding-PJNNIIUO.node +0 -0
  183. package/dist/onnxruntime_binding-UN6SPTQK.node +0 -0
  184. package/dist/outbound-gateway-WE7Q623W.js +0 -1
  185. package/dist/presets-UKC5MHGV.js +0 -1
  186. package/dist/role-presets-5DDTPDJ4.js +0 -1
  187. package/dist/role-workspace-IHQZS56U.js +0 -1
  188. package/dist/roles-DLCEQ7V7.js +0 -1
  189. package/dist/server-bus-N5LCY73J.js +0 -1
  190. package/dist/session-manager-UOMXOJJX.js +0 -1
  191. package/dist/skill-registry-Q5GXSF6I.js +0 -1
  192. package/dist/target-resolution-ARTZKRBA.js +0 -1
  193. package/dist/task-templates-XZWRTAQ5.js +0 -1
  194. package/dist/template-dispatch-UFAGUOHR.js +0 -1
  195. package/dist/token-estimator-HMPVGDCN.js +0 -1
  196. package/web/dist/assets/Chat-PUJ7hpK9.js +0 -2
  197. package/web/dist/assets/Dashboard-CmRIajQD.js +0 -1
  198. package/web/dist/assets/Events-Bfjb3zYt.js +0 -1
  199. package/web/dist/assets/Goals-CXSFLkYn.js +0 -1
  200. package/web/dist/assets/Plugins-D4L5kw9U.js +0 -1
  201. package/web/dist/assets/RoleDetail-JXZ2Wb0p.js +0 -33
  202. package/web/dist/assets/Roles-DsCqCFHr.js +0 -1
  203. package/web/dist/assets/TaskDetail-ZAA7QN_T.js +0 -2
  204. package/web/dist/assets/Work-D2E3HWPo.js +0 -1
  205. package/web/dist/assets/api-D-UzHSDq.js +0 -1
  206. package/web/dist/assets/index-6f2jcj0h.css +0 -2
  207. package/web/dist/assets/index-CtdnsiU1.js +0 -12
  208. package/web/dist/assets/vendor-icons-ClLF5FTT.js +0 -1
@@ -0,0 +1,1006 @@
1
+ import{d as P,e as G,h as H}from"./chunk-WBAPIPST.js";import{c as g,h as B}from"./chunk-BLCNUT53.js";import{c as M}from"./chunk-FCV2DPZQ.js";import{constants as re,cpSync as te,copyFileSync as W,existsSync as u,lstatSync as se,mkdirSync as Y,readdirSync as ie,realpathSync as D,rmSync as K,statSync as h,unlinkSync as j}from"fs";import{dirname as $,extname as Ee,isAbsolute as Te,join as L,sep as O}from"path";function q(){return process.env.ADAM_TEST_DIR||P}function ne(){return L(q(),["work","flows"].join(""))}function x(){return L(q(),"template-executions")}function V(e){return L(x(),e,"artifacts")}function oe(e){let a=V(e);return Y(a,{recursive:!0}),a}function ve(e,a,m){if(!Te(e))throw new Error(`path must be absolute: ${e}`);let _=D(a),d=_.endsWith(O)?_:_+O;if(m){let l=D(e),A=l.endsWith(O)?l:l+O;if(A===d||A.startsWith(d))return;throw new Error(`path escapes workspace: ${e} (resolved=${l}, root=${_})`)}if(u(e))throw se(e).isSymbolicLink()?new Error(`destination already exists and is a symlink: ${e}`):new Error(`destination already exists: ${e}`);let N=D($(e)),I=N.endsWith(O)?N:N+O;if(!(I===d||I.startsWith(d)))throw new Error(`destination escapes workspace: ${e} (parent resolved=${N}, root=${_})`)}function fe(e){let a=oe(e.executionId),m=L(a,`${e.artifactId}.bin`);return W(e.sourcePath,m),{blobPath:m,sizeBytes:h(m).size}}function ge(e){j(e)}function Se(e){if(!u(e.blobPath))throw new Error(`blob file missing on disk: ${e.blobPath}`);return W(e.blobPath,e.destPath,re.COPYFILE_EXCL),{sizeBytes:h(e.destPath).size}}function J(e){try{j(e)}catch(a){v.warn({err:a,blobPath:e},"Failed to remove TemplateExecution artifact blob")}}function Ce(e){try{K(L(x(),e),{recursive:!0,force:!0})}catch(a){v.warn({err:a,executionId:e},"Failed to remove TemplateExecution artifacts directory")}}function Ue(e,a,m){let _=V(e);if(!u(_))return 0;let d=0;for(let N of ie(_)){if(Ee(N)!==".bin")continue;let I=N.slice(0,-4);if(a.has(I))continue;let l=L(_,N),A=h(l);Date.now()-A.mtimeMs<m||(J(l),d++)}return d}async function De(e,a){let{deleteArtifactsByExecutionAndStep:m}=await import("./template-execution-artifacts-NEPSVD2B.js"),_=m(e,a),d=0;for(let N of _)N.blobPath&&u(N.blobPath)&&(J(N.blobPath),d++);return v.debug({executionId:e,stepId:a,deletedRows:_.length,deletedFiles:d},"cleanSlatePriorAttempt: done"),{deletedRows:_.length,deletedFiles:d}}function z(e){let a=ne();if(!u(a)||!e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='template_execution_artifacts'").get())return;let _=e.prepare(`
2
+ SELECT id, execution_id, blob_path
3
+ FROM template_execution_artifacts
4
+ WHERE blob_path IS NOT NULL
5
+ `).all(),d=a.endsWith(O)?a:a+O,N=x(),I=new Set;for(let l of _){if(!l.blob_path.startsWith(d))continue;let A=L(a,l.execution_id),X=L(N,l.execution_id),U=L(N,l.blob_path.slice(d.length));try{if(u(A)&&!u(X)&&(Y($(X),{recursive:!0}),te(A,X,{recursive:!0,dereference:!1,force:!1})),!u(U)){v.warn({artifactId:l.id,blobPath:l.blob_path},"TemplateExecution artifact migration skipped missing copied blob");continue}e.prepare("UPDATE template_execution_artifacts SET blob_path = ? WHERE id = ?").run(U,l.id),I.add(l.execution_id)}catch(F){v.warn({err:F,artifactId:l.id,executionId:l.execution_id},"TemplateExecution artifact migration failed")}}for(let l of I){let A=L(N,l);if(u(A))try{K(L(a,l),{recursive:!0,force:!0})}catch(X){v.warn({err:X,executionId:l},"Failed to remove migrated legacy artifact directory")}}}var v,Q=M(()=>{"use strict";H();B();v=g("watchdog")});import _e from"better-sqlite3";import{existsSync as ae,mkdirSync as ce}from"fs";import{dirname as le}from"path";function pe(e){e.exec(`
6
+ CREATE TABLE IF NOT EXISTS server_state (
7
+ id INTEGER PRIMARY KEY CHECK(id = 1),
8
+ sdk_session_id TEXT,
9
+ user_task_session_id TEXT,
10
+ workspace_path TEXT,
11
+ schema_version INTEGER DEFAULT 0,
12
+ created_at INTEGER NOT NULL DEFAULT (unixepoch('now') * 1000),
13
+ last_active_at INTEGER
14
+ );
15
+ `),e.prepare("PRAGMA table_info(server_state)").all().some(s=>s.name==="schema_version")||e.exec("ALTER TABLE server_state ADD COLUMN schema_version INTEGER DEFAULT 0");let _=e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0;if(_<2){let s=["delivery_log","delivery_rules","manager_decisions","skill_scores","approval_rules","task_plans","calibration_history","task_plugins","marketplaces","plugins","trials","strategies","metric_tree","goals","chat_messages","chat_sessions","channels","evolution_audit","step_logs","task_templates","memories","tasks","config","memories_fts","memories_fts_config","memories_fts_data","memories_fts_docsize","memories_fts_idx"];for(let t of s)try{e.exec(`DROP TABLE IF EXISTS ${t}`)}catch{}for(let t of["memories_fts_insert","memories_fts_delete","memories_fts_update"])try{e.exec(`DROP TRIGGER IF EXISTS ${t}`)}catch{}}if(e.exec(`
16
+ CREATE TABLE IF NOT EXISTS tasks (
17
+ id TEXT PRIMARY KEY,
18
+ parent_id TEXT,
19
+ status TEXT NOT NULL DEFAULT 'pending',
20
+ prompt TEXT NOT NULL,
21
+ config TEXT NOT NULL,
22
+ result TEXT,
23
+ error TEXT,
24
+ sdk_session_id TEXT,
25
+ template_id TEXT,
26
+ original_prompt TEXT,
27
+ role_id TEXT,
28
+ source_session_id TEXT,
29
+ notify_targets TEXT,
30
+ deliver_to TEXT,
31
+ report_to TEXT,
32
+ created_at INTEGER NOT NULL,
33
+ started_at INTEGER,
34
+ completed_at INTEGER,
35
+ cost_usd REAL,
36
+ token_usage TEXT,
37
+ num_turns INTEGER,
38
+ total_duration_ms INTEGER
39
+ );
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
42
+ CREATE INDEX IF NOT EXISTS idx_tasks_created_at ON tasks(created_at);
43
+ CREATE INDEX IF NOT EXISTS idx_tasks_template_id ON tasks(template_id);
44
+ CREATE INDEX IF NOT EXISTS idx_tasks_role_id ON tasks(role_id);
45
+
46
+ CREATE TABLE IF NOT EXISTS step_logs (
47
+ id TEXT PRIMARY KEY,
48
+ task_id TEXT NOT NULL,
49
+ "index" INTEGER NOT NULL,
50
+ type TEXT NOT NULL,
51
+ content TEXT NOT NULL,
52
+ tool_name TEXT,
53
+ tool_input TEXT,
54
+ tool_output TEXT,
55
+ truncated INTEGER DEFAULT 0,
56
+ timestamp INTEGER NOT NULL,
57
+ token_usage TEXT,
58
+ plan_step_index INTEGER
59
+ );
60
+
61
+ CREATE INDEX IF NOT EXISTS idx_step_logs_task_index ON step_logs(task_id, "index");
62
+
63
+ CREATE TABLE IF NOT EXISTS config (
64
+ key TEXT PRIMARY KEY,
65
+ value TEXT NOT NULL
66
+ );
67
+
68
+ CREATE TABLE IF NOT EXISTS evolution_audit (
69
+ id TEXT PRIMARY KEY,
70
+ timestamp INTEGER NOT NULL,
71
+ old_rules TEXT,
72
+ new_rules TEXT,
73
+ diff TEXT,
74
+ trigger_task_id TEXT,
75
+ role_id TEXT,
76
+ source TEXT DEFAULT 'reflection'
77
+ );
78
+
79
+ CREATE INDEX IF NOT EXISTS idx_evolution_audit_role_id ON evolution_audit(role_id);
80
+
81
+ CREATE TABLE IF NOT EXISTS memories (
82
+ id TEXT PRIMARY KEY,
83
+ role_id TEXT NOT NULL,
84
+ type TEXT NOT NULL CHECK(type IN ('event', 'thought', 'reflection')),
85
+ content TEXT NOT NULL,
86
+ embedding BLOB,
87
+ keywords TEXT,
88
+ importance INTEGER NOT NULL CHECK(importance BETWEEN 1 AND 5),
89
+ source_type TEXT NOT NULL,
90
+ source_task_id TEXT,
91
+ evidence TEXT,
92
+ created_at INTEGER NOT NULL,
93
+ last_accessed INTEGER NOT NULL,
94
+ retrieved_count INTEGER DEFAULT 0
95
+ );
96
+
97
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
98
+ content,
99
+ keywords,
100
+ content='memories',
101
+ content_rowid='rowid'
102
+ );
103
+
104
+ CREATE INDEX IF NOT EXISTS idx_memories_role_id ON memories(role_id);
105
+ CREATE INDEX IF NOT EXISTS idx_memories_created_at ON memories(created_at);
106
+ CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
107
+
108
+ -- FTS5 content sync triggers
109
+ CREATE TRIGGER IF NOT EXISTS memories_fts_insert AFTER INSERT ON memories BEGIN
110
+ INSERT INTO memories_fts(rowid, content, keywords) VALUES (new.rowid, new.content, new.keywords);
111
+ END;
112
+ CREATE TRIGGER IF NOT EXISTS memories_fts_delete AFTER DELETE ON memories BEGIN
113
+ INSERT INTO memories_fts(memories_fts, rowid, content, keywords) VALUES ('delete', old.rowid, old.content, old.keywords);
114
+ END;
115
+ CREATE TRIGGER IF NOT EXISTS memories_fts_update AFTER UPDATE ON memories BEGIN
116
+ INSERT INTO memories_fts(memories_fts, rowid, content, keywords) VALUES ('delete', old.rowid, old.content, old.keywords);
117
+ INSERT INTO memories_fts(rowid, content, keywords) VALUES (new.rowid, new.content, new.keywords);
118
+ END;
119
+ `),e.exec(`
120
+ CREATE TABLE IF NOT EXISTS goals (
121
+ id TEXT PRIMARY KEY,
122
+ name TEXT NOT NULL,
123
+ description TEXT,
124
+ role TEXT NOT NULL,
125
+ metric_type TEXT NOT NULL,
126
+ target_value REAL NOT NULL,
127
+ current_value REAL NOT NULL DEFAULT 0,
128
+ deadline INTEGER NOT NULL,
129
+ budget_usd REAL NOT NULL,
130
+ status TEXT NOT NULL DEFAULT 'pending',
131
+ created_at INTEGER NOT NULL,
132
+ updated_at INTEGER,
133
+ notify_targets TEXT,
134
+ deliver_to TEXT
135
+ );
136
+
137
+ CREATE INDEX IF NOT EXISTS idx_goals_status ON goals(status);
138
+ CREATE INDEX IF NOT EXISTS idx_goals_deadline ON goals(deadline);
139
+
140
+ CREATE TABLE IF NOT EXISTS metric_tree (
141
+ id TEXT PRIMARY KEY,
142
+ goal_id TEXT NOT NULL REFERENCES goals(id) ON DELETE CASCADE,
143
+ level TEXT NOT NULL CHECK(level IN ('L0', 'L1', 'L2', 'L3')),
144
+ parent_id TEXT REFERENCES metric_tree(id) ON DELETE SET NULL,
145
+ name TEXT NOT NULL,
146
+ description TEXT,
147
+ weight REAL NOT NULL DEFAULT 1.0,
148
+ calibration_factor REAL DEFAULT 1.0,
149
+ created_at INTEGER NOT NULL
150
+ );
151
+
152
+ CREATE INDEX IF NOT EXISTS idx_metric_tree_goal_id ON metric_tree(goal_id);
153
+ CREATE INDEX IF NOT EXISTS idx_metric_tree_level ON metric_tree(level);
154
+ CREATE INDEX IF NOT EXISTS idx_metric_tree_parent_id ON metric_tree(parent_id);
155
+
156
+ CREATE TABLE IF NOT EXISTS strategies (
157
+ id TEXT PRIMARY KEY,
158
+ role_id TEXT NOT NULL,
159
+ task_type TEXT NOT NULL,
160
+ name TEXT NOT NULL,
161
+ prompt_template TEXT NOT NULL,
162
+ alpha REAL NOT NULL DEFAULT 0.5,
163
+ beta REAL NOT NULL DEFAULT 0.5,
164
+ total_trials INTEGER DEFAULT 0,
165
+ avg_reward REAL,
166
+ created_at INTEGER NOT NULL,
167
+ updated_at INTEGER
168
+ );
169
+
170
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_strategies_role_task_type ON strategies(role_id, task_type, name);
171
+ CREATE INDEX IF NOT EXISTS idx_strategies_role ON strategies(role_id);
172
+
173
+ CREATE TABLE IF NOT EXISTS trials (
174
+ id TEXT PRIMARY KEY,
175
+ strategy_id TEXT NOT NULL REFERENCES strategies(id) ON DELETE CASCADE,
176
+ goal_id TEXT NOT NULL REFERENCES goals(id) ON DELETE CASCADE,
177
+ task_id TEXT REFERENCES tasks(id) ON DELETE SET NULL,
178
+ reward REAL,
179
+ metric_l2_score REAL,
180
+ metric_l3_score REAL,
181
+ context TEXT,
182
+ completed_at INTEGER NOT NULL
183
+ );
184
+
185
+ CREATE INDEX IF NOT EXISTS idx_trials_strategy_id ON trials(strategy_id);
186
+ CREATE INDEX IF NOT EXISTS idx_trials_goal_id ON trials(goal_id);
187
+ CREATE INDEX IF NOT EXISTS idx_trials_task_id ON trials(task_id);
188
+ CREATE INDEX IF NOT EXISTS idx_trials_completed_at ON trials(completed_at);
189
+
190
+ CREATE TABLE IF NOT EXISTS task_templates (
191
+ id TEXT PRIMARY KEY,
192
+ name TEXT NOT NULL,
193
+ description TEXT,
194
+ trigger_type TEXT NOT NULL,
195
+ trigger_cron TEXT,
196
+ trigger_event TEXT,
197
+ steps TEXT NOT NULL,
198
+ role_preference TEXT,
199
+ config TEXT,
200
+ tags TEXT,
201
+ enabled INTEGER DEFAULT 1,
202
+ created_at INTEGER NOT NULL,
203
+ updated_at INTEGER,
204
+ source_session_id TEXT,
205
+ notify_targets TEXT,
206
+ deliver_to TEXT,
207
+ goal_ids TEXT
208
+ );
209
+
210
+ CREATE TABLE IF NOT EXISTS task_plugins (
211
+ id TEXT PRIMARY KEY,
212
+ task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
213
+ plugin_path TEXT NOT NULL,
214
+ plugin_name TEXT NOT NULL,
215
+ role_id TEXT,
216
+ used_at INTEGER NOT NULL
217
+ );
218
+
219
+ CREATE INDEX IF NOT EXISTS idx_task_plugins_task_id ON task_plugins(task_id);
220
+ CREATE INDEX IF NOT EXISTS idx_task_plugins_plugin_path ON task_plugins(plugin_path);
221
+ CREATE INDEX IF NOT EXISTS idx_task_plugins_role_id ON task_plugins(role_id);
222
+ `),e.exec(`
223
+ CREATE TABLE IF NOT EXISTS chat_sessions (
224
+ id TEXT PRIMARY KEY,
225
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'archived')),
226
+ source_type TEXT NOT NULL,
227
+ source_channel_id TEXT,
228
+ source_chat_id TEXT,
229
+ title TEXT,
230
+ created_at INTEGER NOT NULL,
231
+ last_active_at INTEGER NOT NULL,
232
+ archived_at INTEGER,
233
+ message_count INTEGER DEFAULT 0
234
+ );
235
+
236
+ CREATE INDEX IF NOT EXISTS idx_sessions_status ON chat_sessions(status);
237
+ CREATE INDEX IF NOT EXISTS idx_sessions_last_active ON chat_sessions(last_active_at);
238
+ CREATE INDEX IF NOT EXISTS idx_sessions_source ON chat_sessions(source_type, source_channel_id, source_chat_id);
239
+
240
+ CREATE TABLE IF NOT EXISTS chat_messages (
241
+ id TEXT PRIMARY KEY,
242
+ session_id TEXT NOT NULL REFERENCES chat_sessions(id) ON DELETE CASCADE,
243
+ role TEXT NOT NULL CHECK(role IN ('user', 'assistant')),
244
+ content TEXT NOT NULL,
245
+ source_type TEXT NOT NULL,
246
+ task_id TEXT,
247
+ channel_message_id TEXT,
248
+ metadata TEXT,
249
+ created_at INTEGER NOT NULL
250
+ );
251
+
252
+ CREATE INDEX IF NOT EXISTS idx_messages_session ON chat_messages(session_id, created_at);
253
+ CREATE INDEX IF NOT EXISTS idx_messages_task ON chat_messages(task_id);
254
+
255
+ CREATE TABLE IF NOT EXISTS channels (
256
+ id TEXT PRIMARY KEY,
257
+ name TEXT NOT NULL,
258
+ platform TEXT NOT NULL,
259
+ enabled INTEGER DEFAULT 1,
260
+ status TEXT NOT NULL DEFAULT 'disconnected',
261
+ config TEXT NOT NULL,
262
+ linked_role_id TEXT,
263
+ allowed_chat_ids TEXT,
264
+ viewer_key TEXT,
265
+ created_at INTEGER NOT NULL,
266
+ updated_at INTEGER,
267
+ last_message_at INTEGER,
268
+ message_count INTEGER DEFAULT 0
269
+ );
270
+
271
+ CREATE INDEX IF NOT EXISTS idx_channels_platform ON channels(platform);
272
+ CREATE INDEX IF NOT EXISTS idx_channels_enabled ON channels(enabled);
273
+ CREATE INDEX IF NOT EXISTS idx_channels_linked_role_id ON channels(linked_role_id);
274
+ `),e.exec(`
275
+ CREATE TABLE IF NOT EXISTS task_plans (
276
+ id TEXT PRIMARY KEY,
277
+ task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
278
+ plan_json TEXT NOT NULL,
279
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'approved', 'denied', 'completed')),
280
+ approval_type TEXT CHECK(approval_type IN ('once', 'permanent')),
281
+ deviation_report_json TEXT,
282
+ learned_rules_json TEXT,
283
+ created_at INTEGER NOT NULL,
284
+ approved_at INTEGER,
285
+ reviewed_at INTEGER
286
+ );
287
+
288
+ CREATE INDEX IF NOT EXISTS idx_task_plans_task_id ON task_plans(task_id);
289
+ CREATE INDEX IF NOT EXISTS idx_task_plans_status ON task_plans(status);
290
+
291
+ CREATE TABLE IF NOT EXISTS approval_rules (
292
+ id TEXT PRIMARY KEY,
293
+ role_id TEXT,
294
+ task_pattern TEXT NOT NULL,
295
+ max_risk_level TEXT NOT NULL CHECK(max_risk_level IN ('low', 'medium', 'high')),
296
+ created_at INTEGER NOT NULL,
297
+ created_by_task_id TEXT REFERENCES tasks(id)
298
+ );
299
+
300
+ CREATE INDEX IF NOT EXISTS idx_approval_rules_role_id ON approval_rules(role_id);
301
+ `),e.exec(`
302
+ CREATE TABLE IF NOT EXISTS role_scores (
303
+ id TEXT PRIMARY KEY,
304
+ role_id TEXT NOT NULL,
305
+ task_id TEXT NOT NULL REFERENCES tasks(id),
306
+ score_json TEXT NOT NULL,
307
+ ema_score REAL NOT NULL,
308
+ created_at INTEGER NOT NULL
309
+ );
310
+
311
+ CREATE INDEX IF NOT EXISTS idx_role_scores_role_id ON role_scores(role_id);
312
+ CREATE INDEX IF NOT EXISTS idx_role_scores_task_id ON role_scores(task_id);
313
+ CREATE INDEX IF NOT EXISTS idx_role_scores_created_at ON role_scores(created_at);
314
+ `),e.exec(`
315
+ CREATE TABLE IF NOT EXISTS manager_decisions (
316
+ id TEXT PRIMARY KEY,
317
+ task_id TEXT NOT NULL REFERENCES tasks(id),
318
+ role_id TEXT,
319
+ decision_type TEXT NOT NULL,
320
+ boundary_json TEXT,
321
+ reason TEXT,
322
+ created_at INTEGER NOT NULL
323
+ );
324
+
325
+ CREATE INDEX IF NOT EXISTS idx_manager_decisions_task_id ON manager_decisions(task_id);
326
+ CREATE INDEX IF NOT EXISTS idx_manager_decisions_role_id ON manager_decisions(role_id);
327
+ `),e.exec(`
328
+ CREATE TABLE IF NOT EXISTS delivery_rules (
329
+ id TEXT PRIMARY KEY,
330
+ event_type TEXT NOT NULL,
331
+ match_criteria TEXT NOT NULL,
332
+ target TEXT NOT NULL,
333
+ format_template TEXT,
334
+ max_per_minute INTEGER DEFAULT 5,
335
+ skip_origin_channel INTEGER DEFAULT 1,
336
+ enabled INTEGER DEFAULT 1,
337
+ created_at INTEGER NOT NULL,
338
+ created_by TEXT
339
+ );
340
+
341
+ CREATE INDEX IF NOT EXISTS idx_delivery_rules_event_type ON delivery_rules(event_type);
342
+ CREATE INDEX IF NOT EXISTS idx_delivery_rules_enabled ON delivery_rules(enabled);
343
+
344
+ CREATE TABLE IF NOT EXISTS delivery_log (
345
+ id TEXT PRIMARY KEY,
346
+ rule_id TEXT NOT NULL REFERENCES delivery_rules(id),
347
+ task_id TEXT REFERENCES tasks(id),
348
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'delivered', 'failed', 'expired')),
349
+ target TEXT NOT NULL,
350
+ content TEXT NOT NULL,
351
+ attempts INTEGER DEFAULT 0,
352
+ error TEXT,
353
+ created_at INTEGER NOT NULL,
354
+ delivered_at INTEGER,
355
+ expires_at INTEGER NOT NULL
356
+ );
357
+
358
+ CREATE INDEX IF NOT EXISTS idx_delivery_log_status ON delivery_log(status);
359
+ CREATE INDEX IF NOT EXISTS idx_delivery_log_expires ON delivery_log(expires_at);
360
+ CREATE INDEX IF NOT EXISTS idx_delivery_log_rule_id ON delivery_log(rule_id);
361
+ `),e.exec(`
362
+ CREATE TABLE IF NOT EXISTS calibration_history (
363
+ id TEXT PRIMARY KEY,
364
+ goal_id TEXT NOT NULL,
365
+ factors_json TEXT NOT NULL,
366
+ l0_score REAL NOT NULL,
367
+ l1_trend REAL NOT NULL,
368
+ l2_trend REAL NOT NULL,
369
+ l3_trend REAL NOT NULL,
370
+ applied INTEGER NOT NULL DEFAULT 0,
371
+ computed_at INTEGER NOT NULL
372
+ );
373
+
374
+ CREATE INDEX IF NOT EXISTS idx_calibration_goal ON calibration_history(goal_id);
375
+ CREATE INDEX IF NOT EXISTS idx_calibration_computed ON calibration_history(computed_at);
376
+ `),_<2&&e.exec("UPDATE server_state SET schema_version = 2 WHERE id = 1"),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<4&&(e.exec(`
377
+ CREATE TABLE IF NOT EXISTS roles (
378
+ id TEXT PRIMARY KEY,
379
+ name TEXT NOT NULL UNIQUE,
380
+ cag_prompt TEXT NOT NULL DEFAULT '',
381
+ learned_rules TEXT,
382
+ memory_stream_id TEXT NOT NULL,
383
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'inactive', 'retired', 'probation', 'dead')),
384
+ performance_score REAL,
385
+ preferences TEXT,
386
+ created_at INTEGER NOT NULL,
387
+ updated_at INTEGER,
388
+ importance_trigger_curr INTEGER DEFAULT 150,
389
+ allowed_tools TEXT,
390
+ disallowed_tools TEXT,
391
+ evaluation_criteria TEXT,
392
+ execution_mode TEXT DEFAULT 'isolated',
393
+ model TEXT,
394
+ max_budget_usd REAL,
395
+ approval_required TEXT,
396
+ source TEXT DEFAULT 'system',
397
+ additional_directories TEXT,
398
+ allowed_channels TEXT,
399
+ mcp_servers TEXT,
400
+ inherit_user_settings INTEGER DEFAULT 0,
401
+ os_capabilities TEXT
402
+ );
403
+
404
+ CREATE INDEX IF NOT EXISTS idx_roles_status ON roles(status);
405
+ CREATE INDEX IF NOT EXISTS idx_roles_name ON roles(name);
406
+
407
+ CREATE TABLE IF NOT EXISTS role_plugins (
408
+ role_id TEXT NOT NULL,
409
+ plugin_id TEXT NOT NULL,
410
+ bound_at INTEGER NOT NULL,
411
+ PRIMARY KEY (role_id, plugin_id)
412
+ );
413
+ `),e.prepare("PRAGMA table_info(tasks)").all().some(t=>t.name==="role_id")||(e.exec("ALTER TABLE tasks ADD COLUMN role_id TEXT"),e.exec("CREATE INDEX IF NOT EXISTS idx_tasks_role_id ON tasks(role_id)")),e.exec("UPDATE server_state SET schema_version = 4 WHERE id = 1")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<5&&(e.exec(`
414
+ DROP TABLE IF EXISTS memories;
415
+ CREATE TABLE memories (
416
+ id TEXT PRIMARY KEY,
417
+ role_id TEXT NOT NULL,
418
+ type TEXT NOT NULL CHECK(type IN ('event', 'thought', 'reflection')),
419
+ content TEXT NOT NULL,
420
+ embedding BLOB,
421
+ keywords TEXT,
422
+ importance INTEGER NOT NULL CHECK(importance BETWEEN 1 AND 5),
423
+ source_type TEXT NOT NULL,
424
+ source_task_id TEXT,
425
+ evidence TEXT,
426
+ created_at INTEGER NOT NULL,
427
+ last_accessed INTEGER NOT NULL,
428
+ retrieved_count INTEGER DEFAULT 0
429
+ );
430
+ CREATE INDEX IF NOT EXISTS idx_memories_role_id ON memories(role_id);
431
+ CREATE INDEX IF NOT EXISTS idx_memories_created_at ON memories(created_at);
432
+ CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
433
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
434
+ content, keywords,
435
+ content='memories',
436
+ content_rowid='rowid'
437
+ );
438
+ CREATE TRIGGER IF NOT EXISTS memories_fts_insert AFTER INSERT ON memories BEGIN
439
+ INSERT INTO memories_fts(rowid, content, keywords) VALUES (new.rowid, new.content, new.keywords);
440
+ END;
441
+ CREATE TRIGGER IF NOT EXISTS memories_fts_delete AFTER DELETE ON memories BEGIN
442
+ INSERT INTO memories_fts(memories_fts, rowid, content, keywords) VALUES ('delete', old.rowid, old.content, old.keywords);
443
+ END;
444
+ CREATE TRIGGER IF NOT EXISTS memories_fts_update AFTER UPDATE ON memories BEGIN
445
+ INSERT INTO memories_fts(memories_fts, rowid, content, keywords) VALUES ('delete', old.rowid, old.content, old.keywords);
446
+ INSERT INTO memories_fts(rowid, content, keywords) VALUES (new.rowid, new.content, new.keywords);
447
+ END;
448
+ `),e.exec(`
449
+ DROP TABLE IF EXISTS skill_scores;
450
+ CREATE TABLE IF NOT EXISTS role_scores (
451
+ id TEXT PRIMARY KEY,
452
+ role_id TEXT NOT NULL,
453
+ task_id TEXT NOT NULL REFERENCES tasks(id),
454
+ score_json TEXT NOT NULL,
455
+ ema_score REAL NOT NULL,
456
+ created_at INTEGER NOT NULL
457
+ );
458
+ CREATE INDEX IF NOT EXISTS idx_role_scores_role_id ON role_scores(role_id);
459
+ CREATE INDEX IF NOT EXISTS idx_role_scores_task_id ON role_scores(task_id);
460
+ CREATE INDEX IF NOT EXISTS idx_role_scores_created_at ON role_scores(created_at);
461
+ `),e.exec(`
462
+ DROP TABLE IF EXISTS evolution_audit;
463
+ CREATE TABLE evolution_audit (
464
+ id TEXT PRIMARY KEY,
465
+ timestamp INTEGER NOT NULL,
466
+ old_rules TEXT,
467
+ new_rules TEXT,
468
+ diff TEXT,
469
+ trigger_task_id TEXT,
470
+ role_id TEXT,
471
+ source TEXT DEFAULT 'reflection'
472
+ );
473
+ CREATE INDEX IF NOT EXISTS idx_evolution_audit_role_id ON evolution_audit(role_id);
474
+ `),e.exec("UPDATE server_state SET schema_version = 5 WHERE id = 1")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<6&&(e.prepare("PRAGMA table_info(roles)").all().some(t=>t.name==="importance_trigger_curr")||e.exec("ALTER TABLE roles ADD COLUMN importance_trigger_curr INTEGER DEFAULT 150"),e.exec("UPDATE server_state SET schema_version = 6 WHERE id = 1")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<7&&(e.prepare("PRAGMA table_info(tasks)").all().some(t=>t.name==="source_session_id")||e.exec("ALTER TABLE tasks ADD COLUMN source_session_id TEXT"),e.exec("UPDATE server_state SET schema_version = 7 WHERE id = 1")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<8){let s=e.prepare("PRAGMA table_info(goals)").all();s.some(r=>r.name==="source_session_id")||e.exec("ALTER TABLE goals ADD COLUMN source_session_id TEXT"),s.some(r=>r.name==="notify_targets")||e.exec("ALTER TABLE goals ADD COLUMN notify_targets TEXT");let t=e.prepare("PRAGMA table_info(task_templates)").all();t.some(r=>r.name==="source_session_id")||e.exec("ALTER TABLE task_templates ADD COLUMN source_session_id TEXT"),t.some(r=>r.name==="notify_targets")||e.exec("ALTER TABLE task_templates ADD COLUMN notify_targets TEXT"),t.some(r=>r.name==="goal_ids")||e.exec("ALTER TABLE task_templates ADD COLUMN goal_ids TEXT"),e.exec("UPDATE goals SET status = 'active' WHERE status IN ('pending','planning','executing','evaluating','replanning')"),e.exec("UPDATE server_state SET schema_version = 8 WHERE id = 1")}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<10){e.exec("PRAGMA foreign_keys = OFF"),e.exec("DROP TABLE IF EXISTS tasks_new"),e.exec("DROP TABLE IF EXISTS chat_sessions_new"),e.exec("DROP TABLE IF EXISTS task_plans_new"),e.exec("DROP TABLE IF EXISTS task_plugins_new"),e.exec("DROP TABLE IF EXISTS approval_rules_new"),e.exec("DROP TABLE IF EXISTS manager_decisions_new"),e.exec("DROP TABLE IF EXISTS channels_new");let s=e.prepare("PRAGMA table_info(roles)").all();s.some(o=>o.name==="allowed_tools")||e.exec("ALTER TABLE roles ADD COLUMN allowed_tools TEXT"),s.some(o=>o.name==="disallowed_tools")||e.exec("ALTER TABLE roles ADD COLUMN disallowed_tools TEXT"),s.some(o=>o.name==="evaluation_criteria")||e.exec("ALTER TABLE roles ADD COLUMN evaluation_criteria TEXT"),s.some(o=>o.name==="execution_mode")||e.exec("ALTER TABLE roles ADD COLUMN execution_mode TEXT DEFAULT 'isolated'"),s.some(o=>o.name==="model")||e.exec("ALTER TABLE roles ADD COLUMN model TEXT"),s.some(o=>o.name==="max_budget_usd")||e.exec("ALTER TABLE roles ADD COLUMN max_budget_usd REAL"),s.some(o=>o.name==="approval_required")||e.exec("ALTER TABLE roles ADD COLUMN approval_required TEXT"),s.some(o=>o.name==="source")||e.exec("ALTER TABLE roles ADD COLUMN source TEXT DEFAULT 'system'"),e.exec("DROP TABLE IF EXISTS agents"),e.exec("DROP TABLE IF EXISTS role_skills"),e.exec(`
475
+ CREATE TABLE IF NOT EXISTS tasks_new (
476
+ id TEXT PRIMARY KEY,
477
+ parent_id TEXT,
478
+ status TEXT NOT NULL DEFAULT 'pending',
479
+ prompt TEXT NOT NULL,
480
+ config TEXT NOT NULL,
481
+ result TEXT,
482
+ error TEXT,
483
+ sdk_session_id TEXT,
484
+ template_id TEXT,
485
+ original_prompt TEXT,
486
+ role_id TEXT,
487
+ source_session_id TEXT,
488
+ notify_targets TEXT,
489
+ deliver_to TEXT,
490
+ report_to TEXT,
491
+ created_at INTEGER NOT NULL,
492
+ started_at INTEGER,
493
+ completed_at INTEGER,
494
+ cost_usd REAL,
495
+ token_usage TEXT,
496
+ num_turns INTEGER,
497
+ total_duration_ms INTEGER
498
+ );
499
+ `);let t=new Set(["id","status","prompt","config","created_at"]),r=["id","parent_id","status","prompt","config","result","error","sdk_session_id","template_id","original_prompt","role_id","source_session_id","notify_targets","deliver_to","report_to","created_at","started_at","completed_at","cost_usd","token_usage","num_turns","total_duration_ms"],i=new Set(e.prepare("PRAGMA table_info(tasks)").all().map(o=>o.name)),E=r.map(o=>i.has(o)?t.has(o)?`COALESCE(${o}, '')`:o:"NULL").join(",");e.exec(`INSERT INTO tasks_new SELECT ${E} FROM tasks`),e.exec("DROP TABLE tasks"),e.exec("ALTER TABLE tasks_new RENAME TO tasks"),e.exec("CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)"),e.exec("CREATE INDEX IF NOT EXISTS idx_tasks_created_at ON tasks(created_at)"),e.exec("CREATE INDEX IF NOT EXISTS idx_tasks_template_id ON tasks(template_id)"),e.exec("CREATE INDEX IF NOT EXISTS idx_tasks_role_id ON tasks(role_id)"),e.exec(`
500
+ CREATE TABLE IF NOT EXISTS chat_sessions_new (
501
+ id TEXT PRIMARY KEY,
502
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'archived')),
503
+ source_type TEXT NOT NULL,
504
+ source_channel_id TEXT,
505
+ source_chat_id TEXT,
506
+ title TEXT,
507
+ created_at INTEGER NOT NULL,
508
+ last_active_at INTEGER NOT NULL,
509
+ archived_at INTEGER,
510
+ message_count INTEGER DEFAULT 0
511
+ );
512
+ `),e.exec("INSERT INTO chat_sessions_new SELECT id,status,source_type,source_channel_id,source_chat_id,title,created_at,last_active_at,archived_at,message_count FROM chat_sessions"),e.exec("DROP TABLE chat_sessions"),e.exec("ALTER TABLE chat_sessions_new RENAME TO chat_sessions"),e.exec("CREATE INDEX IF NOT EXISTS idx_sessions_status ON chat_sessions(status)"),e.exec("CREATE INDEX IF NOT EXISTS idx_sessions_last_active ON chat_sessions(last_active_at)"),e.exec("CREATE INDEX IF NOT EXISTS idx_sessions_source ON chat_sessions(source_type, source_channel_id, source_chat_id)"),e.exec(`
513
+ CREATE TABLE IF NOT EXISTS task_plans_new (
514
+ id TEXT PRIMARY KEY,
515
+ task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
516
+ plan_json TEXT NOT NULL,
517
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'approved', 'denied', 'completed')),
518
+ approval_type TEXT CHECK(approval_type IN ('once', 'permanent')),
519
+ deviation_report_json TEXT,
520
+ learned_rules_json TEXT,
521
+ created_at INTEGER NOT NULL,
522
+ approved_at INTEGER,
523
+ reviewed_at INTEGER
524
+ );
525
+ `),e.exec("INSERT INTO task_plans_new SELECT id,task_id,plan_json,status,approval_type,deviation_report_json,learned_rules_json,created_at,approved_at,reviewed_at FROM task_plans"),e.exec("DROP TABLE task_plans"),e.exec("ALTER TABLE task_plans_new RENAME TO task_plans"),e.exec("CREATE INDEX IF NOT EXISTS idx_task_plans_task_id ON task_plans(task_id)"),e.exec("CREATE INDEX IF NOT EXISTS idx_task_plans_status ON task_plans(status)"),e.prepare("PRAGMA table_info(task_plugins)").all().some(o=>o.name==="skill_id")&&(e.exec(`
526
+ CREATE TABLE IF NOT EXISTS task_plugins_new (
527
+ id TEXT PRIMARY KEY,
528
+ task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
529
+ plugin_path TEXT NOT NULL,
530
+ plugin_name TEXT NOT NULL,
531
+ role_id TEXT,
532
+ used_at INTEGER NOT NULL
533
+ );
534
+ `),e.exec("INSERT INTO task_plugins_new SELECT id,task_id,plugin_path,plugin_name,skill_id,used_at FROM task_plugins"),e.exec("DROP TABLE task_plugins"),e.exec("ALTER TABLE task_plugins_new RENAME TO task_plugins")),e.exec("CREATE INDEX IF NOT EXISTS idx_task_plugins_task_id ON task_plugins(task_id)"),e.exec("CREATE INDEX IF NOT EXISTS idx_task_plugins_plugin_path ON task_plugins(plugin_path)"),e.exec("CREATE INDEX IF NOT EXISTS idx_task_plugins_role_id ON task_plugins(role_id)"),e.prepare("PRAGMA table_info(approval_rules)").all().some(o=>o.name==="skill_id")&&(e.exec(`
535
+ CREATE TABLE IF NOT EXISTS approval_rules_new (
536
+ id TEXT PRIMARY KEY,
537
+ role_id TEXT,
538
+ task_pattern TEXT NOT NULL,
539
+ max_risk_level TEXT NOT NULL CHECK(max_risk_level IN ('low', 'medium', 'high')),
540
+ created_at INTEGER NOT NULL,
541
+ created_by_task_id TEXT REFERENCES tasks(id)
542
+ );
543
+ `),e.exec("INSERT INTO approval_rules_new SELECT id,skill_id,task_pattern,max_risk_level,created_at,created_by_task_id FROM approval_rules"),e.exec("DROP TABLE approval_rules"),e.exec("ALTER TABLE approval_rules_new RENAME TO approval_rules")),e.exec("CREATE INDEX IF NOT EXISTS idx_approval_rules_role_id ON approval_rules(role_id)"),e.prepare("PRAGMA table_info(manager_decisions)").all().some(o=>o.name==="skill_id")&&(e.exec(`
544
+ CREATE TABLE IF NOT EXISTS manager_decisions_new (
545
+ id TEXT PRIMARY KEY,
546
+ task_id TEXT NOT NULL REFERENCES tasks(id),
547
+ role_id TEXT,
548
+ decision_type TEXT NOT NULL,
549
+ boundary_json TEXT,
550
+ reason TEXT,
551
+ created_at INTEGER NOT NULL
552
+ );
553
+ `),e.exec("INSERT INTO manager_decisions_new SELECT id,task_id,skill_id,decision_type,boundary_json,reason,created_at FROM manager_decisions"),e.exec("DROP TABLE manager_decisions"),e.exec("ALTER TABLE manager_decisions_new RENAME TO manager_decisions")),e.exec("CREATE INDEX IF NOT EXISTS idx_manager_decisions_task_id ON manager_decisions(task_id)"),e.exec("CREATE INDEX IF NOT EXISTS idx_manager_decisions_role_id ON manager_decisions(role_id)"),e.prepare("PRAGMA table_info(channels)").all().some(o=>o.name==="linked_skill_id")&&(e.exec(`
554
+ CREATE TABLE IF NOT EXISTS channels_new (
555
+ id TEXT PRIMARY KEY,
556
+ name TEXT NOT NULL,
557
+ platform TEXT NOT NULL,
558
+ enabled INTEGER DEFAULT 1,
559
+ status TEXT NOT NULL DEFAULT 'disconnected',
560
+ config TEXT NOT NULL,
561
+ linked_role_id TEXT,
562
+ allowed_chat_ids TEXT,
563
+ created_at INTEGER NOT NULL,
564
+ updated_at INTEGER,
565
+ last_message_at INTEGER,
566
+ message_count INTEGER DEFAULT 0
567
+ );
568
+ `),e.exec("INSERT INTO channels_new SELECT id,name,platform,enabled,status,config,linked_skill_id,allowed_chat_ids,created_at,updated_at,last_message_at,message_count FROM channels"),e.exec("DROP TABLE channels"),e.exec("ALTER TABLE channels_new RENAME TO channels")),e.exec("CREATE INDEX IF NOT EXISTS idx_channels_platform ON channels(platform)"),e.exec("CREATE INDEX IF NOT EXISTS idx_channels_enabled ON channels(enabled)"),e.exec("CREATE INDEX IF NOT EXISTS idx_channels_linked_role_id ON channels(linked_role_id)"),e.exec(`
569
+ CREATE TABLE IF NOT EXISTS role_plugins (
570
+ role_id TEXT NOT NULL,
571
+ plugin_id TEXT NOT NULL,
572
+ bound_at INTEGER NOT NULL,
573
+ PRIMARY KEY (role_id, plugin_id)
574
+ );
575
+ `),e.exec("UPDATE server_state SET schema_version = 10 WHERE id = 1"),e.exec("PRAGMA foreign_keys = ON")}if(_<11){try{e.exec("ALTER TABLE task_templates RENAME COLUMN skill_preference TO role_preference")}catch(s){let t=e.prepare("PRAGMA table_info(task_templates)").all(),r=t.some(E=>E.name==="role_preference"),i=t.some(E=>E.name==="skill_preference");if(!r&&i)throw s}e.exec("UPDATE server_state SET schema_version = 11 WHERE id = 1")}if(_<12&&(e.prepare("PRAGMA table_info(server_state)").all().some(t=>t.name==="tools_fingerprint")||e.exec("ALTER TABLE server_state ADD COLUMN tools_fingerprint TEXT"),e.exec("UPDATE server_state SET schema_version = 12 WHERE id = 1")),_<13&&(e.prepare("PRAGMA table_info(roles)").all().some(t=>t.name==="additional_directories")||e.exec("ALTER TABLE roles ADD COLUMN additional_directories TEXT"),e.exec("UPDATE server_state SET schema_version = 13 WHERE id = 1")),_<14){let s=e.prepare("PRAGMA table_info(roles)").all();s.some(i=>i.name==="allowed_channels")||e.exec("ALTER TABLE roles ADD COLUMN allowed_channels TEXT"),s.some(i=>i.name==="mcp_servers")||e.exec("ALTER TABLE roles ADD COLUMN mcp_servers TEXT");let t=e.prepare("PRAGMA table_info(tasks)").all();t.some(i=>i.name==="deliver_to")||e.exec("ALTER TABLE tasks ADD COLUMN deliver_to TEXT"),t.some(i=>i.name==="report_to")||e.exec("ALTER TABLE tasks ADD COLUMN report_to TEXT"),e.prepare("PRAGMA table_info(goals)").all().some(i=>i.name==="deliver_to")||e.exec("ALTER TABLE goals ADD COLUMN deliver_to TEXT"),e.exec("UPDATE server_state SET schema_version = 14 WHERE id = 1")}if(_<15&&(e.prepare("PRAGMA table_info(roles)").all().some(t=>t.name==="inherit_user_settings")||e.exec("ALTER TABLE roles ADD COLUMN inherit_user_settings INTEGER DEFAULT 0"),e.exec("UPDATE server_state SET schema_version = 15 WHERE id = 1")),_<16&&(e.prepare("PRAGMA table_info(task_templates)").all().some(t=>t.name==="deliver_to")||e.exec("ALTER TABLE task_templates ADD COLUMN deliver_to TEXT"),e.exec("UPDATE server_state SET schema_version = 16 WHERE id = 1")),_<17){e.exec("PRAGMA foreign_keys = OFF"),e.exec("DROP TABLE IF EXISTS plugins"),e.exec("DROP TABLE IF EXISTS role_plugins"),e.exec("DROP TABLE IF EXISTS marketplaces"),e.exec("DROP INDEX IF EXISTS idx_plugins_source"),e.exec("DROP INDEX IF EXISTS idx_plugins_enabled");try{let r=e.prepare("SELECT id, additional_directories FROM roles WHERE additional_directories IS NOT NULL").all();for(let i of r)try{let E=JSON.parse(i.additional_directories);if(E.length>0&&typeof E[0]=="object"&&E[0]!==null&&"path"in E[0])continue;let T=E.map(n=>typeof n=="string"?{path:n}:n);e.prepare("UPDATE roles SET additional_directories = ? WHERE id = ?").run(JSON.stringify(T),i.id)}catch{}}catch{}let s=e.prepare("PRAGMA table_info(tasks)").all();s.some(r=>r.name==="deliver_to")||e.exec("ALTER TABLE tasks ADD COLUMN deliver_to TEXT"),s.some(r=>r.name==="report_to")||e.exec("ALTER TABLE tasks ADD COLUMN report_to TEXT");let t=e.prepare("PRAGMA table_info(strategies)").all();t.some(r=>r.name==="role")&&!t.some(r=>r.name==="role_id")&&(e.exec("ALTER TABLE strategies RENAME COLUMN role TO role_id"),e.exec("DROP INDEX IF EXISTS idx_strategies_role_task_type"),e.exec("DROP INDEX IF EXISTS idx_strategies_role"),e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_strategies_role_task_type ON strategies(role_id, task_type, name)"),e.exec("CREATE INDEX IF NOT EXISTS idx_strategies_role ON strategies(role_id)")),e.exec("UPDATE server_state SET schema_version = 17 WHERE id = 1"),e.exec("PRAGMA foreign_keys = ON")}if(_<18){let s=e.prepare("PRAGMA table_info(tasks)").all();s.some(r=>r.name==="deliver_to")||e.exec("ALTER TABLE tasks ADD COLUMN deliver_to TEXT"),s.some(r=>r.name==="report_to")||e.exec("ALTER TABLE tasks ADD COLUMN report_to TEXT");let t=e.prepare("PRAGMA table_info(strategies)").all();t.some(r=>r.name==="role")&&!t.some(r=>r.name==="role_id")&&(e.exec("ALTER TABLE strategies RENAME COLUMN role TO role_id"),e.exec("DROP INDEX IF EXISTS idx_strategies_role_task_type"),e.exec("DROP INDEX IF EXISTS idx_strategies_role"),e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_strategies_role_task_type ON strategies(role_id, task_type, name)"),e.exec("CREATE INDEX IF NOT EXISTS idx_strategies_role ON strategies(role_id)")),e.exec("UPDATE server_state SET schema_version = 18 WHERE id = 1")}e.prepare("PRAGMA table_info(delivery_log)").all().some(s=>s.name==="source")||(e.exec(`
576
+ CREATE TABLE IF NOT EXISTS delivery_log_new (
577
+ id TEXT PRIMARY KEY,
578
+ rule_id TEXT REFERENCES delivery_rules(id),
579
+ task_id TEXT,
580
+ status TEXT NOT NULL DEFAULT 'pending',
581
+ target TEXT NOT NULL,
582
+ content TEXT NOT NULL DEFAULT '',
583
+ attempts INTEGER NOT NULL DEFAULT 0,
584
+ error TEXT,
585
+ created_at INTEGER NOT NULL,
586
+ delivered_at INTEGER,
587
+ expires_at INTEGER NOT NULL,
588
+ source TEXT,
589
+ message_type TEXT
590
+ )
591
+ `),e.exec(`INSERT INTO delivery_log_new (id, rule_id, task_id, status, target, content, attempts, error, created_at, delivered_at, expires_at)
592
+ SELECT id, rule_id, task_id, status, target, content, attempts, error, created_at, delivered_at, expires_at FROM delivery_log`),e.exec("DROP TABLE delivery_log"),e.exec("ALTER TABLE delivery_log_new RENAME TO delivery_log"),e.exec("CREATE INDEX IF NOT EXISTS idx_delivery_log_rule ON delivery_log(rule_id)"),e.exec("CREATE INDEX IF NOT EXISTS idx_delivery_log_task ON delivery_log(task_id)")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<20&&(e.prepare("PRAGMA table_info(goals)").all().some(r=>r.name==="report_to")||e.exec("ALTER TABLE goals ADD COLUMN report_to TEXT"),e.prepare("PRAGMA table_info(task_templates)").all().some(r=>r.name==="report_to")||e.exec("ALTER TABLE task_templates ADD COLUMN report_to TEXT"),e.exec("UPDATE goals SET report_to = notify_targets WHERE notify_targets IS NOT NULL"),e.exec("UPDATE task_templates SET report_to = notify_targets WHERE notify_targets IS NOT NULL"),e.exec("UPDATE server_state SET schema_version = 20 WHERE id = 1")),e.prepare("PRAGMA table_info(config)").all().some(s=>s.name==="updated_at")||(e.exec("ALTER TABLE config ADD COLUMN updated_at INTEGER NOT NULL DEFAULT 0"),e.exec("UPDATE server_state SET schema_version = 21 WHERE id = 1"));let k=e.prepare("PRAGMA table_info(memories)").all();k.some(s=>s.name==="tier")||(e.exec("ALTER TABLE memories ADD COLUMN tier TEXT NOT NULL DEFAULT 'episodic'"),e.exec("CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)")),k.some(s=>s.name==="superseded_by")||(e.exec("ALTER TABLE memories ADD COLUMN superseded_by TEXT"),e.exec("CREATE INDEX IF NOT EXISTS idx_memories_superseded ON memories(superseded_by)"));let w=e.prepare("PRAGMA table_info(memories)").all();w.some(s=>s.name==="tier")&&w.some(s=>s.name==="superseded_by")&&(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<22&&e.exec("UPDATE server_state SET schema_version = 22 WHERE id = 1");{let s=e.prepare("PRAGMA table_info(roles)").all();s.some(r=>r.name==="permission_mode")||e.exec("ALTER TABLE roles ADD COLUMN permission_mode TEXT DEFAULT NULL"),s.some(r=>r.name==="allowed_bash_patterns")||e.exec("ALTER TABLE roles ADD COLUMN allowed_bash_patterns TEXT DEFAULT NULL"),s.some(r=>r.name==="denied_bash_patterns")||e.exec("ALTER TABLE roles ADD COLUMN denied_bash_patterns TEXT DEFAULT NULL"),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<23&&e.exec("UPDATE server_state SET schema_version = 23 WHERE id = 1")}if(e.prepare("PRAGMA table_info(roles)").all().some(r=>r.name==="env_vars")||e.prepare("ALTER TABLE roles ADD COLUMN env_vars TEXT DEFAULT NULL").run(),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<24&&e.prepare("UPDATE server_state SET schema_version = 24 WHERE id = 1").run(),_<25&&(e.exec(`
593
+ CREATE TABLE IF NOT EXISTS template_executions (
594
+ id TEXT PRIMARY KEY,
595
+ template_id TEXT NOT NULL,
596
+ status TEXT NOT NULL DEFAULT 'running',
597
+ step_statuses TEXT NOT NULL DEFAULT '{}',
598
+ started_at INTEGER NOT NULL,
599
+ completed_at INTEGER,
600
+ error TEXT,
601
+ FOREIGN KEY (template_id) REFERENCES task_templates(id)
602
+ )
603
+ `),e.exec("UPDATE server_state SET schema_version = 25 WHERE id = 1")),_<26){let s=`
604
+ CREATE TABLE IF NOT EXISTS template_execution_artifacts (
605
+ id TEXT PRIMARY KEY,
606
+ execution_id TEXT NOT NULL,
607
+ step_id TEXT NOT NULL,
608
+ key TEXT NOT NULL,
609
+ kind TEXT NOT NULL CHECK(kind IN ('json', 'file')),
610
+ value_json TEXT,
611
+ blob_path TEXT,
612
+ mime TEXT,
613
+ size_bytes INTEGER NOT NULL,
614
+ created_at INTEGER NOT NULL,
615
+ UNIQUE(execution_id, step_id, key),
616
+ FOREIGN KEY (execution_id) REFERENCES template_executions(id) ON DELETE CASCADE
617
+ );
618
+ CREATE INDEX IF NOT EXISTS idx_template_execution_artifacts_execution
619
+ ON template_execution_artifacts (execution_id);
620
+ CREATE INDEX IF NOT EXISTS idx_template_execution_artifacts_step
621
+ ON template_execution_artifacts (execution_id, step_id);
622
+ `,t=`
623
+ CREATE TABLE IF NOT EXISTS artifact_access_log (
624
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
625
+ timestamp INTEGER NOT NULL,
626
+ task_id TEXT,
627
+ role_id TEXT,
628
+ execution_id TEXT NOT NULL,
629
+ step_id TEXT,
630
+ tool TEXT NOT NULL,
631
+ artifact_key TEXT,
632
+ artifact_id TEXT,
633
+ size_bytes INTEGER,
634
+ outcome TEXT NOT NULL CHECK(outcome IN ('success', 'denied', 'error')),
635
+ error_reason TEXT
636
+ );
637
+ CREATE INDEX IF NOT EXISTS idx_artifact_access_log_execution
638
+ ON artifact_access_log (execution_id, timestamp);
639
+ CREATE INDEX IF NOT EXISTS idx_artifact_access_log_role
640
+ ON artifact_access_log (role_id, timestamp);
641
+ `;e.exec(s),e.exec(t),e.prepare("PRAGMA table_info(tasks)").all().some(i=>i.name==="step_id")||e.prepare("ALTER TABLE tasks ADD COLUMN step_id TEXT").run(),e.exec("UPDATE server_state SET schema_version = 26 WHERE id = 1")}e.prepare("PRAGMA table_info(roles)").all().some(r=>r.name==="os_capabilities")||e.prepare("ALTER TABLE roles ADD COLUMN os_capabilities TEXT DEFAULT NULL").run(),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<27&&e.prepare("UPDATE server_state SET schema_version = 27 WHERE id = 1").run();{let s=e.prepare("PRAGMA table_info(manager_decisions)").all();s.some(r=>r.name==="requirements_json")||e.prepare("ALTER TABLE manager_decisions ADD COLUMN requirements_json TEXT").run(),s.some(r=>r.name==="fit_score")||e.prepare("ALTER TABLE manager_decisions ADD COLUMN fit_score REAL").run(),s.some(r=>r.name==="candidates_json")||e.prepare("ALTER TABLE manager_decisions ADD COLUMN candidates_json TEXT").run(),s.some(r=>r.name==="tie_break_reason")||e.prepare("ALTER TABLE manager_decisions ADD COLUMN tie_break_reason TEXT").run(),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<28&&e.prepare("UPDATE server_state SET schema_version = 28 WHERE id = 1").run()}{let s=[[/\brm -rf\b/,["rm -rf *"]],[/^git push/,["git push*"]],[/^git reset/,["git reset*"]],[/\bcurl.*POST\b/i,["curl * -X POST*","curl * --request POST*"]]],t=e.prepare("SELECT key, value FROM config WHERE key = 'defaults.approvalRequired'").all();for(let r of t)try{let i=JSON.parse(r.value),E=[];for(let n of i){let c=!1;for(let[p,o]of s)if(p.test(n)){E.push(...o),c=!0,S.info({from:n,to:o},"Config: migrated approvalRequired pattern from regex to glob");break}c||(/[.+?^${}()|[\]\\]/.test(n)&&S.warn({pattern:n},"Config: approvalRequired pattern contains regex metacharacters that won't work with glob matching; update to glob syntax (use * for wildcards)"),E.push(n))}let T=[...new Set(E)];e.prepare("UPDATE config SET value = ?, updated_at = ? WHERE key = ?").run(JSON.stringify(T),Date.now(),r.key)}catch{}}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<31){let t=e.prepare("SELECT count(*) AS n FROM task_templates WHERE trigger_type IN ('event', 'task_complete')").get();t.n>0&&S.info({legacyCount:t.n},"normalizing legacy template trigger types"),e.prepare(`
642
+ UPDATE task_templates
643
+ SET trigger_type='template_complete',
644
+ trigger_event=REPLACE(trigger_event, ?, 'template_complete:')
645
+ WHERE trigger_type='event' AND trigger_event LIKE ?
646
+ `).run(C,`${C}%`),e.prepare("UPDATE task_templates SET trigger_type='template_complete' WHERE trigger_type='event'").run(),e.prepare("UPDATE task_templates SET trigger_type='manual' WHERE trigger_type='task_complete'").run();let r=e.prepare("SELECT count(*) AS n FROM task_templates WHERE trigger_type IN ('event', 'task_complete')").get();r.n>0&&S.warn({orphan:r.n},"migration left orphan legacy trigger_type rows; manual inspection required"),e.prepare("UPDATE server_state SET schema_version = 31 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<32&&(e.exec(`
647
+ CREATE TABLE IF NOT EXISTS event_defs (
648
+ id TEXT PRIMARY KEY, name TEXT NOT NULL, source_type TEXT NOT NULL,
649
+ source_config TEXT NOT NULL, enabled INTEGER NOT NULL DEFAULT 1,
650
+ description TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL
651
+ );
652
+ CREATE INDEX IF NOT EXISTS idx_event_defs_source_type ON event_defs(source_type, enabled);
653
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_event_defs_name ON event_defs(name);
654
+
655
+ CREATE TABLE IF NOT EXISTS events (
656
+ id TEXT PRIMARY KEY, event_def_id TEXT,
657
+ occurred_at TEXT NOT NULL, ingested_at TEXT NOT NULL, user_day TEXT,
658
+ source TEXT NOT NULL, type TEXT NOT NULL, payload TEXT NOT NULL,
659
+ confidence REAL NOT NULL DEFAULT 1.0, dedup_key TEXT NOT NULL,
660
+ related_entities TEXT, trust_level TEXT NOT NULL DEFAULT 'trusted'
661
+ );
662
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_events_dedup ON events(source, dedup_key);
663
+ CREATE INDEX IF NOT EXISTS idx_events_type ON events(type);
664
+ CREATE INDEX IF NOT EXISTS idx_events_def_id ON events(event_def_id, occurred_at);
665
+ `),e.prepare("UPDATE server_state SET schema_version = 32 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<33){let t=e.prepare(`
666
+ SELECT name FROM sqlite_master
667
+ WHERE type='table' AND name IN ('template_executions', ?)
668
+ ORDER BY CASE name WHEN 'template_executions' THEN 0 ELSE 1 END
669
+ LIMIT 1
670
+ `).get(y);if(t){let r=t.name;e.prepare(`PRAGMA table_info(${r})`).all().some(n=>n.name==="event_id")||e.prepare(`ALTER TABLE ${r} ADD COLUMN event_id TEXT`).run();let T=r==="template_executions"?"idx_template_executions_event_id":b;e.prepare(`CREATE INDEX IF NOT EXISTS ${T} ON ${r}(event_id)`).run()}e.prepare("UPDATE server_state SET schema_version = 33 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<34&&(e.prepare("PRAGMA table_info(tasks)").all().some(i=>i.name==="block_reason_json")||e.prepare("ALTER TABLE tasks ADD COLUMN block_reason_json TEXT").run(),e.prepare("UPDATE server_state SET schema_version = 34 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<35){e.prepare("PRAGMA table_info(roles)").all().some(i=>i.name==="preset_id")||e.prepare("ALTER TABLE roles ADD COLUMN preset_id TEXT").run();let r=e.prepare("PRAGMA table_info(task_templates)").all();r.some(i=>i.name==="is_preset")||e.prepare("ALTER TABLE task_templates ADD COLUMN is_preset INTEGER NOT NULL DEFAULT 0").run(),r.some(i=>i.name==="preset_id")||e.prepare("ALTER TABLE task_templates ADD COLUMN preset_id TEXT").run(),e.prepare("UPDATE server_state SET schema_version = 35 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<36){let t=[["Engineer","engineer"],["Reviewer","reviewer"],["Researcher","researcher"],["Writer","writer"],["Chat Manager","chat-manager"],["adam-automator","adam-automator"]];for(let[r,i]of t)e.prepare("UPDATE roles SET preset_id = ? WHERE name = ? AND preset_id IS NULL").run(i,r);e.prepare("UPDATE server_state SET schema_version = 36 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<37&&(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='feature_requests'").all().length===0&&(e.exec(`
671
+ CREATE TABLE feature_requests (
672
+ id TEXT PRIMARY KEY,
673
+ source_session_id TEXT,
674
+ source_message_id TEXT,
675
+ extracted_at INTEGER NOT NULL,
676
+ extracted_by_role_id TEXT,
677
+ content TEXT NOT NULL,
678
+ summary TEXT,
679
+ status TEXT NOT NULL DEFAULT 'new' CHECK(status IN ('new','reviewed','dismissed','converted')),
680
+ tags TEXT,
681
+ evidence_quote TEXT,
682
+ created_at INTEGER NOT NULL,
683
+ updated_at INTEGER NOT NULL
684
+ )
685
+ `),e.exec("CREATE INDEX IF NOT EXISTS idx_feature_requests_status ON feature_requests(status)"),e.exec("CREATE INDEX IF NOT EXISTS idx_feature_requests_extracted_at ON feature_requests(extracted_at DESC)")),e.prepare("UPDATE server_state SET schema_version = 37 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<38&&(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='mistake_patterns'").all().length===0&&(e.exec(`
686
+ CREATE TABLE mistake_patterns (
687
+ id TEXT PRIMARY KEY,
688
+ dimension_type TEXT NOT NULL,
689
+ dimension_value TEXT NOT NULL,
690
+ count INTEGER NOT NULL DEFAULT 1,
691
+ role_ids TEXT NOT NULL DEFAULT '[]',
692
+ sample_evidence_ids TEXT NOT NULL DEFAULT '[]',
693
+ status TEXT NOT NULL DEFAULT 'new' CHECK(status IN ('new','acknowledged','dismissed')),
694
+ first_seen INTEGER NOT NULL,
695
+ last_seen INTEGER NOT NULL,
696
+ created_at INTEGER NOT NULL,
697
+ updated_at INTEGER NOT NULL
698
+ )
699
+ `),e.exec("CREATE INDEX IF NOT EXISTS idx_mistake_patterns_status ON mistake_patterns(status)"),e.exec("CREATE INDEX IF NOT EXISTS idx_mistake_patterns_last_seen ON mistake_patterns(last_seen)"),e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_mistake_patterns_dim ON mistake_patterns(dimension_type, dimension_value)")),e.prepare("UPDATE server_state SET schema_version = 38 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<39){let t=e.prepare("SELECT source_task_id, COUNT(*) as cnt FROM memories WHERE source_task_id IS NOT NULL AND type = 'thought' GROUP BY source_task_id HAVING cnt > 1").all();if(t.length>0){console.info(`[db migration v39] dedupe ${t.length} (source_task_id, type='thought') groups before adding unique index`);for(let r of t){let i=e.prepare("SELECT id, length(content) as len FROM memories WHERE source_task_id = ? AND type = 'thought' ORDER BY len DESC, created_at ASC").all(r.source_task_id),E=i[0].id,T=i.slice(1).map(c=>c.id),n=T.map(()=>"?").join(",");e.prepare(`DELETE FROM memories WHERE id IN (${n})`).run(...T),console.info(`[db migration v39] group source_task_id=${r.source_task_id}: kept ${E} (len ${i[0].len}), deleted ${T.length}`)}}e.prepare("CREATE UNIQUE INDEX IF NOT EXISTS idx_memories_thought_per_task ON memories(source_task_id) WHERE source_task_id IS NOT NULL AND type = 'thought'").run(),e.prepare("UPDATE server_state SET schema_version = 39 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<40){let t=["tasks","step_logs","delivery_log","evolution_audit","chat_messages"];for(let r of t)e.prepare(`PRAGMA table_info(${r})`).all().some(E=>E.name==="trace_id")||(e.prepare(`ALTER TABLE ${r} ADD COLUMN trace_id TEXT`).run(),e.prepare(`CREATE INDEX IF NOT EXISTS idx_${r}_trace_id ON ${r}(trace_id) WHERE trace_id IS NOT NULL`).run(),console.info(`[db migration v40] added trace_id to ${r}`));e.prepare("UPDATE server_state SET schema_version = 40 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<41&&(e.prepare(`
700
+ UPDATE task_templates
701
+ SET trigger_type = 'template_complete'
702
+ WHERE trigger_type = ?
703
+ `).run(ee),e.prepare(`
704
+ UPDATE task_templates
705
+ SET trigger_event = REPLACE(trigger_event, ?, 'template_complete:')
706
+ WHERE trigger_event LIKE ?
707
+ `).run(C,`${C}%`),e.prepare("UPDATE server_state SET schema_version = 41 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<42){let t=e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(y),r=e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='template_executions'").get();t&&!r&&e.prepare(`ALTER TABLE ${y} RENAME TO template_executions`).run(),e.exec(`
708
+ CREATE TABLE IF NOT EXISTS template_executions (
709
+ id TEXT PRIMARY KEY,
710
+ template_id TEXT NOT NULL,
711
+ status TEXT NOT NULL DEFAULT 'running',
712
+ step_statuses TEXT NOT NULL DEFAULT '{}',
713
+ started_at INTEGER NOT NULL,
714
+ completed_at INTEGER,
715
+ error TEXT,
716
+ event_id TEXT,
717
+ FOREIGN KEY (template_id) REFERENCES task_templates(id)
718
+ )
719
+ `),e.prepare("PRAGMA table_info(template_executions)").all().some(E=>E.name==="event_id")||e.prepare("ALTER TABLE template_executions ADD COLUMN event_id TEXT").run(),e.prepare(`DROP INDEX IF EXISTS ${b}`).run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_template_executions_event_id ON template_executions(event_id)").run(),e.prepare("UPDATE server_state SET schema_version = 42 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<43){let t=e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").get(Z),r=e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='template_execution_artifacts'").get();t&&!r&&e.prepare(`ALTER TABLE ${Z} RENAME TO template_execution_artifacts`).run(),e.exec(`
720
+ CREATE TABLE IF NOT EXISTS template_execution_artifacts (
721
+ id TEXT PRIMARY KEY,
722
+ execution_id TEXT NOT NULL,
723
+ step_id TEXT NOT NULL,
724
+ key TEXT NOT NULL,
725
+ kind TEXT NOT NULL CHECK(kind IN ('json', 'file')),
726
+ value_json TEXT,
727
+ blob_path TEXT,
728
+ mime TEXT,
729
+ size_bytes INTEGER NOT NULL,
730
+ created_at INTEGER NOT NULL,
731
+ UNIQUE(execution_id, step_id, key),
732
+ FOREIGN KEY (execution_id) REFERENCES template_executions(id) ON DELETE CASCADE
733
+ )
734
+ `),e.prepare(`DROP INDEX IF EXISTS ${Ne}`).run(),e.prepare(`DROP INDEX IF EXISTS ${de}`).run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_template_execution_artifacts_execution ON template_execution_artifacts(execution_id)").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_template_execution_artifacts_step ON template_execution_artifacts(execution_id, step_id)").run(),z(e),e.prepare("UPDATE server_state SET schema_version = 43 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<44&&(e.prepare("PRAGMA table_info(tasks)").all().some(r=>r.name==="error_category")||e.prepare("ALTER TABLE tasks ADD COLUMN error_category TEXT").run(),e.prepare("UPDATE server_state SET schema_version = 44 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<45&&(e.prepare("PRAGMA table_info(tasks)").all().some(r=>r.name==="retry_count")||e.prepare("ALTER TABLE tasks ADD COLUMN retry_count INTEGER NOT NULL DEFAULT 0").run(),e.exec(`
735
+ CREATE TABLE IF NOT EXISTS delayed_retries (
736
+ id TEXT PRIMARY KEY,
737
+ task_id TEXT NOT NULL,
738
+ retry_at INTEGER NOT NULL,
739
+ created_at INTEGER NOT NULL
740
+ )
741
+ `),e.exec("CREATE INDEX IF NOT EXISTS idx_delayed_retries_retry_at ON delayed_retries(retry_at)"),e.exec("CREATE INDEX IF NOT EXISTS idx_delayed_retries_task_id ON delayed_retries(task_id)"),e.prepare("UPDATE server_state SET schema_version = 45 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<46&&(e.prepare("PRAGMA table_info(role_scores)").all().some(r=>r.name==="task_type")||e.prepare("ALTER TABLE role_scores ADD COLUMN task_type TEXT").run(),e.prepare("UPDATE server_state SET schema_version = 46 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<47&&(e.prepare("PRAGMA table_info(template_execution_artifacts)").all().some(i=>i.name==="original_filename")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN original_filename TEXT").run(),e.prepare("UPDATE server_state SET schema_version = 47 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<48){let t=e.prepare("PRAGMA table_info(chat_messages)").all(),r=i=>t.some(E=>E.name===i);r("kind")||e.prepare("ALTER TABLE chat_messages ADD COLUMN kind TEXT").run(),r("parent_message_id")||e.prepare("ALTER TABLE chat_messages ADD COLUMN parent_message_id TEXT").run(),r("thread_root")||e.prepare("ALTER TABLE chat_messages ADD COLUMN thread_root TEXT").run(),r("prompt_id")||e.prepare("ALTER TABLE chat_messages ADD COLUMN prompt_id TEXT").run(),r("approval_shape")||e.prepare("ALTER TABLE chat_messages ADD COLUMN approval_shape TEXT").run(),r("role_id")||e.prepare("ALTER TABLE chat_messages ADD COLUMN role_id TEXT").run(),r("attachments")||e.prepare("ALTER TABLE chat_messages ADD COLUMN attachments TEXT").run(),r("mirrored_to_targets")||e.prepare("ALTER TABLE chat_messages ADD COLUMN mirrored_to_targets TEXT").run(),r("platform_message_id")||e.prepare("ALTER TABLE chat_messages ADD COLUMN platform_message_id TEXT").run(),r("seq")||e.prepare("ALTER TABLE chat_messages ADD COLUMN seq INTEGER").run(),e.prepare("UPDATE chat_messages SET kind = 'user_message' WHERE kind IS NULL AND role = 'user'").run(),e.prepare("UPDATE chat_messages SET kind = 'assistant_text' WHERE kind IS NULL AND role = 'assistant'").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_chat_messages_thread_root ON chat_messages(thread_root, created_at) WHERE thread_root IS NOT NULL").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_chat_messages_prompt_id ON chat_messages(prompt_id) WHERE prompt_id IS NOT NULL").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_chat_messages_platform_msg ON chat_messages(platform_message_id) WHERE platform_message_id IS NOT NULL").run(),e.prepare("UPDATE server_state SET schema_version = 48 WHERE id = 1").run(),console.info("[db migration v48] chat_messages: added 10 envelope columns + 3 indexes; back-filled kind")}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<49&&(e.exec(`
742
+ CREATE TABLE IF NOT EXISTS pending_prompts (
743
+ id TEXT PRIMARY KEY,
744
+ session_id TEXT NOT NULL,
745
+ task_id TEXT,
746
+ message_id TEXT NOT NULL,
747
+ shape TEXT NOT NULL CHECK(shape IN ('yes_no','choose_one','free_input')),
748
+ expected_shape_json TEXT,
749
+ asked_at INTEGER NOT NULL,
750
+ expires_at INTEGER NOT NULL,
751
+ resolved_at INTEGER,
752
+ resolved_by_message_id TEXT,
753
+ resolved_via TEXT,
754
+ resolved_value TEXT,
755
+ expired_reason TEXT
756
+ )
757
+ `),e.exec("CREATE INDEX IF NOT EXISTS idx_pending_prompts_session_open ON pending_prompts(session_id, expires_at) WHERE resolved_at IS NULL"),e.exec("CREATE INDEX IF NOT EXISTS idx_pending_prompts_task ON pending_prompts(task_id) WHERE task_id IS NOT NULL"),e.prepare("UPDATE server_state SET schema_version = 49 WHERE id = 1").run(),console.info("[db migration v49] pending_prompts: created table + 2 indexes")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<50){let t=e.prepare("PRAGMA table_info(template_execution_artifacts)").all(),r=i=>t.some(E=>E.name===i);r("locator")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN locator TEXT").run(),r("content_hash")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN content_hash TEXT").run(),r("retention_hint")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN retention_hint TEXT").run(),r("encryption_class")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN encryption_class TEXT").run(),r("purpose")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN purpose TEXT").run(),r("replaces")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN replaces TEXT").run(),r("produced_by_role")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN produced_by_role TEXT").run(),r("access")||e.prepare("ALTER TABLE template_execution_artifacts ADD COLUMN access TEXT").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_artifacts_content_hash ON template_execution_artifacts(content_hash) WHERE content_hash IS NOT NULL").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_artifacts_replaces ON template_execution_artifacts(replaces) WHERE replaces IS NOT NULL").run(),e.prepare("UPDATE server_state SET schema_version = 50 WHERE id = 1").run(),console.info("[db migration v50] template_execution_artifacts: added 8 storage-hook columns + 2 indexes")}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<51){let t=e.prepare("PRAGMA table_info(chat_messages)").all();t.some(r=>r.name==="source_channel_id")||e.exec("ALTER TABLE chat_messages ADD COLUMN source_channel_id TEXT"),t.some(r=>r.name==="source_chat_id")||e.exec("ALTER TABLE chat_messages ADD COLUMN source_chat_id TEXT"),e.prepare("UPDATE server_state SET schema_version = 51 WHERE id = 1").run(),console.info("[db migration v51] chat_messages: added source_channel_id + source_chat_id columns")}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<52&&(e.exec(`
758
+ CREATE TABLE IF NOT EXISTS audit_violations (
759
+ id TEXT PRIMARY KEY,
760
+ step_task_id TEXT NOT NULL,
761
+ execution_id TEXT,
762
+ role_id TEXT NOT NULL,
763
+ contract_field TEXT NOT NULL,
764
+ layer TEXT NOT NULL CHECK(layer IN ('A', 'B')),
765
+ severity TEXT NOT NULL CHECK(severity IN ('error', 'warning')),
766
+ message TEXT NOT NULL,
767
+ metadata_json TEXT,
768
+ created_at INTEGER NOT NULL
769
+ );
770
+ CREATE INDEX IF NOT EXISTS idx_audit_violations_role ON audit_violations(role_id, created_at DESC);
771
+ CREATE INDEX IF NOT EXISTS idx_audit_violations_task ON audit_violations(step_task_id);
772
+ CREATE INDEX IF NOT EXISTS idx_audit_violations_execution ON audit_violations(execution_id, created_at DESC);
773
+ `),e.prepare("UPDATE server_state SET schema_version = 52 WHERE id = 1").run(),console.info("[db migration v52] audit_violations: added contract-violation audit table + 3 indexes")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<53){let t=e.prepare("SELECT id, learned_rules FROM roles").all(),r=e.prepare("UPDATE roles SET learned_rules = ? WHERE id = ?"),i=0;for(let E of t){if(!E.learned_rules)continue;let T;try{T=JSON.parse(E.learned_rules)}catch{continue}if(Array.isArray(T)){let n={stylePreferences:T.filter(c=>typeof c=="string"),avoidedActions:[],pinnedParameters:[]};r.run(JSON.stringify(n),E.id),i+=1}}e.prepare("UPDATE server_state SET schema_version = 53 WHERE id = 1").run(),console.info(`[db migration v53] learned_rules: wrapped ${i} legacy string[] rows into structured form`)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<54){e.exec(`
774
+ CREATE TABLE IF NOT EXISTS user_visible_events (
775
+ id TEXT PRIMARY KEY,
776
+ event_key TEXT NOT NULL UNIQUE,
777
+ source_type TEXT NOT NULL CHECK(source_type IN ('task','template_execution','unknown')),
778
+ source_id TEXT NOT NULL,
779
+ task_id TEXT,
780
+ template_id TEXT,
781
+ template_name TEXT,
782
+ message_type TEXT NOT NULL,
783
+ viewer_key TEXT NOT NULL,
784
+ title TEXT,
785
+ content_preview TEXT NOT NULL,
786
+ attachments_json TEXT NOT NULL DEFAULT '[]',
787
+ targets_json TEXT NOT NULL DEFAULT '[]',
788
+ first_delivered_at INTEGER NOT NULL,
789
+ last_delivered_at INTEGER NOT NULL,
790
+ created_at INTEGER NOT NULL,
791
+ trace_id TEXT
792
+ );
793
+ CREATE INDEX IF NOT EXISTS idx_user_visible_events_viewer_time
794
+ ON user_visible_events(viewer_key, last_delivered_at DESC);
795
+ CREATE INDEX IF NOT EXISTS idx_user_visible_events_viewer_source
796
+ ON user_visible_events(viewer_key, source_id);
797
+ CREATE INDEX IF NOT EXISTS idx_user_visible_events_trace_id
798
+ ON user_visible_events(trace_id) WHERE trace_id IS NOT NULL;
799
+ `);let t="local-owner",r=e.prepare("SELECT value FROM config WHERE key = 'identity.ownerViewerKey'").get();if(r)try{let T=JSON.parse(r.value);typeof T=="string"&&T.trim().length>0&&(t=T)}catch{r.value.trim().length>0&&(t=r.value)}let i=e.prepare("SELECT id, config FROM channels").all(),E=e.prepare("UPDATE channels SET config = ?, updated_at = ? WHERE id = ?");for(let T of i)try{let n=JSON.parse(T.config);(typeof n.viewerKey!="string"||n.viewerKey.trim().length===0)&&(n.viewerKey=t,E.run(JSON.stringify(n),Date.now(),T.id))}catch{}e.prepare("UPDATE server_state SET schema_version = 54 WHERE id = 1").run(),console.info("[db migration v54] user_visible_events: created delivery ledger and backfilled channel viewerKey")}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<55&&(e.exec(`
800
+ CREATE TABLE IF NOT EXISTS audit_diagnostics (
801
+ id TEXT PRIMARY KEY,
802
+ source TEXT NOT NULL,
803
+ severity TEXT NOT NULL CHECK(severity IN ('info','warning','error')),
804
+ trace_id TEXT,
805
+ source_id TEXT,
806
+ message TEXT NOT NULL,
807
+ created_at INTEGER NOT NULL
808
+ );
809
+ CREATE INDEX IF NOT EXISTS idx_audit_diagnostics_source_created
810
+ ON audit_diagnostics(source, created_at DESC);
811
+ CREATE INDEX IF NOT EXISTS idx_audit_diagnostics_trace_id
812
+ ON audit_diagnostics(trace_id) WHERE trace_id IS NOT NULL;
813
+ `),e.prepare("UPDATE server_state SET schema_version = 55 WHERE id = 1").run(),console.info("[db migration v55] audit_diagnostics: added diagnostic table + indexes")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<56&&(e.exec(`
814
+ CREATE TABLE IF NOT EXISTS runtime_effects (
815
+ id TEXT PRIMARY KEY,
816
+ trace_id TEXT,
817
+ effect_type TEXT NOT NULL,
818
+ effect_category TEXT NOT NULL,
819
+ entity_type TEXT NOT NULL,
820
+ entity_id TEXT,
821
+ field_path TEXT,
822
+ before_json TEXT,
823
+ after_json TEXT,
824
+ created_at INTEGER NOT NULL,
825
+ actor_role_id TEXT,
826
+ tool_name TEXT
827
+ );
828
+ CREATE INDEX IF NOT EXISTS idx_runtime_effects_trace
829
+ ON runtime_effects(trace_id, created_at) WHERE trace_id IS NOT NULL;
830
+ CREATE INDEX IF NOT EXISTS idx_runtime_effects_category
831
+ ON runtime_effects(effect_category, created_at);
832
+
833
+ CREATE TABLE IF NOT EXISTS assistant_commitment_audits (
834
+ id TEXT PRIMARY KEY,
835
+ trace_id TEXT,
836
+ session_id TEXT,
837
+ message_id TEXT,
838
+ status TEXT NOT NULL CHECK(status IN ('passed','blocked')),
839
+ claim_type TEXT NOT NULL,
840
+ claim_text TEXT NOT NULL,
841
+ evidence_effect_ids TEXT NOT NULL DEFAULT '[]',
842
+ created_at INTEGER NOT NULL,
843
+ reason TEXT
844
+ );
845
+ CREATE INDEX IF NOT EXISTS idx_assistant_commitment_audits_trace
846
+ ON assistant_commitment_audits(trace_id, created_at) WHERE trace_id IS NOT NULL;
847
+ CREATE INDEX IF NOT EXISTS idx_assistant_commitment_audits_session
848
+ ON assistant_commitment_audits(session_id, created_at) WHERE session_id IS NOT NULL;
849
+ `),e.prepare("UPDATE server_state SET schema_version = 56 WHERE id = 1").run(),console.info("[db migration v56] runtime_effects + assistant_commitment_audits: added audit evidence tables")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<57&&(e.exec(`
850
+ CREATE TABLE IF NOT EXISTS assistant_delivery_commitments (
851
+ id TEXT PRIMARY KEY,
852
+ trace_id TEXT,
853
+ session_id TEXT NOT NULL,
854
+ source_message_id TEXT,
855
+ task_id TEXT,
856
+ commitment_type TEXT NOT NULL CHECK(commitment_type IN ('future_delivery')),
857
+ status TEXT NOT NULL CHECK(status IN ('pending','fulfilled','failed','blocked','cancelled')),
858
+ target_json TEXT NOT NULL,
859
+ artifact_expectation_json TEXT,
860
+ evidence_json TEXT,
861
+ failure_reason TEXT,
862
+ created_at INTEGER NOT NULL,
863
+ updated_at INTEGER NOT NULL,
864
+ fulfilled_at INTEGER
865
+ );
866
+ CREATE INDEX IF NOT EXISTS idx_assistant_delivery_commitments_task_status
867
+ ON assistant_delivery_commitments(task_id, status) WHERE task_id IS NOT NULL;
868
+ CREATE INDEX IF NOT EXISTS idx_assistant_delivery_commitments_trace
869
+ ON assistant_delivery_commitments(trace_id, created_at) WHERE trace_id IS NOT NULL;
870
+ CREATE INDEX IF NOT EXISTS idx_assistant_delivery_commitments_session
871
+ ON assistant_delivery_commitments(session_id, created_at);
872
+ CREATE INDEX IF NOT EXISTS idx_assistant_delivery_commitments_source_message
873
+ ON assistant_delivery_commitments(source_message_id) WHERE source_message_id IS NOT NULL;
874
+ `),e.prepare("UPDATE server_state SET schema_version = 57 WHERE id = 1").run(),console.info("[db migration v57] assistant_delivery_commitments: added ChatManager delivery commitment table")),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<58){e.prepare("PRAGMA table_info(channels)").all().some(n=>n.name==="viewer_key")||e.exec("ALTER TABLE channels ADD COLUMN viewer_key TEXT");let r="local-owner",i=e.prepare("SELECT value FROM config WHERE key = 'identity.ownerViewerKey'").get();if(i)try{let n=JSON.parse(i.value);typeof n=="string"&&n.trim().length>0&&(r=n)}catch{i.value.trim().length>0&&(r=i.value)}let E=e.prepare("SELECT id, config FROM channels").all(),T=e.prepare("UPDATE channels SET config = ?, viewer_key = ?, updated_at = ? WHERE id = ?");for(let n of E)try{let c=JSON.parse(n.config),p=typeof c.viewerKey=="string"&&c.viewerKey.trim().length>0?c.viewerKey:r;delete c.viewerKey,T.run(JSON.stringify(c),p,Date.now(),n.id)}catch{e.prepare("UPDATE channels SET viewer_key = ?, updated_at = ? WHERE id = ?").run(r,Date.now(),n.id)}e.prepare("UPDATE server_state SET schema_version = 58 WHERE id = 1").run(),console.info("[db migration v58] channels: extracted viewerKey from config into viewer_key column")}{let s=["^Task assigned to role [A-Z]$","^List files in the current directory\\.?$","^ping role payload$"];try{let r=e.prepare("SELECT id FROM delivery_rules WHERE created_by = 'system' AND target LIKE '%_default_block_%'").all();for(let i of r)e.prepare("DELETE FROM delivery_rules WHERE id = ?").run(i.id),console.info(`[db v59 repair] removed legacy bad rule ${i.id}`);e.prepare("DELETE FROM config WHERE key = 'delivery.defaultExcludePromptPatterns' AND value LIKE '%E2E_TEST_MODE%'").run()}catch(r){console.warn("[db v59 repair] cleanup of legacy seed failed (non-fatal):",r)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<59){let r=e.prepare("SELECT id, match_criteria FROM delivery_rules WHERE event_type = 'task_complete'").all(),i=0;for(let E of r)try{let T=E.match_criteria?JSON.parse(E.match_criteria):{};if(!(!T.templateId&&!T.roleId&&!T.promptPattern&&!T.taskStatus))continue;let c=Array.isArray(T.excludePromptPatterns)?T.excludePromptPatterns:[],p=[...new Set([...c,...s])],o={...T,excludePromptPatterns:p};e.prepare("UPDATE delivery_rules SET match_criteria = ? WHERE id = ?").run(JSON.stringify(o),E.id),i++}catch{}e.prepare("UPDATE server_state SET schema_version = 59 WHERE id = 1").run(),console.info(`[db migration v59] delivery: seeded excludePromptPatterns on ${i} catch-all rule(s)`)}try{let r=e.prepare("SELECT id, match_criteria FROM delivery_rules WHERE event_type = 'task_complete'").all();for(let i of r)try{let E=i.match_criteria?JSON.parse(i.match_criteria):{};if(!(!E.templateId&&!E.roleId&&!E.promptPattern&&!E.taskStatus))continue;let n=Array.isArray(E.excludePromptPatterns)?E.excludePromptPatterns:[],c=s.filter(f=>!n.includes(f));if(c.length===0)continue;let p=[...n,...c],o={...E,excludePromptPatterns:p};e.prepare("UPDATE delivery_rules SET match_criteria = ? WHERE id = ?").run(JSON.stringify(o),i.id),console.info(`[db v59 reconcile] added ${c.length} default exclude pattern(s) to rule ${i.id}`)}catch{}}catch(r){console.warn("[db v59 reconcile] post-migration repair failed (non-fatal):",r)}}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<60){if(e.prepare("PRAGMA table_info(delivery_log)").all().some(r=>r.name==="execution_id")||(e.prepare("ALTER TABLE delivery_log ADD COLUMN execution_id TEXT").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_delivery_log_execution_id ON delivery_log (execution_id)").run()),!e.prepare("SELECT id FROM delivery_rules WHERE event_type = ?").get("template_execution_failed")){let r=e.prepare("SELECT id, target, match_criteria FROM delivery_rules WHERE event_type = 'task_complete' AND enabled = 1").all(),i=null;for(let c of r)try{let p=c.match_criteria?JSON.parse(c.match_criteria):{};if(!p.templateId&&!p.roleId&&!p.promptPattern&&!p.taskStatus){let f=JSON.parse(c.target);if(f?.type==="channel"&&typeof f.channelId=="string"){i=f.channelId;break}}}catch{}let E=`tpl-fail-${Date.now()}`,T=i?{type:"channel",channelId:i}:{type:"channel",channelId:"REPLACE_ME"},n=i?1:0;e.prepare("INSERT INTO delivery_rules (id, event_type, match_criteria, target, max_per_minute, skip_origin_channel, enabled, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run(E,"template_execution_failed","{}",JSON.stringify(T),3,0,n,Date.now()),i?console.info(`[db migration v60] seeded template_execution_failed delivery rule targeting channel ${i}`):console.warn("[db migration v60] no primary channel found for template_execution_failed rule; created as disabled (channelId=REPLACE_ME)")}e.prepare("UPDATE server_state SET schema_version = 60 WHERE id = 1").run()}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<61&&(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='effect_receipts'").get()||(e.prepare(`
875
+ CREATE TABLE effect_receipts (
876
+ id TEXT PRIMARY KEY,
877
+ trace_id TEXT NOT NULL,
878
+ task_id TEXT,
879
+ session_id TEXT,
880
+ effect_category TEXT NOT NULL CHECK(effect_category IN ('outbound_message','entity_mutation')),
881
+ verb TEXT NOT NULL,
882
+ entity_type TEXT NOT NULL,
883
+ entity_id TEXT,
884
+ entity_ids_json TEXT,
885
+ target_json TEXT,
886
+ payload_json TEXT,
887
+ field_changes_json TEXT,
888
+ scope_json TEXT,
889
+ actor_json TEXT NOT NULL,
890
+ created_at INTEGER NOT NULL,
891
+ CHECK ((entity_id IS NULL) OR (entity_ids_json IS NULL))
892
+ )
893
+ `).run(),e.prepare("CREATE INDEX idx_effect_receipts_trace ON effect_receipts(trace_id, created_at)").run(),e.prepare("CREATE INDEX idx_effect_receipts_task ON effect_receipts(task_id, created_at) WHERE task_id IS NOT NULL").run(),e.prepare("CREATE INDEX idx_effect_receipts_entity ON effect_receipts(entity_type, entity_id) WHERE entity_id IS NOT NULL").run(),e.prepare("CREATE INDEX idx_effect_receipts_category_verb ON effect_receipts(effect_category, verb)").run()),e.prepare("UPDATE server_state SET schema_version = 61 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<62&&(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='effect_receipts'").get()&&(e.prepare("PRAGMA table_info(effect_receipts)").all().some(E=>E.name==="outcome")||(e.prepare("ALTER TABLE effect_receipts ADD COLUMN outcome TEXT NOT NULL DEFAULT 'success' CHECK(outcome IN ('success','failure'))").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_effect_receipts_outcome ON effect_receipts (effect_category, outcome, trace_id)").run())),e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='template_executions'").get()&&(e.prepare("PRAGMA table_info(template_executions)").all().some(E=>E.name==="step_results_json")||e.prepare("ALTER TABLE template_executions ADD COLUMN step_results_json TEXT").run()),e.prepare("UPDATE server_state SET schema_version = 62 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<63&&(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='assistant_claims'").get()||(e.prepare(`
894
+ CREATE TABLE assistant_claims (
895
+ id TEXT PRIMARY KEY,
896
+ trace_id TEXT NOT NULL,
897
+ session_id TEXT,
898
+ task_id TEXT,
899
+ source_message_id TEXT,
900
+ claims_json TEXT NOT NULL,
901
+ declared_at INTEGER NOT NULL
902
+ )
903
+ `).run(),e.prepare("CREATE INDEX idx_assistant_claims_trace ON assistant_claims(trace_id, declared_at)").run(),e.prepare("CREATE INDEX idx_assistant_claims_session ON assistant_claims(session_id, declared_at) WHERE session_id IS NOT NULL").run()),e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='assistant_claim_audits'").get()||(e.prepare(`
904
+ CREATE TABLE assistant_claim_audits (
905
+ id TEXT PRIMARY KEY,
906
+ trace_id TEXT NOT NULL,
907
+ session_id TEXT,
908
+ message_id TEXT,
909
+ status TEXT NOT NULL CHECK(status IN ('passed','blocked')),
910
+ per_claim_json TEXT NOT NULL DEFAULT '[]',
911
+ replacement_text TEXT,
912
+ created_at INTEGER NOT NULL
913
+ )
914
+ `).run(),e.prepare("CREATE INDEX idx_assistant_claim_audits_trace ON assistant_claim_audits(trace_id, created_at)").run(),e.prepare("CREATE INDEX idx_assistant_claim_audits_session ON assistant_claim_audits(session_id, created_at) WHERE session_id IS NOT NULL").run()),e.prepare("UPDATE server_state SET schema_version = 63 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<64&&(e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='auditor_divergence_log'").get()||(e.prepare(`
915
+ CREATE TABLE auditor_divergence_log (
916
+ id TEXT PRIMARY KEY,
917
+ trace_id TEXT NOT NULL,
918
+ session_id TEXT,
919
+ message_id TEXT,
920
+ task_id TEXT,
921
+ wire_point TEXT NOT NULL CHECK(wire_point IN ('message_handler','chat_manager_envelope')),
922
+ old_verdict TEXT NOT NULL CHECK(old_verdict IN ('passed','blocked')),
923
+ new_verdict TEXT NOT NULL CHECK(new_verdict IN ('passed','blocked')),
924
+ divergence_subtype TEXT NOT NULL CHECK(divergence_subtype IN ('old_blocks_new_passes','old_passes_new_blocks')),
925
+ old_replacement_text TEXT,
926
+ new_replacement_text TEXT,
927
+ recorded_at INTEGER NOT NULL
928
+ )
929
+ `).run(),e.prepare("CREATE INDEX idx_auditor_divergence_trace ON auditor_divergence_log(trace_id, recorded_at)").run(),e.prepare("CREATE INDEX idx_auditor_divergence_subtype ON auditor_divergence_log(divergence_subtype, recorded_at)").run(),e.prepare("CREATE INDEX idx_auditor_divergence_session ON auditor_divergence_log(session_id, recorded_at) WHERE session_id IS NOT NULL").run()),e.prepare("UPDATE server_state SET schema_version = 64 WHERE id = 1").run()),(e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<65)try{e.prepare("PRAGMA table_info(assistant_claim_audits)").all().some(i=>i.name==="claim_source")||e.prepare("ALTER TABLE assistant_claim_audits ADD COLUMN claim_source TEXT NOT NULL DEFAULT 'vacuous'").run(),e.prepare("PRAGMA table_info(auditor_divergence_log)").all().some(i=>i.name==="verdict_pair")||e.prepare("ALTER TABLE auditor_divergence_log ADD COLUMN verdict_pair TEXT NOT NULL DEFAULT 'agreed_pass'").run(),e.prepare(`
930
+ UPDATE auditor_divergence_log
931
+ SET verdict_pair = divergence_subtype
932
+ WHERE verdict_pair IS NULL OR verdict_pair = 'agreed_pass'
933
+ AND divergence_subtype IN ('old_blocks_new_passes', 'old_passes_new_blocks')
934
+ `).run();let t=e.prepare("DELETE FROM effect_receipts WHERE trace_id LIKE 'trace-%' OR trace_id LIKE 'test-%'").run().changes;t>0&&console.info(`[db migration] v65: cleaned ${t} fixture row(s) from effect_receipts`),e.prepare("UPDATE server_state SET schema_version = 65 WHERE id = 1").run()}catch(t){throw t}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<66)try{let t=e.prepare("PRAGMA table_info(roles)").all();t.some(r=>r.name==="effort_tier")||e.prepare("ALTER TABLE roles ADD COLUMN effort_tier TEXT").run(),t.some(r=>r.name==="skills")||e.prepare("ALTER TABLE roles ADD COLUMN skills TEXT").run(),e.prepare("UPDATE server_state SET schema_version = 66 WHERE id = 1").run()}catch(t){throw new Error(`Schema v66 migration failed: ${t}`)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<67)try{e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='chat_tool_calls'").get()||(e.exec(`
935
+ CREATE TABLE chat_tool_calls (
936
+ id TEXT PRIMARY KEY,
937
+ trace_id TEXT NOT NULL,
938
+ session_id TEXT,
939
+ tool_name TEXT NOT NULL,
940
+ tool_input_json TEXT,
941
+ tool_output_summary TEXT,
942
+ called_at INTEGER NOT NULL
943
+ )
944
+ `),e.exec(`
945
+ CREATE INDEX idx_chat_tool_calls_trace ON chat_tool_calls(trace_id, called_at)
946
+ `),e.exec(`
947
+ CREATE INDEX idx_chat_tool_calls_session ON chat_tool_calls(session_id, called_at) WHERE session_id IS NOT NULL
948
+ `)),e.prepare("UPDATE server_state SET schema_version = 67 WHERE id = 1").run()}catch(t){throw new Error(`Schema v67 migration failed: ${t}`)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<68)try{e.prepare("PRAGMA table_info(memories)").all().some(T=>T.name==="kind")||e.exec("ALTER TABLE memories ADD COLUMN kind TEXT NOT NULL DEFAULT 'observation'"),e.prepare("PRAGMA table_info(roles)").all().some(T=>T.name==="last_reflection_at")||e.exec("ALTER TABLE roles ADD COLUMN last_reflection_at INTEGER"),e.prepare("PRAGMA table_info(server_state)").all().some(T=>T.name==="last_memory_gc_at")||e.exec("ALTER TABLE server_state ADD COLUMN last_memory_gc_at INTEGER"),e.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='beliefs'").get()||(e.exec(`
949
+ CREATE TABLE beliefs (
950
+ id TEXT PRIMARY KEY,
951
+ role_id TEXT NOT NULL,
952
+ content TEXT NOT NULL,
953
+ confidence REAL NOT NULL DEFAULT 0.5,
954
+ use_count INTEGER NOT NULL DEFAULT 0,
955
+ success_count INTEGER NOT NULL DEFAULT 0,
956
+ is_anti INTEGER NOT NULL DEFAULT 0 CHECK(is_anti IN (0, 1)),
957
+ evidence_obs_ids TEXT,
958
+ embedding BLOB,
959
+ superseded_by TEXT,
960
+ created_at INTEGER NOT NULL,
961
+ last_used_at INTEGER NOT NULL,
962
+ last_validated_at INTEGER NOT NULL
963
+ )
964
+ `),e.exec("CREATE INDEX idx_beliefs_role_id ON beliefs(role_id)"),e.exec("CREATE INDEX idx_beliefs_role_anti ON beliefs(role_id, is_anti)"),e.exec("CREATE INDEX idx_beliefs_last_used ON beliefs(last_used_at)"),e.exec(`
965
+ CREATE VIRTUAL TABLE beliefs_fts USING fts5(content, content='beliefs', content_rowid='rowid')
966
+ `),e.exec(`
967
+ CREATE TRIGGER beliefs_fts_insert AFTER INSERT ON beliefs BEGIN
968
+ INSERT INTO beliefs_fts(rowid, content) VALUES (new.rowid, new.content);
969
+ END
970
+ `),e.exec(`
971
+ CREATE TRIGGER beliefs_fts_delete AFTER DELETE ON beliefs BEGIN
972
+ INSERT INTO beliefs_fts(beliefs_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
973
+ END
974
+ `),e.exec(`
975
+ CREATE TRIGGER beliefs_fts_update AFTER UPDATE ON beliefs BEGIN
976
+ INSERT INTO beliefs_fts(beliefs_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
977
+ INSERT INTO beliefs_fts(rowid, content) VALUES (new.rowid, new.content);
978
+ END
979
+ `)),e.prepare("UPDATE server_state SET schema_version = 68 WHERE id = 1").run()}catch(t){throw new Error(`Schema v68 migration failed: ${t}`)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<69)try{e.prepare("PRAGMA table_info(tasks)").all().some(i=>i.name==="context_meta")||e.exec("ALTER TABLE tasks ADD COLUMN context_meta TEXT"),e.prepare("PRAGMA table_info(roles)").all().some(i=>i.name==="memory_budget_tokens")||e.exec("ALTER TABLE roles ADD COLUMN memory_budget_tokens INTEGER"),e.prepare("UPDATE server_state SET schema_version = 69 WHERE id = 1").run()}catch(t){throw new Error(`Schema v69 migration failed: ${t}`)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<70)try{e.prepare("PRAGMA table_info(task_templates)").all().some(r=>r.name==="retry_policy")||e.exec("ALTER TABLE task_templates ADD COLUMN retry_policy TEXT"),e.prepare("UPDATE server_state SET schema_version = 70 WHERE id = 1").run()}catch(t){throw new Error(`Schema v70 migration failed: ${t}`)}if((e.prepare("SELECT schema_version FROM server_state WHERE id = 1").get()?.schema_version??0)<71)try{e.prepare(`CREATE TABLE IF NOT EXISTS extensions (
980
+ id TEXT PRIMARY KEY,
981
+ name TEXT NOT NULL UNIQUE,
982
+ version TEXT NOT NULL,
983
+ manifest_json TEXT NOT NULL,
984
+ install_source TEXT NOT NULL DEFAULT 'upload',
985
+ package_hash TEXT NOT NULL,
986
+ default_config_json TEXT,
987
+ created_at INTEGER NOT NULL,
988
+ updated_at INTEGER NOT NULL
989
+ )`).run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_extensions_name ON extensions(name)").run(),e.prepare(`CREATE TABLE IF NOT EXISTS role_extensions (
990
+ id TEXT PRIMARY KEY,
991
+ role_id TEXT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
992
+ extension_id TEXT NOT NULL REFERENCES extensions(id) ON DELETE CASCADE,
993
+ enabled INTEGER NOT NULL DEFAULT 1,
994
+ config_override_json TEXT,
995
+ generated_server_name TEXT NOT NULL,
996
+ created_at INTEGER NOT NULL,
997
+ updated_at INTEGER NOT NULL,
998
+ UNIQUE(role_id, extension_id)
999
+ )`).run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_role_extensions_role_id ON role_extensions(role_id)").run(),e.prepare("CREATE INDEX IF NOT EXISTS idx_role_extensions_extension_id ON role_extensions(extension_id)").run(),e.prepare(`CREATE TABLE IF NOT EXISTS extension_health (
1000
+ extension_id TEXT PRIMARY KEY REFERENCES extensions(id) ON DELETE CASCADE,
1001
+ last_run_at INTEGER,
1002
+ last_status TEXT,
1003
+ last_error TEXT,
1004
+ last_role_id TEXT,
1005
+ last_task_id TEXT
1006
+ )`).run(),e.prepare("UPDATE server_state SET schema_version = 71 WHERE id = 1").run()}catch(t){throw new Error(`Schema v71 migration failed: ${t}`)}try{let s=e.prepare("SELECT id, name, steps, role_preference FROM task_templates WHERE enabled = 1").all(),t=0;for(let r of s){if(r.role_preference)continue;let i;try{i=JSON.parse(r.steps)}catch{continue}if(!Array.isArray(i))continue;let E=!1;for(let T of i){let n=typeof T.roleId=="string"&&T.roleId.length>0,c=T.autoSelectRole===!0;!n&&!c&&(T.autoSelectRole=!0,T.requirements===void 0&&(T.requirements={}),E=!0)}E&&(e.prepare("UPDATE task_templates SET steps = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(i),Date.now(),r.id),t+=1,console.info(`[db migration] template auto-repaired: id=${r.id} name=${r.name}`))}t>0&&console.info(`[db migration] auto-repaired ${t} enabled template(s) with missing role config`)}catch(s){console.error("[db migration] template auto-repair failed:",s)}}function Pe(){if(R)return R;let e=process.env.ADAM_DB_PATH||G,a=le(e);return ae(a)||ce(a,{recursive:!0}),R=new _e(e),R.pragma("journal_mode = WAL"),R.pragma("foreign_keys = ON"),R.pragma("trusted_schema = ON"),pe(R),R}function Ge(){R&&(R.close(),R=null)}var S,ee,C,y,Z,b,Ne,de,R,me=M(()=>{H();B();Q();S=g("store"),ee=["work","flow_complete"].join(""),C=`${ee}:`,y=["work","flow_executions"].join(""),Z=["work","flow_artifacts"].join(""),b=["idx","work","flow_executions_event_id"].join("_"),Ne=["idx","work","flow_artifacts_execution"].join("_"),de=["idx","work","flow_artifacts_step"].join("_"),R=null});export{oe as a,ve as b,fe as c,ge as d,Se as e,J as f,Ce as g,Ue as h,De as i,Q as j,pe as k,Pe as l,Ge as m,me as n};