@crewx/sdk 0.9.0-rc.6 → 0.9.0-rc.60

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 (126) hide show
  1. package/README.md +1 -1
  2. package/dist/activity-log/builder.d.ts +55 -6
  3. package/dist/config/canonicalize-agent-options.d.ts +17 -0
  4. package/dist/config/global-settings.d.ts +19 -0
  5. package/dist/config/migrate-grok-mode.d.ts +6 -0
  6. package/dist/config/model-compat.d.ts +16 -0
  7. package/dist/config/models.generated.d.ts +55 -0
  8. package/dist/config/models.remote.d.ts +4 -0
  9. package/dist/config/overdrive.d.ts +31 -0
  10. package/dist/config/pricing.d.ts +9 -5
  11. package/dist/config/pricing.generated.d.ts +4 -0
  12. package/dist/config/pricing.types.d.ts +4 -0
  13. package/dist/config/timeout.config.d.ts +3 -0
  14. package/dist/config/wi-boards.d.ts +19 -0
  15. package/dist/context-budget/index.d.ts +105 -0
  16. package/dist/conversation/index.d.ts +1 -1
  17. package/dist/conversation/to-template-messages.d.ts +7 -0
  18. package/dist/conversation/types.d.ts +1 -0
  19. package/dist/desktop/command-runner.d.ts +4 -0
  20. package/dist/desktop/default-adapters.d.ts +4 -0
  21. package/dist/desktop/global-install.d.ts +19 -0
  22. package/dist/desktop/index.d.ts +2 -0
  23. package/dist/desktop/index.js +3 -0
  24. package/dist/desktop/install.d.ts +5 -0
  25. package/dist/desktop/lnk.d.ts +22 -0
  26. package/dist/desktop/manifest.d.ts +21 -0
  27. package/dist/desktop/types.d.ts +67 -0
  28. package/dist/desktop/version.d.ts +1 -0
  29. package/dist/desktop/windows-paths.d.ts +21 -0
  30. package/dist/desktop/wrapper.d.ts +18 -0
  31. package/dist/esm/desktop/index.js +3 -0
  32. package/dist/esm/index.js +240 -102
  33. package/dist/esm/plugins/index.js +150 -90
  34. package/dist/esm/publish/index.js +1 -0
  35. package/dist/esm/repository/index.js +126 -66
  36. package/dist/esm/testing/index.js +1 -1
  37. package/dist/events/types.d.ts +3 -0
  38. package/dist/facade/Crewx.d.ts +28 -0
  39. package/dist/index.browser.d.ts +6 -1
  40. package/dist/index.browser.js +6 -2
  41. package/dist/index.d.ts +37 -9
  42. package/dist/index.js +240 -102
  43. package/dist/internal/windows-spawn.d.ts +10 -0
  44. package/dist/migrations/0008_careful_black_bird.sql +17 -0
  45. package/dist/migrations/0009_hot_dark_phoenix.sql +1 -0
  46. package/dist/migrations/0010_analyze_stats.sql +6 -0
  47. package/dist/migrations/0011_far_black_tarantula.sql +1 -0
  48. package/dist/migrations/0012_blue_turbo.sql +23 -0
  49. package/dist/migrations/0013_hesitant_adam_destine.sql +15 -0
  50. package/dist/migrations/0014_organic_mongu.sql +73 -0
  51. package/dist/migrations/meta/0008_snapshot.json +1327 -0
  52. package/dist/migrations/meta/0009_snapshot.json +1335 -0
  53. package/dist/migrations/meta/0010_snapshot.json +1335 -0
  54. package/dist/migrations/meta/0011_snapshot.json +1342 -0
  55. package/dist/migrations/meta/0012_snapshot.json +1494 -0
  56. package/dist/migrations/meta/0013_snapshot.json +1592 -0
  57. package/dist/migrations/meta/0014_snapshot.json +1975 -0
  58. package/dist/migrations/meta/_journal.json +49 -0
  59. package/dist/paths.d.ts +1 -0
  60. package/dist/plugin/types.d.ts +1 -0
  61. package/dist/plugins/index.js +150 -90
  62. package/dist/provider/acp/adapters/claude.d.ts +0 -1
  63. package/dist/provider/acp/connection.d.ts +4 -0
  64. package/dist/provider/acp/meta.d.ts +15 -0
  65. package/dist/provider/bridge.d.ts +16 -1
  66. package/dist/provider/classify-task-error.d.ts +2 -0
  67. package/dist/provider/cli/adapter.types.d.ts +6 -0
  68. package/dist/provider/cli/adapters/cli-knob.util.d.ts +6 -0
  69. package/dist/provider/cli/adapters/grok.d.ts +2 -0
  70. package/dist/provider/cli/adapters/index.d.ts +1 -0
  71. package/dist/provider/cli/index.d.ts +1 -1
  72. package/dist/provider/cli/meta.d.ts +8 -1
  73. package/dist/provider/errors.d.ts +1 -0
  74. package/dist/provider/idle-watchdog.d.ts +19 -0
  75. package/dist/provider/models.d.ts +26 -24
  76. package/dist/provider/order.d.ts +1 -1
  77. package/dist/provider/parse-usage.d.ts +6 -0
  78. package/dist/provider/provider-selection.d.ts +8 -0
  79. package/dist/provider/redact-technical-message.d.ts +1 -0
  80. package/dist/provider/task-error.types.d.ts +16 -0
  81. package/dist/publish/auth-boundary.d.ts +22 -0
  82. package/dist/publish/auth-json.d.ts +11 -0
  83. package/dist/publish/constants.d.ts +6 -0
  84. package/dist/publish/index.d.ts +30 -0
  85. package/dist/publish/index.js +1 -0
  86. package/dist/publish/manifest.d.ts +17 -0
  87. package/dist/publish/marketplace-api.constants.d.ts +1 -0
  88. package/dist/publish/pack.d.ts +2 -0
  89. package/dist/publish/scan.d.ts +9 -0
  90. package/dist/publish/secrets.d.ts +6 -0
  91. package/dist/publish/upload.d.ts +18 -0
  92. package/dist/repository/agent-suggestion.repository.d.ts +34 -0
  93. package/dist/repository/index.d.ts +7 -1
  94. package/dist/repository/index.js +126 -66
  95. package/dist/repository/notification.repository.d.ts +58 -0
  96. package/dist/repository/task.repository.d.ts +94 -0
  97. package/dist/repository/thread.repository.d.ts +16 -2
  98. package/dist/repository/usage-report.repository.d.ts +27 -0
  99. package/dist/schema/agent-suggestions.d.ts +199 -0
  100. package/dist/schema/index.d.ts +5 -0
  101. package/dist/schema/notifications.d.ts +303 -0
  102. package/dist/schema/ui-action-receipts.d.ts +303 -0
  103. package/dist/schema/ui-instances.d.ts +267 -0
  104. package/dist/schema/usage-reports.d.ts +252 -0
  105. package/dist/testing/index.d.ts +1 -0
  106. package/dist/testing/index.js +1 -1
  107. package/dist/types/index.d.ts +448 -3
  108. package/dist/ui-card/index.d.ts +2 -0
  109. package/dist/ui-card/legacy-card-parser.d.ts +11 -0
  110. package/dist/ui-instance/definition.d.ts +6 -0
  111. package/dist/ui-instance/errors.d.ts +17 -0
  112. package/dist/ui-instance/index.d.ts +6 -0
  113. package/dist/ui-instance/json.d.ts +5 -0
  114. package/dist/ui-instance/runtime.d.ts +13 -0
  115. package/dist/ui-instance/store.d.ts +65 -0
  116. package/dist/ui-instance/types.d.ts +200 -0
  117. package/dist/utils/crewx-home.d.ts +1 -0
  118. package/dist/utils/id.d.ts +1 -1
  119. package/dist/utils/timestamp.d.ts +1 -0
  120. package/dist/wi/create.d.ts +48 -0
  121. package/dist/wi/select.d.ts +20 -0
  122. package/package.json +19 -3
  123. package/templates/agents/default.yaml +175 -117
  124. package/templates/documents/crewx-manual.md +138 -138
  125. package/templates/workflows/wi-default-flow.yaml +65 -0
  126. package/templates/workflows/wi-plan-flow.yaml +140 -0
