@crewx/sdk 0.9.0-rc.65 → 0.9.0-rc.67

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.
@@ -1,47 +1,54 @@
1
- 'use strict';var Ye=require('fs'),gt=require('path'),Nn=require('os'),drizzleOrm=require('drizzle-orm'),crypto=require('crypto'),sqliteCore=require('drizzle-orm/sqlite-core');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var Ye__default=/*#__PURE__*/_interopDefault(Ye);var gt__namespace=/*#__PURE__*/_interopNamespace(gt);var Nn__default=/*#__PURE__*/_interopDefault(Nn);var Kt=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});var T=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:gt.join(Nn__default.default.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(t){return t instanceof Error&&/no such table:/i.test(t.message)}dbExists(t){return Ye.existsSync(t??this.resolveDbPath())}};var d=class extends Error{code;cause;constructor(t,e,n){super(e),this.name="RepositoryError",this.code=t,this.cause=n,Object.setPrototypeOf(this,new.target.prototype);}};function w(i){let t=Kt("better-sqlite3"),{drizzle:e}=Kt("drizzle-orm/better-sqlite3"),n=new t(i);return n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),n.exec("PRAGMA analysis_limit = 400"),n.exec("PRAGMA optimize"),{db:e(n),runRaw:(r,o=[])=>n.prepare(r).run(...o),close:()=>n.close()}}var Te=new Set,vn={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 re(i,t){return (i.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function An(i,t){if(t>0||!re(i,"tasks"))return;let e=i.all("PRAGMA table_info(tasks)"),n=new Set(e.map(r=>r.name));for(let[r,o]of Object.entries(vn))n.has(r)||i.run(`ALTER TABLE tasks ADD COLUMN ${r} ${o}`);}var In={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"},"0015_panoramic_gorilla_man":{project_id:"TEXT",workspace_id:"TEXT"}};function Pn(i,t,e){if(!re(i,"__drizzle_migrations")||!re(i,"tasks"))return;let n=i.all(e`SELECT hash FROM __drizzle_migrations`),r=new Set(n.map(a=>a.hash)),o=JSON.parse(Ye.readFileSync(gt__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let a of o.entries){let c=In[a.tag];if(!c)continue;let u=gt__namespace.default.join(t,`${a.tag}.sql`);if(!Ye.existsSync(u))continue;let l=Ye.readFileSync(u,"utf-8"),p=crypto.createHash("sha256").update(l).digest("hex");if(r.has(p))continue;let h=i.all("PRAGMA table_info(tasks)"),f=new Set(h.map(m=>m.name));for(let[m,M]of Object.entries(c))f.has(m)||(i.run(`ALTER TABLE tasks ADD COLUMN ${m} ${M}`),f.add(m));}}function On(i,t,e){let n=i.all(e`SELECT hash FROM __drizzle_migrations`),r=new Set(n.map(a=>a.hash)),o=JSON.parse(Ye.readFileSync(gt__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let a of o.entries){let c=gt__namespace.default.join(t,`${a.tag}.sql`);if(!Ye.existsSync(c))continue;let u=Ye.readFileSync(c,"utf-8"),l=crypto.createHash("sha256").update(u).digest("hex");if(r.has(l))continue;let p=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,h=[],f;for(;(f=p.exec(u))!==null;)h.push({table:f[1],column:f[2]});if(h.length===0||!u.split(/-->\s*statement-breakpoint/).map(F=>F.trim()).filter(Boolean).every(F=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(F)))continue;h.every(({table:F,column:K})=>i.all(`PRAGMA table_info("${F}")`).some(st=>st.name===K))&&i.run(e`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${a.when})`);}}function Pt(i){let{migrate:t}=Kt("drizzle-orm/better-sqlite3/migrator"),{sql:e}=Kt("drizzle-orm"),n=[gt__namespace.default.join(__dirname,"../migrations"),gt__namespace.default.join(__dirname,"migrations"),gt__namespace.default.join(__dirname,"../../../../drizzle/migrations"),gt__namespace.default.join(process.cwd(),"drizzle/migrations")],r=n.find(l=>Ye.existsSync(gt__namespace.default.join(l,"meta/_journal.json")));if(!r)throw new Error(`migrations folder not found. Searched:
1
+ 'use strict';var mn=require('fs'),ye=require('path'),_r=require('os'),drizzleOrm=require('drizzle-orm'),crypto=require('crypto'),sqliteCore=require('drizzle-orm/sqlite-core');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var mn__namespace=/*#__PURE__*/_interopNamespace(mn);var ye__namespace=/*#__PURE__*/_interopNamespace(ye);var _r__default=/*#__PURE__*/_interopDefault(_r);var Be=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var x=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:ye.join(_r__default.default.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(e){return e instanceof Error&&/no such table:/i.test(e.message)}dbExists(e){return mn.existsSync(e??this.resolveDbPath())}};var d=class extends Error{code;cause;constructor(e,t,n){super(t),this.name="RepositoryError",this.code=e,this.cause=n,Object.setPrototypeOf(this,new.target.prototype);}};var Ut=r=>{try{return mn__namespace.statSync(`${r}-wal`).size}catch{return 0}},Ht=32*1024*1024;function k(r){let e=Be("better-sqlite3"),{drizzle:t}=Be("drizzle-orm/better-sqlite3"),n=new e(r);return n.exec("PRAGMA journal_mode = WAL"),n.exec(`PRAGMA journal_size_limit = ${Ht}`),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),n.exec("PRAGMA analysis_limit = 400"),n.exec("PRAGMA optimize"),{db:t(n),runRaw:(o,s=[])=>n.prepare(o).run(...s),close:()=>n.close()}}function gr(r,e="TRUNCATE"){if(e!=="PASSIVE"&&e!=="TRUNCATE")throw new Error(`Unsupported journal reclaim mode: ${e}`);let t=Be("better-sqlite3"),n=Ut(r),o;try{o=new t(r),o.pragma("busy_timeout = 1000");let s=o.pragma(`wal_checkpoint(${e})`),a=Ut(r);return {busy:s[0]?.busy===1,walBytesBefore:n,walBytesAfter:a}}finally{o?.close();}}var zt=new Set,fr={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 gt(r,e){return (r.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${e}'`)?.cnt??0)>0}function mr(r,e){if(e>0||!gt(r,"tasks"))return;let t=r.all("PRAGMA table_info(tasks)"),n=new Set(t.map(o=>o.name));for(let[o,s]of Object.entries(fr))n.has(o)||r.run(`ALTER TABLE tasks ADD COLUMN ${o} ${s}`);}var hr={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"},"0015_panoramic_gorilla_man":{project_id:"TEXT",workspace_id:"TEXT"}};function wr(r,e,t){if(!gt(r,"__drizzle_migrations")||!gt(r,"tasks"))return;let n=r.all(t`SELECT hash FROM __drizzle_migrations`),o=new Set(n.map(a=>a.hash)),s=JSON.parse(mn.readFileSync(ye__namespace.default.join(e,"meta/_journal.json"),"utf-8"));for(let a of s.entries){let c=hr[a.tag];if(!c)continue;let u=ye__namespace.default.join(e,`${a.tag}.sql`);if(!mn.existsSync(u))continue;let l=mn.readFileSync(u,"utf-8"),p=crypto.createHash("sha256").update(l).digest("hex");if(o.has(p))continue;let _=r.all("PRAGMA table_info(tasks)"),g=new Set(_.map(m=>m.name));for(let[m,O]of Object.entries(c))g.has(m)||(r.run(`ALTER TABLE tasks ADD COLUMN ${m} ${O}`),g.add(m));}}function kr(r,e,t){let n=r.all(t`SELECT hash FROM __drizzle_migrations`),o=new Set(n.map(a=>a.hash)),s=JSON.parse(mn.readFileSync(ye__namespace.default.join(e,"meta/_journal.json"),"utf-8"));for(let a of s.entries){let c=ye__namespace.default.join(e,`${a.tag}.sql`);if(!mn.existsSync(c))continue;let u=mn.readFileSync(c,"utf-8"),l=crypto.createHash("sha256").update(u).digest("hex");if(o.has(l))continue;let p=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,_=[],g;for(;(g=p.exec(u))!==null;)_.push({table:g[1],column:g[2]});if(_.length===0||!u.split(/-->\s*statement-breakpoint/).map(w=>w.trim()).filter(Boolean).every(w=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(w)))continue;_.every(({table:w,column:j})=>r.all(`PRAGMA table_info("${w}")`).some(W=>W.name===j))&&r.run(t`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${a.when})`);}}function qe(r){let{migrate:e}=Be("drizzle-orm/better-sqlite3/migrator"),{sql:t}=Be("drizzle-orm"),n=[ye__namespace.default.join(__dirname,"../migrations"),ye__namespace.default.join(__dirname,"migrations"),ye__namespace.default.join(__dirname,"../../../../drizzle/migrations"),ye__namespace.default.join(process.cwd(),"drizzle/migrations")],o=n.find(l=>mn.existsSync(ye__namespace.default.join(l,"meta/_journal.json")));if(!o)throw new Error(`migrations folder not found. Searched:
2
2
  ${n.join(`
3
- `)}`);let o=i.get(e`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;o?.cnt&&(a=i.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),An(i,a),o?.cnt&&(On(i,r,e),Pn(i,r,e)),t(i,{migrationsFolder:r});let u=(i.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-a;if(u>0){let l=o?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${l} (${u} migration${u>1?"s":""} applied).`);}}function A(i,t){Te.has(t)||(Pt(i),Te.add(t));}var g=sqliteCore.sqliteTable("workspaces",{id:sqliteCore.text("id").primaryKey(),slug:sqliteCore.text("slug").notNull().unique(),name:sqliteCore.text("name").notNull(),workspace_path:sqliteCore.text("workspace_path"),description:sqliteCore.text("description"),is_active:sqliteCore.integer("is_active").notNull().default(1),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()});var s=sqliteCore.sqliteTable("tasks",{id:sqliteCore.text("id").primaryKey(),agent_id:sqliteCore.text("agent_id").notNull(),user_id:sqliteCore.text("user_id"),prompt:sqliteCore.text("prompt").notNull(),mode:sqliteCore.text("mode").notNull().default("execute"),status:sqliteCore.text("status").notNull().default("running"),result:sqliteCore.text("result"),error:sqliteCore.text("error"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),metadata:sqliteCore.text("metadata"),workspace_id:sqliteCore.text("workspace_id"),trace_id:sqliteCore.text("trace_id"),parent_task_id:sqliteCore.text("parent_task_id"),caller_agent_id:sqliteCore.text("caller_agent_id"),model:sqliteCore.text("model"),platform:sqliteCore.text("platform").default("cli"),crewx_version:sqliteCore.text("crewx_version"),input_tokens:sqliteCore.integer("input_tokens").default(0),output_tokens:sqliteCore.integer("output_tokens").default(0),cost_usd:sqliteCore.real("cost_usd").default(0),pid:sqliteCore.integer("pid"),rendered_prompt:sqliteCore.text("rendered_prompt"),command:sqliteCore.text("command"),coding_agent_command:sqliteCore.text("coding_agent_command"),exit_code:sqliteCore.integer("exit_code"),logs:sqliteCore.text("logs"),thread_id:sqliteCore.text("thread_id"),workspace_ref:sqliteCore.text("workspace_ref"),project_id:sqliteCore.text("project_id"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0),run_epoch:sqliteCore.integer("run_epoch").default(0)},i=>({idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(i.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(i.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(i.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(i.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(i.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(i.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(i.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(i.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(i.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(i.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(i.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(i.workspace_id,i.started_at)}));var _=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>g.id,{onDelete:"set null"}),platform:sqliteCore.text("platform").notNull().default("cli"),title:sqliteCore.text("title"),first_message:sqliteCore.text("first_message"),last_message:sqliteCore.text("last_message"),message_count:sqliteCore.integer("message_count").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),metadata:sqliteCore.text("metadata"),title_locked:sqliteCore.integer("title_locked").notNull().default(0),pinned:sqliteCore.integer("pinned").notNull().default(0),starred:sqliteCore.integer("starred").notNull().default(0)},i=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(i.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(i.workspace_id),idx_threads_ws_updated:sqliteCore.index("idx_threads_ws_updated").on(i.workspace_id,i.updated_at),idx_threads_title:sqliteCore.index("idx_threads_title").on(i.title)}));var wt=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>s.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>wt.id,{onDelete:"set null"}),name:sqliteCore.text("name").notNull(),kind:sqliteCore.text("kind").notNull().default("internal"),status:sqliteCore.text("status").notNull().default("ok"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),error:sqliteCore.text("error"),attributes:sqliteCore.text("attributes")},i=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(i.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(i.parent_span_id)}));var lt=sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>s.id,{onDelete:"cascade"}),session_id:sqliteCore.text("session_id"),tool_name:sqliteCore.text("tool_name").notNull(),files:sqliteCore.text("files"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),duration_ms:sqliteCore.integer("duration_ms"),timestamp:sqliteCore.text("timestamp").notNull()},i=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(i.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(i.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(i.timestamp)}));var tt=sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>_.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),first_task_id:sqliteCore.text("first_task_id").notNull(),mid_task_id:sqliteCore.text("mid_task_id").notNull(),last_task_id:sqliteCore.text("last_task_id").notNull(),task_count:sqliteCore.integer("task_count").notNull(),summary:sqliteCore.text("summary"),source_tokens:sqliteCore.integer("source_tokens").notNull(),summary_tokens:sqliteCore.integer("summary_tokens"),created_at:sqliteCore.text("created_at").notNull()},i=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(i.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(i.thread_id,i.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(i.thread_id,i.seq)}));var Ot=sqliteCore.sqliteTable("request_logs",{id:sqliteCore.text("id").primaryKey(),path:sqliteCore.text("path").notNull(),method:sqliteCore.text("method").notNull(),status_code:sqliteCore.integer("status_code").notNull(),duration_ms:sqliteCore.integer("duration_ms").notNull(),ip:sqliteCore.text("ip"),request_headers:sqliteCore.text("request_headers"),response_headers:sqliteCore.text("response_headers"),request_body:sqliteCore.text("request_body"),response_body:sqliteCore.text("response_body"),query:sqliteCore.text("query"),user_id:sqliteCore.text("user_id"),project_id:sqliteCore.text("project_id"),partition_key:sqliteCore.text("partition_key").notNull(),timestamp:sqliteCore.text("timestamp").notNull().default(drizzleOrm.sql`(datetime('now'))`),metadata:sqliteCore.text("metadata")},i=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(i.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(i.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(i.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(i.partition_key)}));var B=sqliteCore.sqliteTable("usage_limit_snapshots",{id:sqliteCore.text("id").primaryKey(),provider:sqliteCore.text("provider").notNull(),account_ref:sqliteCore.text("account_ref").notNull().default("default"),limit_window:sqliteCore.text("limit_window").notNull(),bucket_start:sqliteCore.text("bucket_start").notNull(),captured_at:sqliteCore.text("captured_at").notNull(),used_percent:sqliteCore.integer("used_percent").notNull(),remaining_percent:sqliteCore.integer("remaining_percent").notNull(),resets_at:sqliteCore.text("resets_at"),source:sqliteCore.text("source").notNull(),metadata:sqliteCore.text("metadata")},i=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(i.provider,i.account_ref,i.limit_window,i.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(i.limit_window,i.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(i.provider,i.limit_window,i.bucket_start)}));var G=sqliteCore.sqliteTable("usage_reports",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),month:sqliteCore.text("month").notNull(),generated_at:sqliteCore.text("generated_at").notNull(),source_range:sqliteCore.text("source_range").notNull(),tier:sqliteCore.text("tier").notNull(),total_tokens:sqliteCore.integer("total_tokens").notNull(),total_cost_usd:sqliteCore.real("total_cost_usd").notNull(),payload:sqliteCore.text("payload").notNull(),payload_hash:sqliteCore.text("payload_hash"),signature:sqliteCore.text("signature"),signed_at:sqliteCore.text("signed_at"),issuer:sqliteCore.text("issuer")},i=>({uniq_usage_reports_ws_month:sqliteCore.uniqueIndex("uniq_usage_reports_ws_month").on(i.workspace_id,i.month)}));var y=sqliteCore.sqliteTable("notifications",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id"),task_id:sqliteCore.text("task_id"),thread_id:sqliteCore.text("thread_id"),source:sqliteCore.text("source").notNull().default("agent"),level:sqliteCore.text("level").notNull().default("info"),title:sqliteCore.text("title").notNull(),body:sqliteCore.text("body"),target_user_id:sqliteCore.text("target_user_id"),created_at:sqliteCore.text("created_at").notNull(),metadata:sqliteCore.text("metadata")},i=>({idx_notifications_ws_created:sqliteCore.index("idx_notifications_ws_created").on(i.workspace_id,drizzleOrm.sql`${i.created_at} DESC`)})),C=sqliteCore.sqliteTable("notification_reads",{notification_id:sqliteCore.text("notification_id").notNull(),user_id:sqliteCore.text("user_id").notNull(),read_at:sqliteCore.text("read_at").notNull()},i=>({pk:sqliteCore.primaryKey({columns:[i.notification_id,i.user_id]})}));var b=sqliteCore.sqliteTable("agent_suggestions",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id").notNull(),task_id:sqliteCore.text("task_id"),type:sqliteCore.text("type").notNull(),status:sqliteCore.text("status").notNull().default("pending"),payload:sqliteCore.text("payload").notNull(),applied_commit_sha:sqliteCore.text("applied_commit_sha"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},i=>({idx_agent_suggestions_ws_agent:sqliteCore.index("idx_agent_suggestions_ws_agent").on(i.workspace_id,i.agent_id),idx_agent_suggestions_ws_created:sqliteCore.index("idx_agent_suggestions_ws_created").on(i.workspace_id,i.created_at)}));sqliteCore.sqliteTable("ui_instances",{id:sqliteCore.text("id").primaryKey().notNull(),definition_id:sqliteCore.text("definition_id").notNull(),definition_version:sqliteCore.integer("definition_version").notNull(),definition_hash:sqliteCore.text("definition_hash").notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),thread_id:sqliteCore.text("thread_id").notNull(),anchor_task_id:sqliteCore.text("anchor_task_id"),domain_ref_json:sqliteCore.text("domain_ref_json").notNull(),state_json:sqliteCore.text("state_json").notNull(),revision:sqliteCore.integer("revision").notNull().default(0),status:sqliteCore.text("status").notNull().default("active"),granted_capabilities_json:sqliteCore.text("granted_capabilities_json").notNull().default("[]"),created_at:sqliteCore.integer("created_at").notNull(),updated_at:sqliteCore.integer("updated_at").notNull()},i=>({idCheck:sqliteCore.check("ui_instances_id_ck",drizzleOrm.sql`length(${i.id}) BETWEEN 5 AND 128 AND ${i.id} GLOB 'uic_*'`),definitionIdCheck:sqliteCore.check("ui_instances_definition_id_ck",drizzleOrm.sql`length(${i.definition_id}) BETWEEN 1 AND 128`),definitionVersionCheck:sqliteCore.check("ui_instances_definition_version_ck",drizzleOrm.sql`${i.definition_version} >= 1`),definitionHashCheck:sqliteCore.check("ui_instances_definition_hash_ck",drizzleOrm.sql`length(${i.definition_hash}) = 64 AND ${i.definition_hash} NOT GLOB '*[^0-9a-f]*'`),workspaceIdCheck:sqliteCore.check("ui_instances_workspace_id_ck",drizzleOrm.sql`length(${i.workspace_id}) BETWEEN 1 AND 256`),threadIdCheck:sqliteCore.check("ui_instances_thread_id_ck",drizzleOrm.sql`length(${i.thread_id}) BETWEEN 1 AND 256`),domainRefJsonCheck:sqliteCore.check("ui_instances_domain_ref_json_ck",drizzleOrm.sql`json_valid(${i.domain_ref_json}) AND json_type(${i.domain_ref_json}) = 'object'`),stateJsonCheck:sqliteCore.check("ui_instances_state_json_ck",drizzleOrm.sql`json_valid(${i.state_json}) AND json_type(${i.state_json}) = 'object'`),revisionCheck:sqliteCore.check("ui_instances_revision_ck",drizzleOrm.sql`${i.revision} >= 0`),statusCheck:sqliteCore.check("ui_instances_status_ck",drizzleOrm.sql`${i.status} IN ('active', 'completed', 'expired', 'revoked', 'unsupported')`),grantedCapabilitiesJsonCheck:sqliteCore.check("ui_instances_granted_capabilities_json_ck",drizzleOrm.sql`json_valid(${i.granted_capabilities_json}) AND json_type(${i.granted_capabilities_json}) = 'array'`),createdAtCheck:sqliteCore.check("ui_instances_created_at_ck",drizzleOrm.sql`${i.created_at} >= 0`),updatedAtCheck:sqliteCore.check("ui_instances_updated_at_ck",drizzleOrm.sql`${i.updated_at} >= ${i.created_at}`),workspaceThreadIdx:sqliteCore.index("ui_instances_workspace_thread_idx").on(i.workspace_id,i.thread_id)}));sqliteCore.sqliteTable("ui_action_receipts",{id:sqliteCore.text("id").primaryKey().notNull(),instance_id:sqliteCore.text("instance_id").notNull(),request_id:sqliteCore.text("request_id").notNull(),action_id:sqliteCore.text("action_id").notNull(),actor_json:sqliteCore.text("actor_json").notNull(),source:sqliteCore.text("source").notNull(),expected_revision:sqliteCore.integer("expected_revision").notNull(),before_revision:sqliteCore.integer("before_revision").notNull(),after_revision:sqliteCore.integer("after_revision"),status:sqliteCore.text("status").notNull(),outcome:sqliteCore.text("outcome"),input_json:sqliteCore.text("input_json").notNull(),result_json:sqliteCore.text("result_json"),error_code:sqliteCore.text("error_code"),requested_at:sqliteCore.integer("requested_at").notNull(),settled_at:sqliteCore.integer("settled_at")},i=>({idCheck:sqliteCore.check("ui_action_receipts_id_ck",drizzleOrm.sql`length(${i.id}) BETWEEN 5 AND 128`),instanceIdCheck:sqliteCore.check("ui_action_receipts_instance_id_ck",drizzleOrm.sql`length(${i.instance_id}) BETWEEN 1 AND 128`),requestIdCheck:sqliteCore.check("ui_action_receipts_request_id_ck",drizzleOrm.sql`length(${i.request_id}) BETWEEN 1 AND 128`),actionIdCheck:sqliteCore.check("ui_action_receipts_action_id_ck",drizzleOrm.sql`length(${i.action_id}) BETWEEN 1 AND 128`),actorJsonCheck:sqliteCore.check("ui_action_receipts_actor_json_ck",drizzleOrm.sql`json_valid(${i.actor_json}) AND json_type(${i.actor_json}) = 'object'`),sourceCheck:sqliteCore.check("ui_action_receipts_source_ck",drizzleOrm.sql`${i.source} IN ('ui_host', 'cli', 'system')`),expectedRevisionCheck:sqliteCore.check("ui_action_receipts_expected_revision_ck",drizzleOrm.sql`${i.expected_revision} >= 0`),beforeRevisionCheck:sqliteCore.check("ui_action_receipts_before_revision_ck",drizzleOrm.sql`${i.before_revision} >= 0`),afterRevisionCheck:sqliteCore.check("ui_action_receipts_after_revision_ck",drizzleOrm.sql`${i.after_revision} IS NULL OR ${i.after_revision} >= 0`),statusCheck:sqliteCore.check("ui_action_receipts_status_ck",drizzleOrm.sql`${i.status} IN ('requested', 'settled')`),outcomeCheck:sqliteCore.check("ui_action_receipts_outcome_ck",drizzleOrm.sql`${i.outcome} IS NULL OR ${i.outcome} IN ('succeeded', 'rejected', 'failed', 'conflicted', 'expired')`),inputJsonCheck:sqliteCore.check("ui_action_receipts_input_json_ck",drizzleOrm.sql`json_valid(${i.input_json}) AND json_type(${i.input_json}) = 'object'`),resultJsonCheck:sqliteCore.check("ui_action_receipts_result_json_ck",drizzleOrm.sql`${i.result_json} IS NULL OR (json_valid(${i.result_json}) AND json_type(${i.result_json}) = 'object')`),requestedAtCheck:sqliteCore.check("ui_action_receipts_requested_at_ck",drizzleOrm.sql`${i.requested_at} >= 0`),settledAtCheck:sqliteCore.check("ui_action_receipts_settled_at_ck",drizzleOrm.sql`${i.settled_at} IS NULL OR ${i.settled_at} >= ${i.requested_at}`),statusTransitionCheck:sqliteCore.check("ui_action_receipts_status_transition_ck",drizzleOrm.sql`(
4
- (${i.status} = 'requested' AND ${i.after_revision} IS NULL AND ${i.outcome} IS NULL AND ${i.settled_at} IS NULL)
3
+ `)}`);let s=r.get(t`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;s?.cnt&&(a=r.get(t`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),mr(r,a),s?.cnt&&(kr(r,o,t),wr(r,o,t)),e(r,{migrationsFolder:o});let u=(r.get(t`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-a;if(u>0){let l=s?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${l} (${u} migration${u>1?"s":""} applied).`);}}function C(r,e){zt.has(e)||(qe(r),zt.add(e));}var h=sqliteCore.sqliteTable("workspaces",{id:sqliteCore.text("id").primaryKey(),slug:sqliteCore.text("slug").notNull().unique(),name:sqliteCore.text("name").notNull(),workspace_path:sqliteCore.text("workspace_path"),description:sqliteCore.text("description"),is_active:sqliteCore.integer("is_active").notNull().default(1),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()});var i=sqliteCore.sqliteTable("tasks",{id:sqliteCore.text("id").primaryKey(),agent_id:sqliteCore.text("agent_id").notNull(),user_id:sqliteCore.text("user_id"),prompt:sqliteCore.text("prompt").notNull(),mode:sqliteCore.text("mode").notNull().default("execute"),status:sqliteCore.text("status").notNull().default("running"),result:sqliteCore.text("result"),error:sqliteCore.text("error"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),metadata:sqliteCore.text("metadata"),workspace_id:sqliteCore.text("workspace_id"),trace_id:sqliteCore.text("trace_id"),parent_task_id:sqliteCore.text("parent_task_id"),caller_agent_id:sqliteCore.text("caller_agent_id"),model:sqliteCore.text("model"),platform:sqliteCore.text("platform").default("cli"),crewx_version:sqliteCore.text("crewx_version"),input_tokens:sqliteCore.integer("input_tokens").default(0),output_tokens:sqliteCore.integer("output_tokens").default(0),cost_usd:sqliteCore.real("cost_usd").default(0),pid:sqliteCore.integer("pid"),rendered_prompt:sqliteCore.text("rendered_prompt"),command:sqliteCore.text("command"),coding_agent_command:sqliteCore.text("coding_agent_command"),exit_code:sqliteCore.integer("exit_code"),logs:sqliteCore.text("logs"),log_storage:sqliteCore.text("log_storage",{enum:["blob","events"]}).notNull().default("blob"),last_log_seq:sqliteCore.integer("last_log_seq").notNull().default(0),log_revision:sqliteCore.integer("log_revision").notNull().default(0),thread_id:sqliteCore.text("thread_id"),workspace_ref:sqliteCore.text("workspace_ref"),project_id:sqliteCore.text("project_id"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0),run_epoch:sqliteCore.integer("run_epoch").default(0)},r=>({log_storage_check:sqliteCore.check("tasks_log_storage_ck",drizzleOrm.sql`${r.log_storage} IN ('blob', 'events')`),idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(r.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(r.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(r.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(r.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(r.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(r.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(r.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(r.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(r.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(r.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(r.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(r.workspace_id,r.started_at)}));var ue=sqliteCore.sqliteTable("task_log_events",{id:sqliteCore.integer("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>i.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),timestamp:sqliteCore.text("timestamp").notNull(),level:sqliteCore.text("level").notNull(),message:sqliteCore.text("message").notNull()},r=>({taskSeqUnique:sqliteCore.uniqueIndex("task_log_events_task_seq_uq").on(r.task_id,r.seq)}));var f=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>h.id,{onDelete:"set null"}),platform:sqliteCore.text("platform").notNull().default("cli"),title:sqliteCore.text("title"),first_message:sqliteCore.text("first_message"),last_message:sqliteCore.text("last_message"),message_count:sqliteCore.integer("message_count").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),metadata:sqliteCore.text("metadata"),title_locked:sqliteCore.integer("title_locked").notNull().default(0),pinned:sqliteCore.integer("pinned").notNull().default(0),starred:sqliteCore.integer("starred").notNull().default(0)},r=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(r.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(r.workspace_id),idx_threads_ws_updated:sqliteCore.index("idx_threads_ws_updated").on(r.workspace_id,r.updated_at),idx_threads_title:sqliteCore.index("idx_threads_title").on(r.title)}));var Ee=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>i.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>Ee.id,{onDelete:"set null"}),name:sqliteCore.text("name").notNull(),kind:sqliteCore.text("kind").notNull().default("internal"),status:sqliteCore.text("status").notNull().default("ok"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),error:sqliteCore.text("error"),attributes:sqliteCore.text("attributes")},r=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(r.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(r.parent_span_id)}));var pe=sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>i.id,{onDelete:"cascade"}),session_id:sqliteCore.text("session_id"),tool_name:sqliteCore.text("tool_name").notNull(),files:sqliteCore.text("files"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),duration_ms:sqliteCore.integer("duration_ms"),timestamp:sqliteCore.text("timestamp").notNull()},r=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(r.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(r.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(r.timestamp)}));var ne=sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>f.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),first_task_id:sqliteCore.text("first_task_id").notNull(),mid_task_id:sqliteCore.text("mid_task_id").notNull(),last_task_id:sqliteCore.text("last_task_id").notNull(),task_count:sqliteCore.integer("task_count").notNull(),summary:sqliteCore.text("summary"),source_tokens:sqliteCore.integer("source_tokens").notNull(),summary_tokens:sqliteCore.integer("summary_tokens"),created_at:sqliteCore.text("created_at").notNull()},r=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(r.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(r.thread_id,r.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(r.thread_id,r.seq)}));var Me=sqliteCore.sqliteTable("request_logs",{id:sqliteCore.text("id").primaryKey(),path:sqliteCore.text("path").notNull(),method:sqliteCore.text("method").notNull(),status_code:sqliteCore.integer("status_code").notNull(),duration_ms:sqliteCore.integer("duration_ms").notNull(),ip:sqliteCore.text("ip"),request_headers:sqliteCore.text("request_headers"),response_headers:sqliteCore.text("response_headers"),request_body:sqliteCore.text("request_body"),response_body:sqliteCore.text("response_body"),query:sqliteCore.text("query"),user_id:sqliteCore.text("user_id"),project_id:sqliteCore.text("project_id"),partition_key:sqliteCore.text("partition_key").notNull(),timestamp:sqliteCore.text("timestamp").notNull().default(drizzleOrm.sql`(datetime('now'))`),metadata:sqliteCore.text("metadata")},r=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(r.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(r.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(r.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(r.partition_key)}));var U=sqliteCore.sqliteTable("usage_limit_snapshots",{id:sqliteCore.text("id").primaryKey(),provider:sqliteCore.text("provider").notNull(),account_ref:sqliteCore.text("account_ref").notNull().default("default"),limit_window:sqliteCore.text("limit_window").notNull(),bucket_start:sqliteCore.text("bucket_start").notNull(),captured_at:sqliteCore.text("captured_at").notNull(),used_percent:sqliteCore.integer("used_percent").notNull(),remaining_percent:sqliteCore.integer("remaining_percent").notNull(),resets_at:sqliteCore.text("resets_at"),source:sqliteCore.text("source").notNull(),metadata:sqliteCore.text("metadata")},r=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(r.provider,r.account_ref,r.limit_window,r.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(r.limit_window,r.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(r.provider,r.limit_window,r.bucket_start)}));var J=sqliteCore.sqliteTable("usage_reports",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),month:sqliteCore.text("month").notNull(),generated_at:sqliteCore.text("generated_at").notNull(),source_range:sqliteCore.text("source_range").notNull(),tier:sqliteCore.text("tier").notNull(),total_tokens:sqliteCore.integer("total_tokens").notNull(),total_cost_usd:sqliteCore.real("total_cost_usd").notNull(),payload:sqliteCore.text("payload").notNull(),payload_hash:sqliteCore.text("payload_hash"),signature:sqliteCore.text("signature"),signed_at:sqliteCore.text("signed_at"),issuer:sqliteCore.text("issuer")},r=>({uniq_usage_reports_ws_month:sqliteCore.uniqueIndex("uniq_usage_reports_ws_month").on(r.workspace_id,r.month)}));var R=sqliteCore.sqliteTable("notifications",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id"),task_id:sqliteCore.text("task_id"),thread_id:sqliteCore.text("thread_id"),source:sqliteCore.text("source").notNull().default("agent"),level:sqliteCore.text("level").notNull().default("info"),title:sqliteCore.text("title").notNull(),body:sqliteCore.text("body"),target_user_id:sqliteCore.text("target_user_id"),created_at:sqliteCore.text("created_at").notNull(),metadata:sqliteCore.text("metadata")},r=>({idx_notifications_ws_created:sqliteCore.index("idx_notifications_ws_created").on(r.workspace_id,drizzleOrm.sql`${r.created_at} DESC`)})),$=sqliteCore.sqliteTable("notification_reads",{notification_id:sqliteCore.text("notification_id").notNull(),user_id:sqliteCore.text("user_id").notNull(),read_at:sqliteCore.text("read_at").notNull()},r=>({pk:sqliteCore.primaryKey({columns:[r.notification_id,r.user_id]})}));var T=sqliteCore.sqliteTable("agent_suggestions",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id").notNull(),task_id:sqliteCore.text("task_id"),type:sqliteCore.text("type").notNull(),status:sqliteCore.text("status").notNull().default("pending"),payload:sqliteCore.text("payload").notNull(),applied_commit_sha:sqliteCore.text("applied_commit_sha"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},r=>({idx_agent_suggestions_ws_agent:sqliteCore.index("idx_agent_suggestions_ws_agent").on(r.workspace_id,r.agent_id),idx_agent_suggestions_ws_created:sqliteCore.index("idx_agent_suggestions_ws_created").on(r.workspace_id,r.created_at)}));sqliteCore.sqliteTable("ui_instances",{id:sqliteCore.text("id").primaryKey().notNull(),definition_id:sqliteCore.text("definition_id").notNull(),definition_version:sqliteCore.integer("definition_version").notNull(),definition_hash:sqliteCore.text("definition_hash").notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),thread_id:sqliteCore.text("thread_id").notNull(),anchor_task_id:sqliteCore.text("anchor_task_id"),domain_ref_json:sqliteCore.text("domain_ref_json").notNull(),state_json:sqliteCore.text("state_json").notNull(),revision:sqliteCore.integer("revision").notNull().default(0),status:sqliteCore.text("status").notNull().default("active"),granted_capabilities_json:sqliteCore.text("granted_capabilities_json").notNull().default("[]"),created_at:sqliteCore.integer("created_at").notNull(),updated_at:sqliteCore.integer("updated_at").notNull()},r=>({idCheck:sqliteCore.check("ui_instances_id_ck",drizzleOrm.sql`length(${r.id}) BETWEEN 5 AND 128 AND ${r.id} GLOB 'uic_*'`),definitionIdCheck:sqliteCore.check("ui_instances_definition_id_ck",drizzleOrm.sql`length(${r.definition_id}) BETWEEN 1 AND 128`),definitionVersionCheck:sqliteCore.check("ui_instances_definition_version_ck",drizzleOrm.sql`${r.definition_version} >= 1`),definitionHashCheck:sqliteCore.check("ui_instances_definition_hash_ck",drizzleOrm.sql`length(${r.definition_hash}) = 64 AND ${r.definition_hash} NOT GLOB '*[^0-9a-f]*'`),workspaceIdCheck:sqliteCore.check("ui_instances_workspace_id_ck",drizzleOrm.sql`length(${r.workspace_id}) BETWEEN 1 AND 256`),threadIdCheck:sqliteCore.check("ui_instances_thread_id_ck",drizzleOrm.sql`length(${r.thread_id}) BETWEEN 1 AND 256`),domainRefJsonCheck:sqliteCore.check("ui_instances_domain_ref_json_ck",drizzleOrm.sql`json_valid(${r.domain_ref_json}) AND json_type(${r.domain_ref_json}) = 'object'`),stateJsonCheck:sqliteCore.check("ui_instances_state_json_ck",drizzleOrm.sql`json_valid(${r.state_json}) AND json_type(${r.state_json}) = 'object'`),revisionCheck:sqliteCore.check("ui_instances_revision_ck",drizzleOrm.sql`${r.revision} >= 0`),statusCheck:sqliteCore.check("ui_instances_status_ck",drizzleOrm.sql`${r.status} IN ('active', 'completed', 'expired', 'revoked', 'unsupported')`),grantedCapabilitiesJsonCheck:sqliteCore.check("ui_instances_granted_capabilities_json_ck",drizzleOrm.sql`json_valid(${r.granted_capabilities_json}) AND json_type(${r.granted_capabilities_json}) = 'array'`),createdAtCheck:sqliteCore.check("ui_instances_created_at_ck",drizzleOrm.sql`${r.created_at} >= 0`),updatedAtCheck:sqliteCore.check("ui_instances_updated_at_ck",drizzleOrm.sql`${r.updated_at} >= ${r.created_at}`),workspaceThreadIdx:sqliteCore.index("ui_instances_workspace_thread_idx").on(r.workspace_id,r.thread_id)}));sqliteCore.sqliteTable("ui_action_receipts",{id:sqliteCore.text("id").primaryKey().notNull(),instance_id:sqliteCore.text("instance_id").notNull(),request_id:sqliteCore.text("request_id").notNull(),action_id:sqliteCore.text("action_id").notNull(),actor_json:sqliteCore.text("actor_json").notNull(),source:sqliteCore.text("source").notNull(),expected_revision:sqliteCore.integer("expected_revision").notNull(),before_revision:sqliteCore.integer("before_revision").notNull(),after_revision:sqliteCore.integer("after_revision"),status:sqliteCore.text("status").notNull(),outcome:sqliteCore.text("outcome"),input_json:sqliteCore.text("input_json").notNull(),result_json:sqliteCore.text("result_json"),error_code:sqliteCore.text("error_code"),requested_at:sqliteCore.integer("requested_at").notNull(),settled_at:sqliteCore.integer("settled_at")},r=>({idCheck:sqliteCore.check("ui_action_receipts_id_ck",drizzleOrm.sql`length(${r.id}) BETWEEN 5 AND 128`),instanceIdCheck:sqliteCore.check("ui_action_receipts_instance_id_ck",drizzleOrm.sql`length(${r.instance_id}) BETWEEN 1 AND 128`),requestIdCheck:sqliteCore.check("ui_action_receipts_request_id_ck",drizzleOrm.sql`length(${r.request_id}) BETWEEN 1 AND 128`),actionIdCheck:sqliteCore.check("ui_action_receipts_action_id_ck",drizzleOrm.sql`length(${r.action_id}) BETWEEN 1 AND 128`),actorJsonCheck:sqliteCore.check("ui_action_receipts_actor_json_ck",drizzleOrm.sql`json_valid(${r.actor_json}) AND json_type(${r.actor_json}) = 'object'`),sourceCheck:sqliteCore.check("ui_action_receipts_source_ck",drizzleOrm.sql`${r.source} IN ('ui_host', 'cli', 'system')`),expectedRevisionCheck:sqliteCore.check("ui_action_receipts_expected_revision_ck",drizzleOrm.sql`${r.expected_revision} >= 0`),beforeRevisionCheck:sqliteCore.check("ui_action_receipts_before_revision_ck",drizzleOrm.sql`${r.before_revision} >= 0`),afterRevisionCheck:sqliteCore.check("ui_action_receipts_after_revision_ck",drizzleOrm.sql`${r.after_revision} IS NULL OR ${r.after_revision} >= 0`),statusCheck:sqliteCore.check("ui_action_receipts_status_ck",drizzleOrm.sql`${r.status} IN ('requested', 'settled')`),outcomeCheck:sqliteCore.check("ui_action_receipts_outcome_ck",drizzleOrm.sql`${r.outcome} IS NULL OR ${r.outcome} IN ('succeeded', 'rejected', 'failed', 'conflicted', 'expired')`),inputJsonCheck:sqliteCore.check("ui_action_receipts_input_json_ck",drizzleOrm.sql`json_valid(${r.input_json}) AND json_type(${r.input_json}) = 'object'`),resultJsonCheck:sqliteCore.check("ui_action_receipts_result_json_ck",drizzleOrm.sql`${r.result_json} IS NULL OR (json_valid(${r.result_json}) AND json_type(${r.result_json}) = 'object')`),requestedAtCheck:sqliteCore.check("ui_action_receipts_requested_at_ck",drizzleOrm.sql`${r.requested_at} >= 0`),settledAtCheck:sqliteCore.check("ui_action_receipts_settled_at_ck",drizzleOrm.sql`${r.settled_at} IS NULL OR ${r.settled_at} >= ${r.requested_at}`),statusTransitionCheck:sqliteCore.check("ui_action_receipts_status_transition_ck",drizzleOrm.sql`(
4
+ (${r.status} = 'requested' AND ${r.after_revision} IS NULL AND ${r.outcome} IS NULL AND ${r.settled_at} IS NULL)
5
5
  OR
6
- (${i.status} = 'settled' AND ${i.after_revision} IS NOT NULL AND ${i.outcome} IS NOT NULL AND ${i.settled_at} IS NOT NULL)
7
- )`),instanceRequestUnique:sqliteCore.uniqueIndex("ui_action_receipts_instance_request_uq").on(i.instance_id,i.request_id),instanceIdIdx:sqliteCore.index("ui_action_receipts_instance_id_idx").on(i.instance_id),requestedAtIdx:sqliteCore.index("ui_action_receipts_requested_at_idx").on(i.requested_at)}));var S=sqliteCore.sqliteTable("projects",{id:sqliteCore.text("id").primaryKey().notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),name:sqliteCore.text("name").notNull(),outcome:sqliteCore.text("outcome").notNull(),due_date:sqliteCore.text("due_date"),scene:sqliteCore.text("scene").notNull().default("planning"),stages_json:sqliteCore.text("stages_json").notNull(),stage_index:sqliteCore.integer("stage_index").notNull(),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),accepted_at:sqliteCore.text("accepted_at"),archived_at:sqliteCore.text("archived_at")},i=>({idCheck:sqliteCore.check("projects_id_ck",drizzleOrm.sql`${i.id} GLOB 'prj_*'`),sceneCheck:sqliteCore.check("projects_scene_ck",drizzleOrm.sql`${i.scene} IN ('planning', 'plan_review', 'running', 'human_wait', 'limit_wait', 'failed_stop', 'analyzing_feedback', 'replanned', 'awaiting_review', 'accepted')`),stagesJsonCheck:sqliteCore.check("projects_stages_json_ck",drizzleOrm.sql`json_valid(${i.stages_json}) AND json_type(${i.stages_json}) = 'array'`),stageIndexCheck:sqliteCore.check("projects_stage_index_ck",drizzleOrm.sql`${i.stage_index} >= 1`)})),Y=sqliteCore.sqliteTable("project_criteria",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>S.id,{onDelete:"cascade"}),position:sqliteCore.integer("position").notNull(),statement:sqliteCore.text("statement").notNull(),verify_status:sqliteCore.text("verify_status").notNull().default("pending"),verified_at:sqliteCore.text("verified_at"),evidence_json:sqliteCore.text("evidence_json").notNull().default("[]"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},i=>({idCheck:sqliteCore.check("project_criteria_id_ck",drizzleOrm.sql`${i.id} GLOB 'pjc_*'`),verifyStatusCheck:sqliteCore.check("project_criteria_verify_status_ck",drizzleOrm.sql`${i.verify_status} IN ('pending', 'verifying', 'passed', 'failed')`),evidenceJsonCheck:sqliteCore.check("project_criteria_evidence_json_ck",drizzleOrm.sql`json_valid(${i.evidence_json}) AND json_type(${i.evidence_json}) = 'array'`),projectPositionUnique:sqliteCore.uniqueIndex("project_criteria_project_position_uq").on(i.project_id,i.position)})),dt=sqliteCore.sqliteTable("project_events",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>S.id,{onDelete:"restrict"}),seq:sqliteCore.integer("seq").notNull(),actor_type:sqliteCore.text("actor_type").notNull(),actor_id:sqliteCore.text("actor_id"),type:sqliteCore.text("type").notNull(),title:sqliteCore.text("title").notNull(),summary:sqliteCore.text("summary"),payload_json:sqliteCore.text("payload_json").notNull().default("{}"),created_at:sqliteCore.text("created_at").notNull()},i=>({idCheck:sqliteCore.check("project_events_id_ck",drizzleOrm.sql`${i.id} GLOB 'pje_*'`),actorTypeCheck:sqliteCore.check("project_events_actor_type_ck",drizzleOrm.sql`${i.actor_type} IN ('user', 'project_manager', 'system')`),payloadJsonCheck:sqliteCore.check("project_events_payload_json_ck",drizzleOrm.sql`json_valid(${i.payload_json}) AND json_type(${i.payload_json}) = 'object'`),projectSeqUnique:sqliteCore.uniqueIndex("project_events_project_seq_uq").on(i.project_id,i.seq)}));function de(i){let t=gt__namespace.resolve(i);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(e,n)=>`${n.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function Be(i){let t=de(i);return crypto.createHash("sha256").update(t).digest("hex")}function Zt(i){return i.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}var ue=class extends T{dbRoot;constructor(t={}){super(),this.dbRoot=t.dbRoot;}resolveDbPath(){return this.dbRoot?gt.join(this.dbRoot,".crewx","crewx.db"):super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{Pt(n.db);}catch(r){throw n.close(),r}return n}resolveSlug(t,e,n){let r=Zt(gt.basename(n)),a=`${Zt(gt.basename(gt.dirname(n)))}-${r}`,c=[r,a];try{let u=l=>t.select({id:g.id}).from(g).where(drizzleOrm.and(drizzleOrm.eq(g.slug,l),drizzleOrm.ne(g.id,e))).limit(1).all().length>0;for(let l of c)if(!u(l))return l;for(let l=2;l<1e3;l+=1){let p=`${a}-${l}`;if(!u(p))return p}}catch{}return r}normalizeLegacySlugs(){if(!this.dbExists())return {updated:0,checked:0};let t=this.openHandle(true);try{let e=t.db.select({id:g.id,slug:g.slug}).from(g).all(),n=0;for(let r of e)if(r.slug.includes("/")){let o=Zt(r.slug.replace(/\//g,"-"));t.db.update(g).set({slug:o,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(g.id,r.id)).run(),n+=1;}return {updated:n,checked:e.length}}catch(e){throw new d("DB_ERROR","Failed to normalize legacy slugs",e)}finally{t.close();}}ensureRow(t,e){let{id:n,slug:r,name:o,workspacePath:a}=e,c=new Date().toISOString();t.insert(g).values({id:n,slug:r,name:o,workspace_path:a,is_active:1,created_at:c,updated_at:c}).onConflictDoNothing().run(),t.update(g).set({workspace_path:a,updated_at:c}).where(drizzleOrm.and(drizzleOrm.eq(g.id,n),drizzleOrm.isNull(g.workspace_path))).run();}registerWorkspace(t){let e=de(t),n=this.openHandle(true);try{let r=Be(e),o=gt.basename(e),a=this.resolveSlug(n.db,r,e);return this.ensureRow(n.db,{id:r,slug:a,name:o,workspacePath:e}),{id:r,slug:a}}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to register workspace",r)}finally{n.close();}}listProjects(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let n=t.isActive!==void 0?drizzleOrm.eq(g.is_active,t.isActive?1:0):void 0,r=e.db.select({count:drizzleOrm.sql`count(*)`}).from(g).where(n).get();return {rows:e.db.select().from(g).where(n).orderBy(drizzleOrm.desc(g.updated_at)).limit(t.limit).offset(t.offset).all(),total:r?.count??0}}catch(n){throw new d("DB_ERROR","Failed to list projects",n)}finally{e.close();}}findById(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(g).where(drizzleOrm.eq(g.id,t)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to find workspace",n)}finally{e.close();}}findAgentsByProject(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.all(drizzleOrm.sql`SELECT DISTINCT agent_id FROM tasks WHERE workspace_id = ${t} AND agent_id IS NOT NULL ORDER BY agent_id`).map(r=>r.agent_id)}catch(n){throw new d("DB_ERROR","Failed to find agents by project",n)}finally{e.close();}}findThreadsByProject(t,e){if(!this.dbExists())return {rows:[],total:0};let n=this.openHandle(false);try{let r=n.db.get(drizzleOrm.sql`SELECT COUNT(*) as count FROM threads WHERE workspace_id = ${t}`);return {rows:n.db.all(drizzleOrm.sql`SELECT t.*,
6
+ (${r.status} = 'settled' AND ${r.after_revision} IS NOT NULL AND ${r.outcome} IS NOT NULL AND ${r.settled_at} IS NOT NULL)
7
+ )`),instanceRequestUnique:sqliteCore.uniqueIndex("ui_action_receipts_instance_request_uq").on(r.instance_id,r.request_id),instanceIdIdx:sqliteCore.index("ui_action_receipts_instance_id_idx").on(r.instance_id),requestedAtIdx:sqliteCore.index("ui_action_receipts_requested_at_idx").on(r.requested_at)}));var v=sqliteCore.sqliteTable("projects",{id:sqliteCore.text("id").primaryKey().notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),name:sqliteCore.text("name").notNull(),outcome:sqliteCore.text("outcome").notNull(),due_date:sqliteCore.text("due_date"),scene:sqliteCore.text("scene").notNull().default("planning"),stages_json:sqliteCore.text("stages_json").notNull(),stage_index:sqliteCore.integer("stage_index").notNull(),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),accepted_at:sqliteCore.text("accepted_at"),archived_at:sqliteCore.text("archived_at")},r=>({idCheck:sqliteCore.check("projects_id_ck",drizzleOrm.sql`${r.id} GLOB 'prj_*'`),sceneCheck:sqliteCore.check("projects_scene_ck",drizzleOrm.sql`${r.scene} IN ('planning', 'plan_review', 'running', 'human_wait', 'limit_wait', 'failed_stop', 'analyzing_feedback', 'replanned', 'awaiting_review', 'accepted')`),stagesJsonCheck:sqliteCore.check("projects_stages_json_ck",drizzleOrm.sql`json_valid(${r.stages_json}) AND json_type(${r.stages_json}) = 'array'`),stageIndexCheck:sqliteCore.check("projects_stage_index_ck",drizzleOrm.sql`${r.stage_index} >= 1`)})),Q=sqliteCore.sqliteTable("project_criteria",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>v.id,{onDelete:"cascade"}),position:sqliteCore.integer("position").notNull(),statement:sqliteCore.text("statement").notNull(),verify_status:sqliteCore.text("verify_status").notNull().default("pending"),verified_at:sqliteCore.text("verified_at"),evidence_json:sqliteCore.text("evidence_json").notNull().default("[]"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},r=>({idCheck:sqliteCore.check("project_criteria_id_ck",drizzleOrm.sql`${r.id} GLOB 'pjc_*'`),verifyStatusCheck:sqliteCore.check("project_criteria_verify_status_ck",drizzleOrm.sql`${r.verify_status} IN ('pending', 'verifying', 'passed', 'failed')`),evidenceJsonCheck:sqliteCore.check("project_criteria_evidence_json_ck",drizzleOrm.sql`json_valid(${r.evidence_json}) AND json_type(${r.evidence_json}) = 'array'`),projectPositionUnique:sqliteCore.uniqueIndex("project_criteria_project_position_uq").on(r.project_id,r.position)})),ce=sqliteCore.sqliteTable("project_events",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>v.id,{onDelete:"restrict"}),seq:sqliteCore.integer("seq").notNull(),actor_type:sqliteCore.text("actor_type").notNull(),actor_id:sqliteCore.text("actor_id"),type:sqliteCore.text("type").notNull(),title:sqliteCore.text("title").notNull(),summary:sqliteCore.text("summary"),payload_json:sqliteCore.text("payload_json").notNull().default("{}"),created_at:sqliteCore.text("created_at").notNull()},r=>({idCheck:sqliteCore.check("project_events_id_ck",drizzleOrm.sql`${r.id} GLOB 'pje_*'`),actorTypeCheck:sqliteCore.check("project_events_actor_type_ck",drizzleOrm.sql`${r.actor_type} IN ('user', 'project_manager', 'system')`),payloadJsonCheck:sqliteCore.check("project_events_payload_json_ck",drizzleOrm.sql`json_valid(${r.payload_json}) AND json_type(${r.payload_json}) = 'object'`),projectSeqUnique:sqliteCore.uniqueIndex("project_events_project_seq_uq").on(r.project_id,r.seq)}));function kt(r){let e=ye__namespace.resolve(r);return process.platform==="win32"&&(e=e.replace(/\\/g,"/"),e=e.replace(/^([A-Z]):/,(t,n)=>`${n.toLowerCase()}:`)),e.length>1&&!/^[a-zA-Z]:\/$/.test(e)&&(e=e.replace(/\/+$/,"")),e}function rn(r){let e=kt(r);return crypto.createHash("sha256").update(e).digest("hex")}function at(r){return r.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}var Rt=class extends x{dbRoot;constructor(e={}){super(),this.dbRoot=e.dbRoot;}resolveDbPath(){return this.dbRoot?ye.join(this.dbRoot,".crewx","crewx.db"):super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{qe(n.db);}catch(o){throw n.close(),o}return n}resolveSlug(e,t,n){let o=at(ye.basename(n)),a=`${at(ye.basename(ye.dirname(n)))}-${o}`,c=[o,a];try{let u=l=>e.select({id:h.id}).from(h).where(drizzleOrm.and(drizzleOrm.eq(h.slug,l),drizzleOrm.ne(h.id,t))).limit(1).all().length>0;for(let l of c)if(!u(l))return l;for(let l=2;l<1e3;l+=1){let p=`${a}-${l}`;if(!u(p))return p}}catch{}return o}normalizeLegacySlugs(){if(!this.dbExists())return {updated:0,checked:0};let e=this.openHandle(true);try{let t=e.db.select({id:h.id,slug:h.slug}).from(h).all(),n=0;for(let o of t)if(o.slug.includes("/")){let s=at(o.slug.replace(/\//g,"-"));e.db.update(h).set({slug:s,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(h.id,o.id)).run(),n+=1;}return {updated:n,checked:t.length}}catch(t){throw new d("DB_ERROR","Failed to normalize legacy slugs",t)}finally{e.close();}}ensureRow(e,t){let{id:n,slug:o,name:s,workspacePath:a}=t,c=new Date().toISOString();e.insert(h).values({id:n,slug:o,name:s,workspace_path:a,is_active:1,created_at:c,updated_at:c}).onConflictDoNothing().run(),e.update(h).set({workspace_path:a,updated_at:c}).where(drizzleOrm.and(drizzleOrm.eq(h.id,n),drizzleOrm.isNull(h.workspace_path))).run();}registerWorkspace(e){let t=kt(e),n=this.openHandle(true);try{let o=rn(t),s=ye.basename(t),a=this.resolveSlug(n.db,o,t);return this.ensureRow(n.db,{id:o,slug:a,name:s,workspacePath:t}),{id:o,slug:a}}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to register workspace",o)}finally{n.close();}}listProjects(e){if(!this.dbExists())return {rows:[],total:0};let t=this.openHandle(false);try{let n=e.isActive!==void 0?drizzleOrm.eq(h.is_active,e.isActive?1:0):void 0,o=t.db.select({count:drizzleOrm.sql`count(*)`}).from(h).where(n).get();return {rows:t.db.select().from(h).where(n).orderBy(drizzleOrm.desc(h.updated_at)).limit(e.limit).offset(e.offset).all(),total:o?.count??0}}catch(n){throw new d("DB_ERROR","Failed to list projects",n)}finally{t.close();}}findById(e){if(!this.dbExists())return;let t=this.openHandle(false);try{return t.db.select().from(h).where(drizzleOrm.eq(h.id,e)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to find workspace",n)}finally{t.close();}}findAgentsByProject(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.all(drizzleOrm.sql`SELECT DISTINCT agent_id FROM tasks WHERE workspace_id = ${e} AND agent_id IS NOT NULL ORDER BY agent_id`).map(o=>o.agent_id)}catch(n){throw new d("DB_ERROR","Failed to find agents by project",n)}finally{t.close();}}findThreadsByProject(e,t){if(!this.dbExists())return {rows:[],total:0};let n=this.openHandle(false);try{let o=n.db.get(drizzleOrm.sql`SELECT COUNT(*) as count FROM threads WHERE workspace_id = ${e}`);return {rows:n.db.all(drizzleOrm.sql`SELECT t.*,
8
8
  (SELECT agent_id FROM tasks tk WHERE tk.thread_id = t.id AND tk.agent_id IS NOT NULL ORDER BY tk.started_at ASC LIMIT 1) AS agent_id
9
9
  FROM threads t
10
- WHERE t.workspace_id = ${t}
10
+ WHERE t.workspace_id = ${e}
11
11
  ORDER BY t.updated_at DESC
12
- LIMIT ${e.limit} OFFSET ${e.offset}`),total:r?.count??0}}catch(r){throw new d("DB_ERROR","Failed to find threads by project",r)}finally{n.close();}}findBySlug(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(g).where(drizzleOrm.eq(g.slug,t)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to find workspace by slug",n)}finally{e.close();}}slugExists(t,e){if(!this.dbExists())return false;let n=this.openHandle(false);try{let r=e?drizzleOrm.and(drizzleOrm.eq(g.slug,t),drizzleOrm.ne(g.id,e)):drizzleOrm.eq(g.slug,t);return !!n.db.select({id:g.id}).from(g).where(r).limit(1).get()}catch(r){throw new d("DB_ERROR","Failed to check slug",r)}finally{n.close();}}insert(t,e,n,r){let o=this.openHandle(true);try{let a=new Date().toISOString();o.db.insert(g).values({id:t,slug:e,name:n,workspace_path:r,is_active:1,created_at:a,updated_at:a}).run();let c=o.db.select().from(g).where(drizzleOrm.eq(g.id,t)).limit(1).get();if(!c)throw new d("DB_ERROR","Insert did not return a row");return c}catch(a){throw a instanceof d?a:new d("DB_ERROR","Failed to insert workspace",a)}finally{o.close();}}update(t,e,n){let r=this.openHandle(true);try{r.runRaw(`UPDATE workspaces SET ${e.join(", ")} WHERE id = ?`,n);let o=r.db.select().from(g).where(drizzleOrm.eq(g.id,t)).limit(1).get();if(!o)throw new d("NOT_FOUND",`Workspace ${t} not found`);return o}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to update workspace",o)}finally{r.close();}}cleanupOrphanWorkspaces(){if(!this.dbExists())return {softDeleted:0,checked:0};let t=this.openHandle(true);try{let e=t.db.select({id:g.id,workspace_path:g.workspace_path}).from(g).where(drizzleOrm.and(drizzleOrm.eq(g.is_active,1),drizzleOrm.isNotNull(g.workspace_path))).all(),n=0;for(let r of e){let o=r.workspace_path;Ye.existsSync(gt.join(o,"crewx.yaml"))||Ye.existsSync(gt.join(o,"crewx.yml"))||(t.db.update(g).set({is_active:0,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(g.id,r.id)).run(),n+=1);}return {softDeleted:n,checked:e.length}}catch(e){throw new d("DB_ERROR","Failed to cleanup orphan workspaces",e)}finally{t.close();}}delete(t){let e=this.openHandle(true);try{e.db.run(drizzleOrm.sql`UPDATE threads SET workspace_id = NULL WHERE workspace_id = ${t}`),e.db.delete(g).where(drizzleOrm.eq(g.id,t)).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to delete workspace",n)}finally{e.close();}}};var qe="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function _r(i){let t=crypto.randomBytes(i*2),e="";for(let n=0;n<t.length&&e.length<i;n++){let r=t[n];r<248&&(e+=qe[r%62]);}for(;e.length<i;)e+=qe[crypto.randomBytes(1)[0]%62];return e}function Rt(i){return `${i}_${_r(8)}`}var yr=new Set(["created","plan_proposed","plan_approved","decision_requested","decision_answered","replanned","stage_advanced","criterion_verified","scene_changed","result_submitted","accepted"]),Er=new Set(["planning","plan_review","running","human_wait","limit_wait","failed_stop","analyzing_feedback","replanned","awaiting_review","accepted"]),Rr=new Set(["pending","verifying","passed","failed"]),br=new Set(["user","project_manager","system"]),Sr=new Set(["task","wi","url"]),xr=/^\d{4}-\d{2}-\d{2}$/;function P(i){throw new d("VALIDATION",i)}function et(i){throw new d("NOT_FOUND",i)}function $(i,t){(typeof i!="string"||i.trim().length===0)&&P(`${t} is required`);}function Tr(i){if(i==null)return;xr.test(i)||P("dueDate must use YYYY-MM-DD");let t=new Date(`${i}T00:00:00.000Z`);(Number.isNaN(t.getTime())||t.toISOString().slice(0,10)!==i)&&P("dueDate must be a valid calendar date");}function Dr(i){(!Array.isArray(i)||i.length===0)&&P("stages must contain at least one stage");let t=new Set;for(let e of i)$(e.key,"stage.key"),$(e.label,"stage.label"),t.has(e.key)&&P(`duplicate stage key: ${e.key}`),t.add(e.key);}function Nr(i){Array.isArray(i)||P("criteria must be an array");for(let t of i)$(t,"criterion.statement");}function Ct(i={}){let t=i.actorType??"system";br.has(t)||P(`invalid actorType: ${String(t)}`);let e=i.actorId??null;return (t==="user"||t==="project_manager")&&(!e||e.trim().length===0)&&P(`actorId is required for ${t}`),{actorType:t,actorId:e}}function Je(i,t){let e=i??{};if((e===null||typeof e!="object"||Array.isArray(e))&&P("event payload must be a JSON object"),t==="accepted")for(let n of ["remainingRisks","nextPlan","lessons","evidenceRefs"])(!Object.prototype.hasOwnProperty.call(e,n)||e[n]===void 0)&&P(`accepted payload requires ${n}`);try{return JSON.stringify(e)}catch(n){throw new d("VALIDATION","event payload must be JSON serializable",n)}}function vr(i){return Array.isArray(i)||P("evidence must be an array"),i.map(t=>((!t||typeof t!="object")&&P("evidence item must be an object"),Sr.has(t.kind)||P(`invalid evidence kind: ${String(t.kind)}`),$(t.ref,"evidence.ref"),t.label!==void 0&&typeof t.label!="string"&&P("evidence.label must be a string"),t.label===void 0?{kind:t.kind,ref:t.ref}:{kind:t.kind,ref:t.ref,label:t.label}))}function Ge(i){try{let t=JSON.parse(i);if(!Array.isArray(t))throw new Error("not an array");return t}catch(t){throw new d("DB_ERROR","Project stages JSON is invalid",t)}}function Ve(i){return $(i.projectId,"projectId"),$(i.title,"title"),yr.has(i.type)||P(`invalid project event type: ${String(i.type)}`),{...Ct(i),payloadJson:Je(i.payload,i.type)}}function At(i,t,e){let n=Ve(t);i.select({id:S.id}).from(S).where(drizzleOrm.eq(S.id,t.projectId)).get()||et(`Project ${t.projectId} not found`);let o=i.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${dt.seq}), 0)`}).from(dt).where(drizzleOrm.eq(dt.project_id,t.projectId)).get()?.maxSeq??0,a=Rt("pje");i.insert(dt).values({id:a,project_id:t.projectId,seq:o+1,actor_type:n.actorType,actor_id:n.actorId,type:t.type,title:t.title,summary:t.summary??null,payload_json:n.payloadJson,created_at:e}).run();let c=i.select().from(dt).where(drizzleOrm.eq(dt.id,a)).get();if(!c)throw new d("DB_ERROR","Event insert did not return a row");return c}var pe=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(!t&&!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}getDetailFromHandle(t,e){let n=t.db.select().from(S).where(drizzleOrm.eq(S.id,e)).get();if(!n)return;let r=t.db.select().from(Y).where(drizzleOrm.eq(Y.project_id,e)).orderBy(drizzleOrm.asc(Y.position)).all();return {...n,stages:Ge(n.stages_json),criteria:r}}getDetailOrThrow(t){let e=this.getProject(t);return e||et(`Project ${t} not found`),e}createProject(t){$(t.workspaceId,"workspaceId"),$(t.name,"name"),$(t.outcome,"outcome"),Tr(t.dueDate),Dr(t.stages),Nr(t.criteria);let e=Rt("prj"),n=new Date().toISOString(),r=this.openHandle(true);try{r.db.transaction(o=>{o.insert(S).values({id:e,workspace_id:t.workspaceId,name:t.name,outcome:t.outcome,due_date:t.dueDate??null,scene:"planning",stages_json:JSON.stringify(t.stages),stage_index:1,created_at:n,updated_at:n,accepted_at:null,archived_at:null}).run(),t.criteria.forEach((a,c)=>{o.insert(Y).values({id:Rt("pjc"),project_id:e,position:c+1,statement:a,verify_status:"pending",verified_at:null,evidence_json:"[]",created_at:n,updated_at:n}).run();}),At(o,{projectId:e,actorType:"system",type:"created",title:"Project created",payload:{}},n);});}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to create project",o)}finally{r.close();}return this.getDetailOrThrow(e)}getProject(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return this.getDetailFromHandle(e,t)}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to get project",n)}finally{e.close();}}listProjectsByWorkspace(t,e={}){if($(t,"workspaceId"),!this.dbExists())return [];let n=this.openHandle(false);try{let r=e.includeArchived?drizzleOrm.eq(S.workspace_id,t):drizzleOrm.and(drizzleOrm.eq(S.workspace_id,t),drizzleOrm.isNull(S.archived_at));return n.db.select({id:S.id}).from(S).where(r).orderBy(drizzleOrm.desc(S.updated_at),drizzleOrm.desc(S.created_at)).all().map(a=>this.getDetailFromHandle(n,a.id)).filter(a=>a!==void 0)}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to list projects",r)}finally{n.close();}}archiveProject(t){$(t,"projectId");let e=this.openHandle(true);try{e.db.update(S).set({archived_at:new Date().toISOString()}).where(drizzleOrm.eq(S.id,t)).run().changes===0&&et(`Project ${t} not found`);}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to archive project",n)}finally{e.close();}return this.getDetailOrThrow(t)}setScene(t,e,n={}){$(t,"projectId"),Er.has(e)||P(`invalid project scene: ${String(e)}`);let r=Ct(n),o=new Date().toISOString(),a=this.openHandle(true);try{a.db.transaction(c=>{let u=c.select().from(S).where(drizzleOrm.eq(S.id,t)).get();u||et(`Project ${t} not found`),c.update(S).set({scene:e,updated_at:o}).where(drizzleOrm.eq(S.id,t)).run(),At(c,{projectId:t,...r,type:"scene_changed",title:"Project scene changed",payload:{before:u.scene,after:e}},o);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to set project scene",c)}finally{a.close();}return this.getDetailOrThrow(t)}setStageIndex(t,e,n={}){$(t,"projectId"),Number.isInteger(e)||P("stage index must be an integer");let r=Ct(n),o=new Date().toISOString(),a=this.openHandle(true);try{a.db.transaction(c=>{let u=c.select().from(S).where(drizzleOrm.eq(S.id,t)).get();u||et(`Project ${t} not found`);let l=Ge(u.stages_json);(e<1||e>l.length)&&P("stage index is outside the project stages"),c.update(S).set({stage_index:e,updated_at:o}).where(drizzleOrm.eq(S.id,t)).run(),At(c,{projectId:t,...r,type:"stage_advanced",title:"Project stage advanced",payload:{before:u.stage_index,after:e}},o);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to set project stage",c)}finally{a.close();}return this.getDetailOrThrow(t)}setCriterionVerify(t,e,n,r={}){let o=typeof t=="string"?{projectId:typeof n=="string"?t:void 0,criterionId:typeof n=="string"?e:t,verifyStatus:typeof n=="string"?n:e,...typeof n=="string"?r:n}:t,a=o.verifyStatus??o.status;(!a||!Rr.has(a))&&P(`invalid criterion status: ${String(a)}`),$(o.criterionId,"criterionId");let c=Ct(o),u=new Date().toISOString(),l=this.openHandle(true),p;try{l.db.transaction(f=>{let m=f.select().from(Y).where(drizzleOrm.eq(Y.id,o.criterionId)).get();m||et(`Criterion ${o.criterionId} not found`),p=m.project_id,o.projectId&&o.projectId!==m.project_id&&et(`Criterion ${o.criterionId} not found in project ${o.projectId}`),f.update(Y).set({verify_status:a,verified_at:a==="passed"?u:null,updated_at:u}).where(drizzleOrm.eq(Y.id,o.criterionId)).run(),At(f,{projectId:m.project_id,...c,type:"criterion_verified",title:"Criterion verification updated",payload:{criterionId:o.criterionId,status:a}},u);});}catch(f){throw f instanceof d?f:new d("DB_ERROR","Failed to set criterion verification",f)}finally{l.close();}let h=p?this.getProject(p)?.criteria.find(f=>f.id===o.criterionId):void 0;return h||et(`Criterion ${o.criterionId} not found`),h}setCriterionEvidence(t,e,n,r={}){let o=typeof t=="string"?{projectId:Array.isArray(n)?t:void 0,criterionId:Array.isArray(n)?e:t,evidence:Array.isArray(n)?n:e,...Array.isArray(n)?r:n}:t;$(o.criterionId,"criterionId");let a=vr(o.evidence),c=Ct(o),u=new Date().toISOString(),l=this.openHandle(true),p;try{l.db.transaction(f=>{let m=f.select().from(Y).where(drizzleOrm.eq(Y.id,o.criterionId)).get();m||et(`Criterion ${o.criterionId} not found`),p=m.project_id,o.projectId&&o.projectId!==m.project_id&&et(`Criterion ${o.criterionId} not found in project ${o.projectId}`),f.update(Y).set({evidence_json:JSON.stringify(a),updated_at:u}).where(drizzleOrm.eq(Y.id,o.criterionId)).run(),At(f,{projectId:m.project_id,...c,type:"criterion_verified",title:"Criterion evidence updated",payload:{criterionId:o.criterionId,evidence:a}},u);});}catch(f){throw f instanceof d?f:new d("DB_ERROR","Failed to set criterion evidence",f)}finally{l.close();}let h=p?this.getProject(p)?.criteria.find(f=>f.id===o.criterionId):void 0;return h||et(`Criterion ${o.criterionId} not found`),h}appendEvent(t,e){let n=typeof t=="string"?{...e,projectId:t}:t;Ve(n);let r=new Date().toISOString(),o=this.openHandle(true),a;try{o.db.transaction(c=>{a=At(c,n,r);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to append project event",c)}finally{o.close();}if(!a)throw new d("DB_ERROR","Event append did not return a row");return a}listEvents(t,e={}){if($(t,"projectId"),e.afterSeq!==void 0&&(!Number.isInteger(e.afterSeq)||e.afterSeq<0)&&P("afterSeq must be a non-negative integer"),e.limit!==void 0&&(!Number.isInteger(e.limit)||e.limit<1)&&P("limit must be a positive integer"),!this.dbExists())return [];let n=this.openHandle(false);try{let r=[drizzleOrm.eq(dt.project_id,t)];e.afterSeq!==void 0&&r.push(drizzleOrm.gt(dt.seq,e.afterSeq));let o=n.db.select().from(dt).where(drizzleOrm.and(...r)).orderBy(drizzleOrm.asc(dt.seq));return e.limit!==void 0&&(o=o.limit(e.limit)),o.all()}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to list project events",r)}finally{n.close();}}acceptProject(t,e){$(t,"projectId");let n=Ct(e),r={remainingRisks:e.remainingRisks,nextPlan:e.nextPlan,lessons:e.lessons,evidenceRefs:e.evidenceRefs};Je(r,"accepted");let o=new Date().toISOString(),a=this.openHandle(true);try{a.db.transaction(c=>{c.select({id:S.id}).from(S).where(drizzleOrm.eq(S.id,t)).get()||et(`Project ${t} not found`),c.update(S).set({scene:"accepted",accepted_at:o,updated_at:o}).where(drizzleOrm.eq(S.id,t)).run(),At(c,{projectId:t,...n,type:"accepted",title:"Project accepted",payload:r},o);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to accept project",c)}finally{a.close();}return this.getDetailOrThrow(t)}};var Qe=[g,s,_,wt,lt,tt,Ot];function Pr(){return gt__namespace.default.join(Nn__default.default.homedir(),".crewx","crewx.db")}function Or(i){if(!Ye__default.default.existsSync(i))return null;let t=Math.floor(Date.now()/1e3),e=`${i}.bak-${t}`;return Ye__default.default.copyFileSync(i,e),e}function Ze(i){let t=i.all("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");return new Set(t.map(e=>e.name))}function Cr(i){return i==null||typeof i=="object"&&"queryChunks"in i?null:typeof i=="number"?String(i):typeof i=="boolean"?i?"1":"0":typeof i=="string"?`'${i.replace(/'/g,"''")}'`:String(i)}function jr(i){let t=i.getSQLType(),e=`"${i.name}" ${t}`,n=Cr(i.default);return n!==null&&(e+=` DEFAULT ${n}`),i.notNull&&(e+=" NOT NULL"),e}function $r(i,t){let e=t?.dbPath??Pr(),n=t?.force??false,r=t?.dryRun??false,o=r?null:Or(e);if(n&&!r)try{i.run("DELETE FROM __drizzle_migrations");}catch{}let a=Ze(i);if(!r)try{Pt(i);}catch(h){let f=h instanceof Error?`${h.message} ${h.cause?.message??""}`:"";if(!n||!f.includes("duplicate column"))throw h}let c,u;r?(c=Qe.map(f=>sqliteCore.getTableConfig(f).name).filter(f=>!a.has(f)),u=a):(u=Ze(i),c=[...u].filter(h=>!a.has(h)));let l=[],p=[];for(let h of Qe){let f=sqliteCore.getTableConfig(h),m=f.name;if(!u.has(m))continue;let M=i.all(`PRAGMA table_info("${m}")`),F=new Set(M.map(I=>I.name)),K=new Set(f.columns.map(I=>I.name));for(let I of f.columns)if(!F.has(I.name)){if(!r){let st=jr(I);i.run(`ALTER TABLE "${m}" ADD COLUMN ${st}`);}l.push({table:m,column:I.name});}for(let I of M)K.has(I.name)||p.push(`${m}.${I.name} exists in DB but not in schema (untouched)`);}return {created:c,altered:l,warnings:p,backupPath:o}}function tn(i){let t=i.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let e=t.lastIndexOf("/");return e>=0&&(t=t.slice(e+1)),t=t.replace(/-\d{8}$/,""),t}var St="2026-05-09",zr="0.8.9-rc.13",xt=10,Tt=parseInt(zr.split("rc.")[1]);function en(){let i=drizzleOrm.sql`
12
+ LIMIT ${t.limit} OFFSET ${t.offset}`),total:o?.count??0}}catch(o){throw new d("DB_ERROR","Failed to find threads by project",o)}finally{n.close();}}findBySlug(e){if(!this.dbExists())return;let t=this.openHandle(false);try{return t.db.select().from(h).where(drizzleOrm.eq(h.slug,e)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to find workspace by slug",n)}finally{t.close();}}slugExists(e,t){if(!this.dbExists())return false;let n=this.openHandle(false);try{let o=t?drizzleOrm.and(drizzleOrm.eq(h.slug,e),drizzleOrm.ne(h.id,t)):drizzleOrm.eq(h.slug,e);return !!n.db.select({id:h.id}).from(h).where(o).limit(1).get()}catch(o){throw new d("DB_ERROR","Failed to check slug",o)}finally{n.close();}}insert(e,t,n,o){let s=this.openHandle(true);try{let a=new Date().toISOString();s.db.insert(h).values({id:e,slug:t,name:n,workspace_path:o,is_active:1,created_at:a,updated_at:a}).run();let c=s.db.select().from(h).where(drizzleOrm.eq(h.id,e)).limit(1).get();if(!c)throw new d("DB_ERROR","Insert did not return a row");return c}catch(a){throw a instanceof d?a:new d("DB_ERROR","Failed to insert workspace",a)}finally{s.close();}}update(e,t,n){let o=this.openHandle(true);try{o.runRaw(`UPDATE workspaces SET ${t.join(", ")} WHERE id = ?`,n);let s=o.db.select().from(h).where(drizzleOrm.eq(h.id,e)).limit(1).get();if(!s)throw new d("NOT_FOUND",`Workspace ${e} not found`);return s}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to update workspace",s)}finally{o.close();}}cleanupOrphanWorkspaces(){if(!this.dbExists())return {softDeleted:0,checked:0};let e=this.openHandle(true);try{let t=e.db.select({id:h.id,workspace_path:h.workspace_path}).from(h).where(drizzleOrm.and(drizzleOrm.eq(h.is_active,1),drizzleOrm.isNotNull(h.workspace_path))).all(),n=0;for(let o of t){let s=o.workspace_path;mn.existsSync(ye.join(s,"crewx.yaml"))||mn.existsSync(ye.join(s,"crewx.yml"))||(e.db.update(h).set({is_active:0,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(h.id,o.id)).run(),n+=1);}return {softDeleted:n,checked:t.length}}catch(t){throw new d("DB_ERROR","Failed to cleanup orphan workspaces",t)}finally{e.close();}}delete(e){let t=this.openHandle(true);try{t.db.run(drizzleOrm.sql`UPDATE threads SET workspace_id = NULL WHERE workspace_id = ${e}`),t.db.delete(h).where(drizzleOrm.eq(h.id,e)).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to delete workspace",n)}finally{t.close();}}};var dn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function ro(r){let e=crypto.randomBytes(r*2),t="";for(let n=0;n<e.length&&t.length<r;n++){let o=e[n];o<248&&(t+=dn[o%62]);}for(;t.length<r;)t+=dn[crypto.randomBytes(1)[0]%62];return t}function De(r){return `${r}_${ro(8)}`}var uo=new Set(["created","plan_proposed","plan_approved","decision_requested","decision_answered","replanned","stage_advanced","criterion_verified","scene_changed","result_submitted","accepted"]),po=new Set(["planning","plan_review","running","human_wait","limit_wait","failed_stop","analyzing_feedback","replanned","awaiting_review","accepted"]),_o=new Set(["pending","verifying","passed","failed"]),go=new Set(["user","project_manager","system"]),fo=new Set(["task","wi","url"]),mo=/^\d{4}-\d{2}-\d{2}$/;function L(r){throw new d("VALIDATION",r)}function re(r){throw new d("NOT_FOUND",r)}function q(r,e){(typeof r!="string"||r.trim().length===0)&&L(`${e} is required`);}function ho(r){if(r==null)return;mo.test(r)||L("dueDate must use YYYY-MM-DD");let e=new Date(`${r}T00:00:00.000Z`);(Number.isNaN(e.getTime())||e.toISOString().slice(0,10)!==r)&&L("dueDate must be a valid calendar date");}function wo(r){(!Array.isArray(r)||r.length===0)&&L("stages must contain at least one stage");let e=new Set;for(let t of r)q(t.key,"stage.key"),q(t.label,"stage.label"),e.has(t.key)&&L(`duplicate stage key: ${t.key}`),e.add(t.key);}function ko(r){Array.isArray(r)||L("criteria must be an array");for(let e of r)q(e,"criterion.statement");}function Ue(r={}){let e=r.actorType??"system";go.has(e)||L(`invalid actorType: ${String(e)}`);let t=r.actorId??null;return (e==="user"||e==="project_manager")&&(!t||t.trim().length===0)&&L(`actorId is required for ${e}`),{actorType:e,actorId:t}}function gn(r,e){let t=r??{};if((t===null||typeof t!="object"||Array.isArray(t))&&L("event payload must be a JSON object"),e==="accepted")for(let n of ["remainingRisks","nextPlan","lessons","evidenceRefs"])(!Object.prototype.hasOwnProperty.call(t,n)||t[n]===void 0)&&L(`accepted payload requires ${n}`);try{return JSON.stringify(t)}catch(n){throw new d("VALIDATION","event payload must be JSON serializable",n)}}function yo(r){return Array.isArray(r)||L("evidence must be an array"),r.map(e=>((!e||typeof e!="object")&&L("evidence item must be an object"),fo.has(e.kind)||L(`invalid evidence kind: ${String(e.kind)}`),q(e.ref,"evidence.ref"),e.label!==void 0&&typeof e.label!="string"&&L("evidence.label must be a string"),e.label===void 0?{kind:e.kind,ref:e.ref}:{kind:e.kind,ref:e.ref,label:e.label}))}function _n(r){try{let e=JSON.parse(r);if(!Array.isArray(e))throw new Error("not an array");return e}catch(e){throw new d("DB_ERROR","Project stages JSON is invalid",e)}}function fn(r){return q(r.projectId,"projectId"),q(r.title,"title"),uo.has(r.type)||L(`invalid project event type: ${String(r.type)}`),{...Ue(r),payloadJson:gn(r.payload,r.type)}}function je(r,e,t){let n=fn(e);r.select({id:v.id}).from(v).where(drizzleOrm.eq(v.id,e.projectId)).get()||re(`Project ${e.projectId} not found`);let s=r.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${ce.seq}), 0)`}).from(ce).where(drizzleOrm.eq(ce.project_id,e.projectId)).get()?.maxSeq??0,a=De("pje");r.insert(ce).values({id:a,project_id:e.projectId,seq:s+1,actor_type:n.actorType,actor_id:n.actorId,type:e.type,title:e.title,summary:e.summary??null,payload_json:n.payloadJson,created_at:t}).run();let c=r.select().from(ce).where(drizzleOrm.eq(ce.id,a)).get();if(!c)throw new d("DB_ERROR","Event insert did not return a row");return c}var Et=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(!e&&!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}getDetailFromHandle(e,t){let n=e.db.select().from(v).where(drizzleOrm.eq(v.id,t)).get();if(!n)return;let o=e.db.select().from(Q).where(drizzleOrm.eq(Q.project_id,t)).orderBy(drizzleOrm.asc(Q.position)).all();return {...n,stages:_n(n.stages_json),criteria:o}}getDetailOrThrow(e){let t=this.getProject(e);return t||re(`Project ${e} not found`),t}createProject(e){q(e.workspaceId,"workspaceId"),q(e.name,"name"),q(e.outcome,"outcome"),ho(e.dueDate),wo(e.stages),ko(e.criteria);let t=De("prj"),n=new Date().toISOString(),o=this.openHandle(true);try{o.db.transaction(s=>{s.insert(v).values({id:t,workspace_id:e.workspaceId,name:e.name,outcome:e.outcome,due_date:e.dueDate??null,scene:"planning",stages_json:JSON.stringify(e.stages),stage_index:1,created_at:n,updated_at:n,accepted_at:null,archived_at:null}).run(),e.criteria.forEach((a,c)=>{s.insert(Q).values({id:De("pjc"),project_id:t,position:c+1,statement:a,verify_status:"pending",verified_at:null,evidence_json:"[]",created_at:n,updated_at:n}).run();}),je(s,{projectId:t,actorType:"system",type:"created",title:"Project created",payload:{}},n);});}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to create project",s)}finally{o.close();}return this.getDetailOrThrow(t)}getProject(e){if(!this.dbExists())return;let t=this.openHandle(false);try{return this.getDetailFromHandle(t,e)}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to get project",n)}finally{t.close();}}listProjectsByWorkspace(e,t={}){if(q(e,"workspaceId"),!this.dbExists())return [];let n=this.openHandle(false);try{let o=t.includeArchived?drizzleOrm.eq(v.workspace_id,e):drizzleOrm.and(drizzleOrm.eq(v.workspace_id,e),drizzleOrm.isNull(v.archived_at));return n.db.select({id:v.id}).from(v).where(o).orderBy(drizzleOrm.desc(v.updated_at),drizzleOrm.desc(v.created_at)).all().map(a=>this.getDetailFromHandle(n,a.id)).filter(a=>a!==void 0)}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to list projects",o)}finally{n.close();}}archiveProject(e){q(e,"projectId");let t=this.openHandle(true);try{t.db.update(v).set({archived_at:new Date().toISOString()}).where(drizzleOrm.eq(v.id,e)).run().changes===0&&re(`Project ${e} not found`);}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to archive project",n)}finally{t.close();}return this.getDetailOrThrow(e)}setScene(e,t,n={}){q(e,"projectId"),po.has(t)||L(`invalid project scene: ${String(t)}`);let o=Ue(n),s=new Date().toISOString(),a=this.openHandle(true);try{a.db.transaction(c=>{let u=c.select().from(v).where(drizzleOrm.eq(v.id,e)).get();u||re(`Project ${e} not found`),c.update(v).set({scene:t,updated_at:s}).where(drizzleOrm.eq(v.id,e)).run(),je(c,{projectId:e,...o,type:"scene_changed",title:"Project scene changed",payload:{before:u.scene,after:t}},s);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to set project scene",c)}finally{a.close();}return this.getDetailOrThrow(e)}setStageIndex(e,t,n={}){q(e,"projectId"),Number.isInteger(t)||L("stage index must be an integer");let o=Ue(n),s=new Date().toISOString(),a=this.openHandle(true);try{a.db.transaction(c=>{let u=c.select().from(v).where(drizzleOrm.eq(v.id,e)).get();u||re(`Project ${e} not found`);let l=_n(u.stages_json);(t<1||t>l.length)&&L("stage index is outside the project stages"),c.update(v).set({stage_index:t,updated_at:s}).where(drizzleOrm.eq(v.id,e)).run(),je(c,{projectId:e,...o,type:"stage_advanced",title:"Project stage advanced",payload:{before:u.stage_index,after:t}},s);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to set project stage",c)}finally{a.close();}return this.getDetailOrThrow(e)}setCriterionVerify(e,t,n,o={}){let s=typeof e=="string"?{projectId:typeof n=="string"?e:void 0,criterionId:typeof n=="string"?t:e,verifyStatus:typeof n=="string"?n:t,...typeof n=="string"?o:n}:e,a=s.verifyStatus??s.status;(!a||!_o.has(a))&&L(`invalid criterion status: ${String(a)}`),q(s.criterionId,"criterionId");let c=Ue(s),u=new Date().toISOString(),l=this.openHandle(true),p;try{l.db.transaction(g=>{let m=g.select().from(Q).where(drizzleOrm.eq(Q.id,s.criterionId)).get();m||re(`Criterion ${s.criterionId} not found`),p=m.project_id,s.projectId&&s.projectId!==m.project_id&&re(`Criterion ${s.criterionId} not found in project ${s.projectId}`),g.update(Q).set({verify_status:a,verified_at:a==="passed"?u:null,updated_at:u}).where(drizzleOrm.eq(Q.id,s.criterionId)).run(),je(g,{projectId:m.project_id,...c,type:"criterion_verified",title:"Criterion verification updated",payload:{criterionId:s.criterionId,status:a}},u);});}catch(g){throw g instanceof d?g:new d("DB_ERROR","Failed to set criterion verification",g)}finally{l.close();}let _=p?this.getProject(p)?.criteria.find(g=>g.id===s.criterionId):void 0;return _||re(`Criterion ${s.criterionId} not found`),_}setCriterionEvidence(e,t,n,o={}){let s=typeof e=="string"?{projectId:Array.isArray(n)?e:void 0,criterionId:Array.isArray(n)?t:e,evidence:Array.isArray(n)?n:t,...Array.isArray(n)?o:n}:e;q(s.criterionId,"criterionId");let a=yo(s.evidence),c=Ue(s),u=new Date().toISOString(),l=this.openHandle(true),p;try{l.db.transaction(g=>{let m=g.select().from(Q).where(drizzleOrm.eq(Q.id,s.criterionId)).get();m||re(`Criterion ${s.criterionId} not found`),p=m.project_id,s.projectId&&s.projectId!==m.project_id&&re(`Criterion ${s.criterionId} not found in project ${s.projectId}`),g.update(Q).set({evidence_json:JSON.stringify(a),updated_at:u}).where(drizzleOrm.eq(Q.id,s.criterionId)).run(),je(g,{projectId:m.project_id,...c,type:"criterion_verified",title:"Criterion evidence updated",payload:{criterionId:s.criterionId,evidence:a}},u);});}catch(g){throw g instanceof d?g:new d("DB_ERROR","Failed to set criterion evidence",g)}finally{l.close();}let _=p?this.getProject(p)?.criteria.find(g=>g.id===s.criterionId):void 0;return _||re(`Criterion ${s.criterionId} not found`),_}appendEvent(e,t){let n=typeof e=="string"?{...t,projectId:e}:e;fn(n);let o=new Date().toISOString(),s=this.openHandle(true),a;try{s.db.transaction(c=>{a=je(c,n,o);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to append project event",c)}finally{s.close();}if(!a)throw new d("DB_ERROR","Event append did not return a row");return a}listEvents(e,t={}){if(q(e,"projectId"),t.afterSeq!==void 0&&(!Number.isInteger(t.afterSeq)||t.afterSeq<0)&&L("afterSeq must be a non-negative integer"),t.limit!==void 0&&(!Number.isInteger(t.limit)||t.limit<1)&&L("limit must be a positive integer"),!this.dbExists())return [];let n=this.openHandle(false);try{let o=[drizzleOrm.eq(ce.project_id,e)];t.afterSeq!==void 0&&o.push(drizzleOrm.gt(ce.seq,t.afterSeq));let s=n.db.select().from(ce).where(drizzleOrm.and(...o)).orderBy(drizzleOrm.asc(ce.seq));return t.limit!==void 0&&(s=s.limit(t.limit)),s.all()}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to list project events",o)}finally{n.close();}}acceptProject(e,t){q(e,"projectId");let n=Ue(t),o={remainingRisks:t.remainingRisks,nextPlan:t.nextPlan,lessons:t.lessons,evidenceRefs:t.evidenceRefs};gn(o,"accepted");let s=new Date().toISOString(),a=this.openHandle(true);try{a.db.transaction(c=>{c.select({id:v.id}).from(v).where(drizzleOrm.eq(v.id,e)).get()||re(`Project ${e} not found`),c.update(v).set({scene:"accepted",accepted_at:s,updated_at:s}).where(drizzleOrm.eq(v.id,e)).run(),je(c,{projectId:e,...n,type:"accepted",title:"Project accepted",payload:o},s);});}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to accept project",c)}finally{a.close();}return this.getDetailOrThrow(e)}};var wn=[h,i,f,Ee,pe,ne,Me];function Eo(){return ye__namespace.default.join(_r__default.default.homedir(),".crewx","crewx.db")}function So(r){if(!mn__namespace.default.existsSync(r))return null;let e=Math.floor(Date.now()/1e3),t=`${r}.bak-${e}`;return mn__namespace.default.copyFileSync(r,t),t}function kn(r){let e=r.all("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");return new Set(e.map(t=>t.name))}function To(r){return r==null||typeof r=="object"&&"queryChunks"in r?null:typeof r=="number"?String(r):typeof r=="boolean"?r?"1":"0":typeof r=="string"?`'${r.replace(/'/g,"''")}'`:String(r)}function vo(r){let e=r.getSQLType(),t=`"${r.name}" ${e}`,n=To(r.default);return n!==null&&(t+=` DEFAULT ${n}`),r.notNull&&(t+=" NOT NULL"),t}function xo(r,e){let t=e?.dbPath??Eo(),n=e?.force??false,o=e?.dryRun??false,s=o?null:So(t);if(n&&!o)try{r.run("DELETE FROM __drizzle_migrations");}catch{}let a=kn(r);if(!o)try{qe(r);}catch(_){let g=_ instanceof Error?`${_.message} ${_.cause?.message??""}`:"";if(!n||!g.includes("duplicate column"))throw _}let c,u;o?(c=wn.map(g=>sqliteCore.getTableConfig(g).name).filter(g=>!a.has(g)),u=a):(u=kn(r),c=[...u].filter(_=>!a.has(_)));let l=[],p=[];for(let _ of wn){let g=sqliteCore.getTableConfig(_),m=g.name;if(!u.has(m))continue;let O=r.all(`PRAGMA table_info("${m}")`),w=new Set(O.map(S=>S.name)),j=new Set(g.columns.map(S=>S.name));for(let S of g.columns)if(!w.has(S.name)){if(!o){let W=vo(S);r.run(`ALTER TABLE "${m}" ADD COLUMN ${W}`);}l.push({table:m,column:S.name});}for(let S of O)j.has(S.name)||p.push(`${m}.${S.name} exists in DB but not in schema (untouched)`);}return {created:c,altered:l,warnings:p,backupPath:s}}function yn(r){let e=r.toLowerCase().trim();e=e.replace(/\[[^\]]*\]$/g,"");let t=e.lastIndexOf("/");return t>=0&&(e=e.slice(t+1)),e=e.replace(/-\d{8}$/,""),e}function Tn(r,e){let t=e===void 0?"":` at index ${e}`;if(!r||typeof r!="object")throw new d("VALIDATION",`Task log entry${t} must be an object`);if(typeof r.timestamp!="string"||typeof r.level!="string"||typeof r.message!="string")throw new d("VALIDATION",`Task log entry${t} must contain string timestamp, level, and message fields`);return {timestamp:r.timestamp,level:r.level,message:r.message}}function En(r,e){if(e===null||e.trim()==="")return [];let t;try{t=JSON.parse(e);}catch(n){throw new d("DB_ERROR",`Malformed legacy task logs: ${r}`,n)}if(!Array.isArray(t))throw new d("DB_ERROR",`Malformed legacy task logs: ${r} (expected an array)`);try{return t.map((n,o)=>Tn(n,o))}catch(n){throw n instanceof d?new d("DB_ERROR",`Malformed legacy task logs: ${r}`,n):n}}function vn(r){if(r.log_storage!=="blob"&&r.log_storage!=="events")throw new d("DB_ERROR",`Invalid task log storage for task: ${r.id}`);if(!Number.isInteger(r.last_log_seq)||r.last_log_seq<0)throw new d("DB_ERROR",`Invalid task log sequence for task: ${r.id}`);if(!Number.isInteger(r.log_revision)||r.log_revision<0)throw new d("DB_ERROR",`Invalid task log revision for task: ${r.id}`);return r.log_storage}function Sn(r){return {taskId:r.id,source:vn(r),revision:r.log_revision,lastSeq:r.last_log_seq}}function Oo(r){if(!Number.isInteger(r)||r<0)throw new d("VALIDATION","Task log tail limit must be a non-negative integer")}var Je=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}findStateRow(e,t){return e.db.select({id:i.id,log_storage:i.log_storage,last_log_seq:i.last_log_seq,log_revision:i.log_revision,logs:i.logs}).from(i).where(drizzleOrm.eq(i.id,t)).limit(1).get()}findStateRowInTransaction(e,t){return e.select({id:i.id,log_storage:i.log_storage,last_log_seq:i.last_log_seq,log_revision:i.log_revision,logs:i.logs}).from(i).where(drizzleOrm.eq(i.id,t)).limit(1).get()}requireStateRowInTransaction(e,t){let n=this.findStateRowInTransaction(e,t);if(!n)throw new d("NOT_FOUND",`Task not found: ${t}`);return n}appendLog(e,t){return this.appendLogs(e,[t])}appendLogs(e,t){let n=t.map((s,a)=>Tn(s,a));if(n.length===0){let s=this.getLogState(e);if(!s)throw new d("NOT_FOUND",`Task not found: ${e}`);return s}let o=this.openHandle(true);try{return o.db.transaction(a=>{let c=this.requireStateRowInTransaction(a,e),u=vn(c);if(u==="blob"){let g=En(e,c.logs);if(a.update(i).set({logs:JSON.stringify([...g,...n]),log_revision:drizzleOrm.sql`${i.log_revision} + 1`}).where(drizzleOrm.eq(i.id,e)).run().changes!==1)throw new d("NOT_FOUND",`Task not found: ${e}`);return {taskId:e,source:u,revision:c.log_revision+1,lastSeq:c.last_log_seq}}let l=c.last_log_seq+1,p=c.last_log_seq+n.length;if(a.insert(ue).values(n.map((g,m)=>({task_id:e,seq:l+m,timestamp:g.timestamp,level:g.level,message:g.message}))).run(),a.update(i).set({last_log_seq:p,log_revision:drizzleOrm.sql`${i.log_revision} + 1`}).where(drizzleOrm.eq(i.id,e)).run().changes!==1)throw new d("NOT_FOUND",`Task not found: ${e}`);return {taskId:e,source:u,revision:c.log_revision+1,lastSeq:p}},{behavior:"immediate"})}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to append task log",s)}finally{o.close();}}getLogState(e){if(!this.dbExists())return;let t=this.openHandle(false);try{let n=this.findStateRow(t,e);return n?Sn(n):void 0}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to read task log state",n)}finally{t.close();}}readLogs(e){return this.readLogsInternal(e)}readLogsTail(e,t){return Oo(t),this.readLogsInternal(e,t)}readTail(e,t){return this.readLogsTail(e,t)}readLogsInternal(e,t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.transaction(o=>{let s=this.findStateRowInTransaction(o,e);if(!s)return;let a=Sn(s);if(a.source==="blob"){let p=En(e,s.logs);return {...a,entries:t===void 0?p:p.slice(Math.max(0,p.length-t))}}let c=o.select({seq:ue.seq,timestamp:ue.timestamp,level:ue.level,message:ue.message}).from(ue).where(drizzleOrm.eq(ue.task_id,e)).orderBy(t===void 0?drizzleOrm.asc(ue.seq):drizzleOrm.desc(ue.seq)),l=(t===void 0?c.all():c.limit(t).all()).map(({timestamp:p,level:_,message:g})=>({timestamp:p,level:_,message:g}));return t!==void 0&&l.reverse(),{...a,entries:l}},{behavior:"deferred"})}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to read task logs",o)}finally{n.close();}}};var Ae="2026-05-09",Uo="0.8.9-rc.13",Ce=10,Le=parseInt(Uo.split("rc.")[1]);function xn(){let r=drizzleOrm.sql`
13
13
  CASE
14
- WHEN ${s.model} LIKE 'claude-%' OR ${s.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
15
- WHEN ${s.model} LIKE 'gpt-%' OR ${s.model} LIKE 'codex-%' THEN 'codex'
16
- WHEN ${s.model} LIKE 'gemini-%' THEN 'gemini'
17
- WHEN ${s.model} LIKE 'grok-%' THEN 'grok'
18
- WHEN ${s.model} LIKE 'zai-%' OR ${s.model} LIKE 'openrouter/z-ai/%' THEN 'opencode'
19
- WHEN ${s.model} LIKE 'minimax/%' THEN 'minimax'
20
- WHEN ${s.model} LIKE 'qwen%' THEN 'qwen'
14
+ WHEN ${i.model} LIKE 'claude-%' OR ${i.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
15
+ WHEN ${i.model} LIKE 'gpt-%' OR ${i.model} LIKE 'codex-%' THEN 'codex'
16
+ WHEN ${i.model} LIKE 'gemini-%' THEN 'gemini'
17
+ WHEN ${i.model} LIKE 'grok-%' THEN 'grok'
18
+ WHEN ${i.model} LIKE 'zai-%' OR ${i.model} LIKE 'openrouter/z-ai/%' THEN 'opencode'
19
+ WHEN ${i.model} LIKE 'minimax/%' THEN 'minimax'
20
+ WHEN ${i.model} LIKE 'qwen%' THEN 'qwen'
21
21
  ELSE 'unknown'
22
22
  END
23
- `,t=drizzleOrm.sql`json_extract(${s.metadata}, '$.provider')`,e=drizzleOrm.sql`trim(${t})`,n=drizzleOrm.sql`substr(${e}, 1, instr(${e}, '/') - 1)`,r=drizzleOrm.sql`
23
+ `,e=drizzleOrm.sql`json_extract(${i.metadata}, '$.provider')`,t=drizzleOrm.sql`trim(${e})`,n=drizzleOrm.sql`substr(${t}, 1, instr(${t}, '/') - 1)`,o=drizzleOrm.sql`
24
24
  CASE
25
- WHEN instr(${e}, '/') > 0
25
+ WHEN instr(${t}, '/') > 0
26
26
  AND ${n} IN ('cli', 'acp', 'api', 'plugin', 'remote')
27
- THEN substr(${e}, instr(${e}, '/') + 1)
28
- ELSE ${e}
27
+ THEN substr(${t}, instr(${t}, '/') + 1)
28
+ ELSE ${t}
29
29
  END
30
30
  `;return drizzleOrm.sql`
31
31
  CASE
32
- WHEN ${s.metadata} IS NULL THEN ${i}
33
- WHEN json_valid(${s.metadata}) = 0 THEN 'unknown'
34
- WHEN json_type(${s.metadata}, '$') IS NOT 'object' THEN 'unknown'
35
- WHEN json_type(${s.metadata}, '$.provider') IS NULL THEN ${i}
36
- WHEN json_type(${s.metadata}, '$.provider') IS NOT 'text' THEN 'unknown'
37
- WHEN ${e} = '' THEN 'unknown'
38
- WHEN trim(${r}) = '' THEN 'unknown'
39
- ELSE ${r}
32
+ WHEN ${i.metadata} IS NULL THEN ${r}
33
+ WHEN json_valid(${i.metadata}) = 0 THEN 'unknown'
34
+ WHEN json_type(${i.metadata}, '$') IS NOT 'object' THEN 'unknown'
35
+ WHEN json_type(${i.metadata}, '$.provider') IS NULL THEN ${r}
36
+ WHEN json_type(${i.metadata}, '$.provider') IS NOT 'text' THEN 'unknown'
37
+ WHEN ${t} = '' THEN 'unknown'
38
+ WHEN trim(${o}) = '' THEN 'unknown'
39
+ ELSE ${o}
40
40
  END
41
- `}var Wr=new Set(["workflow","mcp"]),nn=600*1e3,fe=class extends T{dbPath;pidNullObservedSince=new Map;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}startTask(t){let e=this.openHandle(true);try{e.db.insert(s).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,project_id:t.projectId??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:s.id,set:{pid:drizzleOrm.sql`COALESCE(excluded.pid, ${s.pid})`},setWhere:drizzleOrm.eq(s.status,"running")}).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to start task",n)}finally{e.close();}}listTasksByProjectId(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(s).where(drizzleOrm.eq(s.project_id,t)).orderBy(drizzleOrm.desc(s.started_at)).all()}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to list tasks by project",n)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{let n=t.runEpoch??null;e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
41
+ `}var Fo=new Set(["workflow","mcp"]),Nn=600*1e3,Tt=class extends x{dbPath;taskLogRepository;pidNullObservedSince=new Map;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db")),this.taskLogRepository=new Je({dbPath:this.dbPath});}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}startTask(e){let t=this.openHandle(true);try{let n={id:e.id,agent_id:e.agentId,prompt:e.prompt,mode:e.mode,status:e.status,started_at:e.startedAt,pid:e.pid??null,parent_task_id:e.parentTaskId??null,caller_agent_id:e.callerAgentId??null,trace_id:e.traceId??null,command:e.command??null,metadata:e.metadata??null,workspace_id:e.workspaceId??null,project_id:e.projectId??null,platform:e.platform??"cli",crewx_version:e.crewxVersion??null,thread_id:e.threadId??null,model:e.model??null,rendered_prompt:e.renderedPrompt??null,coding_agent_command:e.codingAgentCommand??null,log_storage:"events"},o=s=>{t.db.insert(i).values(s).onConflictDoUpdate({target:i.id,set:{pid:drizzleOrm.sql`COALESCE(excluded.pid, ${i.pid})`},setWhere:drizzleOrm.eq(i.status,"running")}).run();};try{o(n);}catch(s){let a=s instanceof Error?s.message:typeof s=="object"&&s!==null&&"message"in s?String(s.message):String(s);if(!/log_storage/i.test(a)||!/no such column|no column named/i.test(a))throw s;t.runRaw(`INSERT INTO tasks (
42
+ id, agent_id, prompt, mode, status, started_at, pid,
43
+ parent_task_id, caller_agent_id, trace_id, command, metadata,
44
+ workspace_id, project_id, platform, crewx_version, thread_id,
45
+ model, rendered_prompt, coding_agent_command
46
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
47
+ ON CONFLICT(id) DO UPDATE SET pid = COALESCE(excluded.pid, tasks.pid)
48
+ WHERE tasks.status = 'running'`,[n.id,n.agent_id,n.prompt,n.mode,n.status,n.started_at,n.pid,n.parent_task_id,n.caller_agent_id,n.trace_id,n.command,n.metadata,n.workspace_id,n.project_id,n.platform,n.crewx_version,n.thread_id,n.model,n.rendered_prompt,n.coding_agent_command]);}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to start task",n)}finally{t.close();}}listTasksByProjectId(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(i).where(drizzleOrm.eq(i.project_id,e)).orderBy(drizzleOrm.desc(i.started_at)).all()}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to list tasks by project",n)}finally{t.close();}}finishTask(e){let t=this.openHandle(true);try{let n=e.runEpoch??null;t.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
42
49
  exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
43
50
  model=COALESCE(?, model)
44
- 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,n]);}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to finish task",n)}finally{e.close();}}appendLog(t,e){let n=this.openHandle(true);try{n.db.transaction(r=>{let o=r.select({logs:s.logs}).from(s).where(drizzleOrm.eq(s.id,t)).limit(1).get(),a=o?.logs?JSON.parse(o.logs):[];a.push(e),r.update(s).set({logs:JSON.stringify(a)}).where(drizzleOrm.eq(s.id,t)).run();},{behavior:"immediate"});}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to append log",r)}finally{n.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(s).where(drizzleOrm.eq(s.status,"running")).orderBy(drizzleOrm.desc(s.started_at)).all()}catch(e){throw new d("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(s).orderBy(drizzleOrm.desc(s.started_at)).limit(100).all()}catch(e){throw new d("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(s).where(drizzleOrm.eq(s.id,t)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to get task",n)}finally{e.close();}}killTask(t){if(!this.dbExists())return {killed:false};let e=this.openHandle(true);try{let n=e.db.select({id:s.id,status:s.status,pid:s.pid}).from(s).where(drizzleOrm.eq(s.id,t)).limit(1).get();if(!n||n.status!=="running")return {killed:!1};if(n.pid)try{process.kill(n.pid,"SIGTERM");}catch{}return e.db.update(s).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(s.id,t),drizzleOrm.eq(s.status,"running"))).run(),{killed:!0,pid:n.pid??void 0}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to kill task",n)}finally{e.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let e=t.db.select({id:s.id,pid:s.pid,platform:s.platform,run_epoch:s.run_epoch}).from(s).where(drizzleOrm.eq(s.status,"running")).all(),n=Date.now(),r=new Set,o=0;for(let a of e){if(a.pid){let l=!1;try{process.kill(a.pid,0),l=!0;}catch{}l||(t.db.update(s).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(s.id,a.id),drizzleOrm.eq(s.status,"running"))).run(),o++);continue}if(Wr.has(a.platform??"cli"))continue;let c=`${a.id}:${a.run_epoch??0}`;r.add(c);let u=this.pidNullObservedSince.get(c);if(u===void 0){this.pidNullObservedSince.set(c,n);continue}n-u>=nn&&(t.db.update(s).set({status:"failed",error:"Reaped: pid never recorded after resume (stale running_instruction)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(s.id,a.id),drizzleOrm.eq(s.status,"running"))).run(),o++,this.pidNullObservedSince.delete(c));}for(let a of Array.from(this.pidNullObservedSince.keys()))r.has(a)||this.pidNullObservedSince.delete(a);return o}finally{t.close();}}reapRunningWorkflowTasks(t=nn){if(!this.dbExists())return 0;let e=this.openHandle(true);try{let n=new Date(Date.now()-t).toISOString();return e.db.update(s).set({status:"failed",error:"Reaped: stale workflow run (finally not executed)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(s.status,"running"),drizzleOrm.eq(s.platform,"workflow"),drizzleOrm.isNull(s.pid),drizzleOrm.lt(s.started_at,n),drizzleOrm.or(drizzleOrm.isNull(s.metadata),drizzleOrm.and(drizzleOrm.notLike(s.metadata,'%"kind":"workflow_card"%'),drizzleOrm.notLike(s.metadata,'%"kind":"workflow_ui_instance"%'))))).run().changes??0}finally{e.close();}}findTaskStatus(t,e){let n=this.resolveDbPaths();for(let r of n){if(!Ye.existsSync(r))continue;let o=w(r);try{let a=e?drizzleOrm.eq(s.workspace_id,e):void 0,c=a?drizzleOrm.and(drizzleOrm.eq(s.id,t),a):drizzleOrm.eq(s.id,t),u=o.db.select().from(s).where(c).limit(1).get()??void 0;if(!u){let l=drizzleOrm.or(drizzleOrm.eq(s.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(s.thread_id),drizzleOrm.like(s.command,`%--thread=${t}%`))),p=a?drizzleOrm.and(l,a):l;u=o.db.select().from(s).where(p).orderBy(drizzleOrm.desc(s.started_at)).limit(1).get()??void 0;}if(u)return u}catch(a){throw new d("DB_ERROR","Failed to find task status",a)}finally{o.close();}}}findChildTasks(t,e){let n=this.resolveDbPaths(),r=new Set,o=[];for(let a of n){if(!Ye.existsSync(a))continue;let c=w(a);try{let u=e?drizzleOrm.and(drizzleOrm.eq(s.parent_task_id,t),drizzleOrm.eq(s.workspace_id,e)):drizzleOrm.eq(s.parent_task_id,t),l=c.db.select().from(s).where(u).orderBy(drizzleOrm.asc(s.started_at)).all();for(let p of l)r.has(p.id)||(r.add(p.id),o.push(p));}catch(u){throw new d("DB_ERROR","Failed to find child tasks",u)}finally{c.close();}}return o}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.all(t?drizzleOrm.sql`
51
+ WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[e.status,e.result??null,e.error??null,e.completedAt,e.durationMs??null,e.exitCode??null,e.inputTokens??0,e.outputTokens??0,e.cachedInputTokens??0,e.costUsd??0,e.model??null,e.id,n]);}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to finish task",n)}finally{t.close();}}appendLog(e,t){this.taskLogRepository.appendLog(e,t);}appendLogs(e,t){this.taskLogRepository.appendLogs(e,t);}readLogs(e){return this.taskLogRepository.readLogs(e)}readLogsTail(e,t){return this.taskLogRepository.readLogsTail(e,t)}getLogState(e){return this.taskLogRepository.getLogState(e)}getRunningTasks(){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(i).where(drizzleOrm.eq(i.status,"running")).orderBy(drizzleOrm.desc(i.started_at)).all()}catch(t){throw new d("DB_ERROR","Failed to get running tasks",t)}finally{e.close();}}getAllTasks(){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(i).orderBy(drizzleOrm.desc(i.started_at)).limit(100).all()}catch(t){throw new d("DB_ERROR","Failed to get all tasks",t)}finally{e.close();}}getTask(e){if(!this.dbExists())return;let t=this.openHandle(false);try{return t.db.select().from(i).where(drizzleOrm.eq(i.id,e)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to get task",n)}finally{t.close();}}killTask(e){if(!this.dbExists())return {killed:false};let t=this.openHandle(true);try{let n=t.db.select({id:i.id,status:i.status,pid:i.pid}).from(i).where(drizzleOrm.eq(i.id,e)).limit(1).get();if(!n||n.status!=="running")return {killed:!1};if(n.pid)try{process.kill(n.pid,"SIGTERM");}catch{}return t.db.update(i).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(i.id,e),drizzleOrm.eq(i.status,"running"))).run(),{killed:!0,pid:n.pid??void 0}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to kill task",n)}finally{t.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let e=this.openHandle(true);try{let t=e.db.select({id:i.id,pid:i.pid,platform:i.platform,run_epoch:i.run_epoch}).from(i).where(drizzleOrm.eq(i.status,"running")).all(),n=Date.now(),o=new Set,s=0;for(let a of t){if(a.pid){let l=!1;try{process.kill(a.pid,0),l=!0;}catch{}l||(e.db.update(i).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(i.id,a.id),drizzleOrm.eq(i.status,"running"))).run(),s++);continue}if(Fo.has(a.platform??"cli"))continue;let c=`${a.id}:${a.run_epoch??0}`;o.add(c);let u=this.pidNullObservedSince.get(c);if(u===void 0){this.pidNullObservedSince.set(c,n);continue}n-u>=Nn&&(e.db.update(i).set({status:"failed",error:"Reaped: pid never recorded after resume (stale running_instruction)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(i.id,a.id),drizzleOrm.eq(i.status,"running"))).run(),s++,this.pidNullObservedSince.delete(c));}for(let a of Array.from(this.pidNullObservedSince.keys()))o.has(a)||this.pidNullObservedSince.delete(a);return s}finally{e.close();}}reapRunningWorkflowTasks(e=Nn){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let n=new Date(Date.now()-e).toISOString();return t.db.update(i).set({status:"failed",error:"Reaped: stale workflow run (finally not executed)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(i.status,"running"),drizzleOrm.eq(i.platform,"workflow"),drizzleOrm.isNull(i.pid),drizzleOrm.lt(i.started_at,n),drizzleOrm.or(drizzleOrm.isNull(i.metadata),drizzleOrm.and(drizzleOrm.notLike(i.metadata,'%"kind":"workflow_card"%'),drizzleOrm.notLike(i.metadata,'%"kind":"workflow_ui_instance"%'))))).run().changes??0}finally{t.close();}}findTaskStatus(e,t){let n=this.resolveDbPaths();for(let o of n){if(!mn.existsSync(o))continue;let s=k(o);try{let a=t?drizzleOrm.eq(i.workspace_id,t):void 0,c=a?drizzleOrm.and(drizzleOrm.eq(i.id,e),a):drizzleOrm.eq(i.id,e),u=s.db.select().from(i).where(c).limit(1).get()??void 0;if(!u){let l=drizzleOrm.or(drizzleOrm.eq(i.thread_id,e),drizzleOrm.and(drizzleOrm.isNull(i.thread_id),drizzleOrm.like(i.command,`%--thread=${e}%`))),p=a?drizzleOrm.and(l,a):l;u=s.db.select().from(i).where(p).orderBy(drizzleOrm.desc(i.started_at)).limit(1).get()??void 0;}if(u)return u}catch(a){throw new d("DB_ERROR","Failed to find task status",a)}finally{s.close();}}}findChildTasks(e,t){let n=this.resolveDbPaths(),o=new Set,s=[];for(let a of n){if(!mn.existsSync(a))continue;let c=k(a);try{let u=t?drizzleOrm.and(drizzleOrm.eq(i.parent_task_id,e),drizzleOrm.eq(i.workspace_id,t)):drizzleOrm.eq(i.parent_task_id,e),l=c.db.select().from(i).where(u).orderBy(drizzleOrm.asc(i.started_at)).all();for(let p of l)o.has(p.id)||(o.add(p.id),s.push(p));}catch(u){throw new d("DB_ERROR","Failed to find child tasks",u)}finally{c.close();}}return s}getWorkspaceUsageSummary(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.all(e?drizzleOrm.sql`
45
52
  SELECT
46
53
  COALESCE(workspace_id, 'unknown') AS workspace_id,
47
54
  COALESCE(SUM(input_tokens), 0) AS input_tokens,
@@ -49,7 +56,7 @@ ${n.join(`
49
56
  COALESCE(SUM(cost_usd), 0) AS cost_usd,
50
57
  COUNT(*) AS task_count
51
58
  FROM tasks
52
- WHERE workspace_id = ${t}
59
+ WHERE workspace_id = ${e}
53
60
  GROUP BY workspace_id
54
61
  ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
55
62
  `:drizzleOrm.sql`
@@ -62,7 +69,7 @@ ${n.join(`
62
69
  FROM tasks
63
70
  GROUP BY workspace_id
64
71
  ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
65
- `)}catch(n){throw new d("DB_ERROR","Failed to get workspace usage summary",n)}finally{e.close();}}getThreadTokenUsage(t,e){let n=this.resolveDbPaths(),r=new Set,o=0,a=0,c=0;for(let u of n){if(!Ye.existsSync(u))continue;let l=w(u);try{let p=drizzleOrm.or(drizzleOrm.eq(s.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(s.thread_id),drizzleOrm.like(s.command,`%--thread=${t}%`))),h=e?drizzleOrm.and(p,drizzleOrm.eq(s.workspace_id,e)):p,f=l.db.select({id:s.id,input_tokens:s.input_tokens,output_tokens:s.output_tokens,cost_usd:s.cost_usd}).from(s).where(h).all();for(let m of f)r.has(m.id)||(r.add(m.id),o+=m.input_tokens??0,a+=m.output_tokens??0,c+=m.cost_usd??0);}catch(p){throw new d("DB_ERROR","Failed to get thread token usage",p)}finally{l.close();}}return {inputTokens:o,outputTokens:a,costUsd:c}}findTasksByThread(t,e){let n=this.resolveDbPaths(),r=new Set,o=[];for(let a of n){if(!Ye.existsSync(a))continue;let c=w(a);try{let u=drizzleOrm.or(drizzleOrm.eq(s.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(s.thread_id),drizzleOrm.like(s.command,`%--thread=${t}%`))),l=e?drizzleOrm.and(u,drizzleOrm.eq(s.workspace_id,e)):u,p=c.db.select().from(s).where(l).orderBy(drizzleOrm.asc(s.started_at)).all();for(let h of p)r.has(h.id)||(r.add(h.id),o.push(h));}catch(u){throw new d("DB_ERROR","Failed to find tasks by thread",u)}finally{c.close();}}return o}parseWorkflowCardMetadata(t){if(!t)return {};try{let e=JSON.parse(t);return {kind:typeof e.kind=="string"?e.kind:void 0,workflowRunId:typeof e.workflowRunId=="string"?e.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 e of this.resolveDbPaths()){if(!Ye.existsSync(e))continue;let n=w(e);try{t.push(...n.db.select({id:s.id,agent_id:s.agent_id,thread_id:s.thread_id,workspace_id:s.workspace_id,platform:s.platform,status:s.status,error:s.error,completed_at:s.completed_at,duration_ms:s.duration_ms,started_at:s.started_at,metadata:s.metadata}).from(s).where(drizzleOrm.and(drizzleOrm.eq(s.platform,"workflow"),drizzleOrm.or(drizzleOrm.like(s.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(s.metadata,'%"kind":"workflow_ui_instance"%')))).orderBy(drizzleOrm.desc(s.started_at)).all());}catch(r){throw new d("DB_ERROR","Failed to find workflow parent tasks",r)}finally{n.close();}}return t}batchFetchWorkflowCards(t,e){let n=new Map;if(t.length===0)return n;let r=new Set(t),o=new Map,a=e?drizzleOrm.eq(s.workspace_id,e):void 0,c=(u,l)=>{if(!u)return;let p=o.get(u);if(p&&l.started_at<=p)return;let h=this.parseWorkflowCardMetadata(l.metadata);h.kind!=="workflow_card"&&h.kind!=="workflow_ui_instance"||(o.set(u,l.started_at),n.set(u,{taskId:l.id,workflowRunId:h.workflowRunId,raw:l.result??void 0}));};for(let u of this.resolveDbPaths()){if(!Ye.existsSync(u))continue;let l=w(u);try{let p=drizzleOrm.and(drizzleOrm.inArray(s.thread_id,t),drizzleOrm.or(drizzleOrm.like(s.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(s.metadata,'%"kind":"workflow_ui_instance"%'))),h=l.db.select({id:s.id,thread_id:s.thread_id,metadata:s.metadata,result:s.result,started_at:s.started_at}).from(s).where(a?drizzleOrm.and(p,a):p).all();for(let M of h)c(M.thread_id,M);let f=drizzleOrm.and(drizzleOrm.isNull(s.thread_id),drizzleOrm.or(drizzleOrm.like(s.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(s.metadata,'%"kind":"workflow_ui_instance"%'))),m=l.db.select({id:s.id,command:s.command,metadata:s.metadata,result:s.result,started_at:s.started_at}).from(s).where(a?drizzleOrm.and(f,a):f).all();for(let M of m){let F=this.extractThreadIdFromCommand(M.command);!F||!r.has(F)||c(F,M);}}catch(p){throw new d("DB_ERROR","Failed to batch fetch workflow cards",p)}finally{l.close();}}return n}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let n=[];t.workspaceId&&n.push(drizzleOrm.eq(s.workspace_id,t.workspaceId));let r=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;r&&n.push(drizzleOrm.inArray(s.agent_id,r));let o=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;o&&n.push(drizzleOrm.inArray(s.status,o));let a=t.q??t.search;a&&n.push(drizzleOrm.like(s.prompt,`%${a}%`)),t.from&&n.push(drizzleOrm.gte(s.started_at,t.from)),t.to&&n.push(drizzleOrm.lt(s.started_at,t.to));let c=n.length>0?drizzleOrm.and(...n):void 0,u=e.db.select({count:drizzleOrm.sql`count(*)`}).from(s).where(c).get(),l=(t.sortDir??"DESC")==="ASC"?drizzleOrm.asc(s.started_at):drizzleOrm.desc(s.started_at);return {rows:e.db.select().from(s).where(c).orderBy(l).limit(t.limit).offset(t.offset).all(),total:u?.count??0}}catch(n){throw new d("DB_ERROR","Failed to find all tasks",n)}finally{e.close();}}getAgentUsage(t,e,n){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(n?drizzleOrm.sql`
72
+ `)}catch(n){throw new d("DB_ERROR","Failed to get workspace usage summary",n)}finally{t.close();}}getThreadTokenUsage(e,t){let n=this.resolveDbPaths(),o=new Set,s=0,a=0,c=0;for(let u of n){if(!mn.existsSync(u))continue;let l=k(u);try{let p=drizzleOrm.or(drizzleOrm.eq(i.thread_id,e),drizzleOrm.and(drizzleOrm.isNull(i.thread_id),drizzleOrm.like(i.command,`%--thread=${e}%`))),_=t?drizzleOrm.and(p,drizzleOrm.eq(i.workspace_id,t)):p,g=l.db.select({id:i.id,input_tokens:i.input_tokens,output_tokens:i.output_tokens,cost_usd:i.cost_usd}).from(i).where(_).all();for(let m of g)o.has(m.id)||(o.add(m.id),s+=m.input_tokens??0,a+=m.output_tokens??0,c+=m.cost_usd??0);}catch(p){throw new d("DB_ERROR","Failed to get thread token usage",p)}finally{l.close();}}return {inputTokens:s,outputTokens:a,costUsd:c}}findTasksByThread(e,t){let n=this.resolveDbPaths(),o=new Set,s=[];for(let a of n){if(!mn.existsSync(a))continue;let c=k(a);try{let u=drizzleOrm.or(drizzleOrm.eq(i.thread_id,e),drizzleOrm.and(drizzleOrm.isNull(i.thread_id),drizzleOrm.like(i.command,`%--thread=${e}%`))),l=t?drizzleOrm.and(u,drizzleOrm.eq(i.workspace_id,t)):u,p=c.db.select().from(i).where(l).orderBy(drizzleOrm.asc(i.started_at)).all();for(let _ of p)o.has(_.id)||(o.add(_.id),s.push(_));}catch(u){throw new d("DB_ERROR","Failed to find tasks by thread",u)}finally{c.close();}}return s}parseWorkflowCardMetadata(e){if(!e)return {};try{let t=JSON.parse(e);return {kind:typeof t.kind=="string"?t.kind:void 0,workflowRunId:typeof t.workflowRunId=="string"?t.workflowRunId:void 0}}catch{return {}}}extractThreadIdFromCommand(e){return e?/--thread=(\S+)/.exec(e)?.[1]??null:null}findRunningWorkflowParentTasks(){if(!this.dbExists())return [];let e=[];for(let t of this.resolveDbPaths()){if(!mn.existsSync(t))continue;let n=k(t);try{e.push(...n.db.select({id:i.id,agent_id:i.agent_id,thread_id:i.thread_id,workspace_id:i.workspace_id,platform:i.platform,status:i.status,error:i.error,completed_at:i.completed_at,duration_ms:i.duration_ms,started_at:i.started_at,metadata:i.metadata}).from(i).where(drizzleOrm.and(drizzleOrm.eq(i.platform,"workflow"),drizzleOrm.or(drizzleOrm.like(i.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(i.metadata,'%"kind":"workflow_ui_instance"%')))).orderBy(drizzleOrm.desc(i.started_at)).all());}catch(o){throw new d("DB_ERROR","Failed to find workflow parent tasks",o)}finally{n.close();}}return e}batchFetchWorkflowCards(e,t){let n=new Map;if(e.length===0)return n;let o=new Set(e),s=new Map,a=t?drizzleOrm.eq(i.workspace_id,t):void 0,c=(u,l)=>{if(!u)return;let p=s.get(u);if(p&&l.started_at<=p)return;let _=this.parseWorkflowCardMetadata(l.metadata);_.kind!=="workflow_card"&&_.kind!=="workflow_ui_instance"||(s.set(u,l.started_at),n.set(u,{taskId:l.id,workflowRunId:_.workflowRunId,raw:l.result??void 0}));};for(let u of this.resolveDbPaths()){if(!mn.existsSync(u))continue;let l=k(u);try{let p=drizzleOrm.and(drizzleOrm.inArray(i.thread_id,e),drizzleOrm.or(drizzleOrm.like(i.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(i.metadata,'%"kind":"workflow_ui_instance"%'))),_=l.db.select({id:i.id,thread_id:i.thread_id,metadata:i.metadata,result:i.result,started_at:i.started_at}).from(i).where(a?drizzleOrm.and(p,a):p).all();for(let O of _)c(O.thread_id,O);let g=drizzleOrm.and(drizzleOrm.isNull(i.thread_id),drizzleOrm.or(drizzleOrm.like(i.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(i.metadata,'%"kind":"workflow_ui_instance"%'))),m=l.db.select({id:i.id,command:i.command,metadata:i.metadata,result:i.result,started_at:i.started_at}).from(i).where(a?drizzleOrm.and(g,a):g).all();for(let O of m){let w=this.extractThreadIdFromCommand(O.command);!w||!o.has(w)||c(w,O);}}catch(p){throw new d("DB_ERROR","Failed to batch fetch workflow cards",p)}finally{l.close();}}return n}findAllTasks(e){if(!this.dbExists())return {rows:[],total:0};let t=this.openHandle(false);try{let n=[];e.workspaceId&&n.push(drizzleOrm.eq(i.workspace_id,e.workspaceId));let o=e.agents&&e.agents.length>0?e.agents:e.agentId?[e.agentId]:null;o&&n.push(drizzleOrm.inArray(i.agent_id,o));let s=e.statuses&&e.statuses.length>0?e.statuses:e.status?[e.status]:null;s&&n.push(drizzleOrm.inArray(i.status,s));let a=e.q??e.search;a&&n.push(drizzleOrm.like(i.prompt,`%${a}%`)),e.from&&n.push(drizzleOrm.gte(i.started_at,e.from)),e.to&&n.push(drizzleOrm.lt(i.started_at,e.to));let c=n.length>0?drizzleOrm.and(...n):void 0,u=t.db.select({count:drizzleOrm.sql`count(*)`}).from(i).where(c).get(),l=(e.sortDir??"DESC")==="ASC"?drizzleOrm.asc(i.started_at):drizzleOrm.desc(i.started_at);return {rows:t.db.select().from(i).where(c).orderBy(l).limit(e.limit).offset(e.offset).all(),total:u?.count??0}}catch(n){throw new d("DB_ERROR","Failed to find all tasks",n)}finally{t.close();}}getAgentUsage(e,t,n){if(!this.dbExists())return [];let o=this.openHandle(false);try{return o.db.all(n?drizzleOrm.sql`
66
73
  SELECT
67
74
  t.agent_id,
68
75
  t.workspace_id,
@@ -70,11 +77,11 @@ ${n.join(`
70
77
  COALESCE(SUM(
71
78
  COALESCE(t.input_tokens, 0)
72
79
  + CASE
73
- WHEN t.started_at >= ${St}
80
+ WHEN t.started_at >= ${Ae}
74
81
  AND (
75
82
  t.crewx_version IS NULL
76
83
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
77
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${xt}) AS INTEGER) < ${Tt})
84
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${Ce}) AS INTEGER) < ${Le})
78
85
  )
79
86
  THEN COALESCE(t.cached_input_tokens, 0)
80
87
  ELSE 0
@@ -85,19 +92,19 @@ ${n.join(`
85
92
  COALESCE(SUM(t.cost_usd), 0) AS cost_usd
86
93
  FROM tasks t
87
94
  WHERE t.status IN ('completed', 'success')
88
- AND t.started_at >= ${t}
89
- AND t.started_at < ${e}
95
+ AND t.started_at >= ${e}
96
+ AND t.started_at < ${t}
90
97
  AND t.workspace_id = ${n}
91
98
  GROUP BY t.agent_id, t.workspace_id
92
99
  ORDER BY (
93
100
  COALESCE(SUM(
94
101
  COALESCE(t.input_tokens, 0)
95
102
  + CASE
96
- WHEN t.started_at >= ${St}
103
+ WHEN t.started_at >= ${Ae}
97
104
  AND (
98
105
  t.crewx_version IS NULL
99
106
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
100
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${xt}) AS INTEGER) < ${Tt})
107
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${Ce}) AS INTEGER) < ${Le})
101
108
  )
102
109
  THEN COALESCE(t.cached_input_tokens, 0)
103
110
  ELSE 0
@@ -113,11 +120,11 @@ ${n.join(`
113
120
  COALESCE(SUM(
114
121
  COALESCE(t.input_tokens, 0)
115
122
  + CASE
116
- WHEN t.started_at >= ${St}
123
+ WHEN t.started_at >= ${Ae}
117
124
  AND (
118
125
  t.crewx_version IS NULL
119
126
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
120
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${xt}) AS INTEGER) < ${Tt})
127
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${Ce}) AS INTEGER) < ${Le})
121
128
  )
122
129
  THEN COALESCE(t.cached_input_tokens, 0)
123
130
  ELSE 0
@@ -128,18 +135,18 @@ ${n.join(`
128
135
  COALESCE(SUM(t.cost_usd), 0) AS cost_usd
129
136
  FROM tasks t
130
137
  WHERE t.status IN ('completed', 'success')
131
- AND t.started_at >= ${t}
132
- AND t.started_at < ${e}
138
+ AND t.started_at >= ${e}
139
+ AND t.started_at < ${t}
133
140
  GROUP BY t.agent_id, t.workspace_id
134
141
  ORDER BY (
135
142
  COALESCE(SUM(
136
143
  COALESCE(t.input_tokens, 0)
137
144
  + CASE
138
- WHEN t.started_at >= ${St}
145
+ WHEN t.started_at >= ${Ae}
139
146
  AND (
140
147
  t.crewx_version IS NULL
141
148
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
142
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${xt}) AS INTEGER) < ${Tt})
149
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${Ce}) AS INTEGER) < ${Le})
143
150
  )
144
151
  THEN COALESCE(t.cached_input_tokens, 0)
145
152
  ELSE 0
@@ -147,18 +154,18 @@ ${n.join(`
147
154
  ), 0)
148
155
  + COALESCE(SUM(t.output_tokens), 0)
149
156
  ) DESC
150
- `).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(o){throw new d("DB_ERROR","Failed to get agent usage",o)}finally{r.close();}}getAgentUsageTrendRaw(t,e,n){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(n?drizzleOrm.sql`
157
+ `).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(s){throw new d("DB_ERROR","Failed to get agent usage",s)}finally{o.close();}}getAgentUsageTrendRaw(e,t,n){if(!this.dbExists())return [];let o=this.openHandle(false);try{return o.db.all(n?drizzleOrm.sql`
151
158
  SELECT
152
159
  date(t.started_at) AS date,
153
160
  t.agent_id,
154
161
  COALESCE(SUM(
155
162
  COALESCE(t.input_tokens, 0)
156
163
  + CASE
157
- WHEN t.started_at >= ${St}
164
+ WHEN t.started_at >= ${Ae}
158
165
  AND (
159
166
  t.crewx_version IS NULL
160
167
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
161
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${xt}) AS INTEGER) < ${Tt})
168
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${Ce}) AS INTEGER) < ${Le})
162
169
  )
163
170
  THEN COALESCE(t.cached_input_tokens, 0)
164
171
  ELSE 0
@@ -169,8 +176,8 @@ ${n.join(`
169
176
  COALESCE(SUM(t.cost_usd), 0) AS cost_usd
170
177
  FROM tasks t
171
178
  WHERE t.status IN ('completed', 'success')
172
- AND t.started_at >= ${t}
173
- AND t.started_at < ${e}
179
+ AND t.started_at >= ${e}
180
+ AND t.started_at < ${t}
174
181
  AND t.workspace_id = ${n}
175
182
  GROUP BY date(t.started_at), t.agent_id
176
183
  ORDER BY date(t.started_at) ASC
@@ -181,11 +188,11 @@ ${n.join(`
181
188
  COALESCE(SUM(
182
189
  COALESCE(t.input_tokens, 0)
183
190
  + CASE
184
- WHEN t.started_at >= ${St}
191
+ WHEN t.started_at >= ${Ae}
185
192
  AND (
186
193
  t.crewx_version IS NULL
187
194
  OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
188
- OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${xt}) AS INTEGER) < ${Tt})
195
+ OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${Ce}) AS INTEGER) < ${Le})
189
196
  )
190
197
  THEN COALESCE(t.cached_input_tokens, 0)
191
198
  ELSE 0
@@ -196,78 +203,93 @@ ${n.join(`
196
203
  COALESCE(SUM(t.cost_usd), 0) AS cost_usd
197
204
  FROM tasks t
198
205
  WHERE t.status IN ('completed', 'success')
199
- AND t.started_at >= ${t}
200
- AND t.started_at < ${e}
206
+ AND t.started_at >= ${e}
207
+ AND t.started_at < ${t}
201
208
  GROUP BY date(t.started_at), t.agent_id
202
209
  ORDER BY date(t.started_at) ASC
203
- `).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(o){throw new d("DB_ERROR","Failed to get agent usage trend",o)}finally{r.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(s).where(drizzleOrm.and(drizzleOrm.eq(s.id,t),drizzleOrm.eq(s.workspace_id,e))).limit(1).get()??void 0}catch(r){throw new d("DB_ERROR","Failed to find task for stop",r)}finally{n.close();}}findLatestTaskByMetadata(t){if(!this.dbExists())return null;let e=this.openHandle(false);try{return e.db.select({id:s.id,thread_id:s.thread_id,status:s.status,result:s.result,error:s.error,started_at:s.started_at,completed_at:s.completed_at,metadata:s.metadata}).from(s).where(drizzleOrm.and(drizzleOrm.eq(s.agent_id,t.agentId),drizzleOrm.eq(s.workspace_id,t.workspaceId),drizzleOrm.sql`${s.metadata} IS NOT NULL AND json_valid(${s.metadata}) AND json_extract(${s.metadata}, '$.' || ${t.metaKey}) = ${t.metaValue}`)).orderBy(drizzleOrm.desc(s.started_at)).limit(1).get()??null}catch(n){throw new d("DB_ERROR","Failed to find latest task by metadata",n)}finally{e.close();}}markTaskFailed(t,e,n){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=new Date().toISOString(),a=n?drizzleOrm.and(drizzleOrm.eq(s.id,t),drizzleOrm.eq(s.status,"running"),drizzleOrm.eq(s.workspace_id,n)):drizzleOrm.and(drizzleOrm.eq(s.id,t),drizzleOrm.eq(s.status,"running"));r.db.update(s).set({status:"failed",error:e,completed_at:o}).where(a).run();}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to mark task failed",o)}finally{r.close();}}findTasksByPromptHint(t,e){let n=this.resolveDbPaths(),r=new Set,o=[];for(let a of n){if(!Ye.existsSync(a))continue;let c=w(a);try{let u=e?drizzleOrm.and(drizzleOrm.like(s.prompt,`%${t}%`),drizzleOrm.eq(s.workspace_id,e)):drizzleOrm.like(s.prompt,`%${t}%`),l=c.db.select().from(s).where(u).orderBy(drizzleOrm.asc(s.started_at)).all();for(let p of l)r.has(p.id)||(r.add(p.id),o.push(p));}catch(u){throw new d("DB_ERROR","Failed to find tasks by prompt hint",u)}finally{c.close();}}return o}getProviderUsage(t,e,n){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=en(),a=drizzleOrm.sql`
204
- COALESCE(${s.input_tokens}, 0)
210
+ `).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(s){throw new d("DB_ERROR","Failed to get agent usage trend",s)}finally{o.close();}}findTaskForStop(e,t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(i).where(drizzleOrm.and(drizzleOrm.eq(i.id,e),drizzleOrm.eq(i.workspace_id,t))).limit(1).get()??void 0}catch(o){throw new d("DB_ERROR","Failed to find task for stop",o)}finally{n.close();}}findLatestTaskByMetadata(e){if(!this.dbExists())return null;let t=this.openHandle(false);try{return t.db.select({id:i.id,thread_id:i.thread_id,status:i.status,result:i.result,error:i.error,started_at:i.started_at,completed_at:i.completed_at,metadata:i.metadata}).from(i).where(drizzleOrm.and(drizzleOrm.eq(i.agent_id,e.agentId),drizzleOrm.eq(i.workspace_id,e.workspaceId),drizzleOrm.sql`${i.metadata} IS NOT NULL AND json_valid(${i.metadata}) AND json_extract(${i.metadata}, '$.' || ${e.metaKey}) = ${e.metaValue}`)).orderBy(drizzleOrm.desc(i.started_at)).limit(1).get()??null}catch(n){throw new d("DB_ERROR","Failed to find latest task by metadata",n)}finally{t.close();}}markTaskFailed(e,t,n){if(!this.dbExists())return;let o=this.openHandle(true);try{let s=new Date().toISOString(),a=n?drizzleOrm.and(drizzleOrm.eq(i.id,e),drizzleOrm.eq(i.status,"running"),drizzleOrm.eq(i.workspace_id,n)):drizzleOrm.and(drizzleOrm.eq(i.id,e),drizzleOrm.eq(i.status,"running"));o.db.update(i).set({status:"failed",error:t,completed_at:s}).where(a).run();}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to mark task failed",s)}finally{o.close();}}findTasksByPromptHint(e,t){let n=this.resolveDbPaths(),o=new Set,s=[];for(let a of n){if(!mn.existsSync(a))continue;let c=k(a);try{let u=t?drizzleOrm.and(drizzleOrm.like(i.prompt,`%${e}%`),drizzleOrm.eq(i.workspace_id,t)):drizzleOrm.like(i.prompt,`%${e}%`),l=c.db.select().from(i).where(u).orderBy(drizzleOrm.asc(i.started_at)).all();for(let p of l)o.has(p.id)||(o.add(p.id),s.push(p));}catch(u){throw new d("DB_ERROR","Failed to find tasks by prompt hint",u)}finally{c.close();}}return s}getProviderUsage(e,t,n){if(!this.dbExists())return [];let o=this.openHandle(false);try{let s=xn(),a=drizzleOrm.sql`
211
+ COALESCE(${i.input_tokens}, 0)
205
212
  + CASE
206
- WHEN ${s.started_at} >= ${St}
213
+ WHEN ${i.started_at} >= ${Ae}
207
214
  AND (
208
- ${s.crewx_version} IS NULL
209
- OR (${s.crewx_version} LIKE '0.8.%' AND ${s.crewx_version} NOT LIKE '0.8.9%')
210
- OR (${s.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${s.crewx_version}, ${xt}) AS INTEGER) < ${Tt})
215
+ ${i.crewx_version} IS NULL
216
+ OR (${i.crewx_version} LIKE '0.8.%' AND ${i.crewx_version} NOT LIKE '0.8.9%')
217
+ OR (${i.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${i.crewx_version}, ${Ce}) AS INTEGER) < ${Le})
211
218
  )
212
- THEN COALESCE(${s.cached_input_tokens}, 0)
219
+ THEN COALESCE(${i.cached_input_tokens}, 0)
213
220
  ELSE 0
214
221
  END
215
- `,c=n?drizzleOrm.sql`WHERE ${s.status} IN ('completed', 'success') AND ${s.started_at} >= ${t} AND ${s.started_at} < ${e} AND ${s.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${s.status} IN ('completed', 'success') AND ${s.started_at} >= ${t} AND ${s.started_at} < ${e}`;return r.db.all(drizzleOrm.sql`
222
+ `,c=n?drizzleOrm.sql`WHERE ${i.status} IN ('completed', 'success') AND ${i.started_at} >= ${e} AND ${i.started_at} < ${t} AND ${i.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${i.status} IN ('completed', 'success') AND ${i.started_at} >= ${e} AND ${i.started_at} < ${t}`;return o.db.all(drizzleOrm.sql`
216
223
  SELECT
217
- ${o} AS provider,
224
+ ${s} AS provider,
218
225
  COUNT(*) AS total_tasks,
219
226
  COALESCE(SUM(${a}), 0) AS input_tokens,
220
- COALESCE(SUM(${s.output_tokens}), 0) AS output_tokens,
221
- COALESCE(SUM(${s.cached_input_tokens}), 0) AS cached_input_tokens,
222
- COALESCE(SUM(${s.cost_usd}), 0) AS cost_usd,
223
- COALESCE(SUM(${s.duration_ms}), 0) AS active_duration_ms,
224
- MAX(${s.completed_at}) AS last_active_at
225
- FROM ${s}
227
+ COALESCE(SUM(${i.output_tokens}), 0) AS output_tokens,
228
+ COALESCE(SUM(${i.cached_input_tokens}), 0) AS cached_input_tokens,
229
+ COALESCE(SUM(${i.cost_usd}), 0) AS cost_usd,
230
+ COALESCE(SUM(${i.duration_ms}), 0) AS active_duration_ms,
231
+ MAX(${i.completed_at}) AS last_active_at
232
+ FROM ${i}
226
233
  ${c}
227
- GROUP BY ${o}
228
- ORDER BY (COALESCE(SUM(${a}), 0) + COALESCE(SUM(${s.output_tokens}), 0)) DESC
229
- `).map(l=>({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}))}catch(o){throw new d("DB_ERROR","Failed to get provider usage",o)}finally{r.close();}}getModelUsage(t,e,n){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=en(),a=drizzleOrm.sql`
230
- COALESCE(${s.input_tokens}, 0)
234
+ GROUP BY ${s}
235
+ ORDER BY (COALESCE(SUM(${a}), 0) + COALESCE(SUM(${i.output_tokens}), 0)) DESC
236
+ `).map(l=>({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}))}catch(s){throw new d("DB_ERROR","Failed to get provider usage",s)}finally{o.close();}}getModelUsage(e,t,n){if(!this.dbExists())return [];let o=this.openHandle(false);try{let s=xn(),a=drizzleOrm.sql`
237
+ COALESCE(${i.input_tokens}, 0)
231
238
  + CASE
232
- WHEN ${s.started_at} >= ${St}
239
+ WHEN ${i.started_at} >= ${Ae}
233
240
  AND (
234
- ${s.crewx_version} IS NULL
235
- OR (${s.crewx_version} LIKE '0.8.%' AND ${s.crewx_version} NOT LIKE '0.8.9%')
236
- OR (${s.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${s.crewx_version}, ${xt}) AS INTEGER) < ${Tt})
241
+ ${i.crewx_version} IS NULL
242
+ OR (${i.crewx_version} LIKE '0.8.%' AND ${i.crewx_version} NOT LIKE '0.8.9%')
243
+ OR (${i.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${i.crewx_version}, ${Ce}) AS INTEGER) < ${Le})
237
244
  )
238
- THEN COALESCE(${s.cached_input_tokens}, 0)
245
+ THEN COALESCE(${i.cached_input_tokens}, 0)
239
246
  ELSE 0
240
247
  END
241
- `,c=n?drizzleOrm.sql`WHERE ${s.status} IN ('completed', 'success') AND ${s.started_at} >= ${t} AND ${s.started_at} < ${e} AND ${s.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${s.status} IN ('completed', 'success') AND ${s.started_at} >= ${t} AND ${s.started_at} < ${e}`,u=r.db.all(drizzleOrm.sql`
248
+ `,c=n?drizzleOrm.sql`WHERE ${i.status} IN ('completed', 'success') AND ${i.started_at} >= ${e} AND ${i.started_at} < ${t} AND ${i.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${i.status} IN ('completed', 'success') AND ${i.started_at} >= ${e} AND ${i.started_at} < ${t}`,u=o.db.all(drizzleOrm.sql`
242
249
  SELECT
243
- ${s.model} AS model,
244
- ${o} AS provider,
250
+ ${i.model} AS model,
251
+ ${s} AS provider,
245
252
  COUNT(*) AS total_tasks,
246
253
  COALESCE(SUM(${a}), 0) AS input_tokens,
247
- COALESCE(SUM(${s.output_tokens}), 0) AS output_tokens,
248
- COALESCE(SUM(${s.cached_input_tokens}), 0) AS cached_input_tokens,
249
- COALESCE(SUM(${s.cost_usd}), 0) AS cost_usd,
250
- COALESCE(SUM(${s.duration_ms}), 0) AS active_duration_ms,
251
- MAX(${s.completed_at}) AS last_active_at
252
- FROM ${s}
254
+ COALESCE(SUM(${i.output_tokens}), 0) AS output_tokens,
255
+ COALESCE(SUM(${i.cached_input_tokens}), 0) AS cached_input_tokens,
256
+ COALESCE(SUM(${i.cost_usd}), 0) AS cost_usd,
257
+ COALESCE(SUM(${i.duration_ms}), 0) AS active_duration_ms,
258
+ MAX(${i.completed_at}) AS last_active_at
259
+ FROM ${i}
253
260
  ${c}
254
- GROUP BY ${s.model}, ${o}
255
- `),l=new Map;for(let p of u){let h=tn(p.model??""),f=JSON.stringify([p.provider,h]),m=l.get(f);m?(m.totalTasks+=p.total_tasks,m.inputTokens+=p.input_tokens,m.outputTokens+=p.output_tokens,m.cachedInputTokens+=p.cached_input_tokens,m.costUsd+=p.cost_usd,m.totalTokens+=p.input_tokens+p.output_tokens,m.activeDurationMs+=p.active_duration_ms??0,p.last_active_at&&(!m.lastActiveAt||p.last_active_at>m.lastActiveAt)&&(m.lastActiveAt=p.last_active_at)):l.set(f,{model:h,provider:p.provider,totalTasks:p.total_tasks,inputTokens:p.input_tokens,outputTokens:p.output_tokens,cachedInputTokens:p.cached_input_tokens,costUsd:p.cost_usd,totalTokens:p.input_tokens+p.output_tokens,activeDurationMs:p.active_duration_ms??0,lastActiveAt:p.last_active_at??null});}return Array.from(l.values()).sort((p,h)=>h.costUsd-p.costUsd)}catch(o){throw new d("DB_ERROR","Failed to get model usage",o)}finally{r.close();}}getTasksForReport(t,e,n){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=n?drizzleOrm.sql`WHERE ${s.started_at} >= ${t} AND ${s.started_at} < ${e} AND ${s.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${s.started_at} >= ${t} AND ${s.started_at} < ${e}`;return r.db.all(drizzleOrm.sql`
261
+ GROUP BY ${i.model}, ${s}
262
+ `),l=new Map;for(let p of u){let _=yn(p.model??""),g=JSON.stringify([p.provider,_]),m=l.get(g);m?(m.totalTasks+=p.total_tasks,m.inputTokens+=p.input_tokens,m.outputTokens+=p.output_tokens,m.cachedInputTokens+=p.cached_input_tokens,m.costUsd+=p.cost_usd,m.totalTokens+=p.input_tokens+p.output_tokens,m.activeDurationMs+=p.active_duration_ms??0,p.last_active_at&&(!m.lastActiveAt||p.last_active_at>m.lastActiveAt)&&(m.lastActiveAt=p.last_active_at)):l.set(g,{model:_,provider:p.provider,totalTasks:p.total_tasks,inputTokens:p.input_tokens,outputTokens:p.output_tokens,cachedInputTokens:p.cached_input_tokens,costUsd:p.cost_usd,totalTokens:p.input_tokens+p.output_tokens,activeDurationMs:p.active_duration_ms??0,lastActiveAt:p.last_active_at??null});}return Array.from(l.values()).sort((p,_)=>_.costUsd-p.costUsd)}catch(s){throw new d("DB_ERROR","Failed to get model usage",s)}finally{o.close();}}getTasksForReport(e,t,n){if(!this.dbExists())return [];let o=this.openHandle(false);try{let s=n?drizzleOrm.sql`WHERE ${i.started_at} >= ${e} AND ${i.started_at} < ${t} AND ${i.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${i.started_at} >= ${e} AND ${i.started_at} < ${t}`;return o.db.all(drizzleOrm.sql`
256
263
  SELECT
257
- ${s.thread_id} AS thread_id,
258
- ${s.agent_id} AS agent_id,
259
- ${s.started_at} AS started_at,
260
- ${s.status} AS status,
261
- ${s.error} AS error,
262
- ${s.exit_code} AS exit_code
263
- FROM ${s}
264
- ${o}
265
- ORDER BY ${s.started_at} ASC
266
- `).map(c=>({threadId:c.thread_id,agentId:c.agent_id,startedAt:c.started_at,status:c.status,error:c.error,exitCode:c.exit_code}))}catch(o){throw new d("DB_ERROR","Failed to get tasks for report",o)}finally{r.close();}}findTaskEvidence(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{let n=[];t.workspaceId&&n.push(drizzleOrm.eq(s.workspace_id,t.workspaceId)),t.agents&&t.agents.length>0&&n.push(drizzleOrm.inArray(s.agent_id,t.agents)),t.statuses&&t.statuses.length>0&&n.push(drizzleOrm.inArray(s.status,t.statuses)),t.from&&n.push(drizzleOrm.gte(s.started_at,t.from)),t.to&&n.push(drizzleOrm.lt(s.started_at,t.to));let r=n.length>0?drizzleOrm.and(...n):void 0,o=(t.order??"DESC")==="ASC"?drizzleOrm.asc(s.started_at):drizzleOrm.desc(s.started_at),a={id:s.id,agent_id:s.agent_id,status:s.status,prompt:s.prompt,started_at:s.started_at,completed_at:s.completed_at,thread_id:s.thread_id};return t.limit?e.db.select(a).from(s).where(r).orderBy(o).limit(t.limit).all():e.db.select(a).from(s).where(r).orderBy(o).all()}catch(n){throw new d("DB_ERROR","Failed to find task evidence",n)}finally{e.close();}}findThreadChains(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{let n=t.maxThreads??8,r=t.maxTurnsPerThread??4,o=[drizzleOrm.isNotNull(s.thread_id),drizzleOrm.isNull(s.parent_task_id),drizzleOrm.isNull(s.caller_agent_id),drizzleOrm.or(drizzleOrm.isNull(s.platform),drizzleOrm.ne(s.platform,"workflow")),drizzleOrm.or(drizzleOrm.isNull(s.metadata),drizzleOrm.and(drizzleOrm.notLike(s.metadata,'%"kind":"workflow_card"%'),drizzleOrm.notLike(s.metadata,'%"kind":"workflow_ui_instance"%'))),drizzleOrm.or(drizzleOrm.isNull(s.metadata),drizzleOrm.notLike(s.metadata,'%"retriedFromTaskId"%'))];t.workspaceId&&o.push(drizzleOrm.eq(s.workspace_id,t.workspaceId)),t.from&&o.push(drizzleOrm.gte(s.started_at,t.from)),t.to&&o.push(drizzleOrm.lt(s.started_at,t.to));let a=e.db.select({id:s.id,agent_id:s.agent_id,status:s.status,prompt:s.prompt,started_at:s.started_at,completed_at:s.completed_at,thread_id:s.thread_id}).from(s).where(drizzleOrm.and(...o)).orderBy(drizzleOrm.asc(s.started_at),drizzleOrm.asc(s.id)).all(),c=new Map;for(let l of a){if(!l.thread_id)continue;let p={id:l.id,agentId:l.agent_id,status:l.status,prompt:l.prompt,startedAt:l.started_at,completedAt:l.completed_at},h=c.get(l.thread_id);h?h.push(p):c.set(l.thread_id,[p]);}let u=[];for(let[l,p]of c){let h=p.filter(f=>f.agentId===t.targetAgentId).length;h<2||u.push({threadId:l,targetAgentTurnCount:h,turns:p});}return u.sort((l,p)=>{let h=l.turns[l.turns.length-1].startedAt,f=p.turns[p.turns.length-1].startedAt;return h<f?1:h>f?-1:0}),u.slice(0,n).map(l=>({threadId:l.threadId,targetAgentTurnCount:l.targetAgentTurnCount,turns:l.turns.slice(-r)}))}catch(n){throw new d("DB_ERROR","Failed to find thread chains",n)}finally{e.close();}}};var he=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}validateWorkspaceId(t,e){return t.db.select({id:g.id}).from(g).where(drizzleOrm.eq(g.id,e)).limit(1).get()?e:null}topLevelTaskPredicateSql(t="child"){return drizzleOrm.sql.raw(`NOT EXISTS (
264
+ ${i.thread_id} AS thread_id,
265
+ ${i.agent_id} AS agent_id,
266
+ ${i.started_at} AS started_at,
267
+ ${i.status} AS status,
268
+ ${i.error} AS error,
269
+ ${i.exit_code} AS exit_code
270
+ FROM ${i}
271
+ ${s}
272
+ ORDER BY ${i.started_at} ASC
273
+ `).map(c=>({threadId:c.thread_id,agentId:c.agent_id,startedAt:c.started_at,status:c.status,error:c.error,exitCode:c.exit_code}))}catch(s){throw new d("DB_ERROR","Failed to get tasks for report",s)}finally{o.close();}}findTaskEvidence(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{let n=[];e.workspaceId&&n.push(drizzleOrm.eq(i.workspace_id,e.workspaceId)),e.agents&&e.agents.length>0&&n.push(drizzleOrm.inArray(i.agent_id,e.agents)),e.statuses&&e.statuses.length>0&&n.push(drizzleOrm.inArray(i.status,e.statuses)),e.from&&n.push(drizzleOrm.gte(i.started_at,e.from)),e.to&&n.push(drizzleOrm.lt(i.started_at,e.to));let o=n.length>0?drizzleOrm.and(...n):void 0,s=(e.order??"DESC")==="ASC"?drizzleOrm.asc(i.started_at):drizzleOrm.desc(i.started_at),a={id:i.id,agent_id:i.agent_id,status:i.status,prompt:i.prompt,started_at:i.started_at,completed_at:i.completed_at,thread_id:i.thread_id};return e.limit?t.db.select(a).from(i).where(o).orderBy(s).limit(e.limit).all():t.db.select(a).from(i).where(o).orderBy(s).all()}catch(n){throw new d("DB_ERROR","Failed to find task evidence",n)}finally{t.close();}}findThreadChains(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{let n=e.maxThreads??8,o=e.maxTurnsPerThread??4,s=[drizzleOrm.isNotNull(i.thread_id),drizzleOrm.isNull(i.parent_task_id),drizzleOrm.isNull(i.caller_agent_id),drizzleOrm.or(drizzleOrm.isNull(i.platform),drizzleOrm.ne(i.platform,"workflow")),drizzleOrm.or(drizzleOrm.isNull(i.metadata),drizzleOrm.and(drizzleOrm.notLike(i.metadata,'%"kind":"workflow_card"%'),drizzleOrm.notLike(i.metadata,'%"kind":"workflow_ui_instance"%'))),drizzleOrm.or(drizzleOrm.isNull(i.metadata),drizzleOrm.notLike(i.metadata,'%"retriedFromTaskId"%'))];e.workspaceId&&s.push(drizzleOrm.eq(i.workspace_id,e.workspaceId)),e.from&&s.push(drizzleOrm.gte(i.started_at,e.from)),e.to&&s.push(drizzleOrm.lt(i.started_at,e.to));let a=t.db.select({id:i.id,agent_id:i.agent_id,status:i.status,prompt:i.prompt,started_at:i.started_at,completed_at:i.completed_at,thread_id:i.thread_id}).from(i).where(drizzleOrm.and(...s)).orderBy(drizzleOrm.asc(i.started_at),drizzleOrm.asc(i.id)).all(),c=new Map;for(let l of a){if(!l.thread_id)continue;let p={id:l.id,agentId:l.agent_id,status:l.status,prompt:l.prompt,startedAt:l.started_at,completedAt:l.completed_at},_=c.get(l.thread_id);_?_.push(p):c.set(l.thread_id,[p]);}let u=[];for(let[l,p]of c){let _=p.filter(g=>g.agentId===e.targetAgentId).length;_<2||u.push({threadId:l,targetAgentTurnCount:_,turns:p});}return u.sort((l,p)=>{let _=l.turns[l.turns.length-1].startedAt,g=p.turns[p.turns.length-1].startedAt;return _<g?1:_>g?-1:0}),u.slice(0,n).map(l=>({threadId:l.threadId,targetAgentTurnCount:l.targetAgentTurnCount,turns:l.turns.slice(-o)}))}catch(n){throw new d("DB_ERROR","Failed to find thread chains",n)}finally{t.close();}}};var Cn=["success","failed","completed"],_t=10*1024*1024*1024,Ln=256,Yo=new Set(Cn),z=class extends Error{constructor(t,n,o="metadata"){super(n);this.taskId=t;this.kind=o;this.name="MigrationTaskError";}taskId;kind};function Pn(r){return r||(process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:ye.join(_r.homedir(),".crewx","crewx.db"))}function Xo(){return Be("better-sqlite3")}function On(r,e){let t=r===":memory:";if(!t&&!mn.existsSync(r))throw new Error(`Database not found: ${r}`);let n=new(Xo())(r,{readonly:e,fileMustExist:!t,timeout:5e3});return n.pragma("foreign_keys = ON"),n.pragma("busy_timeout = 5000"),n}function He(r,e,t=[]){return r.prepare(e).all(...t)}function Fe(r,e,t=[]){return r.prepare(e).get(...t)}function Qo(r,e,t=[]){return r.prepare(e).run(...t)}function Zo(r,e,t=[]){return r.prepare(e).iterate(...t)}function es(r){return typeof r=="string"&&r.length>0?r:"<unknown>"}function jn(r){return typeof r=="string"&&Yo.has(r)}function Dn(r,e){r.set(e,(r.get(e)??0)+1);}function In(r){return Object.fromEntries([...r.entries()].sort(([e],[t])=>e.localeCompare(t)))}function ts(r){let e=new Set(He(r,"SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('tasks', 'task_log_events')").map(a=>a.name)),t=["tasks","task_log_events"].filter(a=>!e.has(a));if(t.length>0)throw new Error(`Database schema is missing required table(s): ${t.join(", ")}`);let n=new Set(He(r,"PRAGMA table_info('tasks')").map(a=>a.name)),s=["id","status","logs","log_storage","last_log_seq","log_revision"].filter(a=>!n.has(a));if(s.length>0)throw new Error(`Database schema is missing required tasks column(s): ${s.join(", ")}`)}function $n(r,e){if(e==null)return {entries:[]};if(typeof e!="string")throw new z(r,"Malformed task logs: tasks.logs must be JSON text or null","malformed");if(e.trim()==="")return {entries:[]};let t;try{t=JSON.parse(e);}catch(o){let s=o instanceof Error?o.message:String(o);throw new z(r,`Malformed JSON in tasks.logs (${s})`,"malformed")}if(!Array.isArray(t))throw new z(r,"Malformed task logs: expected a JSON array","malformed");let n=[];for(let[o,s]of t.entries()){if(s===null||typeof s!="object"||typeof s.timestamp!="string"||typeof s.level!="string"||typeof s.message!="string")throw new z(r,`Malformed task logs: entry ${o} must contain string timestamp, level, and message fields`,"malformed");let a=s;n.push({timestamp:a.timestamp,level:a.level,message:a.message});}return {entries:n}}function Nt(r,e){if(!Number.isInteger(r.last_log_seq)||r.last_log_seq<0)throw new z(r.id,"Invalid last_log_seq metadata","metadata");if(!Number.isInteger(r.log_revision)||r.log_revision<0)throw new z(r.id,"Invalid log_revision metadata","metadata");if(e==="blob"&&r.last_log_seq!==0)throw new z(r.id,"Blob source must have last_log_seq=0","metadata")}function ns(r){let e=He(r,`SELECT task_id, COUNT(*) AS event_count
274
+ FROM task_log_events GROUP BY task_id`);return new Map(e.map(t=>[t.task_id,t.event_count]))}function rs(r){let e=ns(r),t=new Map,n=[],o=[],s=[],a=new Map,c=new Map,u=0,l=0,p=0,_=0,g=0,m=0;for(let O of Zo(r,`SELECT id, status, logs, log_storage, last_log_seq, log_revision
275
+ FROM tasks ORDER BY id`)){let w=O,j=es(w.status);if(Dn(a,j),t.set(w.id,{id:w.id,status:w.status,log_storage:w.log_storage,last_log_seq:w.last_log_seq,log_revision:w.log_revision}),u+=1,w.log_storage==="events"){_+=1;try{Nt(w,"events");}catch(we){s.push(Dt(we,w.id));}w.logs!==null&&s.push({taskId:w.id,reason:"Event source still has a non-null tasks.logs blob",kind:"mixed-source"});continue}if(w.log_storage!=="blob"){s.push({taskId:w.id,reason:`Unknown log_storage value: ${w.log_storage}`,kind:"invalid-source"});continue}l+=1;let S=jn(w.status);S||(p+=1,Dn(c,j)),typeof w.logs=="string"?m+=Buffer.byteLength(w.logs,"utf8"):Buffer.isBuffer(w.logs)&&(m+=w.logs.byteLength);let W=e.get(w.id)??0;W>0&&s.push({taskId:w.id,reason:`Blob source already has ${W} task_log_events row(s)`,kind:"mixed-source"});let xe;try{xe=$n(w.id,w.logs),g+=xe.entries.length,Nt(w,"blob");}catch(we){let ke=Dt(we,w.id);s.push(ke),ke.kind==="malformed"&&o.push(ke);continue}W>0||S&&n.push(w.id);}return {taskCount:u,candidateTaskCount:l,eligibleTaskCount:n.length,eventSourceTasks:_,statusCounts:In(a),deferredTaskCount:p,deferredStatusCounts:In(c),entryCount:g,sourceBytes:m,candidateIds:n,malformedRows:o,failures:s,tasks:t}}function Dt(r,e){return r instanceof z?{taskId:r.taskId,reason:r.message,kind:r.kind}:{taskId:e,reason:r instanceof Error?r.message:String(r),kind:"metadata"}}function os(r){return Fe(r,"SELECT COUNT(*) AS count FROM tasks WHERE status IN ('pending', 'running')")?.count??0}function ss(r){return Fe(r,"SELECT COUNT(*) AS count FROM tasks WHERE log_storage = 'blob'")?.count??0}function is(r){if(r===":memory:")return 0;let e=t=>{try{return mn.statSync(t).size}catch{return 0}};return e(r)+e(`${r}-wal`)}function as(r,e){return is(r)+e*Ln}function Bn(r,e){return Number.isFinite(r)&&Number.isFinite(e)&&r>=e+_t}function An(r){let e=ye.dirname(ye.resolve(r));for(;!mn.existsSync(e);){let t=ye.dirname(e);if(t===e)break;e=t;}return e}function qn(r,e,t){let n=[...new Set([An(r),...t?[An(t)]:[]])],o=[],s=Number.POSITIVE_INFINITY;for(let u of n)try{let l=mn.statfsSync(u);s=Math.min(s,l.bavail*l.bsize);}catch(l){s=0,o.push(`Unable to inspect free space for ${u}: ${l instanceof Error?l.message:String(l)}`);}let a=as(r,e),c=a+_t;return {estimatedFreeSpaceBytes:a,requiredFreeSpaceBytes:c,availableFreeSpaceBytes:Number.isFinite(s)?Math.floor(s):0,minimumFreeSpaceReserveBytes:_t,freeSpaceGatePassed:Bn(Number.isFinite(s)?Math.floor(s):0,a),warnings:o}}function Mn(r){return new Set(r.map(e=>e.taskId)).size}function Un(r){try{let e=r.pragma("wal_checkpoint(TRUNCATE)"),t=Array.isArray(e)?e[0]:e,n=t!==null&&typeof t=="object"&&"busy"in t?Number(t.busy):0;return n>0?`WAL checkpoint(TRUNCATE) busy (${n}); continuing without failing migration`:void 0}catch(e){return `WAL checkpoint(TRUNCATE) warning; continuing without failing migration: ${e instanceof Error?e.message:String(e)}`}}function ut(r,e,t,n,o=qn(e,t.entryCount)){let s=n.failures??t.failures,a=n.malformedRows??t.malformedRows,{ok:c,...u}=n;return {mode:r,ok:c,dbPath:e,activeTaskCount:n.activeTaskCount??0,taskCount:t.taskCount,candidateTaskCount:t.candidateTaskCount,eligibleTaskCount:t.eligibleTaskCount,statusCounts:t.statusCounts,deferredTaskCount:t.deferredTaskCount,deferredStatusCounts:t.deferredStatusCounts,entryCount:t.entryCount,sourceBytes:t.sourceBytes,estimatedFreeSpaceBytes:o.estimatedFreeSpaceBytes,requiredFreeSpaceBytes:o.requiredFreeSpaceBytes,availableFreeSpaceBytes:o.availableFreeSpaceBytes,minimumFreeSpaceReserveBytes:o.minimumFreeSpaceReserveBytes,freeSpaceGatePassed:o.freeSpaceGatePassed,migratedTasks:n.migratedTasks??0,migratedEntries:n.migratedEntries??0,skippedTasks:n.skippedTasks??t.eventSourceTasks,failedTasks:n.failedTasks??Mn(s),malformedRows:a,failures:s,logicalSourceBytesRemoved:n.logicalSourceBytesRemoved??0,warnings:n.warnings??o.warnings,remainingTaskCount:n.remainingTaskCount??t.candidateTaskCount,...u}}function ds(r,e){return r.length!==e.length?false:r.every((t,n)=>{let o=e[n];return t.seq===n+1&&t.timestamp===o.timestamp&&t.level===o.level&&t.message===o.message})}function cs(r,e){return r.transaction(()=>{let n=Fe(r,`SELECT id, status, logs, log_storage, last_log_seq, log_revision
276
+ FROM tasks WHERE id = ?`,[e]);if(!n)throw new z(e,"Task disappeared before migration","metadata");if(n.log_storage==="events")return {status:"skipped",entryCount:0,sourceBytes:0};if(n.log_storage!=="blob")throw new z(e,`Unknown log_storage value: ${n.log_storage}`,"invalid-source");if(!jn(n.status))return {status:"deferred",entryCount:0,sourceBytes:0};let o=n.logs,s=$n(e,o);Nt(n,"blob");let a=Fe(r,"SELECT COUNT(*) AS count FROM task_log_events WHERE task_id = ?",[e])?.count??0;if(a!==0)throw new z(e,`Blob source already has ${a} task_log_events row(s)`,"mixed-source");let c=r.prepare(`INSERT INTO task_log_events (task_id, seq, timestamp, level, message)
277
+ VALUES (?, ?, ?, ?, ?)`);for(let[_,g]of s.entries.entries())c.run(e,_+1,g.timestamp,g.level,g.message);let u=He(r,`SELECT seq, timestamp, level, message
278
+ FROM task_log_events WHERE task_id = ? ORDER BY seq`,[e]);if(!ds(u,s.entries))throw new z(e,"Event parity check failed before source clear","metadata");if(Qo(r,`UPDATE tasks
279
+ SET log_storage = 'events', last_log_seq = ?, log_revision = log_revision + 1, logs = NULL
280
+ WHERE id = ? AND log_storage = 'blob' AND logs IS ?`,[s.entries.length,e,o]).changes!==1)throw new z(e,"Task changed while migration was in progress","metadata");let p=Fe(r,`SELECT id, status, logs, log_storage, last_log_seq, log_revision
281
+ FROM tasks WHERE id = ?`,[e]);if(!p||p.log_storage!=="events"||p.logs!==null||p.last_log_seq!==s.entries.length||p.log_revision!==n.log_revision+1)throw new z(e,"Final task metadata parity check failed","metadata");return {status:"migrated",entryCount:s.entries.length,sourceBytes:typeof o=="string"?Buffer.byteLength(o,"utf8"):Buffer.isBuffer(o)?o.byteLength:0}}).immediate()}function Fn(r){let e=new Date().toISOString().replace(/[-:.TZ]/g,"").slice(0,14),t=crypto.randomBytes(6).toString("hex");return `${r}.task-log-backup-${e}-${t}.sqlite`}async function ls(r,e,t){let n=t??Fn(e);if(ye.resolve(n)===ye.resolve(e))throw new Error("Backup path must be different from the source database");if(mn.existsSync(n))throw new Error(`Refusing to overwrite existing backup: ${n}`);if(mn.mkdirSync(ye.dirname(n),{recursive:true}),await r.backup(n),!mn.existsSync(n))throw new Error(`SQLite backup was not created: ${n}`);let o=On(n,true);try{let s=o.pragma("integrity_check",{simple:!0});if(s!=="ok")throw new Error(`Backup integrity check failed: ${s}`)}finally{o.close();}return n}function us(r){let e=He(r,`SELECT task_id AS taskId,
282
+ COUNT(*) AS eventCount,
283
+ COUNT(DISTINCT seq) AS distinctSeqCount,
284
+ MIN(seq) AS minSeq,
285
+ MAX(seq) AS maxSeq
286
+ FROM task_log_events GROUP BY task_id`),t=e.reduce((n,o)=>n+o.eventCount,0);return {rows:e,eventCount:t}}function ve(r,e,t,n={}){return {taskId:r,kind:e,reason:t,...n}}function ps(r,e,t){let n=[];for(let _ of t.failures)_.kind==="malformed"?n.push(ve(_.taskId,"malformed-blob",_.reason)):_.kind==="mixed-source"?n.push(ve(_.taskId,"mixed-source",_.reason)):n.push(ve(_.taskId,"source-invariant",_.reason));let o=us(r),s=new Map(o.rows.map(_=>[_.taskId,_]));for(let _ of o.rows){let g=t.tasks.get(_.taskId);if(!g){n.push(ve(null,"orphan-event",`Event rows reference missing task ${_.taskId}`,{actual:_.eventCount}));continue}(_.minSeq===null||_.minSeq<1||_.distinctSeqCount!==_.maxSeq)&&n.push(ve(g.id,"seq-gap","Task event sequence has a gap or invalid starting sequence",{expected:_.maxSeq??0,actual:_.distinctSeqCount})),g.log_storage==="events"&&g.last_log_seq!==_.eventCount&&n.push(ve(g.id,"count-mismatch","last_log_seq does not match task_log_events row count",{expected:g.last_log_seq??0,actual:_.eventCount}));}for(let _ of t.tasks.values())_.log_storage==="events"&&!s.has(_.id)&&_.last_log_seq!==0&&n.push(ve(_.id,"count-mismatch","Event-source task has no rows for its last_log_seq",{expected:_.last_log_seq??0,actual:0}));for(let _ of He(r,`SELECT task_id AS taskId, seq, COUNT(*) AS duplicateCount
287
+ FROM task_log_events GROUP BY task_id, seq HAVING COUNT(*) > 1`))n.push(ve(_.taskId,"duplicate-seq",`Duplicate task event sequence ${_.seq}`,{actual:_.duplicateCount,seq:_.seq}));let a=Fe(r,`SELECT COUNT(*) AS count FROM task_log_events
288
+ WHERE seq IS NULL OR seq < 1 OR timestamp IS NULL OR level IS NULL OR message IS NULL`)?.count??0;a>0&&n.push(ve(null,"invalid-event","Event rows contain invalid sequence or null payload fields",{actual:a}));let c=new Set(n.flatMap(_=>_.taskId?[_.taskId]:[])),u=n.map(_=>({taskId:_.taskId??"(orphan)",reason:_.reason,kind:_.kind==="malformed-blob"?"malformed":_.kind==="mixed-source"?"mixed-source":"metadata"})),l=u.filter(_=>_.kind==="malformed"),p={checkedTasks:t.taskCount,eventSourceTasks:t.eventSourceTasks,blobSourceTasks:t.candidateTaskCount,eventCount:o.eventCount,orphanEventCount:n.filter(_=>_.kind==="orphan-event").length,failedTasks:c.size,issues:n};return ut("verify",e,t,{ok:n.length===0,migratedTasks:t.eventSourceTasks,migratedEntries:o.eventCount,skippedTasks:t.candidateTaskCount,failedTasks:c.size,malformedRows:l,failures:u,remainingTaskCount:t.candidateTaskCount,verification:p})}function _s(r){if(r.mode!=="apply"&&r.batchTasks!==void 0)throw new Error("--batch-tasks is only valid with --apply");if(r.batchTasks!==void 0&&(!Number.isInteger(r.batchTasks)||r.batchTasks<1))throw new Error("--batch-tasks must be a positive integer")}async function gs(r){_s(r);let e=Pn(r.dbPath),t=On(e,r.mode!=="apply");try{ts(t);let n=rs(t),o=os(t);if(r.mode==="verify")return {...ps(t,e,n),activeTaskCount:o};if(r.mode==="dry-run")return ut("dry-run",e,n,{ok:n.failures.length===0,activeTaskCount:o,skippedTasks:n.eventSourceTasks,remainingTaskCount:n.candidateTaskCount});let s=r.backupPath??Fn(e),a=qn(e,n.entryCount,s);if(!a.freeSpaceGatePassed)return ut("apply",e,n,{ok:!1,activeTaskCount:o,blockedReason:`Apply blocked: available free space (${a.availableFreeSpaceBytes} bytes) is below the required ${a.requiredFreeSpaceBytes} bytes (including a ${a.minimumFreeSpaceReserveBytes} byte reserve)`,skippedTasks:n.eventSourceTasks,remainingTaskCount:n.candidateTaskCount},a);let c=await ls(t,e,s),u=[...n.failures],l=r.batchTasks===void 0?n.candidateIds:n.candidateIds.slice(0,r.batchTasks),p=r.batchTasks??Math.max(l.length,1),_=0,g=0,m=0,O=[...a.warnings];for(let[w,j]of l.entries()){try{let S=cs(t,j);S.status==="migrated"&&(_+=1,g+=S.entryCount,m+=S.sourceBytes);}catch(S){u.push(Dt(S,j));}if((w+1)%p===0||w===l.length-1){let S=Un(t);S&&O.push(S);}}return ut("apply",e,n,{ok:u.length===0,activeTaskCount:o,backupPath:c,backupMethod:"sqlite-online-backup",migratedTasks:_,migratedEntries:g,logicalSourceBytesRemoved:m,failedTasks:Mn(u),failures:u,malformedRows:n.malformedRows,remainingTaskCount:ss(t),skippedTasks:n.eventSourceTasks,warnings:O},a)}finally{t.close();}}function fs(r){return ye.basename(r)}var It=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}validateWorkspaceId(e,t){return e.db.select({id:h.id}).from(h).where(drizzleOrm.eq(h.id,t)).limit(1).get()?t:null}topLevelTaskPredicateSql(e="child"){return drizzleOrm.sql.raw(`NOT EXISTS (
267
289
  SELECT 1 FROM tasks parent
268
- WHERE parent.id = ${t}.parent_task_id
269
- AND parent.thread_id = ${t}.thread_id
270
- )`)}findAllThreads(t){let e=this.resolveDbPaths(),n=new Set,r=[];for(let o of e){if(!Ye.existsSync(o))continue;let a=w(o);try{let c=t?drizzleOrm.eq(_.workspace_id,t):void 0,u=a.db.select().from(_).where(c).orderBy(drizzleOrm.desc(_.updated_at)).all();for(let l of u)n.has(l.id)||(n.add(l.id),r.push(l));}catch(c){throw new d("DB_ERROR","Failed to find all threads",c)}finally{a.close();}}return r}findThreadsByIdsOrTitles(t,e){if(t.length===0)return [];let n=this.resolveDbPaths(),r=new Set,o=[];for(let a of n){if(!Ye.existsSync(a))continue;let c=w(a);try{let u=drizzleOrm.or(drizzleOrm.inArray(_.id,t),drizzleOrm.inArray(_.title,t)),l=e?drizzleOrm.and(u,drizzleOrm.eq(_.workspace_id,e)):u,p=c.db.select().from(_).where(l).orderBy(drizzleOrm.desc(_.updated_at)).all();for(let h of p)r.has(h.id)||(r.add(h.id),o.push(h));}catch(u){throw new d("DB_ERROR","Failed to find threads by ids or titles",u)}finally{c.close();}}return o}findThreadById(t,e){let n=this.resolveDbPaths();for(let r of n){if(!Ye.existsSync(r))continue;let o=w(r);try{let a=drizzleOrm.eq(_.id,t),c=e?drizzleOrm.and(a,drizzleOrm.eq(_.workspace_id,e)):a,u=o.db.select().from(_).where(c).limit(1).get()??void 0;if(u)return u}catch(a){throw new d("DB_ERROR","Failed to find thread by id",a)}finally{o.close();}}}threadExists(t,e){let n=this.resolveDbPaths();for(let r of n){if(!Ye.existsSync(r))continue;let o=w(r);try{let a=drizzleOrm.eq(_.id,t),c=e?drizzleOrm.and(a,drizzleOrm.eq(_.workspace_id,e)):a;if(o.db.select({id:_.id}).from(_).where(c).limit(1).get())return !0}catch(a){throw new d("DB_ERROR","Failed to check thread existence",a)}finally{o.close();}}return false}aggregateTaskStats(t,e){let n=this.resolveDbPaths(),r=0,o=0,a=0,c=0,u=0,l=new Set;for(let p of n){if(!Ye.existsSync(p))continue;let h=w(p);try{let f=h.db.get(drizzleOrm.sql`
290
+ WHERE parent.id = ${e}.parent_task_id
291
+ AND parent.thread_id = ${e}.thread_id
292
+ )`)}findAllThreads(e){let t=this.resolveDbPaths(),n=new Set,o=[];for(let s of t){if(!mn.existsSync(s))continue;let a=k(s);try{let c=e?drizzleOrm.eq(f.workspace_id,e):void 0,u=a.db.select().from(f).where(c).orderBy(drizzleOrm.desc(f.updated_at)).all();for(let l of u)n.has(l.id)||(n.add(l.id),o.push(l));}catch(c){throw new d("DB_ERROR","Failed to find all threads",c)}finally{a.close();}}return o}findThreadsByIdsOrTitles(e,t){if(e.length===0)return [];let n=this.resolveDbPaths(),o=new Set,s=[];for(let a of n){if(!mn.existsSync(a))continue;let c=k(a);try{let u=drizzleOrm.or(drizzleOrm.inArray(f.id,e),drizzleOrm.inArray(f.title,e)),l=t?drizzleOrm.and(u,drizzleOrm.eq(f.workspace_id,t)):u,p=c.db.select().from(f).where(l).orderBy(drizzleOrm.desc(f.updated_at)).all();for(let _ of p)o.has(_.id)||(o.add(_.id),s.push(_));}catch(u){throw new d("DB_ERROR","Failed to find threads by ids or titles",u)}finally{c.close();}}return s}findThreadById(e,t){let n=this.resolveDbPaths();for(let o of n){if(!mn.existsSync(o))continue;let s=k(o);try{let a=drizzleOrm.eq(f.id,e),c=t?drizzleOrm.and(a,drizzleOrm.eq(f.workspace_id,t)):a,u=s.db.select().from(f).where(c).limit(1).get()??void 0;if(u)return u}catch(a){throw new d("DB_ERROR","Failed to find thread by id",a)}finally{s.close();}}}threadExists(e,t){let n=this.resolveDbPaths();for(let o of n){if(!mn.existsSync(o))continue;let s=k(o);try{let a=drizzleOrm.eq(f.id,e),c=t?drizzleOrm.and(a,drizzleOrm.eq(f.workspace_id,t)):a;if(s.db.select({id:f.id}).from(f).where(c).limit(1).get())return !0}catch(a){throw new d("DB_ERROR","Failed to check thread existence",a)}finally{s.close();}}return false}aggregateTaskStats(e,t){let n=this.resolveDbPaths(),o=0,s=0,a=0,c=0,u=0,l=new Set;for(let p of n){if(!mn.existsSync(p))continue;let _=k(p);try{let g=_.db.get(drizzleOrm.sql`
271
293
  SELECT
272
294
  count(*) AS cnt,
273
295
  COALESCE(SUM(child.input_tokens), 0) AS total_input,
@@ -275,48 +297,48 @@ ${n.join(`
275
297
  COALESCE(SUM(child.cached_input_tokens), 0) AS total_cached,
276
298
  COALESCE(SUM(child.cost_usd), 0) AS total_cost
277
299
  FROM tasks child
278
- WHERE child.thread_id = ${t}
300
+ WHERE child.thread_id = ${e}
279
301
  AND ${this.topLevelTaskPredicateSql()}
280
- ${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
281
- `);f&&(r+=f.cnt,o+=f.total_input,a+=f.total_output,c+=f.total_cached,u+=f.total_cost);let m=h.db.all(drizzleOrm.sql`
302
+ ${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
303
+ `);g&&(o+=g.cnt,s+=g.total_input,a+=g.total_output,c+=g.total_cached,u+=g.total_cost);let m=_.db.all(drizzleOrm.sql`
282
304
  SELECT DISTINCT child.agent_id FROM tasks child
283
- WHERE child.thread_id = ${t}
305
+ WHERE child.thread_id = ${e}
284
306
  AND child.agent_id IS NOT NULL AND child.agent_id != ''
285
307
  AND ${this.topLevelTaskPredicateSql()}
286
- ${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
287
- `);for(let M of m)l.add(M.agent_id);}catch(f){throw new d("DB_ERROR","Failed to aggregate task stats",f)}finally{h.close();}}return {taskCount:r,inputTokens:o,outputTokens:a,cachedInputTokens:c,costUsd:u,agentIds:Array.from(l)}}findTopLevelTasks(t,e,n){let r=this.resolveDbPaths(),o=new Set,a=[];for(let c of r){if(!Ye.existsSync(c))continue;let u=w(c);try{let l;n!==void 0?l=u.db.all(drizzleOrm.sql`
308
+ ${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
309
+ `);for(let O of m)l.add(O.agent_id);}catch(g){throw new d("DB_ERROR","Failed to aggregate task stats",g)}finally{_.close();}}return {taskCount:o,inputTokens:s,outputTokens:a,cachedInputTokens:c,costUsd:u,agentIds:Array.from(l)}}findTopLevelTasks(e,t,n){let o=this.resolveDbPaths(),s=new Set,a=[];for(let c of o){if(!mn.existsSync(c))continue;let u=k(c);try{let l;n!==void 0?l=u.db.all(drizzleOrm.sql`
288
310
  SELECT * FROM (
289
311
  SELECT child.*,
290
312
  ROW_NUMBER() OVER (PARTITION BY child.agent_id ORDER BY child.started_at DESC) AS rn
291
313
  FROM tasks child
292
- WHERE child.thread_id = ${t}
314
+ WHERE child.thread_id = ${e}
293
315
  AND ${this.topLevelTaskPredicateSql()}
294
- ${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
316
+ ${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
295
317
  ) ranked
296
318
  WHERE rn <= ${n}
297
319
  ORDER BY started_at ASC
298
320
  `):l=u.db.all(drizzleOrm.sql`
299
321
  SELECT child.* FROM tasks child
300
- WHERE child.thread_id = ${t}
322
+ WHERE child.thread_id = ${e}
301
323
  AND ${this.topLevelTaskPredicateSql()}
302
- ${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
324
+ ${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
303
325
  ORDER BY child.started_at ASC
304
- `);for(let p of l)o.has(p.id)||(o.add(p.id),a.push(p));}catch(l){throw new d("DB_ERROR","Failed to find top-level tasks",l)}finally{u.close();}}if(n!==void 0&&r.length>1){let c=new Map;for(let u of a){let l=u.agent_id??"";c.has(l)||c.set(l,[]),c.get(l).push(u);}a=[];for(let u of c.values())u.sort((l,p)=>(p.started_at??"").localeCompare(l.started_at??"")),a.push(...u.slice(0,n));a.sort((u,l)=>(u.started_at??"").localeCompare(l.started_at??""));}return a}findAllTasks(t,e){let n=this.resolveDbPaths(),r=new Set,o=[];for(let a of n){if(!Ye.existsSync(a))continue;let c=w(a);try{let u=drizzleOrm.eq(s.thread_id,t),l=e?drizzleOrm.and(u,drizzleOrm.eq(s.workspace_id,e)):u,p=c.db.select().from(s).where(l).orderBy(drizzleOrm.asc(s.started_at)).all();for(let h of p)r.has(h.id)||(r.add(h.id),o.push(h));}catch(u){throw new d("DB_ERROR","Failed to find all tasks for thread",u)}finally{c.close();}}return o}findTaskById(t,e,n){let r=this.resolveDbPaths();for(let o of r){if(!Ye.existsSync(o))continue;let a=w(o);try{let c=drizzleOrm.and(drizzleOrm.eq(s.id,e),drizzleOrm.eq(s.thread_id,t)),u=n?drizzleOrm.and(c,drizzleOrm.eq(s.workspace_id,n)):c,l=a.db.select().from(s).where(u).limit(1).get();if(!l)continue;let p=a.db.select().from(s).where(drizzleOrm.eq(s.parent_task_id,l.id)).orderBy(drizzleOrm.asc(s.started_at)).all();return {task:l,children:p}}catch(c){throw new d("DB_ERROR","Failed to find task by id",c)}finally{a.close();}}}batchFetchTasksQuery(t,e){return drizzleOrm.sql`
326
+ `);for(let p of l)s.has(p.id)||(s.add(p.id),a.push(p));}catch(l){throw new d("DB_ERROR","Failed to find top-level tasks",l)}finally{u.close();}}if(n!==void 0&&o.length>1){let c=new Map;for(let u of a){let l=u.agent_id??"";c.has(l)||c.set(l,[]),c.get(l).push(u);}a=[];for(let u of c.values())u.sort((l,p)=>(p.started_at??"").localeCompare(l.started_at??"")),a.push(...u.slice(0,n));a.sort((u,l)=>(u.started_at??"").localeCompare(l.started_at??""));}return a}findAllTasks(e,t){let n=this.resolveDbPaths(),o=new Set,s=[];for(let a of n){if(!mn.existsSync(a))continue;let c=k(a);try{let u=drizzleOrm.eq(i.thread_id,e),l=t?drizzleOrm.and(u,drizzleOrm.eq(i.workspace_id,t)):u,p=c.db.select().from(i).where(l).orderBy(drizzleOrm.asc(i.started_at)).all();for(let _ of p)o.has(_.id)||(o.add(_.id),s.push(_));}catch(u){throw new d("DB_ERROR","Failed to find all tasks for thread",u)}finally{c.close();}}return s}findTaskById(e,t,n){let o=this.resolveDbPaths();for(let s of o){if(!mn.existsSync(s))continue;let a=k(s);try{let c=drizzleOrm.and(drizzleOrm.eq(i.id,t),drizzleOrm.eq(i.thread_id,e)),u=n?drizzleOrm.and(c,drizzleOrm.eq(i.workspace_id,n)):c,l=a.db.select().from(i).where(u).limit(1).get();if(!l)continue;let p=a.db.select().from(i).where(drizzleOrm.eq(i.parent_task_id,l.id)).orderBy(drizzleOrm.asc(i.started_at)).all();return {task:l,children:p}}catch(c){throw new d("DB_ERROR","Failed to find task by id",c)}finally{a.close();}}}batchFetchTasksQuery(e,t){return drizzleOrm.sql`
305
327
  SELECT child.id, child.thread_id, child.agent_id, child.status,
306
328
  child.parent_task_id, child.started_at, child.completed_at,
307
329
  child.duration_ms, child.input_tokens, child.output_tokens,
308
330
  child.cost_usd, child.error
309
331
  FROM tasks child INDEXED BY idx_tasks_thread_id
310
- WHERE child.thread_id IN (${drizzleOrm.sql.join(t.map(n=>drizzleOrm.sql`${n}`),drizzleOrm.sql`, `)})
332
+ WHERE child.thread_id IN (${drizzleOrm.sql.join(e.map(n=>drizzleOrm.sql`${n}`),drizzleOrm.sql`, `)})
311
333
  AND ${this.topLevelTaskPredicateSql()}
312
- ${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
334
+ ${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
313
335
  ORDER BY child.started_at ASC
314
- `}batchFetchTasks(t,e){let n=new Map;if(t.length===0)return n;let r=this.resolveDbPaths();for(let o of r){if(!Ye.existsSync(o))continue;let a=w(o);try{let c=a.db.all(this.batchFetchTasksQuery(t,e));for(let u of c){let l=u.thread_id;n.has(l)||n.set(l,[]),n.get(l).push(u);}}catch(c){throw new d("DB_ERROR","Failed to batch fetch tasks",c)}finally{a.close();}}return n}explainBatchFetchTasksPlan(t,e){let n=this.resolveDbPaths();for(let r of n){if(!Ye.existsSync(r))continue;let o=w(r);try{return o.db.all(drizzleOrm.sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(t,e)}`).map(c=>c.detail)}finally{o.close();}}return []}updateThreadTitle(t,e,n){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=drizzleOrm.eq(_.id,t),a=n?drizzleOrm.and(o,drizzleOrm.eq(_.workspace_id,n)):o;if(!r.db.select({id:_.id}).from(_).where(a).limit(1).get())return;r.db.update(_).set({title:e,title_locked:1,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(_.id,t)).run();}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to update thread title",o)}finally{r.close();}}upsertThread(t,e){let n=this.openHandle(true);try{let r=e.workspaceId?this.validateWorkspaceId(n,e.workspaceId):null,o=new Date().toISOString();if(n.db.select({id:_.id,message_count:_.message_count}).from(_).where(drizzleOrm.eq(_.id,t)).limit(1).get()){let c={updated_at:o};e.title!==void 0&&(c.title=e.title),e.titleLocked!==void 0&&(c.title_locked=e.titleLocked?1:0),n.db.update(_).set(c).where(drizzleOrm.eq(_.id,t)).run();}else n.db.insert(_).values({id:t,platform:e.platform,workspace_id:r,title:e.title??null,title_locked:e.titleLocked?1:0,message_count:0,created_at:o,updated_at:o}).run();}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to upsert thread",r)}finally{n.close();}}ensureThread(t,e,n){let r=this.openHandle(true);try{let o=n?this.validateWorkspaceId(r,n):null,a=r.db.select({id:_.id,platform:_.platform,workspace_id:_.workspace_id}).from(_).where(drizzleOrm.eq(_.id,t)).limit(1).get();if(a){o&&!a.workspace_id&&r.db.update(_).set({workspace_id:o}).where(drizzleOrm.eq(_.id,t)).run();return}let c=new Date().toISOString();r.db.insert(_).values({id:t,platform:e,workspace_id:o,message_count:0,created_at:c,updated_at:c}).run();}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to ensure thread",o)}finally{r.close();}}saveUserMessage(t,e,n){if(!this.dbExists())return {firstMessage:false};let r=this.openHandle(true);try{let o=new Date().toISOString();return {firstMessage:r.db.transaction(c=>{let l=c.select({message_count:_.message_count}).from(_).where(drizzleOrm.eq(_.id,t)).limit(1).get()?.message_count===0;return c.run(drizzleOrm.sql`
336
+ `}batchFetchTasks(e,t){let n=new Map;if(e.length===0)return n;let o=this.resolveDbPaths();for(let s of o){if(!mn.existsSync(s))continue;let a=k(s);try{let c=a.db.all(this.batchFetchTasksQuery(e,t));for(let u of c){let l=u.thread_id;n.has(l)||n.set(l,[]),n.get(l).push(u);}}catch(c){throw new d("DB_ERROR","Failed to batch fetch tasks",c)}finally{a.close();}}return n}explainBatchFetchTasksPlan(e,t){let n=this.resolveDbPaths();for(let o of n){if(!mn.existsSync(o))continue;let s=k(o);try{return s.db.all(drizzleOrm.sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(e,t)}`).map(c=>c.detail)}finally{s.close();}}return []}updateThreadTitle(e,t,n){if(!this.dbExists())return;let o=this.openHandle(true);try{let s=drizzleOrm.eq(f.id,e),a=n?drizzleOrm.and(s,drizzleOrm.eq(f.workspace_id,n)):s;if(!o.db.select({id:f.id}).from(f).where(a).limit(1).get())return;o.db.update(f).set({title:t,title_locked:1,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(f.id,e)).run();}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to update thread title",s)}finally{o.close();}}upsertThread(e,t){let n=this.openHandle(true);try{let o=t.workspaceId?this.validateWorkspaceId(n,t.workspaceId):null,s=new Date().toISOString();if(n.db.select({id:f.id,message_count:f.message_count}).from(f).where(drizzleOrm.eq(f.id,e)).limit(1).get()){let c={updated_at:s};t.title!==void 0&&(c.title=t.title),t.titleLocked!==void 0&&(c.title_locked=t.titleLocked?1:0),n.db.update(f).set(c).where(drizzleOrm.eq(f.id,e)).run();}else n.db.insert(f).values({id:e,platform:t.platform,workspace_id:o,title:t.title??null,title_locked:t.titleLocked?1:0,message_count:0,created_at:s,updated_at:s}).run();}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to upsert thread",o)}finally{n.close();}}ensureThread(e,t,n){let o=this.openHandle(true);try{let s=n?this.validateWorkspaceId(o,n):null,a=o.db.select({id:f.id,platform:f.platform,workspace_id:f.workspace_id}).from(f).where(drizzleOrm.eq(f.id,e)).limit(1).get();if(a){s&&!a.workspace_id&&o.db.update(f).set({workspace_id:s}).where(drizzleOrm.eq(f.id,e)).run();return}let c=new Date().toISOString();o.db.insert(f).values({id:e,platform:t,workspace_id:s,message_count:0,created_at:c,updated_at:c}).run();}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to ensure thread",s)}finally{o.close();}}saveUserMessage(e,t,n){if(!this.dbExists())return {firstMessage:false};let o=this.openHandle(true);try{let s=new Date().toISOString();return {firstMessage:o.db.transaction(c=>{let l=c.select({message_count:f.message_count}).from(f).where(drizzleOrm.eq(f.id,e)).limit(1).get()?.message_count===0;return c.run(drizzleOrm.sql`
315
337
  UPDATE threads
316
- SET first_message = COALESCE(first_message, ${e}),
317
- title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${e}, 1, 60) ELSE title END,
318
- last_message = ${e},
338
+ SET first_message = COALESCE(first_message, ${t}),
339
+ title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${t}, 1, 60) ELSE title END,
340
+ last_message = ${t},
319
341
  message_count = message_count + 1,
320
- updated_at = ${o}
321
- WHERE id = ${t}
322
- `),l},{behavior:"immediate"})}}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to save user message",o)}finally{r.close();}}saveAssistantMessage(t,e,n){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=new Date().toISOString();r.db.update(_).set({last_message:e,updated_at:o}).where(drizzleOrm.eq(_.id,t)).run();}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to save assistant message",o)}finally{r.close();}}updateThread(t,e){if(!this.dbExists())return;let n=this.openHandle(true);try{let r={updated_at:new Date().toISOString()};e.title!==void 0&&(r.title=e.title,r.title_locked=1),e.titleLocked!==void 0&&(r.title_locked=e.titleLocked?1:0),n.db.update(_).set(r).where(drizzleOrm.eq(_.id,t)).run();}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to update thread",r)}finally{n.close();}}togglePin(t,e){let n=this.openHandle(true);try{let r=e?drizzleOrm.and(drizzleOrm.eq(_.id,t),drizzleOrm.eq(_.workspace_id,e)):drizzleOrm.eq(_.id,t),o=n.db.select({pinned:_.pinned,metadata:_.metadata}).from(_).where(r).get();if(!o)return null;let a=o.pinned?0:1,c=o.metadata?JSON.parse(o.metadata):{};if(a){let u=e?drizzleOrm.and(drizzleOrm.eq(_.pinned,1),drizzleOrm.eq(_.workspace_id,e)):drizzleOrm.eq(_.pinned,1),l=n.db.select({metadata:_.metadata}).from(_).where(u).all(),p=null;for(let h of l){let f=h.metadata?JSON.parse(h.metadata):{};typeof f.pinOrder=="number"&&(p===null||f.pinOrder<p)&&(p=f.pinOrder);}c.pinOrder=p===null?0:p-1;}else delete c.pinOrder;return n.db.update(_).set({pinned:a,metadata:Object.keys(c).length>0?JSON.stringify(c):null}).where(r).run(),{pinned:!!a}}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to toggle pin",r)}finally{n.close();}}reorderPins(t,e){let n=this.openHandle(true);try{for(let r=0;r<t.length;r++){let o=e?drizzleOrm.and(drizzleOrm.eq(_.id,t[r]),drizzleOrm.eq(_.workspace_id,e)):drizzleOrm.eq(_.id,t[r]),a=n.db.select({metadata:_.metadata}).from(_).where(o).get();if(!a)continue;let c=a.metadata?JSON.parse(a.metadata):{};c.pinOrder=r+1,n.db.update(_).set({metadata:JSON.stringify(c)}).where(o).run();}}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to reorder pins",r)}finally{n.close();}}toggleStar(t,e){let n=this.openHandle(true);try{let r=e?drizzleOrm.and(drizzleOrm.eq(_.id,t),drizzleOrm.eq(_.workspace_id,e)):drizzleOrm.eq(_.id,t),o=n.db.select({starred:_.starred}).from(_).where(r).get();if(!o)return null;let a=o.starred?0:1;return n.db.update(_).set({starred:a}).where(r).run(),{starred:!!a}}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to toggle star",r)}finally{n.close();}}resolveOverdriveForRequest(t,e,n,r){let a=this.openHandle(true);try{let c=e?drizzleOrm.and(drizzleOrm.eq(_.id,t),drizzleOrm.eq(_.workspace_id,e)):drizzleOrm.eq(_.id,t);return a.db.transaction(l=>{let p=l.select({metadata:_.metadata}).from(_).where(c).get();if(!p)return null;let h=p.metadata?JSON.parse(p.metadata):{},f=h.overdrive??{},m=r?.defaultTurns??f.defaultTurns??3,M=r?.updatedBy??"ui",F=new Date().toISOString(),K,I,st,Lt;switch(n){case "enable-count":{let Bt=r?.turns??m,Ut=r?.consumeCurrent?Math.max(Bt-1,0):Bt;K=Ut>0?"count":"off",I=Ut,st=!0,Lt="count";break}case "enable-latch":{K="latch",I=0,st=!0,Lt="latch";break}case "disable":{K="off",I=0,st=!1;break}default:{let Bt=f.state??"off",Ut=typeof f.remaining=="number"?f.remaining:0;if(Bt==="count"&&Ut>0){let xe=Ut-1;xe<=0?(K="off",I=0):(K="count",I=xe),st=!0,Lt="count";}else Bt==="latch"?(K="latch",I=0,st=!0,Lt="latch"):(K="off",I=0,st=!1);break}}return h.overdrive={state:K,remaining:I,defaultTurns:m,updatedAt:F,updatedBy:M},l.update(_).set({metadata:JSON.stringify(h),updated_at:F}).where(c).run(),{applied:st,appliedMode:Lt,state:K,remaining:I}},{behavior:"immediate"})}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to resolve overdrive",c)}finally{a.close();}}};var ge=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}insertSpan(t){let e=this.openHandle(true);try{e.db.insert(wt).values(t).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to insert span",n)}finally{e.close();}}findByTaskId(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(wt).where(drizzleOrm.eq(wt.task_id,t)).all()}catch(n){throw new d("DB_ERROR","Failed to find spans by task id",n)}finally{e.close();}}findById(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(wt).where(drizzleOrm.eq(wt.id,t)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to find span by id",n)}finally{e.close();}}};var me=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}insertToolCall(t){let e=this.openHandle(true);try{e.db.insert(lt).values(t).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to insert tool call",n)}finally{e.close();}}findByTaskId(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(lt).where(drizzleOrm.eq(lt.task_id,t)).all()}catch(n){throw new d("DB_ERROR","Failed to find tool calls by task id",n)}finally{e.close();}}aggregateByName(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select({toolName:lt.tool_name,count:drizzleOrm.sql`count(*)`}).from(lt).where(drizzleOrm.eq(lt.task_id,t)).groupBy(lt.tool_name).all().map(n=>({toolName:n.toolName,count:n.count}))}catch(n){throw new d("DB_ERROR","Failed to aggregate tool calls by name",n)}finally{e.close();}}};var we=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}ensureThreadExists(t,e){if(!t.db.select({id:_.id}).from(_).where(drizzleOrm.eq(_.id,e)).limit(1).get())throw new d("NOT_FOUND",`Thread not found: ${e}`)}findByThreadId(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return this.ensureThreadExists(e,t),e.db.select().from(tt).where(drizzleOrm.eq(tt.thread_id,t)).orderBy(drizzleOrm.asc(tt.seq)).all()}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to find boxes by thread id",n)}finally{e.close();}}findById(t,e){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(tt).where(drizzleOrm.and(drizzleOrm.eq(tt.id,e),drizzleOrm.eq(tt.thread_id,t))).limit(1).get()??void 0}catch(r){throw r instanceof d?r:new d("DB_ERROR","Failed to find box by id",r)}finally{n.close();}}insert(t){let e=this.openHandle(true);try{this.ensureThreadExists(e,t.threadId);try{e.db.insert(tt).values({id:t.id,thread_id:t.threadId,seq:t.seq,first_task_id:t.first_task_id,mid_task_id:t.mid_task_id,last_task_id:t.last_task_id,task_count:t.task_count,summary:t.summary??null,source_tokens:t.source_tokens,summary_tokens:t.summary_tokens??null,created_at:t.created_at}).run();}catch(r){throw r instanceof Error&&/UNIQUE constraint failed/i.test(r.message)?new d("CONFLICT",`Duplicate seq ${String(t.seq)} for thread ${t.threadId}`,r):r}let n=e.db.select().from(tt).where(drizzleOrm.eq(tt.id,t.id)).limit(1).get();if(!n)throw new d("DB_ERROR","Insert did not return a row");return n}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to insert thread box",n)}finally{e.close();}}};var ke=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}bulkInsert(t){if(t.length===0)return;let e=this.openHandle(true);try{let n=new Date().toISOString();e.db.transaction(r=>{for(let o of t)r.insert(Ot).values({id:crypto.randomUUID(),path:o.path,method:o.method,status_code:o.statusCode,duration_ms:o.durationMs,ip:o.ip??null,request_headers:o.requestHeaders??null,response_headers:o.responseHeaders??null,request_body:o.requestBody??null,response_body:o.responseBody??null,query:o.query??null,user_id:o.userId??null,project_id:o.projectId??null,partition_key:o.partitionKey??"default",timestamp:n,metadata:o.metadata??null}).run();});}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to bulk insert request logs",n)}finally{e.close();}}findRecent(t=100){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(Ot).orderBy(drizzleOrm.desc(Ot.timestamp)).limit(t).all()}catch(n){throw new d("DB_ERROR","Failed to find recent request logs",n)}finally{e.close();}}};function fn(i){return new Date(Math.floor(i/3e5)*3e5).toISOString()}var ye=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}upsert(t){let e=this.openHandle(true);try{let n=fn(t.bucketStartMs),r=t.accountRef??"default";e.db.insert(B).values({id:t.id,provider:t.provider,account_ref:r,limit_window:t.limitWindow,bucket_start:n,captured_at:t.capturedAt,used_percent:t.usedPercent,remaining_percent:t.remainingPercent,resets_at:t.resetsAt??null,source:t.source,metadata:t.metadata??null}).onConflictDoUpdate({target:[B.provider,B.account_ref,B.limit_window,B.bucket_start],set:{captured_at:t.capturedAt,used_percent:t.usedPercent,remaining_percent:t.remainingPercent,resets_at:t.resetsAt??null,metadata:t.metadata??null}}).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to upsert usage limit snapshot",n)}finally{e.close();}}getTrends(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{let n=e.db.select({provider:B.provider,bucket_start:B.bucket_start,used_percent:B.used_percent,remaining_percent:B.remaining_percent,resets_at:B.resets_at}).from(B).where(drizzleOrm.and(drizzleOrm.eq(B.limit_window,t.window),drizzleOrm.gte(B.bucket_start,t.fromIso),drizzleOrm.lte(B.bucket_start,t.toIso))).orderBy(drizzleOrm.asc(B.bucket_start)).all(),r=new Map;for(let o of n)r.has(o.provider)||r.set(o.provider,[]),r.get(o.provider).push({bucketStart:o.bucket_start,usedPercent:o.used_percent,remainingPercent:o.remaining_percent,resetsAt:o.resets_at??null});return Array.from(r.entries()).map(([o,a])=>({provider:o,points:a}))}catch(n){throw new d("DB_ERROR","Failed to get usage limit trends",n)}finally{e.close();}}};var Ee=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}publish(t){let e=this.openHandle(true);try{e.db.insert(G).values({id:t.id,workspace_id:t.workspaceId,month:t.month,generated_at:t.generatedAt,source_range:t.sourceRange,tier:t.tier,total_tokens:t.totalTokens,total_cost_usd:t.totalCostUsd,payload:t.payload}).onConflictDoUpdate({target:[G.workspace_id,G.month],set:{generated_at:t.generatedAt,source_range:t.sourceRange,tier:t.tier,total_tokens:t.totalTokens,total_cost_usd:t.totalCostUsd,payload:t.payload}}).run();let n=e.db.select().from(G).where(drizzleOrm.and(drizzleOrm.eq(G.workspace_id,t.workspaceId),drizzleOrm.eq(G.month,t.month))).limit(1).get();if(!n)throw new d("DB_ERROR","Failed to read back published usage report");return n}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to publish usage report",n)}finally{e.close();}}findByMonth(t,e){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(G).where(drizzleOrm.and(drizzleOrm.eq(G.workspace_id,t),drizzleOrm.eq(G.month,e))).limit(1).get()??void 0}catch(r){throw new d("DB_ERROR","Failed to find usage report",r)}finally{n.close();}}listByWorkspace(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(G).where(drizzleOrm.eq(G.workspace_id,t)).orderBy(drizzleOrm.desc(G.month)).all()}catch(n){throw new d("DB_ERROR","Failed to list usage reports",n)}finally{e.close();}}};var En=500,Rn=50,Re=class extends T{dbPath;cap;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db")),this.cap=t.cap??En;}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}create(t){let e=this.openHandle(true);try{let n=Rt("ntf"),r=new Date().toISOString();return e.db.insert(y).values({id:n,workspace_id:t.workspaceId,agent_id:t.agentId??null,task_id:t.taskId??null,thread_id:t.threadId??null,source:t.source??"agent",level:t.level??"info",title:t.title,body:t.body??null,target_user_id:t.targetUserId??null,created_at:r,metadata:t.metadata??null}).run(),this.enforceCap(e,t.workspaceId),{id:n}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to create notification",n)}finally{e.close();}}enforceCap(t,e){let o=(t.db.select({count:drizzleOrm.sql`count(*)`}).from(y).where(drizzleOrm.eq(y.workspace_id,e)).get()?.count??0)-this.cap;if(o<=0)return;let c=t.db.select({id:y.id}).from(y).innerJoin(C,drizzleOrm.eq(C.notification_id,y.id)).where(drizzleOrm.eq(y.workspace_id,e)).groupBy(y.id).orderBy(drizzleOrm.asc(y.created_at)).limit(o).all().map(u=>u.id);c.length!==0&&(t.db.delete(C).where(drizzleOrm.inArray(C.notification_id,c)).run(),t.db.delete(y).where(drizzleOrm.inArray(y.id,c)).run());}list(t){if(!this.dbExists())return [];let e=t.limit??Rn,n=this.openHandle(false);try{return n.db.select({id:y.id,workspace_id:y.workspace_id,agent_id:y.agent_id,task_id:y.task_id,thread_id:y.thread_id,source:y.source,level:y.level,title:y.title,body:y.body,target_user_id:y.target_user_id,created_at:y.created_at,metadata:y.metadata,read_at:C.read_at}).from(y).leftJoin(C,drizzleOrm.and(drizzleOrm.eq(C.notification_id,y.id),drizzleOrm.eq(C.user_id,t.userId))).where(drizzleOrm.eq(y.workspace_id,t.workspaceId)).orderBy(drizzleOrm.desc(y.created_at)).limit(e).all().map(o=>({...o,read_at:o.read_at??null,read:o.read_at!=null}))}catch(r){throw new d("DB_ERROR","Failed to list notifications",r)}finally{n.close();}}unreadCount(t){if(!this.dbExists())return 0;let e=this.openHandle(false);try{return e.db.select({count:drizzleOrm.sql`count(*)`}).from(y).leftJoin(C,drizzleOrm.and(drizzleOrm.eq(C.notification_id,y.id),drizzleOrm.eq(C.user_id,t.userId))).where(drizzleOrm.and(drizzleOrm.eq(y.workspace_id,t.workspaceId),drizzleOrm.isNull(C.notification_id))).get()?.count??0}catch(n){throw new d("DB_ERROR","Failed to count unread notifications",n)}finally{e.close();}}markRead(t){let e=this.openHandle(true);try{if(!e.db.select({id:y.id}).from(y).where(drizzleOrm.and(drizzleOrm.eq(y.id,t.notificationId),drizzleOrm.eq(y.workspace_id,t.workspaceId))).get())throw new d("NOT_FOUND","Notification not found in workspace");return e.db.insert(C).values({notification_id:t.notificationId,user_id:t.userId,read_at:new Date().toISOString()}).onConflictDoNothing().run().changes>0}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to mark notification read",n)}finally{e.close();}}markAllRead(t){let e=this.openHandle(true);try{let n=e.db.select({id:y.id}).from(y).leftJoin(C,drizzleOrm.and(drizzleOrm.eq(C.notification_id,y.id),drizzleOrm.eq(C.user_id,t.userId))).where(drizzleOrm.and(drizzleOrm.eq(y.workspace_id,t.workspaceId),drizzleOrm.isNull(C.notification_id))).all();if(n.length===0)return 0;let r=new Date().toISOString();return e.db.transaction(o=>{for(let a of n)o.insert(C).values({notification_id:a.id,user_id:t.userId,read_at:r}).onConflictDoNothing().run();}),n.length}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to mark all notifications read",n)}finally{e.close();}}};var xn=50,Se=class extends T{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=gt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let r=gt.dirname(e);Ye.existsSync(r)||Ye.mkdirSync(r,{recursive:true});}else if(!Ye.existsSync(e))throw new d("NOT_FOUND","Database not found");let n=w(e);if(t)try{A(n.db,e);}catch(r){throw n.close(),r}return n}create(t){let e=this.openHandle(true);try{let n=new Date().toISOString(),r=[],o=t.map(a=>{let c=Rt("sug");return r.push(c),{id:c,workspace_id:a.workspaceId,agent_id:a.agentId,task_id:a.taskId??null,type:a.type,status:a.status??"pending",payload:a.payload,applied_commit_sha:a.appliedCommitSha??null,created_at:n,updated_at:n}});return o.length>0&&e.db.insert(b).values(o).run(),{ids:r}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to create agent suggestions",n)}finally{e.close();}}findLatestSet(t,e){if(!this.dbExists())return [];let n=this.openHandle(false);try{let r=n.db.select({task_id:b.task_id}).from(b).where(drizzleOrm.and(drizzleOrm.eq(b.workspace_id,t),drizzleOrm.eq(b.agent_id,e))).orderBy(drizzleOrm.desc(b.created_at)).limit(1).get();if(!r)return [];let o=r.task_id===null?drizzleOrm.isNull(b.task_id):drizzleOrm.eq(b.task_id,r.task_id);return n.db.select().from(b).where(drizzleOrm.and(drizzleOrm.eq(b.workspace_id,t),drizzleOrm.eq(b.agent_id,e),o)).orderBy(drizzleOrm.asc(b.created_at)).all()}catch(r){throw new d("DB_ERROR","Failed to find latest agent suggestion set",r)}finally{n.close();}}findSetByTaskId(t,e,n){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.select().from(b).where(drizzleOrm.and(drizzleOrm.eq(b.workspace_id,t),drizzleOrm.eq(b.agent_id,e),drizzleOrm.eq(b.task_id,n))).orderBy(drizzleOrm.asc(b.created_at)).all()}catch(o){throw new d("DB_ERROR","Failed to find agent suggestion set by task id",o)}finally{r.close();}}findById(t,e,n){if(!this.dbExists())return null;let r=this.openHandle(false);try{return r.db.select().from(b).where(drizzleOrm.and(drizzleOrm.eq(b.workspace_id,t),drizzleOrm.eq(b.agent_id,e),drizzleOrm.eq(b.id,n))).get()??null}catch(o){throw new d("DB_ERROR","Failed to find agent suggestion by id",o)}finally{r.close();}}updateStatus(t,e,n){let r=this.openHandle(true);try{let o={status:e,updated_at:new Date().toISOString()};return n!==void 0&&(o.applied_commit_sha=n),r.db.update(b).set(o).where(drizzleOrm.eq(b.id,t)).run().changes>0}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to update agent suggestion status",o)}finally{r.close();}}listByAgent(t,e,n=xn){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.select().from(b).where(drizzleOrm.and(drizzleOrm.eq(b.workspace_id,t),drizzleOrm.eq(b.agent_id,e))).orderBy(drizzleOrm.desc(b.created_at)).limit(n).all()}catch(o){throw new d("DB_ERROR","Failed to list agent suggestions",o)}finally{r.close();}}findDismissed(t,e,n=20){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.select().from(b).where(drizzleOrm.and(drizzleOrm.eq(b.workspace_id,t),drizzleOrm.eq(b.agent_id,e),drizzleOrm.eq(b.status,"dismissed"))).orderBy(drizzleOrm.desc(b.updated_at)).limit(n).all()}catch(o){throw new d("DB_ERROR","Failed to find dismissed agent suggestions",o)}finally{r.close();}}};exports.AgentSuggestionRepository=Se;exports.BaseSqliteRepository=T;exports.DEFAULT_AGENT_SUGGESTION_LIST_LIMIT=xn;exports.DEFAULT_NOTIFICATION_CAP=En;exports.DEFAULT_NOTIFICATION_LIST_LIMIT=Rn;exports.NotificationRepository=Re;exports.ProjectRepository=pe;exports.RepositoryError=d;exports.RequestLogRepository=ke;exports.SpanRepository=ge;exports.TaskRepository=fe;exports.ThreadBoxRepository=we;exports.ThreadRepository=he;exports.ToolCallRepository=me;exports.UsageLimitSnapshotRepository=ye;exports.UsageReportRepository=Ee;exports.WorkspaceRepository=ue;exports.calcBucketStart=fn;exports.openDrizzleDb=w;exports.pushSchema=$r;exports.runMigrations=Pt;exports.runMigrationsOnce=A;exports.tasks=s;
342
+ updated_at = ${s}
343
+ WHERE id = ${e}
344
+ `),l},{behavior:"immediate"})}}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to save user message",s)}finally{o.close();}}saveAssistantMessage(e,t,n){if(!this.dbExists())return;let o=this.openHandle(true);try{let s=new Date().toISOString();o.db.update(f).set({last_message:t,updated_at:s}).where(drizzleOrm.eq(f.id,e)).run();}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to save assistant message",s)}finally{o.close();}}updateThread(e,t){if(!this.dbExists())return;let n=this.openHandle(true);try{let o={updated_at:new Date().toISOString()};t.title!==void 0&&(o.title=t.title,o.title_locked=1),t.titleLocked!==void 0&&(o.title_locked=t.titleLocked?1:0),n.db.update(f).set(o).where(drizzleOrm.eq(f.id,e)).run();}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to update thread",o)}finally{n.close();}}togglePin(e,t){let n=this.openHandle(true);try{let o=t?drizzleOrm.and(drizzleOrm.eq(f.id,e),drizzleOrm.eq(f.workspace_id,t)):drizzleOrm.eq(f.id,e),s=n.db.select({pinned:f.pinned,metadata:f.metadata}).from(f).where(o).get();if(!s)return null;let a=s.pinned?0:1,c=s.metadata?JSON.parse(s.metadata):{};if(a){let u=t?drizzleOrm.and(drizzleOrm.eq(f.pinned,1),drizzleOrm.eq(f.workspace_id,t)):drizzleOrm.eq(f.pinned,1),l=n.db.select({metadata:f.metadata}).from(f).where(u).all(),p=null;for(let _ of l){let g=_.metadata?JSON.parse(_.metadata):{};typeof g.pinOrder=="number"&&(p===null||g.pinOrder<p)&&(p=g.pinOrder);}c.pinOrder=p===null?0:p-1;}else delete c.pinOrder;return n.db.update(f).set({pinned:a,metadata:Object.keys(c).length>0?JSON.stringify(c):null}).where(o).run(),{pinned:!!a}}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to toggle pin",o)}finally{n.close();}}reorderPins(e,t){let n=this.openHandle(true);try{for(let o=0;o<e.length;o++){let s=t?drizzleOrm.and(drizzleOrm.eq(f.id,e[o]),drizzleOrm.eq(f.workspace_id,t)):drizzleOrm.eq(f.id,e[o]),a=n.db.select({metadata:f.metadata}).from(f).where(s).get();if(!a)continue;let c=a.metadata?JSON.parse(a.metadata):{};c.pinOrder=o+1,n.db.update(f).set({metadata:JSON.stringify(c)}).where(s).run();}}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to reorder pins",o)}finally{n.close();}}toggleStar(e,t){let n=this.openHandle(true);try{let o=t?drizzleOrm.and(drizzleOrm.eq(f.id,e),drizzleOrm.eq(f.workspace_id,t)):drizzleOrm.eq(f.id,e),s=n.db.select({starred:f.starred}).from(f).where(o).get();if(!s)return null;let a=s.starred?0:1;return n.db.update(f).set({starred:a}).where(o).run(),{starred:!!a}}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to toggle star",o)}finally{n.close();}}resolveOverdriveForRequest(e,t,n,o){let a=this.openHandle(true);try{let c=t?drizzleOrm.and(drizzleOrm.eq(f.id,e),drizzleOrm.eq(f.workspace_id,t)):drizzleOrm.eq(f.id,e);return a.db.transaction(l=>{let p=l.select({metadata:f.metadata}).from(f).where(c).get();if(!p)return null;let _=p.metadata?JSON.parse(p.metadata):{},g=_.overdrive??{},m=o?.defaultTurns??g.defaultTurns??3,O=o?.updatedBy??"ui",w=new Date().toISOString(),j,S,W,xe;switch(n){case "enable-count":{let we=o?.turns??m,ke=o?.consumeCurrent?Math.max(we-1,0):we;j=ke>0?"count":"off",S=ke,W=!0,xe="count";break}case "enable-latch":{j="latch",S=0,W=!0,xe="latch";break}case "disable":{j="off",S=0,W=!1;break}default:{let we=g.state??"off",ke=typeof g.remaining=="number"?g.remaining:0;if(we==="count"&&ke>0){let Mt=ke-1;Mt<=0?(j="off",S=0):(j="count",S=Mt),W=!0,xe="count";}else we==="latch"?(j="latch",S=0,W=!0,xe="latch"):(j="off",S=0,W=!1);break}}return _.overdrive={state:j,remaining:S,defaultTurns:m,updatedAt:w,updatedBy:O},l.update(f).set({metadata:JSON.stringify(_),updated_at:w}).where(c).run(),{applied:W,appliedMode:xe,state:j,remaining:S}},{behavior:"immediate"})}catch(c){throw c instanceof d?c:new d("DB_ERROR","Failed to resolve overdrive",c)}finally{a.close();}}};var At=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}insertSpan(e){let t=this.openHandle(true);try{t.db.insert(Ee).values(e).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to insert span",n)}finally{t.close();}}findByTaskId(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(Ee).where(drizzleOrm.eq(Ee.task_id,e)).all()}catch(n){throw new d("DB_ERROR","Failed to find spans by task id",n)}finally{t.close();}}findById(e){if(!this.dbExists())return;let t=this.openHandle(false);try{return t.db.select().from(Ee).where(drizzleOrm.eq(Ee.id,e)).limit(1).get()??void 0}catch(n){throw new d("DB_ERROR","Failed to find span by id",n)}finally{t.close();}}};var Ct=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}insertToolCall(e){let t=this.openHandle(true);try{t.db.insert(pe).values(e).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to insert tool call",n)}finally{t.close();}}findByTaskId(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(pe).where(drizzleOrm.eq(pe.task_id,e)).all()}catch(n){throw new d("DB_ERROR","Failed to find tool calls by task id",n)}finally{t.close();}}aggregateByName(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select({toolName:pe.tool_name,count:drizzleOrm.sql`count(*)`}).from(pe).where(drizzleOrm.eq(pe.task_id,e)).groupBy(pe.tool_name).all().map(n=>({toolName:n.toolName,count:n.count}))}catch(n){throw new d("DB_ERROR","Failed to aggregate tool calls by name",n)}finally{t.close();}}};var Lt=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}ensureThreadExists(e,t){if(!e.db.select({id:f.id}).from(f).where(drizzleOrm.eq(f.id,t)).limit(1).get())throw new d("NOT_FOUND",`Thread not found: ${t}`)}findByThreadId(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return this.ensureThreadExists(t,e),t.db.select().from(ne).where(drizzleOrm.eq(ne.thread_id,e)).orderBy(drizzleOrm.asc(ne.seq)).all()}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to find boxes by thread id",n)}finally{t.close();}}findById(e,t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(ne).where(drizzleOrm.and(drizzleOrm.eq(ne.id,t),drizzleOrm.eq(ne.thread_id,e))).limit(1).get()??void 0}catch(o){throw o instanceof d?o:new d("DB_ERROR","Failed to find box by id",o)}finally{n.close();}}insert(e){let t=this.openHandle(true);try{this.ensureThreadExists(t,e.threadId);try{t.db.insert(ne).values({id:e.id,thread_id:e.threadId,seq:e.seq,first_task_id:e.first_task_id,mid_task_id:e.mid_task_id,last_task_id:e.last_task_id,task_count:e.task_count,summary:e.summary??null,source_tokens:e.source_tokens,summary_tokens:e.summary_tokens??null,created_at:e.created_at}).run();}catch(o){throw o instanceof Error&&/UNIQUE constraint failed/i.test(o.message)?new d("CONFLICT",`Duplicate seq ${String(e.seq)} for thread ${e.threadId}`,o):o}let n=t.db.select().from(ne).where(drizzleOrm.eq(ne.id,e.id)).limit(1).get();if(!n)throw new d("DB_ERROR","Insert did not return a row");return n}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to insert thread box",n)}finally{t.close();}}};var Pt=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}bulkInsert(e){if(e.length===0)return;let t=this.openHandle(true);try{let n=new Date().toISOString();t.db.transaction(o=>{for(let s of e)o.insert(Me).values({id:crypto.randomUUID(),path:s.path,method:s.method,status_code:s.statusCode,duration_ms:s.durationMs,ip:s.ip??null,request_headers:s.requestHeaders??null,response_headers:s.responseHeaders??null,request_body:s.requestBody??null,response_body:s.responseBody??null,query:s.query??null,user_id:s.userId??null,project_id:s.projectId??null,partition_key:s.partitionKey??"default",timestamp:n,metadata:s.metadata??null}).run();});}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to bulk insert request logs",n)}finally{t.close();}}findRecent(e=100){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(Me).orderBy(drizzleOrm.desc(Me.timestamp)).limit(e).all()}catch(n){throw new d("DB_ERROR","Failed to find recent request logs",n)}finally{t.close();}}};function Zn(r){return new Date(Math.floor(r/3e5)*3e5).toISOString()}var Ot=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}upsert(e){let t=this.openHandle(true);try{let n=Zn(e.bucketStartMs),o=e.accountRef??"default";t.db.insert(U).values({id:e.id,provider:e.provider,account_ref:o,limit_window:e.limitWindow,bucket_start:n,captured_at:e.capturedAt,used_percent:e.usedPercent,remaining_percent:e.remainingPercent,resets_at:e.resetsAt??null,source:e.source,metadata:e.metadata??null}).onConflictDoUpdate({target:[U.provider,U.account_ref,U.limit_window,U.bucket_start],set:{captured_at:e.capturedAt,used_percent:e.usedPercent,remaining_percent:e.remainingPercent,resets_at:e.resetsAt??null,metadata:e.metadata??null}}).run();}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to upsert usage limit snapshot",n)}finally{t.close();}}getTrends(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{let n=t.db.select({provider:U.provider,bucket_start:U.bucket_start,used_percent:U.used_percent,remaining_percent:U.remaining_percent,resets_at:U.resets_at}).from(U).where(drizzleOrm.and(drizzleOrm.eq(U.limit_window,e.window),drizzleOrm.gte(U.bucket_start,e.fromIso),drizzleOrm.lte(U.bucket_start,e.toIso))).orderBy(drizzleOrm.asc(U.bucket_start)).all(),o=new Map;for(let s of n)o.has(s.provider)||o.set(s.provider,[]),o.get(s.provider).push({bucketStart:s.bucket_start,usedPercent:s.used_percent,remainingPercent:s.remaining_percent,resetsAt:s.resets_at??null});return Array.from(o.entries()).map(([s,a])=>({provider:s,points:a}))}catch(n){throw new d("DB_ERROR","Failed to get usage limit trends",n)}finally{t.close();}}};var jt=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}publish(e){let t=this.openHandle(true);try{t.db.insert(J).values({id:e.id,workspace_id:e.workspaceId,month:e.month,generated_at:e.generatedAt,source_range:e.sourceRange,tier:e.tier,total_tokens:e.totalTokens,total_cost_usd:e.totalCostUsd,payload:e.payload}).onConflictDoUpdate({target:[J.workspace_id,J.month],set:{generated_at:e.generatedAt,source_range:e.sourceRange,tier:e.tier,total_tokens:e.totalTokens,total_cost_usd:e.totalCostUsd,payload:e.payload}}).run();let n=t.db.select().from(J).where(drizzleOrm.and(drizzleOrm.eq(J.workspace_id,e.workspaceId),drizzleOrm.eq(J.month,e.month))).limit(1).get();if(!n)throw new d("DB_ERROR","Failed to read back published usage report");return n}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to publish usage report",n)}finally{t.close();}}findByMonth(e,t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(J).where(drizzleOrm.and(drizzleOrm.eq(J.workspace_id,e),drizzleOrm.eq(J.month,t))).limit(1).get()??void 0}catch(o){throw new d("DB_ERROR","Failed to find usage report",o)}finally{n.close();}}listByWorkspace(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(J).where(drizzleOrm.eq(J.workspace_id,e)).orderBy(drizzleOrm.desc(J.month)).all()}catch(n){throw new d("DB_ERROR","Failed to list usage reports",n)}finally{t.close();}}};var ir=500,ar=50,$t=class extends x{dbPath;cap;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db")),this.cap=e.cap??ir;}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}create(e){let t=this.openHandle(true);try{let n=De("ntf"),o=new Date().toISOString();return t.db.insert(R).values({id:n,workspace_id:e.workspaceId,agent_id:e.agentId??null,task_id:e.taskId??null,thread_id:e.threadId??null,source:e.source??"agent",level:e.level??"info",title:e.title,body:e.body??null,target_user_id:e.targetUserId??null,created_at:o,metadata:e.metadata??null}).run(),this.enforceCap(t,e.workspaceId),{id:n}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to create notification",n)}finally{t.close();}}enforceCap(e,t){let s=(e.db.select({count:drizzleOrm.sql`count(*)`}).from(R).where(drizzleOrm.eq(R.workspace_id,t)).get()?.count??0)-this.cap;if(s<=0)return;let c=e.db.select({id:R.id}).from(R).innerJoin($,drizzleOrm.eq($.notification_id,R.id)).where(drizzleOrm.eq(R.workspace_id,t)).groupBy(R.id).orderBy(drizzleOrm.asc(R.created_at)).limit(s).all().map(u=>u.id);c.length!==0&&(e.db.delete($).where(drizzleOrm.inArray($.notification_id,c)).run(),e.db.delete(R).where(drizzleOrm.inArray(R.id,c)).run());}list(e){if(!this.dbExists())return [];let t=e.limit??ar,n=this.openHandle(false);try{return n.db.select({id:R.id,workspace_id:R.workspace_id,agent_id:R.agent_id,task_id:R.task_id,thread_id:R.thread_id,source:R.source,level:R.level,title:R.title,body:R.body,target_user_id:R.target_user_id,created_at:R.created_at,metadata:R.metadata,read_at:$.read_at}).from(R).leftJoin($,drizzleOrm.and(drizzleOrm.eq($.notification_id,R.id),drizzleOrm.eq($.user_id,e.userId))).where(drizzleOrm.eq(R.workspace_id,e.workspaceId)).orderBy(drizzleOrm.desc(R.created_at)).limit(t).all().map(s=>({...s,read_at:s.read_at??null,read:s.read_at!=null}))}catch(o){throw new d("DB_ERROR","Failed to list notifications",o)}finally{n.close();}}unreadCount(e){if(!this.dbExists())return 0;let t=this.openHandle(false);try{return t.db.select({count:drizzleOrm.sql`count(*)`}).from(R).leftJoin($,drizzleOrm.and(drizzleOrm.eq($.notification_id,R.id),drizzleOrm.eq($.user_id,e.userId))).where(drizzleOrm.and(drizzleOrm.eq(R.workspace_id,e.workspaceId),drizzleOrm.isNull($.notification_id))).get()?.count??0}catch(n){throw new d("DB_ERROR","Failed to count unread notifications",n)}finally{t.close();}}markRead(e){let t=this.openHandle(true);try{if(!t.db.select({id:R.id}).from(R).where(drizzleOrm.and(drizzleOrm.eq(R.id,e.notificationId),drizzleOrm.eq(R.workspace_id,e.workspaceId))).get())throw new d("NOT_FOUND","Notification not found in workspace");return t.db.insert($).values({notification_id:e.notificationId,user_id:e.userId,read_at:new Date().toISOString()}).onConflictDoNothing().run().changes>0}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to mark notification read",n)}finally{t.close();}}markAllRead(e){let t=this.openHandle(true);try{let n=t.db.select({id:R.id}).from(R).leftJoin($,drizzleOrm.and(drizzleOrm.eq($.notification_id,R.id),drizzleOrm.eq($.user_id,e.userId))).where(drizzleOrm.and(drizzleOrm.eq(R.workspace_id,e.workspaceId),drizzleOrm.isNull($.notification_id))).all();if(n.length===0)return 0;let o=new Date().toISOString();return t.db.transaction(s=>{for(let a of n)s.insert($).values({notification_id:a.id,user_id:e.userId,read_at:o}).onConflictDoNothing().run();}),n.length}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to mark all notifications read",n)}finally{t.close();}}};var lr=50,qt=class extends x{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ye.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let o=ye.dirname(t);mn.existsSync(o)||mn.mkdirSync(o,{recursive:true});}else if(!mn.existsSync(t))throw new d("NOT_FOUND","Database not found");let n=k(t);if(e)try{C(n.db,t);}catch(o){throw n.close(),o}return n}create(e){let t=this.openHandle(true);try{let n=new Date().toISOString(),o=[],s=e.map(a=>{let c=De("sug");return o.push(c),{id:c,workspace_id:a.workspaceId,agent_id:a.agentId,task_id:a.taskId??null,type:a.type,status:a.status??"pending",payload:a.payload,applied_commit_sha:a.appliedCommitSha??null,created_at:n,updated_at:n}});return s.length>0&&t.db.insert(T).values(s).run(),{ids:o}}catch(n){throw n instanceof d?n:new d("DB_ERROR","Failed to create agent suggestions",n)}finally{t.close();}}findLatestSet(e,t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let o=n.db.select({task_id:T.task_id}).from(T).where(drizzleOrm.and(drizzleOrm.eq(T.workspace_id,e),drizzleOrm.eq(T.agent_id,t))).orderBy(drizzleOrm.desc(T.created_at)).limit(1).get();if(!o)return [];let s=o.task_id===null?drizzleOrm.isNull(T.task_id):drizzleOrm.eq(T.task_id,o.task_id);return n.db.select().from(T).where(drizzleOrm.and(drizzleOrm.eq(T.workspace_id,e),drizzleOrm.eq(T.agent_id,t),s)).orderBy(drizzleOrm.asc(T.created_at)).all()}catch(o){throw new d("DB_ERROR","Failed to find latest agent suggestion set",o)}finally{n.close();}}findSetByTaskId(e,t,n){if(!this.dbExists())return [];let o=this.openHandle(false);try{return o.db.select().from(T).where(drizzleOrm.and(drizzleOrm.eq(T.workspace_id,e),drizzleOrm.eq(T.agent_id,t),drizzleOrm.eq(T.task_id,n))).orderBy(drizzleOrm.asc(T.created_at)).all()}catch(s){throw new d("DB_ERROR","Failed to find agent suggestion set by task id",s)}finally{o.close();}}findById(e,t,n){if(!this.dbExists())return null;let o=this.openHandle(false);try{return o.db.select().from(T).where(drizzleOrm.and(drizzleOrm.eq(T.workspace_id,e),drizzleOrm.eq(T.agent_id,t),drizzleOrm.eq(T.id,n))).get()??null}catch(s){throw new d("DB_ERROR","Failed to find agent suggestion by id",s)}finally{o.close();}}updateStatus(e,t,n){let o=this.openHandle(true);try{let s={status:t,updated_at:new Date().toISOString()};return n!==void 0&&(s.applied_commit_sha=n),o.db.update(T).set(s).where(drizzleOrm.eq(T.id,e)).run().changes>0}catch(s){throw s instanceof d?s:new d("DB_ERROR","Failed to update agent suggestion status",s)}finally{o.close();}}listByAgent(e,t,n=lr){if(!this.dbExists())return [];let o=this.openHandle(false);try{return o.db.select().from(T).where(drizzleOrm.and(drizzleOrm.eq(T.workspace_id,e),drizzleOrm.eq(T.agent_id,t))).orderBy(drizzleOrm.desc(T.created_at)).limit(n).all()}catch(s){throw new d("DB_ERROR","Failed to list agent suggestions",s)}finally{o.close();}}findDismissed(e,t,n=20){if(!this.dbExists())return [];let o=this.openHandle(false);try{return o.db.select().from(T).where(drizzleOrm.and(drizzleOrm.eq(T.workspace_id,e),drizzleOrm.eq(T.agent_id,t),drizzleOrm.eq(T.status,"dismissed"))).orderBy(drizzleOrm.desc(T.updated_at)).limit(n).all()}catch(s){throw new d("DB_ERROR","Failed to find dismissed agent suggestions",s)}finally{o.close();}}};exports.AgentSuggestionRepository=qt;exports.BaseSqliteRepository=x;exports.CREWX_JOURNAL_SIZE_LIMIT_BYTES=Ht;exports.DEFAULT_AGENT_SUGGESTION_LIST_LIMIT=lr;exports.DEFAULT_NOTIFICATION_CAP=ir;exports.DEFAULT_NOTIFICATION_LIST_LIMIT=ar;exports.NotificationRepository=$t;exports.ProjectRepository=Et;exports.RepositoryError=d;exports.RequestLogRepository=Pt;exports.SpanRepository=At;exports.TASK_LOG_MIGRATION_EVENT_ROW_BYTES=Ln;exports.TASK_LOG_MIGRATION_MIN_FREE_SPACE_BYTES=_t;exports.TASK_LOG_MIGRATION_TERMINAL_STATUSES=Cn;exports.TaskLogRepository=Je;exports.TaskRepository=Tt;exports.ThreadBoxRepository=Lt;exports.ThreadRepository=It;exports.ToolCallRepository=Ct;exports.UsageLimitSnapshotRepository=Ot;exports.UsageReportRepository=jt;exports.WorkspaceRepository=Rt;exports.calcBucketStart=Zn;exports.hasSufficientTaskLogMigrationFreeSpace=Bn;exports.openDrizzleDb=k;exports.pushSchema=xo;exports.reclaimTemporaryJournal=gr;exports.resolveTaskLogMigrationDbPath=Pn;exports.runMigrations=qe;exports.runMigrationsOnce=C;exports.runTaskLogMigration=gs;exports.taskLogBackupName=fs;exports.tasks=i;exports.tryCheckpointTaskLogWal=Un;