@@ -1,19 +1,52 @@
1
- import*as N from'path';import N__default,{join,dirname}from'path';import {fileURLToPath}from'url';import {existsSync,mkdirSync,writeFileSync,appendFileSync,readFileSync}from'fs';import qt,{homedir}from'os';import {createHash}from'crypto';import {sql,eq,desc,and,or,isNull,like,asc,inArray,gte,lt}from'drizzle-orm';import {sqliteTable,text,integer,real,index,unique,uniqueIndex}from'drizzle-orm/sqlite-core';var X=(d=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(d,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):d)(function(d){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+d+'" is not supported')});var $t=()=>fileURLToPath(import.meta.url),Pt=()=>N__default.dirname($t()),f=Pt();var $=class{detach(t){}};function mt(d){let t=e=>String(e).padStart(2,"0");return `${d.getFullYear()}${t(d.getMonth()+1)}${t(d.getDate())}T${t(d.getHours())}${t(d.getMinutes())}${t(d.getSeconds())}`}var ot=class extends ${name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",e=>{try{existsSync(this.logsDir)||mkdirSync(this.logsDir,{recursive:!0});let s=mt(e.timestamp),n=join(this.logsDir,`${s}_${e.traceId}.log`);this.logFiles.set(e.traceId,n);let r=`=== TASK LOG: ${e.traceId} ===
1
+ import*as J from'path';import J__default,{join,dirname}from'path';import {fileURLToPath}from'url';import {existsSync,mkdirSync,writeFileSync,appendFileSync,readFileSync}from'fs';import me,{homedir}from'os';import {createHash}from'crypto';import {sql,eq,desc,and,isNull,lt,or,notLike,like,asc,inArray,gte,isNotNull,ne}from'drizzle-orm';import {sqliteTable,text,integer,real,index,unique,uniqueIndex,primaryKey,check}from'drizzle-orm/sqlite-core';var gt=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var de=()=>fileURLToPath(import.meta.url),ce=()=>J__default.dirname(de()),k=ce();var Q=class{detach(t){}};function Ut(o){let t=n=>String(n).padStart(2,"0");return `${o.getFullYear()}${t(o.getMonth()+1)}${t(o.getDate())}T${t(o.getHours())}${t(o.getMinutes())}${t(o.getSeconds())}`}function Nt(o){let t=o.toISOString();return `${t.slice(0,10)} ${t.slice(11,19)} UTC`}var Ct=class extends Q{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",n=>{try{existsSync(this.logsDir)||mkdirSync(this.logsDir,{recursive:!0});let s=Ut(n.timestamp),r=join(this.logsDir,`${s}_${n.traceId}.log`);this.logFiles.set(n.traceId,r);let i=`=== TASK LOG: ${n.traceId} ===
2
2
  CrewX Version: ${this.version}
3
- Mode: ${e.mode}
4
- Agent: ${e.agentRef}
5
- Started: ${e.timestamp.toLocaleString()}
6
- Message: ${e.message}
3
+ Mode: ${n.mode}
4
+ Agent: ${n.agentRef}
5
+ Started: ${Nt(n.timestamp)}
6
+ Message: ${n.message}
7
7
 
8
- `;writeFileSync(n,r,{encoding:"utf8",mode:384});}catch{}}),t.on("task:output",e=>{try{let s=this.logFiles.get(e.traceId);if(!s)return;let n=new Date().toISOString();appendFileSync(s,`[${n}] STDOUT: ${e.output}
9
- `,"utf8");}catch{}}),t.on("task:end",e=>{try{let s=this.logFiles.get(e.traceId);if(!s)return;let n=new Date().toLocaleString(),r=e.error?`failed: ${e.error.message}`:"completed successfully",i=`[${n}] INFO: Task ${r} in ${e.durationMs}ms
10
- [${n}] INFO: Process closed with exit code: ${e.error?1:0}
11
- `;appendFileSync(s,i,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function Ft(d){let t=N.resolve(d);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(e,s)=>`${s.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function kt(d){let t=Ft(d);return createHash("sha256").update(t).digest("hex")}var q=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:join(qt.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(t){return t instanceof Error&&/no such table:/i.test(t.message)}dbExists(t){return existsSync(t??this.resolveDbPath())}};function T(d){let t=X("better-sqlite3"),{drizzle:e}=X("drizzle-orm/better-sqlite3"),s=new t(d);return s.exec("PRAGMA journal_mode = WAL"),s.exec("PRAGMA busy_timeout = 5000"),s.exec("PRAGMA foreign_keys = ON"),{db:e(s),runRaw:(n,r=[])=>s.prepare(n).run(...r),close:()=>s.close()}}var wt=new Set,Wt={agent_id:"TEXT",status:"TEXT DEFAULT 'running'",started_at:"TEXT",trace_id:"TEXT",parent_task_id:"TEXT",crewx_version:"TEXT",pid:"INTEGER",thread_id:"TEXT",workspace_id:"TEXT",workspace_ref:"TEXT",workspace_name:"TEXT",project_id:"TEXT",project_name:"TEXT"};function it(d,t){return (d.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function jt(d,t){if(t>0||!it(d,"tasks"))return;let e=d.all("PRAGMA table_info(tasks)"),s=new Set(e.map(n=>n.name));for(let[n,r]of Object.entries(Wt))s.has(n)||d.run(`ALTER TABLE tasks ADD COLUMN ${n} ${r}`);}var Kt={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"}};function Gt(d,t,e){if(!it(d,"__drizzle_migrations")||!it(d,"tasks"))return;let s=d.all(e`SELECT hash FROM __drizzle_migrations`),n=new Set(s.map(i=>i.hash)),r=JSON.parse(readFileSync(N__default.join(t,"meta/_journal.json"),"utf-8"));for(let i of r.entries){let a=Kt[i.tag];if(!a)continue;let l=N__default.join(t,`${i.tag}.sql`);if(!existsSync(l))continue;let c=readFileSync(l,"utf-8"),p=createHash("sha256").update(c).digest("hex");if(n.has(p))continue;let k=d.all("PRAGMA table_info(tasks)"),E=new Set(k.map(R=>R.name));for(let[R,G]of Object.entries(a))E.has(R)||(d.run(`ALTER TABLE tasks ADD COLUMN ${R} ${G}`),E.add(R));}}function Xt(d,t,e){let s=d.all(e`SELECT hash FROM __drizzle_migrations`),n=new Set(s.map(i=>i.hash)),r=JSON.parse(readFileSync(N__default.join(t,"meta/_journal.json"),"utf-8"));for(let i of r.entries){let a=N__default.join(t,`${i.tag}.sql`);if(!existsSync(a))continue;let l=readFileSync(a,"utf-8"),c=createHash("sha256").update(l).digest("hex");if(n.has(c))continue;let p=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,k=[],E;for(;(E=p.exec(l))!==null;)k.push({table:E[1],column:E[2]});if(k.length===0||!l.split(/-->\s*statement-breakpoint/).map(K=>K.trim()).filter(Boolean).every(K=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(K)))continue;k.every(({table:K,column:Dt})=>d.all(`PRAGMA table_info("${K}")`).some(Nt=>Nt.name===Dt))&&d.run(e`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${c}, ${i.when})`);}}function Yt(d){let{migrate:t}=X("drizzle-orm/better-sqlite3/migrator"),{sql:e}=X("drizzle-orm"),s=[N__default.join(f,"../migrations"),N__default.join(f,"migrations"),N__default.join(f,"../../../../drizzle/migrations"),N__default.join(process.cwd(),"drizzle/migrations")],n=s.find(c=>existsSync(N__default.join(c,"meta/_journal.json")));if(!n)throw new Error(`migrations folder not found. Searched:
8
+ `;writeFileSync(r,i,{encoding:"utf8",mode:384});}catch{}}),t.on("task:output",n=>{try{let s=this.logFiles.get(n.traceId);if(!s)return;let r=new Date().toISOString();appendFileSync(s,`[${r}] STDOUT: ${n.output}
9
+ `,"utf8");}catch{}}),t.on("task:end",n=>{try{let s=this.logFiles.get(n.traceId);if(!s)return;let r=Nt(new Date),i=n.error?`failed: ${n.error.message}`:"completed successfully",a=`[${r}] INFO: Task ${i} in ${n.durationMs}ms
10
+ [${r}] INFO: Process closed with exit code: ${n.error?1:0}
11
+ `;appendFileSync(s,a,"utf8"),this.logFiles.delete(n.traceId);}catch{}}));}detach(t){this.unsubs.forEach(n=>n()),this.unsubs=[],this.logFiles.clear();}};function he(o){let t=J.resolve(o);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(n,s)=>`${s.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function qt(o){let t=he(o);return createHash("sha256").update(t).digest("hex")}var dt=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:join(me.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(t){return t instanceof Error&&/no such table:/i.test(t.message)}dbExists(t){return existsSync(t??this.resolveDbPath())}};function y(o){let t=gt("better-sqlite3"),{drizzle:n}=gt("drizzle-orm/better-sqlite3"),s=new t(o);return s.exec("PRAGMA journal_mode = WAL"),s.exec("PRAGMA busy_timeout = 5000"),s.exec("PRAGMA foreign_keys = ON"),s.exec("PRAGMA analysis_limit = 400"),s.exec("PRAGMA optimize"),{db:n(s),runRaw:(r,i=[])=>s.prepare(r).run(...i),close:()=>s.close()}}var jt=new Set,ke={agent_id:"TEXT",status:"TEXT DEFAULT 'running'",started_at:"TEXT",trace_id:"TEXT",parent_task_id:"TEXT",crewx_version:"TEXT",pid:"INTEGER",thread_id:"TEXT",workspace_id:"TEXT",workspace_ref:"TEXT",workspace_name:"TEXT",project_id:"TEXT",project_name:"TEXT"};function Dt(o,t){return (o.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function we(o,t){if(t>0||!Dt(o,"tasks"))return;let n=o.all("PRAGMA table_info(tasks)"),s=new Set(n.map(r=>r.name));for(let[r,i]of Object.entries(ke))s.has(r)||o.run(`ALTER TABLE tasks ADD COLUMN ${r} ${i}`);}var Ee={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"}};function Se(o,t,n){if(!Dt(o,"__drizzle_migrations")||!Dt(o,"tasks"))return;let s=o.all(n`SELECT hash FROM __drizzle_migrations`),r=new Set(s.map(a=>a.hash)),i=JSON.parse(readFileSync(J__default.join(t,"meta/_journal.json"),"utf-8"));for(let a of i.entries){let d=Ee[a.tag];if(!d)continue;let u=J__default.join(t,`${a.tag}.sql`);if(!existsSync(u))continue;let c=readFileSync(u,"utf-8"),l=createHash("sha256").update(c).digest("hex");if(r.has(l))continue;let h=o.all("PRAGMA table_info(tasks)"),m=new Set(h.map(w=>w.name));for(let[w,$]of Object.entries(d))m.has(w)||(o.run(`ALTER TABLE tasks ADD COLUMN ${w} ${$}`),m.add(w));}}function Te(o,t,n){let s=o.all(n`SELECT hash FROM __drizzle_migrations`),r=new Set(s.map(a=>a.hash)),i=JSON.parse(readFileSync(J__default.join(t,"meta/_journal.json"),"utf-8"));for(let a of i.entries){let d=J__default.join(t,`${a.tag}.sql`);if(!existsSync(d))continue;let u=readFileSync(d,"utf-8"),c=createHash("sha256").update(u).digest("hex");if(r.has(c))continue;let l=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,h=[],m;for(;(m=l.exec(u))!==null;)h.push({table:m[1],column:m[2]});if(h.length===0||!u.split(/-->\s*statement-breakpoint/).map(v=>v.trim()).filter(Boolean).every(v=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(v)))continue;h.every(({table:v,column:B})=>o.all(`PRAGMA table_info("${v}")`).some(G=>G.name===B))&&o.run(n`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${c}, ${a.when})`);}}function Re(o){let{migrate:t}=gt("drizzle-orm/better-sqlite3/migrator"),{sql:n}=gt("drizzle-orm"),s=[J__default.join(k,"../migrations"),J__default.join(k,"migrations"),J__default.join(k,"../../../../drizzle/migrations"),J__default.join(process.cwd(),"drizzle/migrations")],r=s.find(c=>existsSync(J__default.join(c,"meta/_journal.json")));if(!r)throw new Error(`migrations folder not found. Searched:
12
12
  ${s.join(`
13
- `)}`);let r=d.get(e`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),i=0;r?.cnt&&(i=d.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),jt(d,i),r?.cnt&&(Xt(d,n,e),Gt(d,n,e)),t(d,{migrationsFolder:n});let l=(d.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-i;if(l>0){let c=r?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${c} (${l} migration${l>1?"s":""} applied).`);}}function J(d,t){wt.has(t)||(Yt(d),wt.add(t));}var _=class extends Error{code;cause;constructor(t,e,s){super(e),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var W=sqliteTable("workspaces",{id:text("id").primaryKey(),slug:text("slug").notNull().unique(),name:text("name").notNull(),workspace_path:text("workspace_path"),description:text("description"),is_active:integer("is_active").notNull().default(1),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()});var o=sqliteTable("tasks",{id:text("id").primaryKey(),agent_id:text("agent_id").notNull(),user_id:text("user_id"),prompt:text("prompt").notNull(),mode:text("mode").notNull().default("execute"),status:text("status").notNull().default("running"),result:text("result"),error:text("error"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),metadata:text("metadata"),workspace_id:text("workspace_id"),trace_id:text("trace_id"),parent_task_id:text("parent_task_id"),caller_agent_id:text("caller_agent_id"),model:text("model"),platform:text("platform").default("cli"),crewx_version:text("crewx_version"),input_tokens:integer("input_tokens").default(0),output_tokens:integer("output_tokens").default(0),cost_usd:real("cost_usd").default(0),pid:integer("pid"),rendered_prompt:text("rendered_prompt"),command:text("command"),coding_agent_command:text("coding_agent_command"),exit_code:integer("exit_code"),logs:text("logs"),thread_id:text("thread_id"),workspace_ref:text("workspace_ref"),project_id:text("project_id"),project_ref:text("project_ref"),cached_input_tokens:integer("cached_input_tokens").default(0),run_epoch:integer("run_epoch").default(0)},d=>({idx_tasks_agent_id:index("idx_tasks_agent_id").on(d.agent_id),idx_tasks_status:index("idx_tasks_status").on(d.status),idx_tasks_started_at:index("idx_tasks_started_at").on(d.started_at),idx_tasks_trace_id:index("idx_tasks_trace_id").on(d.trace_id),idx_tasks_parent_task_id:index("idx_tasks_parent_task_id").on(d.parent_task_id),idx_tasks_crewx_version:index("idx_tasks_crewx_version").on(d.crewx_version),idx_tasks_pid:index("idx_tasks_pid").on(d.pid),idx_tasks_thread_id:index("idx_tasks_thread_id").on(d.thread_id),idx_tasks_workspace_id:index("idx_tasks_workspace_id").on(d.workspace_id),idx_tasks_workspace_ref:index("idx_tasks_workspace_ref").on(d.workspace_ref),idx_tasks_project_id:index("idx_tasks_project_id").on(d.project_id),idx_tasks_ws_started:index("idx_tasks_ws_started").on(d.workspace_id,d.started_at)}));var u=sqliteTable("threads",{id:text("id").primaryKey(),workspace_id:text("workspace_id").references(()=>W.id,{onDelete:"set null"}),platform:text("platform").notNull().default("cli"),title:text("title"),first_message:text("first_message"),last_message:text("last_message"),message_count:integer("message_count").notNull().default(0),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull(),metadata:text("metadata"),title_locked:integer("title_locked").notNull().default(0),pinned:integer("pinned").notNull().default(0),starred:integer("starred").notNull().default(0)},d=>({idx_threads_updated_at:index("idx_threads_updated_at").on(d.updated_at),idx_threads_workspace_id:index("idx_threads_workspace_id").on(d.workspace_id)}));var ne=sqliteTable("spans",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>o.id,{onDelete:"set null"}),parent_span_id:text("parent_span_id").references(()=>ne.id,{onDelete:"set null"}),name:text("name").notNull(),kind:text("kind").notNull().default("internal"),status:text("status").notNull().default("ok"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),input:text("input"),output:text("output"),error:text("error"),attributes:text("attributes")},d=>({idx_spans_task_id:index("idx_spans_task_id").on(d.task_id),idx_spans_parent_span_id:index("idx_spans_parent_span_id").on(d.parent_span_id)}));sqliteTable("tool_calls",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>o.id,{onDelete:"cascade"}),session_id:text("session_id"),tool_name:text("tool_name").notNull(),files:text("files"),input:text("input"),output:text("output"),duration_ms:integer("duration_ms"),timestamp:text("timestamp").notNull()},d=>({idx_tool_calls_task_id:index("idx_tool_calls_task_id").on(d.task_id),idx_tool_calls_tool_name:index("idx_tool_calls_tool_name").on(d.tool_name),idx_tool_calls_timestamp:index("idx_tool_calls_timestamp").on(d.timestamp)}));sqliteTable("thread_boxes",{id:text("id").primaryKey(),thread_id:text("thread_id").notNull().references(()=>u.id,{onDelete:"cascade"}),seq:integer("seq").notNull(),first_task_id:text("first_task_id").notNull(),mid_task_id:text("mid_task_id").notNull(),last_task_id:text("last_task_id").notNull(),task_count:integer("task_count").notNull(),summary:text("summary"),source_tokens:integer("source_tokens").notNull(),summary_tokens:integer("summary_tokens"),created_at:text("created_at").notNull()},d=>({idx_thread_boxes_thread_id:index("idx_thread_boxes_thread_id").on(d.thread_id),idx_thread_boxes_seq:index("idx_thread_boxes_seq").on(d.thread_id,d.seq),uniq_thread_boxes_thread_seq:unique().on(d.thread_id,d.seq)}));sqliteTable("request_logs",{id:text("id").primaryKey(),path:text("path").notNull(),method:text("method").notNull(),status_code:integer("status_code").notNull(),duration_ms:integer("duration_ms").notNull(),ip:text("ip"),request_headers:text("request_headers"),response_headers:text("response_headers"),request_body:text("request_body"),response_body:text("response_body"),query:text("query"),user_id:text("user_id"),project_id:text("project_id"),partition_key:text("partition_key").notNull(),timestamp:text("timestamp").notNull().default(sql`(datetime('now'))`),metadata:text("metadata")},d=>({idx_request_logs_timestamp:index("idx_request_logs_timestamp").on(d.timestamp),idx_request_logs_path:index("idx_request_logs_path").on(d.path),idx_request_logs_status_code:index("idx_request_logs_status_code").on(d.status_code),idx_request_logs_partition_key:index("idx_request_logs_partition_key").on(d.partition_key)}));sqliteTable("usage_limit_snapshots",{id:text("id").primaryKey(),provider:text("provider").notNull(),account_ref:text("account_ref").notNull().default("default"),limit_window:text("limit_window").notNull(),bucket_start:text("bucket_start").notNull(),captured_at:text("captured_at").notNull(),used_percent:integer("used_percent").notNull(),remaining_percent:integer("remaining_percent").notNull(),resets_at:text("resets_at"),source:text("source").notNull(),metadata:text("metadata")},d=>({uniq_usage_limit_snapshots_bucket:uniqueIndex("uniq_usage_limit_snapshots_bucket").on(d.provider,d.account_ref,d.limit_window,d.bucket_start),idx_usage_limit_snapshots_window_bucket:index("idx_usage_limit_snapshots_window_bucket").on(d.limit_window,d.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:index("idx_usage_limit_snapshots_provider_window_bucket").on(d.provider,d.limit_window,d.bucket_start)}));var F="2026-05-09",ge="0.8.9-rc.13",H=10,z=parseInt(ge.split("rc.")[1]),st=class extends q{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=dirname(e);existsSync(n)||mkdirSync(n,{recursive:true});}else if(!existsSync(e))throw new _("NOT_FOUND","Database not found");let s=T(e);if(t)try{J(s.db,e);}catch(n){throw s.close(),n}return s}startTask(t){let e=this.openHandle(true);try{e.db.insert(o).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null}).onConflictDoUpdate({target:o.id,set:{pid:sql`COALESCE(excluded.pid, ${o.pid})`},setWhere:eq(o.status,"running")}).run();}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to start task",s)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{let s=t.runEpoch??null;e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
13
+ `)}`);let i=o.get(n`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;i?.cnt&&(a=o.get(n`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),we(o,a),i?.cnt&&(Te(o,r,n),Se(o,r,n)),t(o,{migrationsFolder:r});let u=(o.get(n`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-a;if(u>0){let c=i?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${c} (${u} migration${u>1?"s":""} applied).`);}}function kt(o,t){jt.has(t)||(Re(o),jt.add(t));}var p=class extends Error{code;cause;constructor(t,n,s){super(n),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var ct=sqliteTable("workspaces",{id:text("id").primaryKey(),slug:text("slug").notNull().unique(),name:text("name").notNull(),workspace_path:text("workspace_path"),description:text("description"),is_active:integer("is_active").notNull().default(1),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()});var e=sqliteTable("tasks",{id:text("id").primaryKey(),agent_id:text("agent_id").notNull(),user_id:text("user_id"),prompt:text("prompt").notNull(),mode:text("mode").notNull().default("execute"),status:text("status").notNull().default("running"),result:text("result"),error:text("error"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),metadata:text("metadata"),workspace_id:text("workspace_id"),trace_id:text("trace_id"),parent_task_id:text("parent_task_id"),caller_agent_id:text("caller_agent_id"),model:text("model"),platform:text("platform").default("cli"),crewx_version:text("crewx_version"),input_tokens:integer("input_tokens").default(0),output_tokens:integer("output_tokens").default(0),cost_usd:real("cost_usd").default(0),pid:integer("pid"),rendered_prompt:text("rendered_prompt"),command:text("command"),coding_agent_command:text("coding_agent_command"),exit_code:integer("exit_code"),logs:text("logs"),thread_id:text("thread_id"),workspace_ref:text("workspace_ref"),project_id:text("project_id"),project_ref:text("project_ref"),cached_input_tokens:integer("cached_input_tokens").default(0),run_epoch:integer("run_epoch").default(0)},o=>({idx_tasks_agent_id:index("idx_tasks_agent_id").on(o.agent_id),idx_tasks_status:index("idx_tasks_status").on(o.status),idx_tasks_started_at:index("idx_tasks_started_at").on(o.started_at),idx_tasks_trace_id:index("idx_tasks_trace_id").on(o.trace_id),idx_tasks_parent_task_id:index("idx_tasks_parent_task_id").on(o.parent_task_id),idx_tasks_crewx_version:index("idx_tasks_crewx_version").on(o.crewx_version),idx_tasks_pid:index("idx_tasks_pid").on(o.pid),idx_tasks_thread_id:index("idx_tasks_thread_id").on(o.thread_id),idx_tasks_workspace_id:index("idx_tasks_workspace_id").on(o.workspace_id),idx_tasks_workspace_ref:index("idx_tasks_workspace_ref").on(o.workspace_ref),idx_tasks_project_id:index("idx_tasks_project_id").on(o.project_id),idx_tasks_ws_started:index("idx_tasks_ws_started").on(o.workspace_id,o.started_at)}));var _=sqliteTable("threads",{id:text("id").primaryKey(),workspace_id:text("workspace_id").references(()=>ct.id,{onDelete:"set null"}),platform:text("platform").notNull().default("cli"),title:text("title"),first_message:text("first_message"),last_message:text("last_message"),message_count:integer("message_count").notNull().default(0),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull(),metadata:text("metadata"),title_locked:integer("title_locked").notNull().default(0),pinned:integer("pinned").notNull().default(0),starred:integer("starred").notNull().default(0)},o=>({idx_threads_updated_at:index("idx_threads_updated_at").on(o.updated_at),idx_threads_workspace_id:index("idx_threads_workspace_id").on(o.workspace_id),idx_threads_ws_updated:index("idx_threads_ws_updated").on(o.workspace_id,o.updated_at),idx_threads_title:index("idx_threads_title").on(o.title)}));var Oe=sqliteTable("spans",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>e.id,{onDelete:"set null"}),parent_span_id:text("parent_span_id").references(()=>Oe.id,{onDelete:"set null"}),name:text("name").notNull(),kind:text("kind").notNull().default("internal"),status:text("status").notNull().default("ok"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),input:text("input"),output:text("output"),error:text("error"),attributes:text("attributes")},o=>({idx_spans_task_id:index("idx_spans_task_id").on(o.task_id),idx_spans_parent_span_id:index("idx_spans_parent_span_id").on(o.parent_span_id)}));sqliteTable("tool_calls",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>e.id,{onDelete:"cascade"}),session_id:text("session_id"),tool_name:text("tool_name").notNull(),files:text("files"),input:text("input"),output:text("output"),duration_ms:integer("duration_ms"),timestamp:text("timestamp").notNull()},o=>({idx_tool_calls_task_id:index("idx_tool_calls_task_id").on(o.task_id),idx_tool_calls_tool_name:index("idx_tool_calls_tool_name").on(o.tool_name),idx_tool_calls_timestamp:index("idx_tool_calls_timestamp").on(o.timestamp)}));sqliteTable("thread_boxes",{id:text("id").primaryKey(),thread_id:text("thread_id").notNull().references(()=>_.id,{onDelete:"cascade"}),seq:integer("seq").notNull(),first_task_id:text("first_task_id").notNull(),mid_task_id:text("mid_task_id").notNull(),last_task_id:text("last_task_id").notNull(),task_count:integer("task_count").notNull(),summary:text("summary"),source_tokens:integer("source_tokens").notNull(),summary_tokens:integer("summary_tokens"),created_at:text("created_at").notNull()},o=>({idx_thread_boxes_thread_id:index("idx_thread_boxes_thread_id").on(o.thread_id),idx_thread_boxes_seq:index("idx_thread_boxes_seq").on(o.thread_id,o.seq),uniq_thread_boxes_thread_seq:unique().on(o.thread_id,o.seq)}));sqliteTable("request_logs",{id:text("id").primaryKey(),path:text("path").notNull(),method:text("method").notNull(),status_code:integer("status_code").notNull(),duration_ms:integer("duration_ms").notNull(),ip:text("ip"),request_headers:text("request_headers"),response_headers:text("response_headers"),request_body:text("request_body"),response_body:text("response_body"),query:text("query"),user_id:text("user_id"),project_id:text("project_id"),partition_key:text("partition_key").notNull(),timestamp:text("timestamp").notNull().default(sql`(datetime('now'))`),metadata:text("metadata")},o=>({idx_request_logs_timestamp:index("idx_request_logs_timestamp").on(o.timestamp),idx_request_logs_path:index("idx_request_logs_path").on(o.path),idx_request_logs_status_code:index("idx_request_logs_status_code").on(o.status_code),idx_request_logs_partition_key:index("idx_request_logs_partition_key").on(o.partition_key)}));sqliteTable("usage_limit_snapshots",{id:text("id").primaryKey(),provider:text("provider").notNull(),account_ref:text("account_ref").notNull().default("default"),limit_window:text("limit_window").notNull(),bucket_start:text("bucket_start").notNull(),captured_at:text("captured_at").notNull(),used_percent:integer("used_percent").notNull(),remaining_percent:integer("remaining_percent").notNull(),resets_at:text("resets_at"),source:text("source").notNull(),metadata:text("metadata")},o=>({uniq_usage_limit_snapshots_bucket:uniqueIndex("uniq_usage_limit_snapshots_bucket").on(o.provider,o.account_ref,o.limit_window,o.bucket_start),idx_usage_limit_snapshots_window_bucket:index("idx_usage_limit_snapshots_window_bucket").on(o.limit_window,o.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:index("idx_usage_limit_snapshots_provider_window_bucket").on(o.provider,o.limit_window,o.bucket_start)}));sqliteTable("usage_reports",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),month:text("month").notNull(),generated_at:text("generated_at").notNull(),source_range:text("source_range").notNull(),tier:text("tier").notNull(),total_tokens:integer("total_tokens").notNull(),total_cost_usd:real("total_cost_usd").notNull(),payload:text("payload").notNull(),payload_hash:text("payload_hash"),signature:text("signature"),signed_at:text("signed_at"),issuer:text("issuer")},o=>({uniq_usage_reports_ws_month:uniqueIndex("uniq_usage_reports_ws_month").on(o.workspace_id,o.month)}));sqliteTable("notifications",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),agent_id:text("agent_id"),task_id:text("task_id"),thread_id:text("thread_id"),source:text("source").notNull().default("agent"),level:text("level").notNull().default("info"),title:text("title").notNull(),body:text("body"),target_user_id:text("target_user_id"),created_at:text("created_at").notNull(),metadata:text("metadata")},o=>({idx_notifications_ws_created:index("idx_notifications_ws_created").on(o.workspace_id,sql`${o.created_at} DESC`)}));sqliteTable("notification_reads",{notification_id:text("notification_id").notNull(),user_id:text("user_id").notNull(),read_at:text("read_at").notNull()},o=>({pk:primaryKey({columns:[o.notification_id,o.user_id]})}));sqliteTable("agent_suggestions",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),agent_id:text("agent_id").notNull(),task_id:text("task_id"),type:text("type").notNull(),status:text("status").notNull().default("pending"),payload:text("payload").notNull(),applied_commit_sha:text("applied_commit_sha"),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()},o=>({idx_agent_suggestions_ws_agent:index("idx_agent_suggestions_ws_agent").on(o.workspace_id,o.agent_id),idx_agent_suggestions_ws_created:index("idx_agent_suggestions_ws_created").on(o.workspace_id,o.created_at)}));sqliteTable("ui_instances",{id:text("id").primaryKey().notNull(),definition_id:text("definition_id").notNull(),definition_version:integer("definition_version").notNull(),definition_hash:text("definition_hash").notNull(),workspace_id:text("workspace_id").notNull(),thread_id:text("thread_id").notNull(),anchor_task_id:text("anchor_task_id"),domain_ref_json:text("domain_ref_json").notNull(),state_json:text("state_json").notNull(),revision:integer("revision").notNull().default(0),status:text("status").notNull().default("active"),granted_capabilities_json:text("granted_capabilities_json").notNull().default("[]"),created_at:integer("created_at").notNull(),updated_at:integer("updated_at").notNull()},o=>({idCheck:check("ui_instances_id_ck",sql`length(${o.id}) BETWEEN 5 AND 128 AND ${o.id} GLOB 'uic_*'`),definitionIdCheck:check("ui_instances_definition_id_ck",sql`length(${o.definition_id}) BETWEEN 1 AND 128`),definitionVersionCheck:check("ui_instances_definition_version_ck",sql`${o.definition_version} >= 1`),definitionHashCheck:check("ui_instances_definition_hash_ck",sql`length(${o.definition_hash}) = 64 AND ${o.definition_hash} NOT GLOB '*[^0-9a-f]*'`),workspaceIdCheck:check("ui_instances_workspace_id_ck",sql`length(${o.workspace_id}) BETWEEN 1 AND 256`),threadIdCheck:check("ui_instances_thread_id_ck",sql`length(${o.thread_id}) BETWEEN 1 AND 256`),domainRefJsonCheck:check("ui_instances_domain_ref_json_ck",sql`json_valid(${o.domain_ref_json}) AND json_type(${o.domain_ref_json}) = 'object'`),stateJsonCheck:check("ui_instances_state_json_ck",sql`json_valid(${o.state_json}) AND json_type(${o.state_json}) = 'object'`),revisionCheck:check("ui_instances_revision_ck",sql`${o.revision} >= 0`),statusCheck:check("ui_instances_status_ck",sql`${o.status} IN ('active', 'completed', 'expired', 'revoked', 'unsupported')`),grantedCapabilitiesJsonCheck:check("ui_instances_granted_capabilities_json_ck",sql`json_valid(${o.granted_capabilities_json}) AND json_type(${o.granted_capabilities_json}) = 'array'`),createdAtCheck:check("ui_instances_created_at_ck",sql`${o.created_at} >= 0`),updatedAtCheck:check("ui_instances_updated_at_ck",sql`${o.updated_at} >= ${o.created_at}`),workspaceThreadIdx:index("ui_instances_workspace_thread_idx").on(o.workspace_id,o.thread_id)}));sqliteTable("ui_action_receipts",{id:text("id").primaryKey().notNull(),instance_id:text("instance_id").notNull(),request_id:text("request_id").notNull(),action_id:text("action_id").notNull(),actor_json:text("actor_json").notNull(),source:text("source").notNull(),expected_revision:integer("expected_revision").notNull(),before_revision:integer("before_revision").notNull(),after_revision:integer("after_revision"),status:text("status").notNull(),outcome:text("outcome"),input_json:text("input_json").notNull(),result_json:text("result_json"),error_code:text("error_code"),requested_at:integer("requested_at").notNull(),settled_at:integer("settled_at")},o=>({idCheck:check("ui_action_receipts_id_ck",sql`length(${o.id}) BETWEEN 5 AND 128`),instanceIdCheck:check("ui_action_receipts_instance_id_ck",sql`length(${o.instance_id}) BETWEEN 1 AND 128`),requestIdCheck:check("ui_action_receipts_request_id_ck",sql`length(${o.request_id}) BETWEEN 1 AND 128`),actionIdCheck:check("ui_action_receipts_action_id_ck",sql`length(${o.action_id}) BETWEEN 1 AND 128`),actorJsonCheck:check("ui_action_receipts_actor_json_ck",sql`json_valid(${o.actor_json}) AND json_type(${o.actor_json}) = 'object'`),sourceCheck:check("ui_action_receipts_source_ck",sql`${o.source} IN ('ui_host', 'cli', 'system')`),expectedRevisionCheck:check("ui_action_receipts_expected_revision_ck",sql`${o.expected_revision} >= 0`),beforeRevisionCheck:check("ui_action_receipts_before_revision_ck",sql`${o.before_revision} >= 0`),afterRevisionCheck:check("ui_action_receipts_after_revision_ck",sql`${o.after_revision} IS NULL OR ${o.after_revision} >= 0`),statusCheck:check("ui_action_receipts_status_ck",sql`${o.status} IN ('requested', 'settled')`),outcomeCheck:check("ui_action_receipts_outcome_ck",sql`${o.outcome} IS NULL OR ${o.outcome} IN ('succeeded', 'rejected', 'failed', 'conflicted', 'expired')`),inputJsonCheck:check("ui_action_receipts_input_json_ck",sql`json_valid(${o.input_json}) AND json_type(${o.input_json}) = 'object'`),resultJsonCheck:check("ui_action_receipts_result_json_ck",sql`${o.result_json} IS NULL OR (json_valid(${o.result_json}) AND json_type(${o.result_json}) = 'object')`),requestedAtCheck:check("ui_action_receipts_requested_at_ck",sql`${o.requested_at} >= 0`),settledAtCheck:check("ui_action_receipts_settled_at_ck",sql`${o.settled_at} IS NULL OR ${o.settled_at} >= ${o.requested_at}`),statusTransitionCheck:check("ui_action_receipts_status_transition_ck",sql`(
14
+ (${o.status} = 'requested' AND ${o.after_revision} IS NULL AND ${o.outcome} IS NULL AND ${o.settled_at} IS NULL)
15
+ OR
16
+ (${o.status} = 'settled' AND ${o.after_revision} IS NOT NULL AND ${o.outcome} IS NOT NULL AND ${o.settled_at} IS NOT NULL)
17
+ )`),instanceRequestUnique:uniqueIndex("ui_action_receipts_instance_request_uq").on(o.instance_id,o.request_id),instanceIdIdx:index("ui_action_receipts_instance_id_idx").on(o.instance_id),requestedAtIdx:index("ui_action_receipts_requested_at_idx").on(o.requested_at)}));function Zt(o){let t=o.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let n=t.lastIndexOf("/");return n>=0&&(t=t.slice(n+1)),t=t.replace(/-\d{8}$/,""),t}var tt="2026-05-09",on="0.8.9-rc.13",et=10,nt=parseInt(on.split("rc.")[1]);function te(){let o=sql`
18
+ CASE
19
+ WHEN ${e.model} LIKE 'claude-%' OR ${e.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
20
+ WHEN ${e.model} LIKE 'gpt-%' OR ${e.model} LIKE 'codex-%' THEN 'codex'
21
+ WHEN ${e.model} LIKE 'gemini-%' THEN 'gemini'
22
+ WHEN ${e.model} LIKE 'grok-%' THEN 'grok'
23
+ WHEN ${e.model} LIKE 'zai-%' OR ${e.model} LIKE 'openrouter/z-ai/%' THEN 'opencode'
24
+ WHEN ${e.model} LIKE 'minimax/%' THEN 'minimax'
25
+ WHEN ${e.model} LIKE 'qwen%' THEN 'qwen'
26
+ ELSE 'unknown'
27
+ END
28
+ `,t=sql`json_extract(${e.metadata}, '$.provider')`,n=sql`trim(${t})`,s=sql`substr(${n}, 1, instr(${n}, '/') - 1)`,r=sql`
29
+ CASE
30
+ WHEN instr(${n}, '/') > 0
31
+ AND ${s} IN ('cli', 'acp', 'api', 'plugin', 'remote')
32
+ THEN substr(${n}, instr(${n}, '/') + 1)
33
+ ELSE ${n}
34
+ END
35
+ `;return sql`
36
+ CASE
37
+ WHEN ${e.metadata} IS NULL THEN ${o}
38
+ WHEN json_valid(${e.metadata}) = 0 THEN 'unknown'
39
+ WHEN json_type(${e.metadata}, '$') IS NOT 'object' THEN 'unknown'
40
+ WHEN json_type(${e.metadata}, '$.provider') IS NULL THEN ${o}
41
+ WHEN json_type(${e.metadata}, '$.provider') IS NOT 'text' THEN 'unknown'
42
+ WHEN ${n} = '' THEN 'unknown'
43
+ WHEN trim(${r}) = '' THEN 'unknown'
44
+ ELSE ${r}
45
+ END
46
+ `}var an=new Set(["workflow","mcp"]),ee=600*1e3,xt=class extends dt{dbPath;pidNullObservedSince=new Map;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let n=this.resolveDbPath();if(t){let r=dirname(n);existsSync(r)||mkdirSync(r,{recursive:true});}else if(!existsSync(n))throw new p("NOT_FOUND","Database not found");let s=y(n);if(t)try{kt(s.db,n);}catch(r){throw s.close(),r}return s}startTask(t){let n=this.openHandle(true);try{n.db.insert(e).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null}).onConflictDoUpdate({target:e.id,set:{pid:sql`COALESCE(excluded.pid, ${e.pid})`},setWhere:eq(e.status,"running")}).run();}catch(s){throw s instanceof p?s:new p("DB_ERROR","Failed to start task",s)}finally{n.close();}}finishTask(t){let n=this.openHandle(true);try{let s=t.runEpoch??null;n.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
14
47
  exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
15
48
  model=COALESCE(?, model)
16
- WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[t.status,t.result??null,t.error??null,t.completedAt,t.durationMs??null,t.exitCode??null,t.inputTokens??0,t.outputTokens??0,t.cachedInputTokens??0,t.costUsd??0,t.model??null,t.id,s]);}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to finish task",s)}finally{e.close();}}appendLog(t,e){let s=this.openHandle(true);try{s.db.transaction(n=>{let r=n.select({logs:o.logs}).from(o).where(eq(o.id,t)).limit(1).get(),i=r?.logs?JSON.parse(r.logs):[];i.push(e),n.update(o).set({logs:JSON.stringify(i)}).where(eq(o.id,t)).run();},{behavior:"immediate"});}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to append log",n)}finally{s.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).where(eq(o.status,"running")).orderBy(desc(o.started_at)).all()}catch(e){throw new _("DB_ERROR","Failed to get running tasks",e)}finally{t.close();}}getAllTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).orderBy(desc(o.started_at)).limit(100).all()}catch(e){throw new _("DB_ERROR","Failed to get all tasks",e)}finally{t.close();}}getTask(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(o).where(eq(o.id,t)).limit(1).get()??void 0}catch(s){throw new _("DB_ERROR","Failed to get task",s)}finally{e.close();}}killTask(t){if(!this.dbExists())return {killed:false};let e=this.openHandle(true);try{let s=e.db.select({id:o.id,status:o.status,pid:o.pid}).from(o).where(eq(o.id,t)).limit(1).get();if(!s||s.status!=="running")return {killed:!1};if(s.pid)try{process.kill(s.pid,"SIGTERM");}catch{}return e.db.update(o).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(and(eq(o.id,t),eq(o.status,"running"))).run(),{killed:!0,pid:s.pid??void 0}}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to kill task",s)}finally{e.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let e=t.db.select({id:o.id,pid:o.pid}).from(o).where(eq(o.status,"running")).all(),s=0;for(let n of e){if(!n.pid)continue;let r=!1;try{process.kill(n.pid,0),r=!0;}catch{}r||(t.db.update(o).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(and(eq(o.id,n.id),eq(o.status,"running"))).run(),s++);}return s}finally{t.close();}}findTaskStatus(t,e){let s=this.resolveDbPaths();for(let n of s){if(!existsSync(n))continue;let r=T(n);try{let i=e?eq(o.workspace_id,e):void 0,a=i?and(eq(o.id,t),i):eq(o.id,t),l=r.db.select().from(o).where(a).limit(1).get()??void 0;if(!l){let c=or(eq(o.thread_id,t),and(isNull(o.thread_id),like(o.command,`%--thread=${t}%`))),p=i?and(c,i):c;l=r.db.select().from(o).where(p).orderBy(desc(o.started_at)).limit(1).get()??void 0;}if(l)return l}catch(i){throw new _("DB_ERROR","Failed to find task status",i)}finally{r.close();}}}findChildTasks(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!existsSync(i))continue;let a=T(i);try{let l=e?and(eq(o.parent_task_id,t),eq(o.workspace_id,e)):eq(o.parent_task_id,t),c=a.db.select().from(o).where(l).orderBy(asc(o.started_at)).all();for(let p of c)n.has(p.id)||(n.add(p.id),r.push(p));}catch(l){throw new _("DB_ERROR","Failed to find child tasks",l)}finally{a.close();}}return r}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.all(t?sql`
49
+ WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[t.status,t.result??null,t.error??null,t.completedAt,t.durationMs??null,t.exitCode??null,t.inputTokens??0,t.outputTokens??0,t.cachedInputTokens??0,t.costUsd??0,t.model??null,t.id,s]);}catch(s){throw s instanceof p?s:new p("DB_ERROR","Failed to finish task",s)}finally{n.close();}}appendLog(t,n){let s=this.openHandle(true);try{s.db.transaction(r=>{let i=r.select({logs:e.logs}).from(e).where(eq(e.id,t)).limit(1).get(),a=i?.logs?JSON.parse(i.logs):[];a.push(n),r.update(e).set({logs:JSON.stringify(a)}).where(eq(e.id,t)).run();},{behavior:"immediate"});}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to append log",r)}finally{s.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(e).where(eq(e.status,"running")).orderBy(desc(e.started_at)).all()}catch(n){throw new p("DB_ERROR","Failed to get running tasks",n)}finally{t.close();}}getAllTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(e).orderBy(desc(e.started_at)).limit(100).all()}catch(n){throw new p("DB_ERROR","Failed to get all tasks",n)}finally{t.close();}}getTask(t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(e).where(eq(e.id,t)).limit(1).get()??void 0}catch(s){throw new p("DB_ERROR","Failed to get task",s)}finally{n.close();}}killTask(t){if(!this.dbExists())return {killed:false};let n=this.openHandle(true);try{let s=n.db.select({id:e.id,status:e.status,pid:e.pid}).from(e).where(eq(e.id,t)).limit(1).get();if(!s||s.status!=="running")return {killed:!1};if(s.pid)try{process.kill(s.pid,"SIGTERM");}catch{}return n.db.update(e).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(and(eq(e.id,t),eq(e.status,"running"))).run(),{killed:!0,pid:s.pid??void 0}}catch(s){throw s instanceof p?s:new p("DB_ERROR","Failed to kill task",s)}finally{n.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let n=t.db.select({id:e.id,pid:e.pid,platform:e.platform,run_epoch:e.run_epoch}).from(e).where(eq(e.status,"running")).all(),s=Date.now(),r=new Set,i=0;for(let a of n){if(a.pid){let c=!1;try{process.kill(a.pid,0),c=!0;}catch{}c||(t.db.update(e).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(and(eq(e.id,a.id),eq(e.status,"running"))).run(),i++);continue}if(an.has(a.platform??"cli"))continue;let d=`${a.id}:${a.run_epoch??0}`;r.add(d);let u=this.pidNullObservedSince.get(d);if(u===void 0){this.pidNullObservedSince.set(d,s);continue}s-u>=ee&&(t.db.update(e).set({status:"failed",error:"Reaped: pid never recorded after resume (stale running_instruction)",completed_at:new Date().toISOString()}).where(and(eq(e.id,a.id),eq(e.status,"running"))).run(),i++,this.pidNullObservedSince.delete(d));}for(let a of Array.from(this.pidNullObservedSince.keys()))r.has(a)||this.pidNullObservedSince.delete(a);return i}finally{t.close();}}reapRunningWorkflowTasks(t=ee){if(!this.dbExists())return 0;let n=this.openHandle(true);try{let s=new Date(Date.now()-t).toISOString();return n.db.update(e).set({status:"failed",error:"Reaped: stale workflow run (finally not executed)",completed_at:new Date().toISOString()}).where(and(eq(e.status,"running"),eq(e.platform,"workflow"),isNull(e.pid),lt(e.started_at,s),or(isNull(e.metadata),and(notLike(e.metadata,'%"kind":"workflow_card"%'),notLike(e.metadata,'%"kind":"workflow_ui_instance"%'))))).run().changes??0}finally{n.close();}}findTaskStatus(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let i=y(r);try{let a=n?eq(e.workspace_id,n):void 0,d=a?and(eq(e.id,t),a):eq(e.id,t),u=i.db.select().from(e).where(d).limit(1).get()??void 0;if(!u){let c=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),l=a?and(c,a):c;u=i.db.select().from(e).where(l).orderBy(desc(e.started_at)).limit(1).get()??void 0;}if(u)return u}catch(a){throw new p("DB_ERROR","Failed to find task status",a)}finally{i.close();}}}findChildTasks(t,n){let s=this.resolveDbPaths(),r=new Set,i=[];for(let a of s){if(!existsSync(a))continue;let d=y(a);try{let u=n?and(eq(e.parent_task_id,t),eq(e.workspace_id,n)):eq(e.parent_task_id,t),c=d.db.select().from(e).where(u).orderBy(asc(e.started_at)).all();for(let l of c)r.has(l.id)||(r.add(l.id),i.push(l));}catch(u){throw new p("DB_ERROR","Failed to find child tasks",u)}finally{d.close();}}return i}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(t?sql`
17
50
  SELECT
18
51
  COALESCE(workspace_id, 'unknown') AS workspace_id,
19
52
  COALESCE(SUM(input_tokens), 0) AS input_tokens,
@@ -34,7 +67,7 @@ ${s.join(`
34
67
  FROM tasks
35
68
  GROUP BY workspace_id
36
69
  ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
37
- `)}catch(s){throw new _("DB_ERROR","Failed to get workspace usage summary",s)}finally{e.close();}}getThreadTokenUsage(t,e){let s=this.resolveDbPaths(),n=new Set,r=0,i=0,a=0;for(let l of s){if(!existsSync(l))continue;let c=T(l);try{let p=or(eq(o.thread_id,t),and(isNull(o.thread_id),like(o.command,`%--thread=${t}%`))),k=e?and(p,eq(o.workspace_id,e)):p,E=c.db.select({id:o.id,input_tokens:o.input_tokens,output_tokens:o.output_tokens,cost_usd:o.cost_usd}).from(o).where(k).all();for(let R of E)n.has(R.id)||(n.add(R.id),r+=R.input_tokens??0,i+=R.output_tokens??0,a+=R.cost_usd??0);}catch(p){throw new _("DB_ERROR","Failed to get thread token usage",p)}finally{c.close();}}return {inputTokens:r,outputTokens:i,costUsd:a}}findTasksByThread(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!existsSync(i))continue;let a=T(i);try{let l=or(eq(o.thread_id,t),and(isNull(o.thread_id),like(o.command,`%--thread=${t}%`))),c=e?and(l,eq(o.workspace_id,e)):l,p=a.db.select().from(o).where(c).orderBy(asc(o.started_at)).all();for(let k of p)n.has(k.id)||(n.add(k.id),r.push(k));}catch(l){throw new _("DB_ERROR","Failed to find tasks by thread",l)}finally{a.close();}}return r}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(o.workspace_id,t.workspaceId));let n=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;n&&s.push(inArray(o.agent_id,n));let r=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;r&&s.push(inArray(o.status,r));let i=t.q??t.search;i&&s.push(like(o.prompt,`%${i}%`)),t.from&&s.push(gte(o.started_at,t.from)),t.to&&s.push(lt(o.started_at,t.to));let a=s.length>0?and(...s):void 0,l=e.db.select({count:sql`count(*)`}).from(o).where(a).get(),c=(t.sortDir??"DESC")==="ASC"?asc(o.started_at):desc(o.started_at);return {rows:e.db.select().from(o).where(a).orderBy(c).limit(t.limit).offset(t.offset).all(),total:l?.count??0}}catch(s){throw new _("DB_ERROR","Failed to find all tasks",s)}finally{e.close();}}getAgentUsage(t,e,s){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(s?sql`
70
+ `)}catch(s){throw new p("DB_ERROR","Failed to get workspace usage summary",s)}finally{n.close();}}getThreadTokenUsage(t,n){let s=this.resolveDbPaths(),r=new Set,i=0,a=0,d=0;for(let u of s){if(!existsSync(u))continue;let c=y(u);try{let l=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),h=n?and(l,eq(e.workspace_id,n)):l,m=c.db.select({id:e.id,input_tokens:e.input_tokens,output_tokens:e.output_tokens,cost_usd:e.cost_usd}).from(e).where(h).all();for(let w of m)r.has(w.id)||(r.add(w.id),i+=w.input_tokens??0,a+=w.output_tokens??0,d+=w.cost_usd??0);}catch(l){throw new p("DB_ERROR","Failed to get thread token usage",l)}finally{c.close();}}return {inputTokens:i,outputTokens:a,costUsd:d}}findTasksByThread(t,n){let s=this.resolveDbPaths(),r=new Set,i=[];for(let a of s){if(!existsSync(a))continue;let d=y(a);try{let u=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),c=n?and(u,eq(e.workspace_id,n)):u,l=d.db.select().from(e).where(c).orderBy(asc(e.started_at)).all();for(let h of l)r.has(h.id)||(r.add(h.id),i.push(h));}catch(u){throw new p("DB_ERROR","Failed to find tasks by thread",u)}finally{d.close();}}return i}parseWorkflowCardMetadata(t){if(!t)return {};try{let n=JSON.parse(t);return {kind:typeof n.kind=="string"?n.kind:void 0,workflowRunId:typeof n.workflowRunId=="string"?n.workflowRunId:void 0}}catch{return {}}}extractThreadIdFromCommand(t){return t?/--thread=(\S+)/.exec(t)?.[1]??null:null}findRunningWorkflowParentTasks(){if(!this.dbExists())return [];let t=[];for(let n of this.resolveDbPaths()){if(!existsSync(n))continue;let s=y(n);try{t.push(...s.db.select({id:e.id,agent_id:e.agent_id,thread_id:e.thread_id,workspace_id:e.workspace_id,platform:e.platform,status:e.status,error:e.error,completed_at:e.completed_at,duration_ms:e.duration_ms,started_at:e.started_at,metadata:e.metadata}).from(e).where(and(eq(e.platform,"workflow"),or(like(e.metadata,'%"kind":"workflow_card"%'),like(e.metadata,'%"kind":"workflow_ui_instance"%')))).orderBy(desc(e.started_at)).all());}catch(r){throw new p("DB_ERROR","Failed to find workflow parent tasks",r)}finally{s.close();}}return t}batchFetchWorkflowCards(t,n){let s=new Map;if(t.length===0)return s;let r=new Set(t),i=new Map,a=n?eq(e.workspace_id,n):void 0,d=(u,c)=>{if(!u)return;let l=i.get(u);if(l&&c.started_at<=l)return;let h=this.parseWorkflowCardMetadata(c.metadata);h.kind!=="workflow_card"&&h.kind!=="workflow_ui_instance"||(i.set(u,c.started_at),s.set(u,{taskId:c.id,workflowRunId:h.workflowRunId,raw:c.result??void 0}));};for(let u of this.resolveDbPaths()){if(!existsSync(u))continue;let c=y(u);try{let l=and(inArray(e.thread_id,t),or(like(e.metadata,'%"kind":"workflow_card"%'),like(e.metadata,'%"kind":"workflow_ui_instance"%'))),h=c.db.select({id:e.id,thread_id:e.thread_id,metadata:e.metadata,result:e.result,started_at:e.started_at}).from(e).where(a?and(l,a):l).all();for(let $ of h)d($.thread_id,$);let m=and(isNull(e.thread_id),or(like(e.metadata,'%"kind":"workflow_card"%'),like(e.metadata,'%"kind":"workflow_ui_instance"%'))),w=c.db.select({id:e.id,command:e.command,metadata:e.metadata,result:e.result,started_at:e.started_at}).from(e).where(a?and(m,a):m).all();for(let $ of w){let v=this.extractThreadIdFromCommand($.command);!v||!r.has(v)||d(v,$);}}catch(l){throw new p("DB_ERROR","Failed to batch fetch workflow cards",l)}finally{c.close();}}return s}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let n=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(e.workspace_id,t.workspaceId));let r=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;r&&s.push(inArray(e.agent_id,r));let i=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;i&&s.push(inArray(e.status,i));let a=t.q??t.search;a&&s.push(like(e.prompt,`%${a}%`)),t.from&&s.push(gte(e.started_at,t.from)),t.to&&s.push(lt(e.started_at,t.to));let d=s.length>0?and(...s):void 0,u=n.db.select({count:sql`count(*)`}).from(e).where(d).get(),c=(t.sortDir??"DESC")==="ASC"?asc(e.started_at):desc(e.started_at);return {rows:n.db.select().from(e).where(d).orderBy(c).limit(t.limit).offset(t.offset).all(),total:u?.count??0}}catch(s){throw new p("DB_ERROR","Failed to find all tasks",s)}finally{n.close();}}getAgentUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(s?sql`
38
71
  SELECT
39
72
  t.agent_id,
40
73
  t.workspace_id,
@@ -42,11 +75,11 @@ ${s.join(`
42
75
  COALESCE(SUM(
43
76
  COALESCE(t.input_tokens, 0)
44
77
  + CASE
45
- WHEN t.started_at >= ${F}
78
+ WHEN t.started_at >= ${tt}
46
79
  AND (
47
80
  t.crewx_version IS NULL
48
81
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
49
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${H}) AS INTEGER) < ${z})
82
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${et}) AS INTEGER) < ${nt})
50
83
  )
51
84
  THEN COALESCE(t.cached_input_tokens, 0)
52
85
  ELSE 0
@@ -58,18 +91,18 @@ ${s.join(`
58
91
  FROM tasks t
59
92
  WHERE t.status IN ('completed', 'success')
60
93
  AND t.started_at >= ${t}
61
- AND t.started_at < ${e}
94
+ AND t.started_at < ${n}
62
95
  AND t.workspace_id = ${s}
63
96
  GROUP BY t.agent_id, t.workspace_id
64
97
  ORDER BY (
65
98
  COALESCE(SUM(
66
99
  COALESCE(t.input_tokens, 0)
67
100
  + CASE
68
- WHEN t.started_at >= ${F}
101
+ WHEN t.started_at >= ${tt}
69
102
  AND (
70
103
  t.crewx_version IS NULL
71
104
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
72
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${H}) AS INTEGER) < ${z})
105
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${et}) AS INTEGER) < ${nt})
73
106
  )
74
107
  THEN COALESCE(t.cached_input_tokens, 0)
75
108
  ELSE 0
@@ -85,11 +118,11 @@ ${s.join(`
85
118
  COALESCE(SUM(
86
119
  COALESCE(t.input_tokens, 0)
87
120
  + CASE
88
- WHEN t.started_at >= ${F}
121
+ WHEN t.started_at >= ${tt}
89
122
  AND (
90
123
  t.crewx_version IS NULL
91
124
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
92
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${H}) AS INTEGER) < ${z})
125
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${et}) AS INTEGER) < ${nt})
93
126
  )
94
127
  THEN COALESCE(t.cached_input_tokens, 0)
95
128
  ELSE 0
@@ -101,17 +134,17 @@ ${s.join(`
101
134
  FROM tasks t
102
135
  WHERE t.status IN ('completed', 'success')
103
136
  AND t.started_at >= ${t}
104
- AND t.started_at < ${e}
137
+ AND t.started_at < ${n}
105
138
  GROUP BY t.agent_id, t.workspace_id
106
139
  ORDER BY (
107
140
  COALESCE(SUM(
108
141
  COALESCE(t.input_tokens, 0)
109
142
  + CASE
110
- WHEN t.started_at >= ${F}
143
+ WHEN t.started_at >= ${tt}
111
144
  AND (
112
145
  t.crewx_version IS NULL
113
146
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
114
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${H}) AS INTEGER) < ${z})
147
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${et}) AS INTEGER) < ${nt})
115
148
  )
116
149
  THEN COALESCE(t.cached_input_tokens, 0)
117
150
  ELSE 0
@@ -119,18 +152,18 @@ ${s.join(`
119
152
  ), 0)
120
153
  + COALESCE(SUM(t.output_tokens), 0)
121
154
  ) DESC
122
- `).map(i=>({agentId:i.agent_id,workspaceId:i.workspace_id??null,totalTasks:i.total_tasks,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd,totalTokens:i.input_tokens+i.output_tokens}))}catch(r){throw new _("DB_ERROR","Failed to get agent usage",r)}finally{n.close();}}getAgentUsageTrendRaw(t,e,s){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(s?sql`
155
+ `).map(a=>({agentId:a.agent_id,workspaceId:a.workspace_id??null,totalTasks:a.total_tasks,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd,totalTokens:a.input_tokens+a.output_tokens}))}catch(i){throw new p("DB_ERROR","Failed to get agent usage",i)}finally{r.close();}}getAgentUsageTrendRaw(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(s?sql`
123
156
  SELECT
124
157
  date(t.started_at) AS date,
125
158
  t.agent_id,
126
159
  COALESCE(SUM(
127
160
  COALESCE(t.input_tokens, 0)
128
161
  + CASE
129
- WHEN t.started_at >= ${F}
162
+ WHEN t.started_at >= ${tt}
130
163
  AND (
131
164
  t.crewx_version IS NULL
132
165
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
133
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${H}) AS INTEGER) < ${z})
166
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${et}) AS INTEGER) < ${nt})
134
167
  )
135
168
  THEN COALESCE(t.cached_input_tokens, 0)
136
169
  ELSE 0
@@ -142,7 +175,7 @@ ${s.join(`
142
175
  FROM tasks t
143
176
  WHERE t.status IN ('completed', 'success')
144
177
  AND t.started_at >= ${t}
145
- AND t.started_at < ${e}
178
+ AND t.started_at < ${n}
146
179
  AND t.workspace_id = ${s}
147
180
  GROUP BY date(t.started_at), t.agent_id
148
181
  ORDER BY date(t.started_at) ASC
@@ -153,11 +186,11 @@ ${s.join(`
153
186
  COALESCE(SUM(
154
187
  COALESCE(t.input_tokens, 0)
155
188
  + CASE
156
- WHEN t.started_at >= ${F}
189
+ WHEN t.started_at >= ${tt}
157
190
  AND (
158
191
  t.crewx_version IS NULL
159
192
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
160
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${H}) AS INTEGER) < ${z})
193
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${et}) AS INTEGER) < ${nt})
161
194
  )
162
195
  THEN COALESCE(t.cached_input_tokens, 0)
163
196
  ELSE 0
@@ -169,54 +202,77 @@ ${s.join(`
169
202
  FROM tasks t
170
203
  WHERE t.status IN ('completed', 'success')
171
204
  AND t.started_at >= ${t}
172
- AND t.started_at < ${e}
205
+ AND t.started_at < ${n}
173
206
  GROUP BY date(t.started_at), t.agent_id
174
207
  ORDER BY date(t.started_at) ASC
175
- `).map(i=>({date:i.date,agentId:i.agent_id,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd,totalTokens:i.input_tokens+i.output_tokens}))}catch(r){throw new _("DB_ERROR","Failed to get agent usage trend",r)}finally{n.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let s=this.openHandle(false);try{return s.db.select().from(o).where(and(eq(o.id,t),eq(o.workspace_id,e))).limit(1).get()??void 0}catch(n){throw new _("DB_ERROR","Failed to find task for stop",n)}finally{s.close();}}markTaskFailed(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString(),i=s?and(eq(o.id,t),eq(o.status,"running"),eq(o.workspace_id,s)):and(eq(o.id,t),eq(o.status,"running"));n.db.update(o).set({status:"failed",error:e,completed_at:r}).where(i).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to mark task failed",r)}finally{n.close();}}findTasksByPromptHint(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!existsSync(i))continue;let a=T(i);try{let l=e?and(like(o.prompt,`%${t}%`),eq(o.workspace_id,e)):like(o.prompt,`%${t}%`),c=a.db.select().from(o).where(l).orderBy(asc(o.started_at)).all();for(let p of c)n.has(p.id)||(n.add(p.id),r.push(p));}catch(l){throw new _("DB_ERROR","Failed to find tasks by prompt hint",l)}finally{a.close();}}return r}getProviderUsage(t,e,s){if(!this.dbExists())return [];let n=this.openHandle(false);try{let r=sql`
176
- CASE
177
- WHEN ${o.model} LIKE 'claude-%' OR ${o.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
178
- WHEN ${o.model} LIKE 'gpt-%' OR ${o.model} LIKE 'codex-%' THEN 'codex'
179
- WHEN ${o.model} LIKE 'gemini-%' THEN 'gemini'
180
- WHEN ${o.model} LIKE 'zai-%' OR ${o.model} LIKE 'openrouter/z-ai/%' THEN 'opencode'
181
- WHEN ${o.model} LIKE 'minimax/%' THEN 'minimax'
182
- WHEN ${o.model} LIKE 'qwen%' THEN 'qwen'
183
- ELSE 'unknown'
184
- END
185
- `,i=sql`
186
- COALESCE(${o.input_tokens}, 0)
208
+ `).map(a=>({date:a.date,agentId:a.agent_id,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd,totalTokens:a.input_tokens+a.output_tokens}))}catch(i){throw new p("DB_ERROR","Failed to get agent usage trend",i)}finally{r.close();}}findTaskForStop(t,n){if(!this.dbExists())return;let s=this.openHandle(false);try{return s.db.select().from(e).where(and(eq(e.id,t),eq(e.workspace_id,n))).limit(1).get()??void 0}catch(r){throw new p("DB_ERROR","Failed to find task for stop",r)}finally{s.close();}}findLatestTaskByMetadata(t){if(!this.dbExists())return null;let n=this.openHandle(false);try{return n.db.select({id:e.id,thread_id:e.thread_id,status:e.status,result:e.result,error:e.error,started_at:e.started_at,completed_at:e.completed_at,metadata:e.metadata}).from(e).where(and(eq(e.agent_id,t.agentId),eq(e.workspace_id,t.workspaceId),sql`${e.metadata} IS NOT NULL AND json_valid(${e.metadata}) AND json_extract(${e.metadata}, '$.' || ${t.metaKey}) = ${t.metaValue}`)).orderBy(desc(e.started_at)).limit(1).get()??null}catch(s){throw new p("DB_ERROR","Failed to find latest task by metadata",s)}finally{n.close();}}markTaskFailed(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let i=new Date().toISOString(),a=s?and(eq(e.id,t),eq(e.status,"running"),eq(e.workspace_id,s)):and(eq(e.id,t),eq(e.status,"running"));r.db.update(e).set({status:"failed",error:n,completed_at:i}).where(a).run();}catch(i){throw i instanceof p?i:new p("DB_ERROR","Failed to mark task failed",i)}finally{r.close();}}findTasksByPromptHint(t,n){let s=this.resolveDbPaths(),r=new Set,i=[];for(let a of s){if(!existsSync(a))continue;let d=y(a);try{let u=n?and(like(e.prompt,`%${t}%`),eq(e.workspace_id,n)):like(e.prompt,`%${t}%`),c=d.db.select().from(e).where(u).orderBy(asc(e.started_at)).all();for(let l of c)r.has(l.id)||(r.add(l.id),i.push(l));}catch(u){throw new p("DB_ERROR","Failed to find tasks by prompt hint",u)}finally{d.close();}}return i}getProviderUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let i=te(),a=sql`
209
+ COALESCE(${e.input_tokens}, 0)
187
210
  + CASE
188
- WHEN ${o.started_at} >= ${F}
211
+ WHEN ${e.started_at} >= ${tt}
189
212
  AND (
190
- ${o.crewx_version} IS NULL
191
- OR (${o.crewx_version} LIKE '0.8.%' AND ${o.crewx_version} NOT LIKE '0.8.9%')
192
- OR (${o.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${o.crewx_version}, ${H}) AS INTEGER) < ${z})
213
+ ${e.crewx_version} IS NULL
214
+ OR (${e.crewx_version} LIKE '0.8.%' AND ${e.crewx_version} NOT LIKE '0.8.9%')
215
+ OR (${e.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${e.crewx_version}, ${et}) AS INTEGER) < ${nt})
193
216
  )
194
- THEN COALESCE(${o.cached_input_tokens}, 0)
217
+ THEN COALESCE(${e.cached_input_tokens}, 0)
195
218
  ELSE 0
196
219
  END
197
- `,a=s?sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e} AND ${o.workspace_id} = ${s}`:sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e}`;return n.db.all(sql`
220
+ `,d=s?sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`;return r.db.all(sql`
198
221
  SELECT
199
- ${r} AS provider,
222
+ ${i} AS provider,
200
223
  COUNT(*) AS total_tasks,
201
- COALESCE(SUM(${i}), 0) AS input_tokens,
202
- COALESCE(SUM(${o.output_tokens}), 0) AS output_tokens,
203
- COALESCE(SUM(${o.cached_input_tokens}), 0) AS cached_input_tokens,
204
- COALESCE(SUM(${o.cost_usd}), 0) AS cost_usd,
205
- COALESCE(SUM(${o.duration_ms}), 0) AS active_duration_ms,
206
- MAX(${o.completed_at}) AS last_active_at
207
- FROM ${o}
208
- ${a}
209
- GROUP BY provider
210
- ORDER BY (COALESCE(SUM(${i}), 0) + COALESCE(SUM(${o.output_tokens}), 0)) DESC
211
- `).map(c=>({provider:c.provider,totalTasks:c.total_tasks,inputTokens:c.input_tokens,outputTokens:c.output_tokens,cachedInputTokens:c.cached_input_tokens,costUsd:c.cost_usd,totalTokens:c.input_tokens+c.output_tokens,activeDurationMs:c.active_duration_ms??0,lastActiveAt:c.last_active_at??null}))}catch(r){throw new _("DB_ERROR","Failed to get provider usage",r)}finally{n.close();}}};var _t=class extends ${name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=join(t?.dbRoot??homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let e=new st({dbPath:this.dbPath}),s=process.cwd(),r=existsSync(join(s,"crewx.yaml"))||existsSync(join(s,"crewx.yml"))?kt(s):null,i=process.argv.join(" ");this.unsubs.push(t.on("task:start",a=>{try{let l=a.callerAgentId??null,c=a.parentTaskId??null,p=a.rootTraceId??a.traceId,k=a.metadata?JSON.stringify(a.metadata):JSON.stringify({provider:a.provider??"cli/claude"});e.startTask({id:a.traceId,agentId:a.agentRef.replace(/^@/,""),prompt:a.message,mode:a.mode,status:"running",pid:a.pid??null,startedAt:a.timestamp.toISOString(),crewxVersion:this.version,platform:a.platform??"cli",model:a.model??null,renderedPrompt:a.renderedPrompt??null,command:i,codingAgentCommand:a.codingAgentCommand??null,workspaceId:a.workspaceId??r,callerAgentId:l,parentTaskId:c,traceId:p,metadata:k,threadId:a.threadId??null});}catch{}}),t.on("task:output",a=>{try{e.appendLog(a.traceId,{timestamp:a.timestamp.toISOString(),level:a.level??"stdout",message:a.output});}catch{}}),t.on("task:end",a=>{try{let l=typeof a.metadata?.runEpoch=="number"?a.metadata.runEpoch:null;e.finishTask({id:a.traceId,status:a.error?"failed":"success",result:a.result??null,error:a.error?JSON.stringify(a.error):null,completedAt:a.timestamp.toISOString(),durationMs:a.durationMs,exitCode:a.exitCode??null,inputTokens:a.inputTokens??0,outputTokens:a.outputTokens??0,cachedInputTokens:a.cachedInputTokens??0,costUsd:a.costUsd??0,model:a.model??null,runEpoch:l});}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[];}};var nt=class extends q{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=dirname(e);existsSync(n)||mkdirSync(n,{recursive:true});}else if(!existsSync(e))throw new _("NOT_FOUND","Database not found");let s=T(e);if(t)try{J(s.db,e);}catch(n){throw s.close(),n}return s}validateWorkspaceId(t,e){return t.db.select({id:W.id}).from(W).where(eq(W.id,e)).limit(1).get()?e:null}topLevelTaskPredicateSql(t="child"){return sql.raw(`(
212
- ${t}.parent_task_id IS NULL
213
- OR ${t}.parent_task_id = ''
214
- OR NOT EXISTS (
215
- SELECT 1 FROM tasks parent
216
- WHERE parent.id = ${t}.parent_task_id
217
- AND parent.thread_id = ${t}.thread_id
218
- )
219
- )`)}findAllThreads(t){let e=this.resolveDbPaths(),s=new Set,n=[];for(let r of e){if(!existsSync(r))continue;let i=T(r);try{let a=t?eq(u.workspace_id,t):void 0,l=i.db.select().from(u).where(a).orderBy(desc(u.updated_at)).all();for(let c of l)s.has(c.id)||(s.add(c.id),n.push(c));}catch(a){throw new _("DB_ERROR","Failed to find all threads",a)}finally{i.close();}}return n}findThreadById(t,e){let s=this.resolveDbPaths();for(let n of s){if(!existsSync(n))continue;let r=T(n);try{let i=eq(u.id,t),a=e?and(i,eq(u.workspace_id,e)):i,l=r.db.select().from(u).where(a).limit(1).get()??void 0;if(l)return l}catch(i){throw new _("DB_ERROR","Failed to find thread by id",i)}finally{r.close();}}}threadExists(t,e){let s=this.resolveDbPaths();for(let n of s){if(!existsSync(n))continue;let r=T(n);try{let i=eq(u.id,t),a=e?and(i,eq(u.workspace_id,e)):i;if(r.db.select({id:u.id}).from(u).where(a).limit(1).get())return !0}catch(i){throw new _("DB_ERROR","Failed to check thread existence",i)}finally{r.close();}}return false}aggregateTaskStats(t,e){let s=this.resolveDbPaths(),n=0,r=0,i=0,a=0,l=0,c=new Set;for(let p of s){if(!existsSync(p))continue;let k=T(p);try{let E=k.db.get(sql`
224
+ COALESCE(SUM(${a}), 0) AS input_tokens,
225
+ COALESCE(SUM(${e.output_tokens}), 0) AS output_tokens,
226
+ COALESCE(SUM(${e.cached_input_tokens}), 0) AS cached_input_tokens,
227
+ COALESCE(SUM(${e.cost_usd}), 0) AS cost_usd,
228
+ COALESCE(SUM(${e.duration_ms}), 0) AS active_duration_ms,
229
+ MAX(${e.completed_at}) AS last_active_at
230
+ FROM ${e}
231
+ ${d}
232
+ GROUP BY ${i}
233
+ ORDER BY (COALESCE(SUM(${a}), 0) + COALESCE(SUM(${e.output_tokens}), 0)) DESC
234
+ `).map(c=>({provider:c.provider,totalTasks:c.total_tasks,inputTokens:c.input_tokens,outputTokens:c.output_tokens,cachedInputTokens:c.cached_input_tokens,costUsd:c.cost_usd,totalTokens:c.input_tokens+c.output_tokens,activeDurationMs:c.active_duration_ms??0,lastActiveAt:c.last_active_at??null}))}catch(i){throw new p("DB_ERROR","Failed to get provider usage",i)}finally{r.close();}}getModelUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let i=te(),a=sql`
235
+ COALESCE(${e.input_tokens}, 0)
236
+ + CASE
237
+ WHEN ${e.started_at} >= ${tt}
238
+ AND (
239
+ ${e.crewx_version} IS NULL
240
+ OR (${e.crewx_version} LIKE '0.8.%' AND ${e.crewx_version} NOT LIKE '0.8.9%')
241
+ OR (${e.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${e.crewx_version}, ${et}) AS INTEGER) < ${nt})
242
+ )
243
+ THEN COALESCE(${e.cached_input_tokens}, 0)
244
+ ELSE 0
245
+ END
246
+ `,d=s?sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`,u=r.db.all(sql`
247
+ SELECT
248
+ ${e.model} AS model,
249
+ ${i} AS provider,
250
+ COUNT(*) AS total_tasks,
251
+ COALESCE(SUM(${a}), 0) AS input_tokens,
252
+ COALESCE(SUM(${e.output_tokens}), 0) AS output_tokens,
253
+ COALESCE(SUM(${e.cached_input_tokens}), 0) AS cached_input_tokens,
254
+ COALESCE(SUM(${e.cost_usd}), 0) AS cost_usd,
255
+ COALESCE(SUM(${e.duration_ms}), 0) AS active_duration_ms,
256
+ MAX(${e.completed_at}) AS last_active_at
257
+ FROM ${e}
258
+ ${d}
259
+ GROUP BY ${e.model}, ${i}
260
+ `),c=new Map;for(let l of u){let h=Zt(l.model??""),m=JSON.stringify([l.provider,h]),w=c.get(m);w?(w.totalTasks+=l.total_tasks,w.inputTokens+=l.input_tokens,w.outputTokens+=l.output_tokens,w.cachedInputTokens+=l.cached_input_tokens,w.costUsd+=l.cost_usd,w.totalTokens+=l.input_tokens+l.output_tokens,w.activeDurationMs+=l.active_duration_ms??0,l.last_active_at&&(!w.lastActiveAt||l.last_active_at>w.lastActiveAt)&&(w.lastActiveAt=l.last_active_at)):c.set(m,{model:h,provider:l.provider,totalTasks:l.total_tasks,inputTokens:l.input_tokens,outputTokens:l.output_tokens,cachedInputTokens:l.cached_input_tokens,costUsd:l.cost_usd,totalTokens:l.input_tokens+l.output_tokens,activeDurationMs:l.active_duration_ms??0,lastActiveAt:l.last_active_at??null});}return Array.from(c.values()).sort((l,h)=>h.costUsd-l.costUsd)}catch(i){throw new p("DB_ERROR","Failed to get model usage",i)}finally{r.close();}}getTasksForReport(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let i=s?sql`WHERE ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`;return r.db.all(sql`
261
+ SELECT
262
+ ${e.thread_id} AS thread_id,
263
+ ${e.agent_id} AS agent_id,
264
+ ${e.started_at} AS started_at,
265
+ ${e.status} AS status,
266
+ ${e.error} AS error,
267
+ ${e.exit_code} AS exit_code
268
+ FROM ${e}
269
+ ${i}
270
+ ORDER BY ${e.started_at} ASC
271
+ `).map(d=>({threadId:d.thread_id,agentId:d.agent_id,startedAt:d.started_at,status:d.status,error:d.error,exitCode:d.exit_code}))}catch(i){throw new p("DB_ERROR","Failed to get tasks for report",i)}finally{r.close();}}findTaskEvidence(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(e.workspace_id,t.workspaceId)),t.agents&&t.agents.length>0&&s.push(inArray(e.agent_id,t.agents)),t.statuses&&t.statuses.length>0&&s.push(inArray(e.status,t.statuses)),t.from&&s.push(gte(e.started_at,t.from)),t.to&&s.push(lt(e.started_at,t.to));let r=s.length>0?and(...s):void 0,i=(t.order??"DESC")==="ASC"?asc(e.started_at):desc(e.started_at),a={id:e.id,agent_id:e.agent_id,status:e.status,prompt:e.prompt,started_at:e.started_at,completed_at:e.completed_at,thread_id:e.thread_id};return t.limit?n.db.select(a).from(e).where(r).orderBy(i).limit(t.limit).all():n.db.select(a).from(e).where(r).orderBy(i).all()}catch(s){throw new p("DB_ERROR","Failed to find task evidence",s)}finally{n.close();}}findThreadChains(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let s=t.maxThreads??8,r=t.maxTurnsPerThread??4,i=[isNotNull(e.thread_id),isNull(e.parent_task_id),isNull(e.caller_agent_id),or(isNull(e.platform),ne(e.platform,"workflow")),or(isNull(e.metadata),and(notLike(e.metadata,'%"kind":"workflow_card"%'),notLike(e.metadata,'%"kind":"workflow_ui_instance"%'))),or(isNull(e.metadata),notLike(e.metadata,'%"retriedFromTaskId"%'))];t.workspaceId&&i.push(eq(e.workspace_id,t.workspaceId)),t.from&&i.push(gte(e.started_at,t.from)),t.to&&i.push(lt(e.started_at,t.to));let a=n.db.select({id:e.id,agent_id:e.agent_id,status:e.status,prompt:e.prompt,started_at:e.started_at,completed_at:e.completed_at,thread_id:e.thread_id}).from(e).where(and(...i)).orderBy(asc(e.started_at),asc(e.id)).all(),d=new Map;for(let c of a){if(!c.thread_id)continue;let l={id:c.id,agentId:c.agent_id,status:c.status,prompt:c.prompt,startedAt:c.started_at,completedAt:c.completed_at},h=d.get(c.thread_id);h?h.push(l):d.set(c.thread_id,[l]);}let u=[];for(let[c,l]of d){let h=l.filter(m=>m.agentId===t.targetAgentId).length;h<2||u.push({threadId:c,targetAgentTurnCount:h,turns:l});}return u.sort((c,l)=>{let h=c.turns[c.turns.length-1].startedAt,m=l.turns[l.turns.length-1].startedAt;return h<m?1:h>m?-1:0}),u.slice(0,s).map(c=>({threadId:c.threadId,targetAgentTurnCount:c.targetAgentTurnCount,turns:c.turns.slice(-r)}))}catch(s){throw new p("DB_ERROR","Failed to find thread chains",s)}finally{n.close();}}};var Lt=class extends Q{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=join(t?.dbRoot??homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let n=new xt({dbPath:this.dbPath}),s=process.cwd(),i=existsSync(join(s,"crewx.yaml"))||existsSync(join(s,"crewx.yml"))?qt(s):null,a=process.argv.join(" ");this.unsubs.push(t.on("task:start",d=>{try{let u=d.callerAgentId??null,c=d.parentTaskId??null,l=d.rootTraceId??d.traceId,h=d.metadata?JSON.stringify(d.metadata):JSON.stringify({provider:d.provider??"cli/claude"});n.startTask({id:d.traceId,agentId:d.agentRef.replace(/^@/,""),prompt:d.message,mode:d.mode,status:"running",pid:d.pid??null,startedAt:d.timestamp.toISOString(),crewxVersion:this.version,platform:d.platform??"cli",model:d.model??null,renderedPrompt:d.renderedPrompt??null,command:a,codingAgentCommand:d.codingAgentCommand??null,workspaceId:d.workspaceId??i,callerAgentId:u,parentTaskId:c,traceId:l,metadata:h,threadId:d.threadId??null});}catch{}}),t.on("task:output",d=>{try{n.appendLog(d.traceId,{timestamp:d.timestamp.toISOString(),level:d.level??"stdout",message:d.output});}catch{}}),t.on("task:end",d=>{try{let u=typeof d.metadata?.runEpoch=="number"?d.metadata.runEpoch:null,c=d.error?JSON.stringify({code:d.error.code,message:d.error.message,...d.error.providerCode?{providerCode:d.error.providerCode}:{}}):null;n.finishTask({id:d.traceId,status:d.error?"failed":"success",result:d.result??null,error:c,completedAt:d.timestamp.toISOString(),durationMs:d.durationMs,exitCode:d.exitCode??null,inputTokens:d.inputTokens??0,outputTokens:d.outputTokens??0,cachedInputTokens:d.cachedInputTokens??0,costUsd:d.costUsd??0,model:d.model??null,runEpoch:u});}catch{}}));}detach(t){this.unsubs.forEach(n=>n()),this.unsubs=[];}};var bt=class extends dt{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let n=this.resolveDbPath();if(t){let r=dirname(n);existsSync(r)||mkdirSync(r,{recursive:true});}else if(!existsSync(n))throw new p("NOT_FOUND","Database not found");let s=y(n);if(t)try{kt(s.db,n);}catch(r){throw s.close(),r}return s}validateWorkspaceId(t,n){return t.db.select({id:ct.id}).from(ct).where(eq(ct.id,n)).limit(1).get()?n:null}topLevelTaskPredicateSql(t="child"){return sql.raw(`NOT EXISTS (
272
+ SELECT 1 FROM tasks parent
273
+ WHERE parent.id = ${t}.parent_task_id
274
+ AND parent.thread_id = ${t}.thread_id
275
+ )`)}findAllThreads(t){let n=this.resolveDbPaths(),s=new Set,r=[];for(let i of n){if(!existsSync(i))continue;let a=y(i);try{let d=t?eq(_.workspace_id,t):void 0,u=a.db.select().from(_).where(d).orderBy(desc(_.updated_at)).all();for(let c of u)s.has(c.id)||(s.add(c.id),r.push(c));}catch(d){throw new p("DB_ERROR","Failed to find all threads",d)}finally{a.close();}}return r}findThreadsByIdsOrTitles(t,n){if(t.length===0)return [];let s=this.resolveDbPaths(),r=new Set,i=[];for(let a of s){if(!existsSync(a))continue;let d=y(a);try{let u=or(inArray(_.id,t),inArray(_.title,t)),c=n?and(u,eq(_.workspace_id,n)):u,l=d.db.select().from(_).where(c).orderBy(desc(_.updated_at)).all();for(let h of l)r.has(h.id)||(r.add(h.id),i.push(h));}catch(u){throw new p("DB_ERROR","Failed to find threads by ids or titles",u)}finally{d.close();}}return i}findThreadById(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let i=y(r);try{let a=eq(_.id,t),d=n?and(a,eq(_.workspace_id,n)):a,u=i.db.select().from(_).where(d).limit(1).get()??void 0;if(u)return u}catch(a){throw new p("DB_ERROR","Failed to find thread by id",a)}finally{i.close();}}}threadExists(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let i=y(r);try{let a=eq(_.id,t),d=n?and(a,eq(_.workspace_id,n)):a;if(i.db.select({id:_.id}).from(_).where(d).limit(1).get())return !0}catch(a){throw new p("DB_ERROR","Failed to check thread existence",a)}finally{i.close();}}return false}aggregateTaskStats(t,n){let s=this.resolveDbPaths(),r=0,i=0,a=0,d=0,u=0,c=new Set;for(let l of s){if(!existsSync(l))continue;let h=y(l);try{let m=h.db.get(sql`
220
276
  SELECT
221
277
  count(*) AS cnt,
222
278
  COALESCE(SUM(child.input_tokens), 0) AS total_input,
@@ -226,46 +282,50 @@ ${s.join(`
226
282
  FROM tasks child
227
283
  WHERE child.thread_id = ${t}
228
284
  AND ${this.topLevelTaskPredicateSql()}
229
- ${e?sql`AND child.workspace_id = ${e}`:sql``}
230
- `);E&&(n+=E.cnt,r+=E.total_input,i+=E.total_output,a+=E.total_cached,l+=E.total_cost);let R=k.db.all(sql`
285
+ ${n?sql`AND child.workspace_id = ${n}`:sql``}
286
+ `);m&&(r+=m.cnt,i+=m.total_input,a+=m.total_output,d+=m.total_cached,u+=m.total_cost);let w=h.db.all(sql`
231
287
  SELECT DISTINCT child.agent_id FROM tasks child
232
288
  WHERE child.thread_id = ${t}
233
289
  AND child.agent_id IS NOT NULL AND child.agent_id != ''
234
290
  AND ${this.topLevelTaskPredicateSql()}
235
- ${e?sql`AND child.workspace_id = ${e}`:sql``}
236
- `);for(let G of R)c.add(G.agent_id);}catch(E){throw new _("DB_ERROR","Failed to aggregate task stats",E)}finally{k.close();}}return {taskCount:n,inputTokens:r,outputTokens:i,cachedInputTokens:a,costUsd:l,agentIds:Array.from(c)}}findTopLevelTasks(t,e,s){let n=this.resolveDbPaths(),r=new Set,i=[];for(let a of n){if(!existsSync(a))continue;let l=T(a);try{let c;s!==void 0?c=l.db.all(sql`
291
+ ${n?sql`AND child.workspace_id = ${n}`:sql``}
292
+ `);for(let $ of w)c.add($.agent_id);}catch(m){throw new p("DB_ERROR","Failed to aggregate task stats",m)}finally{h.close();}}return {taskCount:r,inputTokens:i,outputTokens:a,cachedInputTokens:d,costUsd:u,agentIds:Array.from(c)}}findTopLevelTasks(t,n,s){let r=this.resolveDbPaths(),i=new Set,a=[];for(let d of r){if(!existsSync(d))continue;let u=y(d);try{let c;s!==void 0?c=u.db.all(sql`
237
293
  SELECT * FROM (
238
294
  SELECT child.*,
239
295
  ROW_NUMBER() OVER (PARTITION BY child.agent_id ORDER BY child.started_at DESC) AS rn
240
296
  FROM tasks child
241
297
  WHERE child.thread_id = ${t}
242
298
  AND ${this.topLevelTaskPredicateSql()}
243
- ${e?sql`AND child.workspace_id = ${e}`:sql``}
299
+ ${n?sql`AND child.workspace_id = ${n}`:sql``}
244
300
  ) ranked
245
301
  WHERE rn <= ${s}
246
302
  ORDER BY started_at ASC
247
- `):c=l.db.all(sql`
303
+ `):c=u.db.all(sql`
248
304
  SELECT child.* FROM tasks child
249
305
  WHERE child.thread_id = ${t}
250
306
  AND ${this.topLevelTaskPredicateSql()}
251
- ${e?sql`AND child.workspace_id = ${e}`:sql``}
307
+ ${n?sql`AND child.workspace_id = ${n}`:sql``}
252
308
  ORDER BY child.started_at ASC
253
- `);for(let p of c)r.has(p.id)||(r.add(p.id),i.push(p));}catch(c){throw new _("DB_ERROR","Failed to find top-level tasks",c)}finally{l.close();}}if(s!==void 0&&n.length>1){let a=new Map;for(let l of i){let c=l.agent_id??"";a.has(c)||a.set(c,[]),a.get(c).push(l);}i=[];for(let l of a.values())l.sort((c,p)=>(p.started_at??"").localeCompare(c.started_at??"")),i.push(...l.slice(0,s));i.sort((l,c)=>(l.started_at??"").localeCompare(c.started_at??""));}return i}findAllTasks(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!existsSync(i))continue;let a=T(i);try{let l=eq(o.thread_id,t),c=e?and(l,eq(o.workspace_id,e)):l,p=a.db.select().from(o).where(c).orderBy(asc(o.started_at)).all();for(let k of p)n.has(k.id)||(n.add(k.id),r.push(k));}catch(l){throw new _("DB_ERROR","Failed to find all tasks for thread",l)}finally{a.close();}}return r}findTaskById(t,e,s){let n=this.resolveDbPaths();for(let r of n){if(!existsSync(r))continue;let i=T(r);try{let a=and(eq(o.id,e),eq(o.thread_id,t)),l=s?and(a,eq(o.workspace_id,s)):a,c=i.db.select().from(o).where(l).limit(1).get();if(!c)continue;let p=i.db.select().from(o).where(eq(o.parent_task_id,c.id)).orderBy(asc(o.started_at)).all();return {task:c,children:p}}catch(a){throw new _("DB_ERROR","Failed to find task by id",a)}finally{i.close();}}}batchFetchTasks(t,e){let s=new Map;if(t.length===0)return s;let n=this.resolveDbPaths();for(let r of n){if(!existsSync(r))continue;let i=T(r);try{let a=i.db.all(sql`
254
- SELECT child.* FROM tasks child
255
- WHERE child.thread_id IN (${sql.join(t.map(l=>sql`${l}`),sql`, `)})
256
- AND ${this.topLevelTaskPredicateSql()}
257
- ${e?sql`AND child.workspace_id = ${e}`:sql``}
258
- ORDER BY child.started_at ASC
259
- `);for(let l of a){let c=l.thread_id;s.has(c)||s.set(c,[]),s.get(c).push(l);}}catch(a){throw new _("DB_ERROR","Failed to batch fetch tasks",a)}finally{i.close();}}return s}updateThreadTitle(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=eq(u.id,t),i=s?and(r,eq(u.workspace_id,s)):r;if(!n.db.select({id:u.id}).from(u).where(i).limit(1).get())return;n.db.update(u).set({title:e,title_locked:1,updated_at:new Date().toISOString()}).where(eq(u.id,t)).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to update thread title",r)}finally{n.close();}}upsertThread(t,e){let s=this.openHandle(true);try{let n=e.workspaceId?this.validateWorkspaceId(s,e.workspaceId):null,r=new Date().toISOString();if(s.db.select({id:u.id,message_count:u.message_count}).from(u).where(eq(u.id,t)).limit(1).get()){let a={updated_at:r};e.title!==void 0&&(a.title=e.title),e.titleLocked!==void 0&&(a.title_locked=e.titleLocked?1:0),s.db.update(u).set(a).where(eq(u.id,t)).run();}else s.db.insert(u).values({id:t,platform:e.platform,workspace_id:n,title:e.title??null,title_locked:e.titleLocked?1:0,message_count:0,created_at:r,updated_at:r}).run();}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to upsert thread",n)}finally{s.close();}}ensureThread(t,e,s){let n=this.openHandle(true);try{let r=s?this.validateWorkspaceId(n,s):null,i=n.db.select({id:u.id,platform:u.platform,workspace_id:u.workspace_id}).from(u).where(eq(u.id,t)).limit(1).get();if(i){r&&!i.workspace_id&&n.db.update(u).set({workspace_id:r}).where(eq(u.id,t)).run();return}let a=new Date().toISOString();n.db.insert(u).values({id:t,platform:e,workspace_id:r,message_count:0,created_at:a,updated_at:a}).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to ensure thread",r)}finally{n.close();}}saveUserMessage(t,e,s){if(!this.dbExists())return {firstMessage:false};let n=this.openHandle(true);try{let r=new Date().toISOString();return {firstMessage:n.db.transaction(a=>{let c=a.select({message_count:u.message_count}).from(u).where(eq(u.id,t)).limit(1).get()?.message_count===0;return a.run(sql`
309
+ `);for(let l of c)i.has(l.id)||(i.add(l.id),a.push(l));}catch(c){throw new p("DB_ERROR","Failed to find top-level tasks",c)}finally{u.close();}}if(s!==void 0&&r.length>1){let d=new Map;for(let u of a){let c=u.agent_id??"";d.has(c)||d.set(c,[]),d.get(c).push(u);}a=[];for(let u of d.values())u.sort((c,l)=>(l.started_at??"").localeCompare(c.started_at??"")),a.push(...u.slice(0,s));a.sort((u,c)=>(u.started_at??"").localeCompare(c.started_at??""));}return a}findAllTasks(t,n){let s=this.resolveDbPaths(),r=new Set,i=[];for(let a of s){if(!existsSync(a))continue;let d=y(a);try{let u=eq(e.thread_id,t),c=n?and(u,eq(e.workspace_id,n)):u,l=d.db.select().from(e).where(c).orderBy(asc(e.started_at)).all();for(let h of l)r.has(h.id)||(r.add(h.id),i.push(h));}catch(u){throw new p("DB_ERROR","Failed to find all tasks for thread",u)}finally{d.close();}}return i}findTaskById(t,n,s){let r=this.resolveDbPaths();for(let i of r){if(!existsSync(i))continue;let a=y(i);try{let d=and(eq(e.id,n),eq(e.thread_id,t)),u=s?and(d,eq(e.workspace_id,s)):d,c=a.db.select().from(e).where(u).limit(1).get();if(!c)continue;let l=a.db.select().from(e).where(eq(e.parent_task_id,c.id)).orderBy(asc(e.started_at)).all();return {task:c,children:l}}catch(d){throw new p("DB_ERROR","Failed to find task by id",d)}finally{a.close();}}}batchFetchTasksQuery(t,n){return sql`
310
+ SELECT child.id, child.thread_id, child.agent_id, child.status,
311
+ child.parent_task_id, child.started_at, child.completed_at,
312
+ child.duration_ms, child.input_tokens, child.output_tokens,
313
+ child.cost_usd, child.error
314
+ FROM tasks child INDEXED BY idx_tasks_thread_id
315
+ WHERE child.thread_id IN (${sql.join(t.map(s=>sql`${s}`),sql`, `)})
316
+ AND ${this.topLevelTaskPredicateSql()}
317
+ ${n?sql`AND child.workspace_id = ${n}`:sql``}
318
+ ORDER BY child.started_at ASC
319
+ `}batchFetchTasks(t,n){let s=new Map;if(t.length===0)return s;let r=this.resolveDbPaths();for(let i of r){if(!existsSync(i))continue;let a=y(i);try{let d=a.db.all(this.batchFetchTasksQuery(t,n));for(let u of d){let c=u.thread_id;s.has(c)||s.set(c,[]),s.get(c).push(u);}}catch(d){throw new p("DB_ERROR","Failed to batch fetch tasks",d)}finally{a.close();}}return s}explainBatchFetchTasksPlan(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let i=y(r);try{return i.db.all(sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(t,n)}`).map(d=>d.detail)}finally{i.close();}}return []}updateThreadTitle(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let i=eq(_.id,t),a=s?and(i,eq(_.workspace_id,s)):i;if(!r.db.select({id:_.id}).from(_).where(a).limit(1).get())return;r.db.update(_).set({title:n,title_locked:1,updated_at:new Date().toISOString()}).where(eq(_.id,t)).run();}catch(i){throw i instanceof p?i:new p("DB_ERROR","Failed to update thread title",i)}finally{r.close();}}upsertThread(t,n){let s=this.openHandle(true);try{let r=n.workspaceId?this.validateWorkspaceId(s,n.workspaceId):null,i=new Date().toISOString();if(s.db.select({id:_.id,message_count:_.message_count}).from(_).where(eq(_.id,t)).limit(1).get()){let d={updated_at:i};n.title!==void 0&&(d.title=n.title),n.titleLocked!==void 0&&(d.title_locked=n.titleLocked?1:0),s.db.update(_).set(d).where(eq(_.id,t)).run();}else s.db.insert(_).values({id:t,platform:n.platform,workspace_id:r,title:n.title??null,title_locked:n.titleLocked?1:0,message_count:0,created_at:i,updated_at:i}).run();}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to upsert thread",r)}finally{s.close();}}ensureThread(t,n,s){let r=this.openHandle(true);try{let i=s?this.validateWorkspaceId(r,s):null,a=r.db.select({id:_.id,platform:_.platform,workspace_id:_.workspace_id}).from(_).where(eq(_.id,t)).limit(1).get();if(a){i&&!a.workspace_id&&r.db.update(_).set({workspace_id:i}).where(eq(_.id,t)).run();return}let d=new Date().toISOString();r.db.insert(_).values({id:t,platform:n,workspace_id:i,message_count:0,created_at:d,updated_at:d}).run();}catch(i){throw i instanceof p?i:new p("DB_ERROR","Failed to ensure thread",i)}finally{r.close();}}saveUserMessage(t,n,s){if(!this.dbExists())return {firstMessage:false};let r=this.openHandle(true);try{let i=new Date().toISOString();return {firstMessage:r.db.transaction(d=>{let c=d.select({message_count:_.message_count}).from(_).where(eq(_.id,t)).limit(1).get()?.message_count===0;return d.run(sql`
260
320
  UPDATE threads
261
- SET first_message = COALESCE(first_message, ${e}),
262
- title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${e}, 1, 60) ELSE title END,
263
- last_message = ${e},
321
+ SET first_message = COALESCE(first_message, ${n}),
322
+ title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${n}, 1, 60) ELSE title END,
323
+ last_message = ${n},
264
324
  message_count = message_count + 1,
265
- updated_at = ${r}
325
+ updated_at = ${i}
266
326
  WHERE id = ${t}
267
- `),c},{behavior:"immediate"})}}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to save user message",r)}finally{n.close();}}saveAssistantMessage(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString();n.db.update(u).set({last_message:e,updated_at:r}).where(eq(u.id,t)).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to save assistant message",r)}finally{n.close();}}updateThread(t,e){if(!this.dbExists())return;let s=this.openHandle(true);try{let n={updated_at:new Date().toISOString()};e.title!==void 0&&(n.title=e.title,n.title_locked=1),e.titleLocked!==void 0&&(n.title_locked=e.titleLocked?1:0),s.db.update(u).set(n).where(eq(u.id,t)).run();}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to update thread",n)}finally{s.close();}}togglePin(t,e){let s=this.openHandle(true);try{let n=e?and(eq(u.id,t),eq(u.workspace_id,e)):eq(u.id,t),r=s.db.select({pinned:u.pinned,metadata:u.metadata}).from(u).where(n).get();if(!r)return null;let i=r.pinned?0:1,a=r.metadata?JSON.parse(r.metadata):{};if(i){let l=e?and(eq(u.pinned,1),eq(u.workspace_id,e)):eq(u.pinned,1),c=s.db.select({metadata:u.metadata}).from(u).where(l).all(),p=0;for(let k of c){let E=k.metadata?JSON.parse(k.metadata):{};typeof E.pinOrder=="number"&&E.pinOrder>p&&(p=E.pinOrder);}a.pinOrder=p+1;}else delete a.pinOrder;return s.db.update(u).set({pinned:i,metadata:Object.keys(a).length>0?JSON.stringify(a):null}).where(n).run(),{pinned:!!i}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to toggle pin",n)}finally{s.close();}}reorderPins(t,e){let s=this.openHandle(true);try{for(let n=0;n<t.length;n++){let r=e?and(eq(u.id,t[n]),eq(u.workspace_id,e)):eq(u.id,t[n]),i=s.db.select({metadata:u.metadata}).from(u).where(r).get();if(!i)continue;let a=i.metadata?JSON.parse(i.metadata):{};a.pinOrder=n+1,s.db.update(u).set({metadata:JSON.stringify(a)}).where(r).run();}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to reorder pins",n)}finally{s.close();}}toggleStar(t,e){let s=this.openHandle(true);try{let n=e?and(eq(u.id,t),eq(u.workspace_id,e)):eq(u.id,t),r=s.db.select({starred:u.starred}).from(u).where(n).get();if(!r)return null;let i=r.starred?0:1;return s.db.update(u).set({starred:i}).where(n).run(),{starred:!!i}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to toggle star",n)}finally{s.close();}}};function ye(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
268
- `).filter(n=>!(n.startsWith("Loaded ")&&n.includes("layouts from")||n.includes("[dotenv@")||n.includes("[Nest]")&&n.includes("DEBUG")||n.startsWith("Registered custom layout:")||n.startsWith("Updated custom layout:"))).join(`
269
- `).trim()}function xe(d){if(!d)return "";let t=d;try{let e=JSON.parse(t);Array.isArray(e)?t=e.filter(s=>s?.type==="text"&&s?.text).map(s=>s.text).join(`
270
- `):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=ye(t);}return t}var rt=class{dbPath;constructor(t){this.dbPath=t??join(homedir(),".crewx","crewx.db");}getThreadRepo(){return new nt({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,s){let n=this.getThreadRepo(),r=n.findThreadById(t);if(r){if(r.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${r.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return {created:false}}return n.ensureThread(t,e,s),{created:true}}async fetchHistory(t,e){let s=e?.limit??100,n=this.getThreadRepo(),r=n.findThreadById(t),i=n.findTopLevelTasks(t,void 0,s),a=new Set(["queued","cancelled"]);i=i.filter(p=>(!p.status||!a.has(p.status))&&(!e?.currentTraceId||p.trace_id!==e.currentTraceId));let l=r?.platform??"cli",c=this.rowsToMessages(i);return {threadId:t,platform:l,messages:c,metadata:{title:r?.title??void 0,firstMessage:r?.first_message??void 0,lastMessage:r?.last_message??void 0,messageCount:r?.message_count??0,updatedAt:r?.updated_at?new Date(r.updated_at).getTime():void 0}}}async saveUserMessage(t,e,s,n){let{firstMessage:r}=this.getThreadRepo().saveUserMessage(t,e);return {id:t,firstMessage:r}}async saveAssistantMessage(t,e,s,n){return this.getThreadRepo().saveAssistantMessage(t,e),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let e=[];for(let s of t){s.prompt&&e.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime(),metadata:{caller_agent_id:s.caller_agent_id}});let n=xe(s.result),r=this.normalizeStatus(s.status);if(n||r==="running"||r==="failed"){let i={agent_id:s.agent_id,task_id:s.id};r&&(i.status=r),r==="failed"&&s.error&&(i.reason=s.error.split(`
271
- `)[0].slice(0,200)),e.push({id:`${s.id}-assistant`,text:n,isAssistant:true,timestamp:new Date(s.started_at).getTime(),metadata:i});}}return e}};var pt=class extends ${name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new rt(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,e,s,n){}async afterAssistantMessage(t,e,s){}attach(t){this.unsubStart=t.on("task:start",async e=>{if(!e.threadId)return;let s=e.platform??"cli";try{let n=await this._provider.ensureThread(e.threadId,s,e.workspaceId),r=await this._provider.saveUserMessage(e.threadId,e.message??"");await this.afterUserMessage(e.threadId,r.id,n.created||r.firstMessage,e);}catch{}}),this.unsubEnd=t.on("task:end",async e=>{if(!e.result)return;let s=e.metadata?.threadId;if(!s)return;let n=e.agentRef?.replace(/^@/,"")??"";try{let{id:r}=await this._provider.saveAssistantMessage(s,e.result,n);await this.afterAssistantMessage(s,r,e);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{pt as ConversationPlugin,ot as FileLoggerPlugin,_t as SqliteTracingPlugin};
327
+ `),c},{behavior:"immediate"})}}catch(i){throw i instanceof p?i:new p("DB_ERROR","Failed to save user message",i)}finally{r.close();}}saveAssistantMessage(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let i=new Date().toISOString();r.db.update(_).set({last_message:n,updated_at:i}).where(eq(_.id,t)).run();}catch(i){throw i instanceof p?i:new p("DB_ERROR","Failed to save assistant message",i)}finally{r.close();}}updateThread(t,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let r={updated_at:new Date().toISOString()};n.title!==void 0&&(r.title=n.title,r.title_locked=1),n.titleLocked!==void 0&&(r.title_locked=n.titleLocked?1:0),s.db.update(_).set(r).where(eq(_.id,t)).run();}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to update thread",r)}finally{s.close();}}togglePin(t,n){let s=this.openHandle(true);try{let r=n?and(eq(_.id,t),eq(_.workspace_id,n)):eq(_.id,t),i=s.db.select({pinned:_.pinned,metadata:_.metadata}).from(_).where(r).get();if(!i)return null;let a=i.pinned?0:1,d=i.metadata?JSON.parse(i.metadata):{};if(a){let u=n?and(eq(_.pinned,1),eq(_.workspace_id,n)):eq(_.pinned,1),c=s.db.select({metadata:_.metadata}).from(_).where(u).all(),l=null;for(let h of c){let m=h.metadata?JSON.parse(h.metadata):{};typeof m.pinOrder=="number"&&(l===null||m.pinOrder<l)&&(l=m.pinOrder);}d.pinOrder=l===null?0:l-1;}else delete d.pinOrder;return s.db.update(_).set({pinned:a,metadata:Object.keys(d).length>0?JSON.stringify(d):null}).where(r).run(),{pinned:!!a}}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to toggle pin",r)}finally{s.close();}}reorderPins(t,n){let s=this.openHandle(true);try{for(let r=0;r<t.length;r++){let i=n?and(eq(_.id,t[r]),eq(_.workspace_id,n)):eq(_.id,t[r]),a=s.db.select({metadata:_.metadata}).from(_).where(i).get();if(!a)continue;let d=a.metadata?JSON.parse(a.metadata):{};d.pinOrder=r+1,s.db.update(_).set({metadata:JSON.stringify(d)}).where(i).run();}}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to reorder pins",r)}finally{s.close();}}toggleStar(t,n){let s=this.openHandle(true);try{let r=n?and(eq(_.id,t),eq(_.workspace_id,n)):eq(_.id,t),i=s.db.select({starred:_.starred}).from(_).where(r).get();if(!i)return null;let a=i.starred?0:1;return s.db.update(_).set({starred:a}).where(r).run(),{starred:!!a}}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to toggle star",r)}finally{s.close();}}resolveOverdriveForRequest(t,n,s,r){let a=this.openHandle(true);try{let d=n?and(eq(_.id,t),eq(_.workspace_id,n)):eq(_.id,t);return a.db.transaction(c=>{let l=c.select({metadata:_.metadata}).from(_).where(d).get();if(!l)return null;let h=l.metadata?JSON.parse(l.metadata):{},m=h.overdrive??{},w=r?.defaultTurns??m.defaultTurns??3,$=r?.updatedBy??"ui",v=new Date().toISOString(),B,j,G,ut;switch(s){case "enable-count":{let lt=r?.turns??w,_t=r?.consumeCurrent?Math.max(lt-1,0):lt;B=_t>0?"count":"off",j=_t,G=!0,ut="count";break}case "enable-latch":{B="latch",j=0,G=!0,ut="latch";break}case "disable":{B="off",j=0,G=!1;break}default:{let lt=m.state??"off",_t=typeof m.remaining=="number"?m.remaining:0;if(lt==="count"&&_t>0){let Mt=_t-1;Mt<=0?(B="off",j=0):(B="count",j=Mt),G=!0,ut="count";}else lt==="latch"?(B="latch",j=0,G=!0,ut="latch"):(B="off",j=0,G=!1);break}}return h.overdrive={state:B,remaining:j,defaultTurns:w,updatedAt:v,updatedBy:$},c.update(_).set({metadata:JSON.stringify(h),updated_at:v}).where(d).run(),{applied:G,appliedMode:ut,state:B,remaining:j}},{behavior:"immediate"})}catch(d){throw d instanceof p?d:new p("DB_ERROR","Failed to resolve overdrive",d)}finally{a.close();}}};function fn(o){return o.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
328
+ `).filter(r=>!(r.startsWith("Loaded ")&&r.includes("layouts from")||r.includes("[dotenv@")||r.includes("[Nest]")&&r.includes("DEBUG")||r.startsWith("Registered custom layout:")||r.startsWith("Updated custom layout:"))).join(`
329
+ `).trim()}function gn(o){if(!o)return "";let t=o;try{let n=JSON.parse(t);Array.isArray(n)?t=n.filter(s=>s?.type==="text"&&s?.text).map(s=>s.text).join(`
330
+ `):n&&typeof n=="object"&&n.result!==void 0&&(t=n.result||"");}catch{t=fn(t);}return t}var At=class{dbPath;constructor(t){this.dbPath=t??join(homedir(),".crewx","crewx.db");}getThreadRepo(){return new bt({dbPath:this.dbPath})}updateThread(t,n){this.getThreadRepo().updateThread(t,{title:n.title});}async ensureThread(t,n,s){let r=this.getThreadRepo(),i=r.findThreadById(t);if(i){if(i.platform!==n)throw new Error(`Thread '${t}' already exists with platform '${i.platform}' \u2014 cannot change to '${n}' (platform is immutable)`);return {created:false}}return r.ensureThread(t,n,s),{created:true}}async fetchHistory(t,n){let s=n?.limit??100,r=this.getThreadRepo(),i=r.findThreadById(t),a=r.findTopLevelTasks(t,void 0,s),d=new Set(["queued","cancelled"]);a=a.filter(l=>(!l.status||!d.has(l.status))&&(!n?.currentTraceId||l.trace_id!==n.currentTraceId));let u=i?.platform??"cli",c=this.rowsToMessages(a);return {threadId:t,platform:u,messages:c,metadata:{title:i?.title??void 0,firstMessage:i?.first_message??void 0,lastMessage:i?.last_message??void 0,messageCount:i?.message_count??0,updatedAt:i?.updated_at?new Date(i.updated_at).getTime():void 0}}}async saveUserMessage(t,n,s,r){let{firstMessage:i}=this.getThreadRepo().saveUserMessage(t,n);return {id:t,firstMessage:i}}async saveAssistantMessage(t,n,s,r){return this.getThreadRepo().saveAssistantMessage(t,n),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let n=[];for(let s of t){s.prompt&&n.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime(),metadata:{caller_agent_id:s.caller_agent_id}});let r=gn(s.result),i=this.normalizeStatus(s.status);if(r||i==="running"||i==="failed"){let a={agent_id:s.agent_id,task_id:s.id};i&&(a.status=i),i==="failed"&&s.error&&(a.reason=s.error.split(`
331
+ `)[0].slice(0,200)),n.push({id:`${s.id}-assistant`,text:r,isAssistant:true,timestamp:new Date(s.started_at).getTime(),metadata:a});}}return n}};var Pt=class extends Q{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new At(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,n,s,r){}async afterAssistantMessage(t,n,s){}attach(t){this.unsubStart=t.on("task:start",async n=>{if(!n.threadId)return;let s=n.platform??"cli";try{let r=await this._provider.ensureThread(n.threadId,s,n.workspaceId),i=await this._provider.saveUserMessage(n.threadId,n.message??"");await this.afterUserMessage(n.threadId,i.id,r.created||i.firstMessage,n);}catch{}}),this.unsubEnd=t.on("task:end",async n=>{if(!n.result)return;let s=n.metadata?.threadId;if(!s)return;let r=n.agentRef?.replace(/^@/,"")??"";try{let{id:i}=await this._provider.saveAssistantMessage(s,n.result,r);await this.afterAssistantMessage(s,i,n);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{Pt as ConversationPlugin,Ct as FileLoggerPlugin,Lt as SqliteTracingPlugin};