@crewx/sdk 0.8.3-rc.6 → 0.8.3-rc.8

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,4 +1,4 @@
1
- 'use strict';var fs=require('fs'),ut=require('path'),At=require('os'),crypto=require('crypto'),drizzleOrm=require('drizzle-orm'),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 ut__namespace=/*#__PURE__*/_interopNamespace(ut);var At__default=/*#__PURE__*/_interopDefault(At);var Q=(d=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(d,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):d)(function(d){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+d+'" is not supported')});var A=class{detach(t){}};function it(d){let t=e=>String(e).padStart(2,"0");return `${d.getFullYear()}${t(d.getMonth()+1)}${t(d.getDate())}T${t(d.getHours())}${t(d.getMinutes())}${t(d.getSeconds())}`}var Z=class extends A{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=ut.join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",e=>{try{fs.existsSync(this.logsDir)||fs.mkdirSync(this.logsDir,{recursive:!0});let s=it(e.timestamp),n=ut.join(this.logsDir,`${s}_${e.traceId}.log`);this.logFiles.set(e.traceId,n);let r=`=== TASK LOG: ${e.traceId} ===
1
+ 'use strict';var fs=require('fs'),tt=require('path'),At=require('os'),crypto=require('crypto'),drizzleOrm=require('drizzle-orm'),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 tt__namespace=/*#__PURE__*/_interopNamespace(tt);var At__default=/*#__PURE__*/_interopDefault(At);var Q=(d=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(d,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):d)(function(d){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+d+'" is not supported')});var A=class{detach(t){}};function at(d){let t=e=>String(e).padStart(2,"0");return `${d.getFullYear()}${t(d.getMonth()+1)}${t(d.getDate())}T${t(d.getHours())}${t(d.getMinutes())}${t(d.getSeconds())}`}var Z=class extends A{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=tt.join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",e=>{try{fs.existsSync(this.logsDir)||fs.mkdirSync(this.logsDir,{recursive:!0});let s=at(e.timestamp),n=tt.join(this.logsDir,`${s}_${e.traceId}.log`);this.logFiles.set(e.traceId,n);let r=`=== TASK LOG: ${e.traceId} ===
2
2
  CrewX Version: ${this.version}
3
3
  Mode: ${e.mode}
4
4
  Agent: ${e.agentRef}
@@ -8,7 +8,9 @@ Message: ${e.message}
8
8
  `;fs.writeFileSync(n,r,{encoding:"utf8",mode:384});}catch{}}),t.on("task:output",e=>{try{let s=this.logFiles.get(e.traceId);if(!s)return;let n=new Date().toISOString();fs.appendFileSync(s,`[${n}] STDOUT: ${e.output}
9
9
  `,"utf8");}catch{}}),t.on("task:end",e=>{try{let s=this.logFiles.get(e.traceId);if(!s)return;let n=new Date().toLocaleString(),r=e.error?`failed: ${e.error.message}`:"completed successfully",i=`[${n}] INFO: Task ${r} in ${e.durationMs}ms
10
10
  [${n}] INFO: Process closed with exit code: ${e.error?1:0}
11
- `;fs.appendFileSync(s,i,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function Tt(d){let t=ut__namespace.resolve(d);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(e,s)=>`${s.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function ct(d){let t=Tt(d);return crypto.createHash("sha256").update(t).digest("hex")}var F=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:ut.join(At__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 fs.existsSync(t??this.resolveDbPath())}};function w(d){let t=Q("better-sqlite3"),{drizzle:e}=Q("drizzle-orm/better-sqlite3"),s=new t(d);return s.exec("PRAGMA journal_mode = WAL"),s.exec("PRAGMA busy_timeout = 5000"),s.exec("PRAGMA foreign_keys = ON"),{db:e(s),runRaw:(n,r=[])=>s.prepare(n).run(...r),close:()=>s.close()}}var pt=new Set;function vt(d){let{migrate:t}=Q("drizzle-orm/better-sqlite3/migrator"),e=ut__namespace.default.join(__dirname,"../migrations"),s=fs.existsSync(e)?e:ut__namespace.default.join(__dirname,"../../../../drizzle/migrations");t(d,{migrationsFolder:s});}function z(d,t){pt.has(t)||(vt(d),pt.add(t));}var c=class extends Error{code;cause;constructor(t,e,s){super(e),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var $=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 o=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"),workspace_name:sqliteCore.text("workspace_name"),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_name:sqliteCore.text("project_name"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0)},d=>({idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(d.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(d.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(d.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(d.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(d.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(d.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(d.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(d.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(d.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(d.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(d.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(d.workspace_id,d.started_at)}));var u=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>$.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)},d=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(d.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(d.workspace_id)}));var Ft=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>o.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>Ft.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")},d=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(d.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(d.parent_span_id)}));sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>o.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()},d=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(d.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(d.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(d.timestamp)}));sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>u.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()},d=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(d.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(d.thread_id,d.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(d.thread_id,d.seq)}));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")},d=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(d.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(d.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(d.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(d.partition_key)}));var K=class extends F{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=ut.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=ut.dirname(e);fs.existsSync(n)||fs.mkdirSync(n,{recursive:true});}else if(!fs.existsSync(e))throw new c("NOT_FOUND","Database not found");let s=w(e);if(t)try{z(s.db,e);}catch(n){throw s.close(),n}return s}startTask(t){let e=this.openHandle(true);try{e.db.insert(o).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,workspace_name:t.workspaceName??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}).onConflictDoNothing().run();}catch(s){throw s instanceof c?s:new c("DB_ERROR","Failed to start task",s)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
11
+ `;fs.appendFileSync(s,i,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function Tt(d){let t=tt__namespace.resolve(d);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(e,s)=>`${s.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function ut(d){let t=Tt(d);return crypto.createHash("sha256").update(t).digest("hex")}var $=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:tt.join(At__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 fs.existsSync(t??this.resolveDbPath())}};function w(d){let t=Q("better-sqlite3"),{drizzle:e}=Q("drizzle-orm/better-sqlite3"),s=new t(d);return s.exec("PRAGMA journal_mode = WAL"),s.exec("PRAGMA busy_timeout = 5000"),s.exec("PRAGMA foreign_keys = ON"),{db:e(s),runRaw:(n,r=[])=>s.prepare(n).run(...r),close:()=>s.close()}}var pt=new Set;function vt(d){let{migrate:t}=Q("drizzle-orm/better-sqlite3/migrator"),e=[tt__namespace.default.join(__dirname,"../migrations"),tt__namespace.default.join(__dirname,"migrations")],s=e.find(n=>fs.existsSync(tt__namespace.default.join(n,"meta/_journal.json")));if(!s)throw new Error(`migrations folder not found. Searched:
12
+ ${e.join(`
13
+ `)}`);t(d,{migrationsFolder:s});}function z(d,t){pt.has(t)||(vt(d),pt.add(t));}var c=class extends Error{code;cause;constructor(t,e,s){super(e),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var F=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 o=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"),workspace_name:sqliteCore.text("workspace_name"),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_name:sqliteCore.text("project_name"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0)},d=>({idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(d.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(d.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(d.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(d.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(d.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(d.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(d.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(d.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(d.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(d.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(d.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(d.workspace_id,d.started_at)}));var u=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>F.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)},d=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(d.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(d.workspace_id)}));var $t=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>o.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>$t.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")},d=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(d.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(d.parent_span_id)}));sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>o.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()},d=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(d.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(d.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(d.timestamp)}));sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>u.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()},d=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(d.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(d.thread_id,d.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(d.thread_id,d.seq)}));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")},d=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(d.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(d.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(d.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(d.partition_key)}));var K=class extends ${dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=tt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=tt.dirname(e);fs.existsSync(n)||fs.mkdirSync(n,{recursive:true});}else if(!fs.existsSync(e))throw new c("NOT_FOUND","Database not found");let s=w(e);if(t)try{z(s.db,e);}catch(n){throw s.close(),n}return s}startTask(t){let e=this.openHandle(true);try{e.db.insert(o).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,workspace_name:t.workspaceName??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}).onConflictDoNothing().run();}catch(s){throw s instanceof c?s:new c("DB_ERROR","Failed to start task",s)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
12
14
  exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
13
15
  model=COALESCE(?, model) WHERE id=?`,[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]);}catch(s){throw s instanceof c?s:new c("DB_ERROR","Failed to finish task",s)}finally{e.close();}}appendLog(t,e){let s=this.openHandle(true);try{s.db.transaction(n=>{let r=n.select({logs:o.logs}).from(o).where(drizzleOrm.eq(o.id,t)).limit(1).get(),i=r?.logs?JSON.parse(r.logs):[];i.push(e),n.update(o).set({logs:JSON.stringify(i)}).where(drizzleOrm.eq(o.id,t)).run();},{behavior:"immediate"});}catch(n){throw n instanceof c?n:new c("DB_ERROR","Failed to append log",n)}finally{s.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).where(drizzleOrm.eq(o.status,"running")).orderBy(drizzleOrm.desc(o.started_at)).all()}catch(e){throw new c("DB_ERROR","Failed to get running tasks",e)}finally{t.close();}}getAllTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).orderBy(drizzleOrm.desc(o.started_at)).limit(100).all()}catch(e){throw new c("DB_ERROR","Failed to get all tasks",e)}finally{t.close();}}getTask(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(o).where(drizzleOrm.eq(o.id,t)).limit(1).get()??void 0}catch(s){throw new c("DB_ERROR","Failed to get task",s)}finally{e.close();}}killTask(t){if(!this.dbExists())return {killed:false};let e=this.openHandle(true);try{let s=e.db.select({id:o.id,status:o.status,pid:o.pid}).from(o).where(drizzleOrm.eq(o.id,t)).limit(1).get();if(!s||s.status!=="running")return {killed:!1};if(s.pid)try{process.kill(s.pid,"SIGTERM");}catch{}return e.db.update(o).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"))).run(),{killed:!0,pid:s.pid??void 0}}catch(s){throw s instanceof c?s:new c("DB_ERROR","Failed to kill task",s)}finally{e.close();}}findTaskStatus(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=w(n);try{let i=e?drizzleOrm.eq(o.workspace_id,e):void 0,l=i?drizzleOrm.and(drizzleOrm.eq(o.id,t),i):drizzleOrm.eq(o.id,t),a=r.db.select().from(o).where(l).limit(1).get()??void 0;if(!a){let _=drizzleOrm.or(drizzleOrm.eq(o.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(o.thread_id),drizzleOrm.like(o.command,`%--thread=${t}%`))),p=i?drizzleOrm.and(_,i):_;a=r.db.select().from(o).where(p).orderBy(drizzleOrm.desc(o.started_at)).limit(1).get()??void 0;}if(a)return a}catch(i){throw new c("DB_ERROR","Failed to find task status",i)}finally{r.close();}}}findChildTasks(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!fs.existsSync(i))continue;let l=w(i);try{let a=e?drizzleOrm.and(drizzleOrm.eq(o.parent_task_id,t),drizzleOrm.eq(o.workspace_id,e)):drizzleOrm.eq(o.parent_task_id,t),_=l.db.select().from(o).where(a).orderBy(drizzleOrm.asc(o.started_at)).all();for(let p of _)n.has(p.id)||(n.add(p.id),r.push(p));}catch(a){throw new c("DB_ERROR","Failed to find child tasks",a)}finally{l.close();}}return r}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.all(t?drizzleOrm.sql`
14
16
  SELECT
@@ -36,6 +38,8 @@ Message: ${e.message}
36
38
  `)}catch(s){throw new c("DB_ERROR","Failed to get workspace usage summary",s)}finally{e.close();}}getThreadTokenUsage(t,e){let s=this.resolveDbPaths(),n=new Set,r=0,i=0,l=0;for(let a of s){if(!fs.existsSync(a))continue;let _=w(a);try{let p=drizzleOrm.or(drizzleOrm.eq(o.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(o.thread_id),drizzleOrm.like(o.command,`%--thread=${t}%`))),g=e?drizzleOrm.and(p,drizzleOrm.eq(o.workspace_id,e)):p,D=_.db.select({id:o.id,input_tokens:o.input_tokens,output_tokens:o.output_tokens,cost_usd:o.cost_usd}).from(o).where(g).all();for(let v of D)n.has(v.id)||(n.add(v.id),r+=v.input_tokens??0,i+=v.output_tokens??0,l+=v.cost_usd??0);}catch(p){throw new c("DB_ERROR","Failed to get thread token usage",p)}finally{_.close();}}return {inputTokens:r,outputTokens:i,costUsd:l}}findTasksByThread(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!fs.existsSync(i))continue;let l=w(i);try{let a=drizzleOrm.or(drizzleOrm.eq(o.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(o.thread_id),drizzleOrm.like(o.command,`%--thread=${t}%`))),_=e?drizzleOrm.and(a,drizzleOrm.eq(o.workspace_id,e)):a,p=l.db.select().from(o).where(_).orderBy(drizzleOrm.asc(o.started_at)).all();for(let g of p)n.has(g.id)||(n.add(g.id),r.push(g));}catch(a){throw new c("DB_ERROR","Failed to find tasks by thread",a)}finally{l.close();}}return r}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(drizzleOrm.eq(o.workspace_id,t.workspaceId));let n=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;n&&s.push(drizzleOrm.inArray(o.agent_id,n));let r=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;r&&s.push(drizzleOrm.inArray(o.status,r));let i=t.q??t.search;i&&s.push(drizzleOrm.like(o.prompt,`%${i}%`)),t.from&&s.push(drizzleOrm.gte(o.started_at,t.from)),t.to&&s.push(drizzleOrm.lt(o.started_at,t.to));let l=s.length>0?drizzleOrm.and(...s):void 0,a=e.db.select({count:drizzleOrm.sql`count(*)`}).from(o).where(l).get(),_=(t.sortDir??"DESC")==="ASC"?drizzleOrm.asc(o.started_at):drizzleOrm.desc(o.started_at);return {rows:e.db.select().from(o).where(l).orderBy(_).limit(t.limit).offset(t.offset).all(),total:a?.count??0}}catch(s){throw new c("DB_ERROR","Failed to find all tasks",s)}finally{e.close();}}getAgentUsage(t,e,s){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(s?drizzleOrm.sql`
37
39
  SELECT
38
40
  t.agent_id,
41
+ t.workspace_id,
42
+ t.workspace_name,
39
43
  COUNT(*) AS total_tasks,
40
44
  COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
41
45
  COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
@@ -46,11 +50,13 @@ Message: ${e.message}
46
50
  AND t.started_at >= ${t}
47
51
  AND t.started_at < ${e}
48
52
  AND t.workspace_name = ${s}
49
- GROUP BY t.agent_id
53
+ GROUP BY t.agent_id, t.workspace_id, t.workspace_name
50
54
  ORDER BY (COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0)) DESC
51
55
  `:drizzleOrm.sql`
52
56
  SELECT
53
57
  t.agent_id,
58
+ t.workspace_id,
59
+ t.workspace_name,
54
60
  COUNT(*) AS total_tasks,
55
61
  COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
56
62
  COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
@@ -60,9 +66,9 @@ Message: ${e.message}
60
66
  WHERE t.status IN ('completed', 'success')
61
67
  AND t.started_at >= ${t}
62
68
  AND t.started_at < ${e}
63
- GROUP BY t.agent_id
69
+ GROUP BY t.agent_id, t.workspace_id, t.workspace_name
64
70
  ORDER BY (COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0)) DESC
65
- `).map(i=>({agentId:i.agent_id,totalTasks:i.total_tasks,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd}))}catch(r){throw new c("DB_ERROR","Failed to get agent usage",r)}finally{n.close();}}getAgentUsageTrendRaw(t,e,s){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(s?drizzleOrm.sql`
71
+ `).map(i=>({agentId:i.agent_id,workspaceId:i.workspace_id??null,workspaceName:i.workspace_name??null,totalTasks:i.total_tasks,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd}))}catch(r){throw new c("DB_ERROR","Failed to get agent usage",r)}finally{n.close();}}getAgentUsageTrendRaw(t,e,s){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(s?drizzleOrm.sql`
66
72
  SELECT
67
73
  date(t.started_at) AS date,
68
74
  t.agent_id,
@@ -91,7 +97,7 @@ Message: ${e.message}
91
97
  AND t.started_at < ${e}
92
98
  GROUP BY date(t.started_at), t.agent_id
93
99
  ORDER BY date(t.started_at) ASC
94
- `).map(i=>({date:i.date,agentId:i.agent_id,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd}))}catch(r){throw new c("DB_ERROR","Failed to get agent usage trend",r)}finally{n.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let s=this.openHandle(false);try{return s.db.select().from(o).where(drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.workspace_id,e))).limit(1).get()??void 0}catch(n){throw new c("DB_ERROR","Failed to find task for stop",n)}finally{s.close();}}markTaskFailed(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString(),i=s?drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"),drizzleOrm.eq(o.workspace_id,s)):drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"));n.db.update(o).set({status:"failed",error:e,completed_at:r}).where(i).run();}catch(r){throw r instanceof c?r:new c("DB_ERROR","Failed to mark task failed",r)}finally{n.close();}}findTasksByPromptHint(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!fs.existsSync(i))continue;let l=w(i);try{let a=e?drizzleOrm.and(drizzleOrm.like(o.prompt,`%${t}%`),drizzleOrm.eq(o.workspace_id,e)):drizzleOrm.like(o.prompt,`%${t}%`),_=l.db.select().from(o).where(a).orderBy(drizzleOrm.asc(o.started_at)).all();for(let p of _)n.has(p.id)||(n.add(p.id),r.push(p));}catch(a){throw new c("DB_ERROR","Failed to find tasks by prompt hint",a)}finally{l.close();}}return r}};var rt=class extends A{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=ut.join(t?.dbRoot??At.homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let e=new K({dbPath:this.dbPath}),s=process.cwd(),n=fs.existsSync(ut.join(s,"crewx.yaml"))||fs.existsSync(ut.join(s,"crewx.yml")),r=n?ct(s):null,i=n?ut.basename(s):null,l=process.argv.join(" ");this.unsubs.push(t.on("task:start",a=>{try{let _=process.env.CREWX_CALLER_AGENT_ID||null,p=process.env.CREWX_PARENT_TASK_ID||null,g=process.env.CREWX_TRACE_ID||a.traceId,D=a.metadata?JSON.stringify(a.metadata):JSON.stringify({provider:a.provider??"cli/claude"});e.startTask({id:a.traceId,agentId:a.agentRef.replace(/^@/,""),prompt:a.message,mode:a.mode,status:"running",pid:a.pid??null,startedAt:a.timestamp.toISOString(),crewxVersion:this.version,platform:a.platform??"cli",model:a.model??null,renderedPrompt:a.renderedPrompt??null,command:l,codingAgentCommand:a.codingAgentCommand??null,workspaceId:a.workspaceId??r,workspaceName:a.workspaceName??i,callerAgentId:_,parentTaskId:p,traceId:g,metadata:D,threadId:a.threadId??null});}catch{}}),t.on("task:output",a=>{try{e.appendLog(a.traceId,{timestamp:a.timestamp.toISOString(),level:a.level??"stdout",message:a.output});}catch{}}),t.on("task:end",a=>{try{e.finishTask({id:a.traceId,status:a.error?"failed":"success",result:a.result??null,error:a.error?JSON.stringify(a.error):null,completedAt:a.timestamp.toISOString(),durationMs:a.durationMs,exitCode:a.exitCode??null,inputTokens:a.inputTokens??0,outputTokens:a.outputTokens??0,cachedInputTokens:a.cachedInputTokens??0,costUsd:a.costUsd??0,model:a.model??null});}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[];}};var J=class extends F{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=ut.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=ut.dirname(e);fs.existsSync(n)||fs.mkdirSync(n,{recursive:true});}else if(!fs.existsSync(e))throw new c("NOT_FOUND","Database not found");let s=w(e);if(t)try{z(s.db,e);}catch(n){throw s.close(),n}return s}validateWorkspaceId(t,e){return t.db.select({id:$.id}).from($).where(drizzleOrm.eq($.id,e)).limit(1).get()?e:null}findAllThreads(t){let e=this.resolveDbPaths(),s=new Set,n=[];for(let r of e){if(!fs.existsSync(r))continue;let i=w(r);try{let l=t?drizzleOrm.or(drizzleOrm.eq(u.workspace_id,t),drizzleOrm.isNull(u.workspace_id)):void 0,a=i.db.select().from(u).where(l).orderBy(drizzleOrm.desc(u.updated_at)).all();for(let _ of a)s.has(_.id)||(s.add(_.id),n.push(_));}catch(l){throw new c("DB_ERROR","Failed to find all threads",l)}finally{i.close();}}return n}findThreadById(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=w(n);try{let i=drizzleOrm.eq(u.id,t),l=e?drizzleOrm.and(i,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):i,a=r.db.select().from(u).where(l).limit(1).get()??void 0;if(a)return a}catch(i){throw new c("DB_ERROR","Failed to find thread by id",i)}finally{r.close();}}}threadExists(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=w(n);try{let i=drizzleOrm.eq(u.id,t),l=e?drizzleOrm.and(i,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):i;if(r.db.select({id:u.id}).from(u).where(l).limit(1).get())return !0}catch(i){throw new c("DB_ERROR","Failed to check thread existence",i)}finally{r.close();}}return false}aggregateTaskStats(t,e){let s=this.resolveDbPaths(),n=0,r=0,i=0,l=0,a=0,_=new Set;for(let p of s){if(!fs.existsSync(p))continue;let g=w(p);try{let D=drizzleOrm.and(drizzleOrm.eq(o.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(o.parent_task_id),drizzleOrm.eq(o.parent_task_id,""))),v=e?drizzleOrm.and(D,drizzleOrm.eq(o.workspace_id,e)):D,B=g.db.select({cnt:drizzleOrm.sql`count(*)`,total_input:drizzleOrm.sql`COALESCE(SUM(input_tokens), 0)`,total_output:drizzleOrm.sql`COALESCE(SUM(output_tokens), 0)`,total_cached:drizzleOrm.sql`COALESCE(SUM(cached_input_tokens), 0)`,total_cost:drizzleOrm.sql`COALESCE(SUM(cost_usd), 0)`}).from(o).where(v).get();B&&(n+=B.cnt,r+=B.total_input,i+=B.total_output,l+=B.total_cached,a+=B.total_cost);let bt=g.db.all(drizzleOrm.sql`
100
+ `).map(i=>({date:i.date,agentId:i.agent_id,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd}))}catch(r){throw new c("DB_ERROR","Failed to get agent usage trend",r)}finally{n.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let s=this.openHandle(false);try{return s.db.select().from(o).where(drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.workspace_id,e))).limit(1).get()??void 0}catch(n){throw new c("DB_ERROR","Failed to find task for stop",n)}finally{s.close();}}markTaskFailed(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString(),i=s?drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"),drizzleOrm.eq(o.workspace_id,s)):drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"));n.db.update(o).set({status:"failed",error:e,completed_at:r}).where(i).run();}catch(r){throw r instanceof c?r:new c("DB_ERROR","Failed to mark task failed",r)}finally{n.close();}}findTasksByPromptHint(t,e){let s=this.resolveDbPaths(),n=new Set,r=[];for(let i of s){if(!fs.existsSync(i))continue;let l=w(i);try{let a=e?drizzleOrm.and(drizzleOrm.like(o.prompt,`%${t}%`),drizzleOrm.eq(o.workspace_id,e)):drizzleOrm.like(o.prompt,`%${t}%`),_=l.db.select().from(o).where(a).orderBy(drizzleOrm.asc(o.started_at)).all();for(let p of _)n.has(p.id)||(n.add(p.id),r.push(p));}catch(a){throw new c("DB_ERROR","Failed to find tasks by prompt hint",a)}finally{l.close();}}return r}};var ot=class extends A{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=tt.join(t?.dbRoot??At.homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let e=new K({dbPath:this.dbPath}),s=process.cwd(),n=fs.existsSync(tt.join(s,"crewx.yaml"))||fs.existsSync(tt.join(s,"crewx.yml")),r=n?ut(s):null,i=n?tt.basename(s):null,l=process.argv.join(" ");this.unsubs.push(t.on("task:start",a=>{try{let _=process.env.CREWX_CALLER_AGENT_ID||null,p=process.env.CREWX_PARENT_TASK_ID||null,g=process.env.CREWX_TRACE_ID||a.traceId,D=a.metadata?JSON.stringify(a.metadata):JSON.stringify({provider:a.provider??"cli/claude"});e.startTask({id:a.traceId,agentId:a.agentRef.replace(/^@/,""),prompt:a.message,mode:a.mode,status:"running",pid:a.pid??null,startedAt:a.timestamp.toISOString(),crewxVersion:this.version,platform:a.platform??"cli",model:a.model??null,renderedPrompt:a.renderedPrompt??null,command:l,codingAgentCommand:a.codingAgentCommand??null,workspaceId:a.workspaceId??r,workspaceName:a.workspaceName??i,callerAgentId:_,parentTaskId:p,traceId:g,metadata:D,threadId:a.threadId??null});}catch{}}),t.on("task:output",a=>{try{e.appendLog(a.traceId,{timestamp:a.timestamp.toISOString(),level:a.level??"stdout",message:a.output});}catch{}}),t.on("task:end",a=>{try{e.finishTask({id:a.traceId,status:a.error?"failed":"success",result:a.result??null,error:a.error?JSON.stringify(a.error):null,completedAt:a.timestamp.toISOString(),durationMs:a.durationMs,exitCode:a.exitCode??null,inputTokens:a.inputTokens??0,outputTokens:a.outputTokens??0,cachedInputTokens:a.cachedInputTokens??0,costUsd:a.costUsd??0,model:a.model??null});}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[];}};var J=class extends ${dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=tt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=tt.dirname(e);fs.existsSync(n)||fs.mkdirSync(n,{recursive:true});}else if(!fs.existsSync(e))throw new c("NOT_FOUND","Database not found");let s=w(e);if(t)try{z(s.db,e);}catch(n){throw s.close(),n}return s}validateWorkspaceId(t,e){return t.db.select({id:F.id}).from(F).where(drizzleOrm.eq(F.id,e)).limit(1).get()?e:null}findAllThreads(t){let e=this.resolveDbPaths(),s=new Set,n=[];for(let r of e){if(!fs.existsSync(r))continue;let i=w(r);try{let l=t?drizzleOrm.or(drizzleOrm.eq(u.workspace_id,t),drizzleOrm.isNull(u.workspace_id)):void 0,a=i.db.select().from(u).where(l).orderBy(drizzleOrm.desc(u.updated_at)).all();for(let _ of a)s.has(_.id)||(s.add(_.id),n.push(_));}catch(l){throw new c("DB_ERROR","Failed to find all threads",l)}finally{i.close();}}return n}findThreadById(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=w(n);try{let i=drizzleOrm.eq(u.id,t),l=e?drizzleOrm.and(i,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):i,a=r.db.select().from(u).where(l).limit(1).get()??void 0;if(a)return a}catch(i){throw new c("DB_ERROR","Failed to find thread by id",i)}finally{r.close();}}}threadExists(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=w(n);try{let i=drizzleOrm.eq(u.id,t),l=e?drizzleOrm.and(i,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):i;if(r.db.select({id:u.id}).from(u).where(l).limit(1).get())return !0}catch(i){throw new c("DB_ERROR","Failed to check thread existence",i)}finally{r.close();}}return false}aggregateTaskStats(t,e){let s=this.resolveDbPaths(),n=0,r=0,i=0,l=0,a=0,_=new Set;for(let p of s){if(!fs.existsSync(p))continue;let g=w(p);try{let D=drizzleOrm.and(drizzleOrm.eq(o.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(o.parent_task_id),drizzleOrm.eq(o.parent_task_id,""))),v=e?drizzleOrm.and(D,drizzleOrm.eq(o.workspace_id,e)):D,B=g.db.select({cnt:drizzleOrm.sql`count(*)`,total_input:drizzleOrm.sql`COALESCE(SUM(input_tokens), 0)`,total_output:drizzleOrm.sql`COALESCE(SUM(output_tokens), 0)`,total_cached:drizzleOrm.sql`COALESCE(SUM(cached_input_tokens), 0)`,total_cost:drizzleOrm.sql`COALESCE(SUM(cost_usd), 0)`}).from(o).where(v).get();B&&(n+=B.cnt,r+=B.total_input,i+=B.total_output,l+=B.total_cached,a+=B.total_cost);let bt=g.db.all(drizzleOrm.sql`
95
101
  SELECT DISTINCT agent_id FROM tasks
96
102
  WHERE thread_id = ${t}
97
103
  AND agent_id IS NOT NULL AND agent_id != ''
@@ -108,4 +114,4 @@ Message: ${e.message}
108
114
  `);}catch(r){throw r instanceof c?r:new c("DB_ERROR","Failed to save user message",r)}finally{n.close();}}saveAssistantMessage(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString();n.db.update(u).set({last_message:e,updated_at:r}).where(drizzleOrm.eq(u.id,t)).run();}catch(r){throw r instanceof c?r:new c("DB_ERROR","Failed to save assistant message",r)}finally{n.close();}}updateThread(t,e){if(!this.dbExists())return;let s=this.openHandle(true);try{let n={updated_at:new Date().toISOString()};e.title!==void 0&&(n.title=e.title,n.title_locked=1),e.titleLocked!==void 0&&(n.title_locked=e.titleLocked?1:0),s.db.update(u).set(n).where(drizzleOrm.eq(u.id,t)).run();}catch(n){throw n instanceof c?n:new c("DB_ERROR","Failed to update thread",n)}finally{s.close();}}};function ie(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
109
115
  `).filter(n=>!(n.startsWith("Loaded ")&&n.includes("layouts from")||n.includes("[dotenv@")||n.includes("[Nest]")&&n.includes("DEBUG")||n.startsWith("Registered custom layout:")||n.startsWith("Updated custom layout:"))).join(`
110
116
  `).trim()}function ae(d){if(!d)return "";let t=d;try{let e=JSON.parse(t);Array.isArray(e)?t=e.filter(s=>s?.type==="text"&&s?.text).map(s=>s.text).join(`
111
- `):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=ie(t);}return t}var V=class{dbPath;constructor(t){this.dbPath=t??ut.join(At.homedir(),".crewx","crewx.db");}getThreadRepo(){return new J({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,s){let n=this.getThreadRepo(),r=n.findThreadById(t);if(r){if(r.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${r.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return}n.ensureThread(t,e,s);}async fetchHistory(t,e){let s=e?.limit??100,n=this.getThreadRepo(),r=n.findThreadById(t),i=n.findTopLevelTasks(t),l=new Set(["done","completed","success"]);i=i.filter(p=>(!p.status||l.has(p.status))&&(!e?.currentTraceId||p.trace_id!==e.currentTraceId)),i=i.slice(0,s);let a=r?.platform??"cli",_=this.rowsToMessages(i);return {threadId:t,platform:a,messages:_,metadata:{title:r?.title??void 0,firstMessage:r?.first_message??void 0,lastMessage:r?.last_message??void 0,messageCount:r?.message_count??0,updatedAt:r?.updated_at?new Date(r.updated_at).getTime():void 0}}}async saveUserMessage(t,e,s,n){this.getThreadRepo().saveUserMessage(t,e);}async saveAssistantMessage(t,e,s,n){this.getThreadRepo().saveAssistantMessage(t,e);}close(){}rowsToMessages(t){let e=[];for(let s of t){s.prompt&&e.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime()});let n=ae(s.result);n&&e.push({id:`${s.id}-assistant`,text:n,isAssistant:true,timestamp:new Date(s.started_at).getTime()});}return e}};var ot=class extends A{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new V(t?.dbPath);}get conversationProvider(){return this._provider}attach(t){this.unsubStart=t.on("task:start",async e=>{if(!e.threadId)return;let s=e.platform??"cli";try{await this._provider.ensureThread(e.threadId,s,e.workspaceId),await this._provider.saveUserMessage(e.threadId,e.message??"");}catch{}}),this.unsubEnd=t.on("task:end",async e=>{if(!e.result)return;let s=e.metadata?.threadId;if(!s)return;let n=e.agentRef?.replace(/^@/,"")??"";try{await this._provider.saveAssistantMessage(s,e.result,n);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};exports.ConversationPlugin=ot;exports.FileLoggerPlugin=Z;exports.SqliteTracingPlugin=rt;
117
+ `):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=ie(t);}return t}var V=class{dbPath;constructor(t){this.dbPath=t??tt.join(At.homedir(),".crewx","crewx.db");}getThreadRepo(){return new J({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,s){let n=this.getThreadRepo(),r=n.findThreadById(t);if(r){if(r.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${r.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return}n.ensureThread(t,e,s);}async fetchHistory(t,e){let s=e?.limit??100,n=this.getThreadRepo(),r=n.findThreadById(t),i=n.findTopLevelTasks(t),l=new Set(["done","completed","success"]);i=i.filter(p=>(!p.status||l.has(p.status))&&(!e?.currentTraceId||p.trace_id!==e.currentTraceId)),i=i.slice(0,s);let a=r?.platform??"cli",_=this.rowsToMessages(i);return {threadId:t,platform:a,messages:_,metadata:{title:r?.title??void 0,firstMessage:r?.first_message??void 0,lastMessage:r?.last_message??void 0,messageCount:r?.message_count??0,updatedAt:r?.updated_at?new Date(r.updated_at).getTime():void 0}}}async saveUserMessage(t,e,s,n){this.getThreadRepo().saveUserMessage(t,e);}async saveAssistantMessage(t,e,s,n){this.getThreadRepo().saveAssistantMessage(t,e);}close(){}rowsToMessages(t){let e=[];for(let s of t){s.prompt&&e.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime()});let n=ae(s.result);n&&e.push({id:`${s.id}-assistant`,text:n,isAssistant:true,timestamp:new Date(s.started_at).getTime()});}return e}};var it=class extends A{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new V(t?.dbPath);}get conversationProvider(){return this._provider}attach(t){this.unsubStart=t.on("task:start",async e=>{if(!e.threadId)return;let s=e.platform??"cli";try{await this._provider.ensureThread(e.threadId,s,e.workspaceId),await this._provider.saveUserMessage(e.threadId,e.message??"");}catch{}}),this.unsubEnd=t.on("task:end",async e=>{if(!e.result)return;let s=e.metadata?.threadId;if(!s)return;let n=e.agentRef?.replace(/^@/,"")??"";try{await this._provider.saveAssistantMessage(s,e.result,n);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};exports.ConversationPlugin=it;exports.FileLoggerPlugin=Z;exports.SqliteTracingPlugin=ot;
@@ -1,4 +1,5 @@
1
1
  import type { ProviderQueryOptions, ProviderUsage } from './bridge.js';
2
+ import type { TaskLogEntry } from '../types/task-log.types.js';
2
3
  export interface CliProviderAdapter {
3
4
  readonly command: string;
4
5
  buildArgs(message: string, options: ProviderQueryOptions, isExecute: boolean): {
@@ -12,6 +13,7 @@ export interface CliProviderAdapter {
12
13
  usage?: ProviderUsage | null;
13
14
  model?: string | null;
14
15
  };
16
+ parseEvent?(line: string, timestamp?: string): TaskLogEntry[];
15
17
  }
16
18
  export declare class RateLimitError extends Error {
17
19
  readonly name = "RateLimitError";
@@ -1,3 +1,3 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
1
+ import type { TaskLogEntry } from '../../types/task-log.types';
2
2
  export declare function isAgentCallCommand(command: string): boolean;
3
3
  export declare function parseAgentCall(timestamp: string, command: string): TaskLogEntry;
@@ -1,7 +1,10 @@
1
1
  import type { CliProviderAdapter } from '../adapter.types.js';
2
+ import type { TaskLogEntry } from '../../types/task-log.types.js';
2
3
  export { claudeAdapter } from './claude.js';
3
4
  export { geminiAdapter } from './gemini.js';
4
5
  export { copilotAdapter } from './copilot.js';
5
6
  export { codexAdapter } from './codex.js';
6
7
  export { opencodeAdapter } from './opencode.js';
8
+ export { isAgentCallCommand, parseAgentCall } from './agent-call.util.js';
7
9
  export declare const BUILTIN_ADAPTERS: Record<string, CliProviderAdapter>;
10
+ export declare function parseStdoutEvent(timestamp: string, message: string, providerId?: string): TaskLogEntry[];
@@ -1,9 +1,11 @@
1
- 'use strict';var fs=require('fs'),gt=require('path'),Ft=require('os'),drizzleOrm=require('drizzle-orm'),sqliteCore=require('drizzle-orm/sqlite-core'),crypto=require('crypto');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 gt__namespace=/*#__PURE__*/_interopNamespace(gt);var Ft__default=/*#__PURE__*/_interopDefault(Ft);var ot=(l=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(l,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):l)(function(l){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+l+'" is not supported')});var R=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:gt.join(Ft__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 fs.existsSync(t??this.resolveDbPath())}};var i=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 m(l){let t=ot("better-sqlite3"),{drizzle:e}=ot("drizzle-orm/better-sqlite3"),n=new t(l);return n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),{db:e(n),runRaw:(s,o=[])=>n.prepare(s).run(...o),close:()=>n.close()}}var kt=new Set;function Q(l){let{migrate:t}=ot("drizzle-orm/better-sqlite3/migrator"),e=gt__namespace.default.join(__dirname,"../migrations"),n=fs.existsSync(e)?e:gt__namespace.default.join(__dirname,"../../../../drizzle/migrations");t(l,{migrationsFolder:n});}function x(l,t){kt.has(t)||(Q(l),kt.add(t));}var p=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 r=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"),workspace_name:sqliteCore.text("workspace_name"),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_name:sqliteCore.text("project_name"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0)},l=>({idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(l.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(l.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(l.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(l.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(l.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(l.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(l.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(l.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(l.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(l.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(l.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(l.workspace_id,l.started_at)}));var u=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>p.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)},l=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(l.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(l.workspace_id)}));var z=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>r.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>z.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")},l=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(l.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(l.parent_span_id)}));var B=sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>r.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()},l=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(l.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(l.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(l.timestamp)}));var C=sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>u.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()},l=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(l.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(l.thread_id,l.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(l.thread_id,l.seq)}));var J=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")},l=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(l.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(l.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(l.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(l.partition_key)}));function it(l){let t=gt__namespace.resolve(l);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 St(l){let t=it(l);return crypto.createHash("sha256").update(t).digest("hex")}var lt=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{Q(n.db);}catch(s){throw n.close(),s}return n}resolveSlug(t,e,n){let s=gt.basename(n),o=`${gt.basename(gt.dirname(n))}/${s}`,a=[s,o];try{let d=c=>t.select({id:p.id}).from(p).where(drizzleOrm.and(drizzleOrm.eq(p.slug,c),drizzleOrm.ne(p.id,e))).limit(1).all().length>0;for(let c of a)if(!d(c))return c;for(let c=2;c<1e3;c+=1){let _=`${o}-${c}`;if(!d(_))return _}}catch{}return s}ensureRow(t,e){let{id:n,slug:s,name:o,workspacePath:a}=e,d=new Date().toISOString();t.insert(p).values({id:n,slug:s,name:o,workspace_path:a,is_active:1,created_at:d,updated_at:d}).onConflictDoNothing().run(),t.update(p).set({workspace_path:a,updated_at:d}).where(drizzleOrm.and(drizzleOrm.eq(p.id,n),drizzleOrm.isNull(p.workspace_path))).run();}registerWorkspace(t){let e=it(t),n=this.openHandle(true);try{let s=St(e),o=gt.basename(e),a=this.resolveSlug(n.db,s,e);return this.ensureRow(n.db,{id:s,slug:a,name:o,workspacePath:e}),{id:s,slug:a}}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to register workspace",s)}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(p.is_active,t.isActive?1:0):void 0,s=e.db.select({count:drizzleOrm.sql`count(*)`}).from(p).where(n).get();return {rows:e.db.select().from(p).where(n).orderBy(drizzleOrm.desc(p.updated_at)).limit(t.limit).offset(t.offset).all(),total:s?.count??0}}catch(n){throw new i("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(p).where(drizzleOrm.eq(p.id,t)).limit(1).get()??void 0}catch(n){throw new i("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(s=>s.agent_id)}catch(n){throw new i("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 s=n.db.get(drizzleOrm.sql`SELECT COUNT(*) as count FROM threads WHERE workspace_id = ${t}`);return {rows:n.db.all(drizzleOrm.sql`SELECT t.*,
1
+ 'use strict';var fs=require('fs'),rt=require('path'),Ft=require('os'),drizzleOrm=require('drizzle-orm'),sqliteCore=require('drizzle-orm/sqlite-core'),crypto=require('crypto');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 rt__namespace=/*#__PURE__*/_interopNamespace(rt);var Ft__default=/*#__PURE__*/_interopDefault(Ft);var ot=(l=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(l,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):l)(function(l){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+l+'" is not supported')});var R=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:rt.join(Ft__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 fs.existsSync(t??this.resolveDbPath())}};var i=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 m(l){let t=ot("better-sqlite3"),{drizzle:e}=ot("drizzle-orm/better-sqlite3"),n=new t(l);return n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),{db:e(n),runRaw:(s,o=[])=>n.prepare(s).run(...o),close:()=>n.close()}}var gt=new Set;function Q(l){let{migrate:t}=ot("drizzle-orm/better-sqlite3/migrator"),e=[rt__namespace.default.join(__dirname,"../migrations"),rt__namespace.default.join(__dirname,"migrations")],n=e.find(s=>fs.existsSync(rt__namespace.default.join(s,"meta/_journal.json")));if(!n)throw new Error(`migrations folder not found. Searched:
2
+ ${e.join(`
3
+ `)}`);t(l,{migrationsFolder:n});}function x(l,t){gt.has(t)||(Q(l),gt.add(t));}var p=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 r=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"),workspace_name:sqliteCore.text("workspace_name"),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_name:sqliteCore.text("project_name"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0)},l=>({idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(l.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(l.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(l.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(l.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(l.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(l.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(l.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(l.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(l.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(l.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(l.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(l.workspace_id,l.started_at)}));var u=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>p.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)},l=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(l.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(l.workspace_id)}));var z=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>r.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>z.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")},l=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(l.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(l.parent_span_id)}));var B=sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>r.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()},l=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(l.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(l.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(l.timestamp)}));var C=sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>u.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()},l=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(l.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(l.thread_id,l.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(l.thread_id,l.seq)}));var J=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")},l=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(l.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(l.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(l.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(l.partition_key)}));function at(l){let t=rt__namespace.resolve(l);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 Dt(l){let t=at(l);return crypto.createHash("sha256").update(t).digest("hex")}var ct=class extends R{dbRoot;constructor(t={}){super(),this.dbRoot=t.dbRoot;}resolveDbPath(){return this.dbRoot?rt.join(this.dbRoot,".crewx","crewx.db"):super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{Q(n.db);}catch(s){throw n.close(),s}return n}resolveSlug(t,e,n){let s=rt.basename(n),o=`${rt.basename(rt.dirname(n))}/${s}`,a=[s,o];try{let d=c=>t.select({id:p.id}).from(p).where(drizzleOrm.and(drizzleOrm.eq(p.slug,c),drizzleOrm.ne(p.id,e))).limit(1).all().length>0;for(let c of a)if(!d(c))return c;for(let c=2;c<1e3;c+=1){let _=`${o}-${c}`;if(!d(_))return _}}catch{}return s}ensureRow(t,e){let{id:n,slug:s,name:o,workspacePath:a}=e,d=new Date().toISOString();t.insert(p).values({id:n,slug:s,name:o,workspace_path:a,is_active:1,created_at:d,updated_at:d}).onConflictDoNothing().run(),t.update(p).set({workspace_path:a,updated_at:d}).where(drizzleOrm.and(drizzleOrm.eq(p.id,n),drizzleOrm.isNull(p.workspace_path))).run();}registerWorkspace(t){let e=at(t),n=this.openHandle(true);try{let s=Dt(e),o=rt.basename(e),a=this.resolveSlug(n.db,s,e);return this.ensureRow(n.db,{id:s,slug:a,name:o,workspacePath:e}),{id:s,slug:a}}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to register workspace",s)}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(p.is_active,t.isActive?1:0):void 0,s=e.db.select({count:drizzleOrm.sql`count(*)`}).from(p).where(n).get();return {rows:e.db.select().from(p).where(n).orderBy(drizzleOrm.desc(p.updated_at)).limit(t.limit).offset(t.offset).all(),total:s?.count??0}}catch(n){throw new i("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(p).where(drizzleOrm.eq(p.id,t)).limit(1).get()??void 0}catch(n){throw new i("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(s=>s.agent_id)}catch(n){throw new i("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 s=n.db.get(drizzleOrm.sql`SELECT COUNT(*) as count FROM threads WHERE workspace_id = ${t}`);return {rows:n.db.all(drizzleOrm.sql`SELECT t.*,
2
4
  (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
3
5
  FROM threads t
4
6
  WHERE t.workspace_id = ${t}
5
7
  ORDER BY t.updated_at DESC
6
- LIMIT ${e.limit} OFFSET ${e.offset}`),total:s?.count??0}}catch(s){throw new i("DB_ERROR","Failed to find threads by project",s)}finally{n.close();}}findBySlug(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(p).where(drizzleOrm.eq(p.slug,t)).limit(1).get()??void 0}catch(n){throw new i("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 s=e?drizzleOrm.and(drizzleOrm.eq(p.slug,t),drizzleOrm.ne(p.id,e)):drizzleOrm.eq(p.slug,t);return !!n.db.select({id:p.id}).from(p).where(s).limit(1).get()}catch(s){throw new i("DB_ERROR","Failed to check slug",s)}finally{n.close();}}insert(t,e,n,s){let o=this.openHandle(true);try{let a=new Date().toISOString();o.db.insert(p).values({id:t,slug:e,name:n,workspace_path:s,is_active:1,created_at:a,updated_at:a}).run();let d=o.db.select().from(p).where(drizzleOrm.eq(p.id,t)).limit(1).get();if(!d)throw new i("DB_ERROR","Insert did not return a row");return d}catch(a){throw a instanceof i?a:new i("DB_ERROR","Failed to insert workspace",a)}finally{o.close();}}update(t,e,n){let s=this.openHandle(true);try{s.runRaw(`UPDATE workspaces SET ${e.join(", ")} WHERE id = ?`,n);let o=s.db.select().from(p).where(drizzleOrm.eq(p.id,t)).limit(1).get();if(!o)throw new i("NOT_FOUND",`Workspace ${t} not found`);return o}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to update workspace",o)}finally{s.close();}}cleanupOrphanWorkspaces(){if(!this.dbExists())return {softDeleted:0,checked:0};let t=this.openHandle(true);try{let e=t.db.select({id:p.id,workspace_path:p.workspace_path}).from(p).where(drizzleOrm.and(drizzleOrm.eq(p.is_active,1),drizzleOrm.isNotNull(p.workspace_path))).all(),n=0;for(let s of e){let o=s.workspace_path;fs.existsSync(gt.join(o,"crewx.yaml"))||fs.existsSync(gt.join(o,"crewx.yml"))||(t.db.update(p).set({is_active:0,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(p.id,s.id)).run(),n+=1);}return {softDeleted:n,checked:e.length}}catch(e){throw new i("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(p).where(drizzleOrm.eq(p.id,t)).run();}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to delete workspace",n)}finally{e.close();}}};var pt=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}startTask(t){let e=this.openHandle(true);try{e.db.insert(r).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,workspace_name:t.workspaceName??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}).onConflictDoNothing().run();}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to start task",n)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
8
+ LIMIT ${e.limit} OFFSET ${e.offset}`),total:s?.count??0}}catch(s){throw new i("DB_ERROR","Failed to find threads by project",s)}finally{n.close();}}findBySlug(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(p).where(drizzleOrm.eq(p.slug,t)).limit(1).get()??void 0}catch(n){throw new i("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 s=e?drizzleOrm.and(drizzleOrm.eq(p.slug,t),drizzleOrm.ne(p.id,e)):drizzleOrm.eq(p.slug,t);return !!n.db.select({id:p.id}).from(p).where(s).limit(1).get()}catch(s){throw new i("DB_ERROR","Failed to check slug",s)}finally{n.close();}}insert(t,e,n,s){let o=this.openHandle(true);try{let a=new Date().toISOString();o.db.insert(p).values({id:t,slug:e,name:n,workspace_path:s,is_active:1,created_at:a,updated_at:a}).run();let d=o.db.select().from(p).where(drizzleOrm.eq(p.id,t)).limit(1).get();if(!d)throw new i("DB_ERROR","Insert did not return a row");return d}catch(a){throw a instanceof i?a:new i("DB_ERROR","Failed to insert workspace",a)}finally{o.close();}}update(t,e,n){let s=this.openHandle(true);try{s.runRaw(`UPDATE workspaces SET ${e.join(", ")} WHERE id = ?`,n);let o=s.db.select().from(p).where(drizzleOrm.eq(p.id,t)).limit(1).get();if(!o)throw new i("NOT_FOUND",`Workspace ${t} not found`);return o}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to update workspace",o)}finally{s.close();}}cleanupOrphanWorkspaces(){if(!this.dbExists())return {softDeleted:0,checked:0};let t=this.openHandle(true);try{let e=t.db.select({id:p.id,workspace_path:p.workspace_path}).from(p).where(drizzleOrm.and(drizzleOrm.eq(p.is_active,1),drizzleOrm.isNotNull(p.workspace_path))).all(),n=0;for(let s of e){let o=s.workspace_path;fs.existsSync(rt.join(o,"crewx.yaml"))||fs.existsSync(rt.join(o,"crewx.yml"))||(t.db.update(p).set({is_active:0,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(p.id,s.id)).run(),n+=1);}return {softDeleted:n,checked:e.length}}catch(e){throw new i("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(p).where(drizzleOrm.eq(p.id,t)).run();}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to delete workspace",n)}finally{e.close();}}};var _t=class extends R{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}startTask(t){let e=this.openHandle(true);try{e.db.insert(r).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,workspace_name:t.workspaceName??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}).onConflictDoNothing().run();}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to start task",n)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
7
9
  exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
8
10
  model=COALESCE(?, model) WHERE id=?`,[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]);}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to finish task",n)}finally{e.close();}}appendLog(t,e){let n=this.openHandle(true);try{n.db.transaction(s=>{let o=s.select({logs:r.logs}).from(r).where(drizzleOrm.eq(r.id,t)).limit(1).get(),a=o?.logs?JSON.parse(o.logs):[];a.push(e),s.update(r).set({logs:JSON.stringify(a)}).where(drizzleOrm.eq(r.id,t)).run();},{behavior:"immediate"});}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to append log",s)}finally{n.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(r).where(drizzleOrm.eq(r.status,"running")).orderBy(drizzleOrm.desc(r.started_at)).all()}catch(e){throw new i("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(r).orderBy(drizzleOrm.desc(r.started_at)).limit(100).all()}catch(e){throw new i("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(r).where(drizzleOrm.eq(r.id,t)).limit(1).get()??void 0}catch(n){throw new i("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:r.id,status:r.status,pid:r.pid}).from(r).where(drizzleOrm.eq(r.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(r).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.status,"running"))).run(),{killed:!0,pid:n.pid??void 0}}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to kill task",n)}finally{e.close();}}findTaskStatus(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=m(s);try{let a=e?drizzleOrm.eq(r.workspace_id,e):void 0,d=a?drizzleOrm.and(drizzleOrm.eq(r.id,t),a):drizzleOrm.eq(r.id,t),c=o.db.select().from(r).where(d).limit(1).get()??void 0;if(!c){let _=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),h=a?drizzleOrm.and(_,a):_;c=o.db.select().from(r).where(h).orderBy(drizzleOrm.desc(r.started_at)).limit(1).get()??void 0;}if(c)return c}catch(a){throw new i("DB_ERROR","Failed to find task status",a)}finally{o.close();}}}findChildTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=e?drizzleOrm.and(drizzleOrm.eq(r.parent_task_id,t),drizzleOrm.eq(r.workspace_id,e)):drizzleOrm.eq(r.parent_task_id,t),_=d.db.select().from(r).where(c).orderBy(drizzleOrm.asc(r.started_at)).all();for(let h of _)s.has(h.id)||(s.add(h.id),o.push(h));}catch(c){throw new i("DB_ERROR","Failed to find child tasks",c)}finally{d.close();}}return o}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.all(t?drizzleOrm.sql`
9
11
  SELECT
@@ -28,9 +30,11 @@
28
30
  FROM tasks
29
31
  GROUP BY workspace_id, workspace_name
30
32
  ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
31
- `)}catch(n){throw new i("DB_ERROR","Failed to get workspace usage summary",n)}finally{e.close();}}getThreadTokenUsage(t,e){let n=this.resolveDbPaths(),s=new Set,o=0,a=0,d=0;for(let c of n){if(!fs.existsSync(c))continue;let _=m(c);try{let h=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),k=e?drizzleOrm.and(h,drizzleOrm.eq(r.workspace_id,e)):h,$=_.db.select({id:r.id,input_tokens:r.input_tokens,output_tokens:r.output_tokens,cost_usd:r.cost_usd}).from(r).where(k).all();for(let L of $)s.has(L.id)||(s.add(L.id),o+=L.input_tokens??0,a+=L.output_tokens??0,d+=L.cost_usd??0);}catch(h){throw new i("DB_ERROR","Failed to get thread token usage",h)}finally{_.close();}}return {inputTokens:o,outputTokens:a,costUsd:d}}findTasksByThread(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),_=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,h=d.db.select().from(r).where(_).orderBy(drizzleOrm.asc(r.started_at)).all();for(let k of h)s.has(k.id)||(s.add(k.id),o.push(k));}catch(c){throw new i("DB_ERROR","Failed to find tasks by thread",c)}finally{d.close();}}return o}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let n=[];t.workspaceId&&n.push(drizzleOrm.eq(r.workspace_id,t.workspaceId));let s=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;s&&n.push(drizzleOrm.inArray(r.agent_id,s));let o=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;o&&n.push(drizzleOrm.inArray(r.status,o));let a=t.q??t.search;a&&n.push(drizzleOrm.like(r.prompt,`%${a}%`)),t.from&&n.push(drizzleOrm.gte(r.started_at,t.from)),t.to&&n.push(drizzleOrm.lt(r.started_at,t.to));let d=n.length>0?drizzleOrm.and(...n):void 0,c=e.db.select({count:drizzleOrm.sql`count(*)`}).from(r).where(d).get(),_=(t.sortDir??"DESC")==="ASC"?drizzleOrm.asc(r.started_at):drizzleOrm.desc(r.started_at);return {rows:e.db.select().from(r).where(d).orderBy(_).limit(t.limit).offset(t.offset).all(),total:c?.count??0}}catch(n){throw new i("DB_ERROR","Failed to find all tasks",n)}finally{e.close();}}getAgentUsage(t,e,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(n?drizzleOrm.sql`
33
+ `)}catch(n){throw new i("DB_ERROR","Failed to get workspace usage summary",n)}finally{e.close();}}getThreadTokenUsage(t,e){let n=this.resolveDbPaths(),s=new Set,o=0,a=0,d=0;for(let c of n){if(!fs.existsSync(c))continue;let _=m(c);try{let h=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),g=e?drizzleOrm.and(h,drizzleOrm.eq(r.workspace_id,e)):h,$=_.db.select({id:r.id,input_tokens:r.input_tokens,output_tokens:r.output_tokens,cost_usd:r.cost_usd}).from(r).where(g).all();for(let L of $)s.has(L.id)||(s.add(L.id),o+=L.input_tokens??0,a+=L.output_tokens??0,d+=L.cost_usd??0);}catch(h){throw new i("DB_ERROR","Failed to get thread token usage",h)}finally{_.close();}}return {inputTokens:o,outputTokens:a,costUsd:d}}findTasksByThread(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),_=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,h=d.db.select().from(r).where(_).orderBy(drizzleOrm.asc(r.started_at)).all();for(let g of h)s.has(g.id)||(s.add(g.id),o.push(g));}catch(c){throw new i("DB_ERROR","Failed to find tasks by thread",c)}finally{d.close();}}return o}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let n=[];t.workspaceId&&n.push(drizzleOrm.eq(r.workspace_id,t.workspaceId));let s=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;s&&n.push(drizzleOrm.inArray(r.agent_id,s));let o=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;o&&n.push(drizzleOrm.inArray(r.status,o));let a=t.q??t.search;a&&n.push(drizzleOrm.like(r.prompt,`%${a}%`)),t.from&&n.push(drizzleOrm.gte(r.started_at,t.from)),t.to&&n.push(drizzleOrm.lt(r.started_at,t.to));let d=n.length>0?drizzleOrm.and(...n):void 0,c=e.db.select({count:drizzleOrm.sql`count(*)`}).from(r).where(d).get(),_=(t.sortDir??"DESC")==="ASC"?drizzleOrm.asc(r.started_at):drizzleOrm.desc(r.started_at);return {rows:e.db.select().from(r).where(d).orderBy(_).limit(t.limit).offset(t.offset).all(),total:c?.count??0}}catch(n){throw new i("DB_ERROR","Failed to find all tasks",n)}finally{e.close();}}getAgentUsage(t,e,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(n?drizzleOrm.sql`
32
34
  SELECT
33
35
  t.agent_id,
36
+ t.workspace_id,
37
+ t.workspace_name,
34
38
  COUNT(*) AS total_tasks,
35
39
  COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
36
40
  COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
@@ -41,11 +45,13 @@
41
45
  AND t.started_at >= ${t}
42
46
  AND t.started_at < ${e}
43
47
  AND t.workspace_name = ${n}
44
- GROUP BY t.agent_id
48
+ GROUP BY t.agent_id, t.workspace_id, t.workspace_name
45
49
  ORDER BY (COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0)) DESC
46
50
  `:drizzleOrm.sql`
47
51
  SELECT
48
52
  t.agent_id,
53
+ t.workspace_id,
54
+ t.workspace_name,
49
55
  COUNT(*) AS total_tasks,
50
56
  COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
51
57
  COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
@@ -55,9 +61,9 @@
55
61
  WHERE t.status IN ('completed', 'success')
56
62
  AND t.started_at >= ${t}
57
63
  AND t.started_at < ${e}
58
- GROUP BY t.agent_id
64
+ GROUP BY t.agent_id, t.workspace_id, t.workspace_name
59
65
  ORDER BY (COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0)) DESC
60
- `).map(a=>({agentId:a.agent_id,totalTasks:a.total_tasks,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd}))}catch(o){throw new i("DB_ERROR","Failed to get agent usage",o)}finally{s.close();}}getAgentUsageTrendRaw(t,e,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(n?drizzleOrm.sql`
66
+ `).map(a=>({agentId:a.agent_id,workspaceId:a.workspace_id??null,workspaceName:a.workspace_name??null,totalTasks:a.total_tasks,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd}))}catch(o){throw new i("DB_ERROR","Failed to get agent usage",o)}finally{s.close();}}getAgentUsageTrendRaw(t,e,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(n?drizzleOrm.sql`
61
67
  SELECT
62
68
  date(t.started_at) AS date,
63
69
  t.agent_id,
@@ -86,13 +92,13 @@
86
92
  AND t.started_at < ${e}
87
93
  GROUP BY date(t.started_at), t.agent_id
88
94
  ORDER BY date(t.started_at) ASC
89
- `).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}))}catch(o){throw new i("DB_ERROR","Failed to get agent usage trend",o)}finally{s.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(r).where(drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.workspace_id,e))).limit(1).get()??void 0}catch(s){throw new i("DB_ERROR","Failed to find task for stop",s)}finally{n.close();}}markTaskFailed(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=new Date().toISOString(),a=n?drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.status,"running"),drizzleOrm.eq(r.workspace_id,n)):drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.status,"running"));s.db.update(r).set({status:"failed",error:e,completed_at:o}).where(a).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to mark task failed",o)}finally{s.close();}}findTasksByPromptHint(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=e?drizzleOrm.and(drizzleOrm.like(r.prompt,`%${t}%`),drizzleOrm.eq(r.workspace_id,e)):drizzleOrm.like(r.prompt,`%${t}%`),_=d.db.select().from(r).where(c).orderBy(drizzleOrm.asc(r.started_at)).all();for(let h of _)s.has(h.id)||(s.add(h.id),o.push(h));}catch(c){throw new i("DB_ERROR","Failed to find tasks by prompt hint",c)}finally{d.close();}}return o}};var _t=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}validateWorkspaceId(t,e){return t.db.select({id:p.id}).from(p).where(drizzleOrm.eq(p.id,e)).limit(1).get()?e:null}findAllThreads(t){let e=this.resolveDbPaths(),n=new Set,s=[];for(let o of e){if(!fs.existsSync(o))continue;let a=m(o);try{let d=t?drizzleOrm.or(drizzleOrm.eq(u.workspace_id,t),drizzleOrm.isNull(u.workspace_id)):void 0,c=a.db.select().from(u).where(d).orderBy(drizzleOrm.desc(u.updated_at)).all();for(let _ of c)n.has(_.id)||(n.add(_.id),s.push(_));}catch(d){throw new i("DB_ERROR","Failed to find all threads",d)}finally{a.close();}}return s}findThreadById(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=m(s);try{let a=drizzleOrm.eq(u.id,t),d=e?drizzleOrm.and(a,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):a,c=o.db.select().from(u).where(d).limit(1).get()??void 0;if(c)return c}catch(a){throw new i("DB_ERROR","Failed to find thread by id",a)}finally{o.close();}}}threadExists(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=m(s);try{let a=drizzleOrm.eq(u.id,t),d=e?drizzleOrm.and(a,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):a;if(o.db.select({id:u.id}).from(u).where(d).limit(1).get())return !0}catch(a){throw new i("DB_ERROR","Failed to check thread existence",a)}finally{o.close();}}return false}aggregateTaskStats(t,e){let n=this.resolveDbPaths(),s=0,o=0,a=0,d=0,c=0,_=new Set;for(let h of n){if(!fs.existsSync(h))continue;let k=m(h);try{let $=drizzleOrm.and(drizzleOrm.eq(r.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(r.parent_task_id),drizzleOrm.eq(r.parent_task_id,""))),L=e?drizzleOrm.and($,drizzleOrm.eq(r.workspace_id,e)):$,j=k.db.select({cnt:drizzleOrm.sql`count(*)`,total_input:drizzleOrm.sql`COALESCE(SUM(input_tokens), 0)`,total_output:drizzleOrm.sql`COALESCE(SUM(output_tokens), 0)`,total_cached:drizzleOrm.sql`COALESCE(SUM(cached_input_tokens), 0)`,total_cost:drizzleOrm.sql`COALESCE(SUM(cost_usd), 0)`}).from(r).where(L).get();j&&(s+=j.cnt,o+=j.total_input,a+=j.total_output,d+=j.total_cached,c+=j.total_cost);let qt=k.db.all(drizzleOrm.sql`
95
+ `).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}))}catch(o){throw new i("DB_ERROR","Failed to get agent usage trend",o)}finally{s.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(r).where(drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.workspace_id,e))).limit(1).get()??void 0}catch(s){throw new i("DB_ERROR","Failed to find task for stop",s)}finally{n.close();}}markTaskFailed(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=new Date().toISOString(),a=n?drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.status,"running"),drizzleOrm.eq(r.workspace_id,n)):drizzleOrm.and(drizzleOrm.eq(r.id,t),drizzleOrm.eq(r.status,"running"));s.db.update(r).set({status:"failed",error:e,completed_at:o}).where(a).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to mark task failed",o)}finally{s.close();}}findTasksByPromptHint(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=e?drizzleOrm.and(drizzleOrm.like(r.prompt,`%${t}%`),drizzleOrm.eq(r.workspace_id,e)):drizzleOrm.like(r.prompt,`%${t}%`),_=d.db.select().from(r).where(c).orderBy(drizzleOrm.asc(r.started_at)).all();for(let h of _)s.has(h.id)||(s.add(h.id),o.push(h));}catch(c){throw new i("DB_ERROR","Failed to find tasks by prompt hint",c)}finally{d.close();}}return o}};var ht=class extends R{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}validateWorkspaceId(t,e){return t.db.select({id:p.id}).from(p).where(drizzleOrm.eq(p.id,e)).limit(1).get()?e:null}findAllThreads(t){let e=this.resolveDbPaths(),n=new Set,s=[];for(let o of e){if(!fs.existsSync(o))continue;let a=m(o);try{let d=t?drizzleOrm.or(drizzleOrm.eq(u.workspace_id,t),drizzleOrm.isNull(u.workspace_id)):void 0,c=a.db.select().from(u).where(d).orderBy(drizzleOrm.desc(u.updated_at)).all();for(let _ of c)n.has(_.id)||(n.add(_.id),s.push(_));}catch(d){throw new i("DB_ERROR","Failed to find all threads",d)}finally{a.close();}}return s}findThreadById(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=m(s);try{let a=drizzleOrm.eq(u.id,t),d=e?drizzleOrm.and(a,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):a,c=o.db.select().from(u).where(d).limit(1).get()??void 0;if(c)return c}catch(a){throw new i("DB_ERROR","Failed to find thread by id",a)}finally{o.close();}}}threadExists(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=m(s);try{let a=drizzleOrm.eq(u.id,t),d=e?drizzleOrm.and(a,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,e),drizzleOrm.isNull(u.workspace_id))):a;if(o.db.select({id:u.id}).from(u).where(d).limit(1).get())return !0}catch(a){throw new i("DB_ERROR","Failed to check thread existence",a)}finally{o.close();}}return false}aggregateTaskStats(t,e){let n=this.resolveDbPaths(),s=0,o=0,a=0,d=0,c=0,_=new Set;for(let h of n){if(!fs.existsSync(h))continue;let g=m(h);try{let $=drizzleOrm.and(drizzleOrm.eq(r.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(r.parent_task_id),drizzleOrm.eq(r.parent_task_id,""))),L=e?drizzleOrm.and($,drizzleOrm.eq(r.workspace_id,e)):$,j=g.db.select({cnt:drizzleOrm.sql`count(*)`,total_input:drizzleOrm.sql`COALESCE(SUM(input_tokens), 0)`,total_output:drizzleOrm.sql`COALESCE(SUM(output_tokens), 0)`,total_cached:drizzleOrm.sql`COALESCE(SUM(cached_input_tokens), 0)`,total_cost:drizzleOrm.sql`COALESCE(SUM(cost_usd), 0)`}).from(r).where(L).get();j&&(s+=j.cnt,o+=j.total_input,a+=j.total_output,d+=j.total_cached,c+=j.total_cost);let qt=g.db.all(drizzleOrm.sql`
90
96
  SELECT DISTINCT agent_id FROM tasks
91
97
  WHERE thread_id = ${t}
92
98
  AND agent_id IS NOT NULL AND agent_id != ''
93
99
  AND (parent_task_id IS NULL OR parent_task_id = '')
94
100
  ${e?drizzleOrm.sql`AND workspace_id = ${e}`:drizzleOrm.sql``}
95
- `);for(let zt of qt)_.add(zt.agent_id);}catch($){throw new i("DB_ERROR","Failed to aggregate task stats",$)}finally{k.close();}}return {taskCount:s,inputTokens:o,outputTokens:a,cachedInputTokens:d,costUsd:c,agentIds:Array.from(_)}}findTopLevelTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=drizzleOrm.and(drizzleOrm.eq(r.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(r.parent_task_id),drizzleOrm.eq(r.parent_task_id,""))),_=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,h=d.db.select().from(r).where(_).orderBy(drizzleOrm.asc(r.started_at)).all();for(let k of h)s.has(k.id)||(s.add(k.id),o.push(k));}catch(c){throw new i("DB_ERROR","Failed to find top-level tasks",c)}finally{d.close();}}return o}findAllTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=drizzleOrm.eq(r.thread_id,t),_=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,h=d.db.select().from(r).where(_).orderBy(drizzleOrm.asc(r.started_at)).all();for(let k of h)s.has(k.id)||(s.add(k.id),o.push(k));}catch(c){throw new i("DB_ERROR","Failed to find all tasks for thread",c)}finally{d.close();}}return o}findTaskById(t,e,n){let s=this.resolveDbPaths();for(let o of s){if(!fs.existsSync(o))continue;let a=m(o);try{let d=drizzleOrm.and(drizzleOrm.eq(r.id,e),drizzleOrm.eq(r.thread_id,t)),c=n?drizzleOrm.and(d,drizzleOrm.eq(r.workspace_id,n)):d,_=a.db.select().from(r).where(c).limit(1).get();if(!_)continue;let h=a.db.select().from(r).where(drizzleOrm.eq(r.parent_task_id,_.id)).orderBy(drizzleOrm.asc(r.started_at)).all();return {task:_,children:h}}catch(d){throw new i("DB_ERROR","Failed to find task by id",d)}finally{a.close();}}}batchFetchTasks(t,e){let n=new Map;if(t.length===0)return n;let s=this.resolveDbPaths();for(let o of s){if(!fs.existsSync(o))continue;let a=m(o);try{let d=drizzleOrm.and(drizzleOrm.inArray(r.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(r.parent_task_id),drizzleOrm.eq(r.parent_task_id,""))),c=e?drizzleOrm.and(d,drizzleOrm.eq(r.workspace_id,e)):d,_=a.db.select().from(r).where(c).orderBy(drizzleOrm.asc(r.started_at)).all();for(let h of _){let k=h.thread_id;n.has(k)||n.set(k,[]),n.get(k).push(h);}}catch(d){throw new i("DB_ERROR","Failed to batch fetch tasks",d)}finally{a.close();}}return n}updateThreadTitle(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=drizzleOrm.eq(u.id,t),a=n?drizzleOrm.and(o,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,n),drizzleOrm.isNull(u.workspace_id))):o;if(!s.db.select({id:u.id}).from(u).where(a).limit(1).get())return;s.db.update(u).set({title:e,title_locked:1,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(u.id,t)).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to update thread title",o)}finally{s.close();}}upsertThread(t,e){let n=this.openHandle(true);try{let s=e.workspaceId?this.validateWorkspaceId(n,e.workspaceId):null,o=new Date().toISOString();if(n.db.select({id:u.id,message_count:u.message_count}).from(u).where(drizzleOrm.eq(u.id,t)).limit(1).get()){let d={updated_at:o};e.title!==void 0&&(d.title=e.title),e.titleLocked!==void 0&&(d.title_locked=e.titleLocked?1:0),n.db.update(u).set(d).where(drizzleOrm.eq(u.id,t)).run();}else n.db.insert(u).values({id:t,platform:e.platform,workspace_id:s,title:e.title??null,title_locked:e.titleLocked?1:0,message_count:0,created_at:o,updated_at:o}).run();}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to upsert thread",s)}finally{n.close();}}ensureThread(t,e,n){let s=this.openHandle(true);try{let o=n?this.validateWorkspaceId(s,n):null,a=s.db.select({id:u.id,platform:u.platform,workspace_id:u.workspace_id}).from(u).where(drizzleOrm.eq(u.id,t)).limit(1).get();if(a){o&&!a.workspace_id&&s.db.update(u).set({workspace_id:o}).where(drizzleOrm.eq(u.id,t)).run();return}let d=new Date().toISOString();s.db.insert(u).values({id:t,platform:e,workspace_id:o,message_count:0,created_at:d,updated_at:d}).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to ensure thread",o)}finally{s.close();}}saveUserMessage(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=new Date().toISOString();s.db.run(drizzleOrm.sql`
101
+ `);for(let zt of qt)_.add(zt.agent_id);}catch($){throw new i("DB_ERROR","Failed to aggregate task stats",$)}finally{g.close();}}return {taskCount:s,inputTokens:o,outputTokens:a,cachedInputTokens:d,costUsd:c,agentIds:Array.from(_)}}findTopLevelTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=drizzleOrm.and(drizzleOrm.eq(r.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(r.parent_task_id),drizzleOrm.eq(r.parent_task_id,""))),_=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,h=d.db.select().from(r).where(_).orderBy(drizzleOrm.asc(r.started_at)).all();for(let g of h)s.has(g.id)||(s.add(g.id),o.push(g));}catch(c){throw new i("DB_ERROR","Failed to find top-level tasks",c)}finally{d.close();}}return o}findAllTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let a of n){if(!fs.existsSync(a))continue;let d=m(a);try{let c=drizzleOrm.eq(r.thread_id,t),_=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,h=d.db.select().from(r).where(_).orderBy(drizzleOrm.asc(r.started_at)).all();for(let g of h)s.has(g.id)||(s.add(g.id),o.push(g));}catch(c){throw new i("DB_ERROR","Failed to find all tasks for thread",c)}finally{d.close();}}return o}findTaskById(t,e,n){let s=this.resolveDbPaths();for(let o of s){if(!fs.existsSync(o))continue;let a=m(o);try{let d=drizzleOrm.and(drizzleOrm.eq(r.id,e),drizzleOrm.eq(r.thread_id,t)),c=n?drizzleOrm.and(d,drizzleOrm.eq(r.workspace_id,n)):d,_=a.db.select().from(r).where(c).limit(1).get();if(!_)continue;let h=a.db.select().from(r).where(drizzleOrm.eq(r.parent_task_id,_.id)).orderBy(drizzleOrm.asc(r.started_at)).all();return {task:_,children:h}}catch(d){throw new i("DB_ERROR","Failed to find task by id",d)}finally{a.close();}}}batchFetchTasks(t,e){let n=new Map;if(t.length===0)return n;let s=this.resolveDbPaths();for(let o of s){if(!fs.existsSync(o))continue;let a=m(o);try{let d=drizzleOrm.and(drizzleOrm.inArray(r.thread_id,t),drizzleOrm.or(drizzleOrm.isNull(r.parent_task_id),drizzleOrm.eq(r.parent_task_id,""))),c=e?drizzleOrm.and(d,drizzleOrm.eq(r.workspace_id,e)):d,_=a.db.select().from(r).where(c).orderBy(drizzleOrm.asc(r.started_at)).all();for(let h of _){let g=h.thread_id;n.has(g)||n.set(g,[]),n.get(g).push(h);}}catch(d){throw new i("DB_ERROR","Failed to batch fetch tasks",d)}finally{a.close();}}return n}updateThreadTitle(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=drizzleOrm.eq(u.id,t),a=n?drizzleOrm.and(o,drizzleOrm.or(drizzleOrm.eq(u.workspace_id,n),drizzleOrm.isNull(u.workspace_id))):o;if(!s.db.select({id:u.id}).from(u).where(a).limit(1).get())return;s.db.update(u).set({title:e,title_locked:1,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(u.id,t)).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to update thread title",o)}finally{s.close();}}upsertThread(t,e){let n=this.openHandle(true);try{let s=e.workspaceId?this.validateWorkspaceId(n,e.workspaceId):null,o=new Date().toISOString();if(n.db.select({id:u.id,message_count:u.message_count}).from(u).where(drizzleOrm.eq(u.id,t)).limit(1).get()){let d={updated_at:o};e.title!==void 0&&(d.title=e.title),e.titleLocked!==void 0&&(d.title_locked=e.titleLocked?1:0),n.db.update(u).set(d).where(drizzleOrm.eq(u.id,t)).run();}else n.db.insert(u).values({id:t,platform:e.platform,workspace_id:s,title:e.title??null,title_locked:e.titleLocked?1:0,message_count:0,created_at:o,updated_at:o}).run();}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to upsert thread",s)}finally{n.close();}}ensureThread(t,e,n){let s=this.openHandle(true);try{let o=n?this.validateWorkspaceId(s,n):null,a=s.db.select({id:u.id,platform:u.platform,workspace_id:u.workspace_id}).from(u).where(drizzleOrm.eq(u.id,t)).limit(1).get();if(a){o&&!a.workspace_id&&s.db.update(u).set({workspace_id:o}).where(drizzleOrm.eq(u.id,t)).run();return}let d=new Date().toISOString();s.db.insert(u).values({id:t,platform:e,workspace_id:o,message_count:0,created_at:d,updated_at:d}).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to ensure thread",o)}finally{s.close();}}saveUserMessage(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=new Date().toISOString();s.db.run(drizzleOrm.sql`
96
102
  UPDATE threads
97
103
  SET first_message = COALESCE(first_message, ${e}),
98
104
  title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${e}, 1, 60) ELSE title END,
@@ -100,4 +106,4 @@
100
106
  message_count = message_count + 1,
101
107
  updated_at = ${o}
102
108
  WHERE id = ${t}
103
- `);}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to save user message",o)}finally{s.close();}}saveAssistantMessage(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=new Date().toISOString();s.db.update(u).set({last_message:e,updated_at:o}).where(drizzleOrm.eq(u.id,t)).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to save assistant message",o)}finally{s.close();}}updateThread(t,e){if(!this.dbExists())return;let n=this.openHandle(true);try{let s={updated_at:new Date().toISOString()};e.title!==void 0&&(s.title=e.title,s.title_locked=1),e.titleLocked!==void 0&&(s.title_locked=e.titleLocked?1:0),n.db.update(u).set(s).where(drizzleOrm.eq(u.id,t)).run();}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to update thread",s)}finally{n.close();}}};var ht=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}insertSpan(t){let e=this.openHandle(true);try{e.db.insert(z).values(t).run();}catch(n){throw n instanceof i?n:new i("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(z).where(drizzleOrm.eq(z.task_id,t)).all()}catch(n){throw new i("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(z).where(drizzleOrm.eq(z.id,t)).limit(1).get()??void 0}catch(n){throw new i("DB_ERROR","Failed to find span by id",n)}finally{e.close();}}};var ft=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}insertToolCall(t){let e=this.openHandle(true);try{e.db.insert(B).values(t).run();}catch(n){throw n instanceof i?n:new i("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(B).where(drizzleOrm.eq(B.task_id,t)).all()}catch(n){throw new i("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:B.tool_name,count:drizzleOrm.sql`count(*)`}).from(B).where(drizzleOrm.eq(B.task_id,t)).groupBy(B.tool_name).all().map(n=>({toolName:n.toolName,count:n.count}))}catch(n){throw new i("DB_ERROR","Failed to aggregate tool calls by name",n)}finally{e.close();}}};var mt=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}ensureThreadExists(t,e){if(!t.db.select({id:u.id}).from(u).where(drizzleOrm.eq(u.id,e)).limit(1).get())throw new i("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(C).where(drizzleOrm.eq(C.thread_id,t)).orderBy(drizzleOrm.asc(C.seq)).all()}catch(n){throw n instanceof i?n:new i("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(C).where(drizzleOrm.and(drizzleOrm.eq(C.id,e),drizzleOrm.eq(C.thread_id,t))).limit(1).get()??void 0}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to find box by id",s)}finally{n.close();}}insert(t){let e=this.openHandle(true);try{this.ensureThreadExists(e,t.threadId);try{e.db.insert(C).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(s){throw s instanceof Error&&/UNIQUE constraint failed/i.test(s.message)?new i("CONFLICT",`Duplicate seq ${String(t.seq)} for thread ${t.threadId}`,s):s}let n=e.db.select().from(C).where(drizzleOrm.eq(C.id,t.id)).limit(1).get();if(!n)throw new i("DB_ERROR","Insert did not return a row");return n}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to insert thread box",n)}finally{e.close();}}};var wt=class extends R{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 s=gt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}bulkInsert(t){if(t.length===0)return;let e=this.openHandle(true);try{let n=new Date().toISOString();e.db.transaction(s=>{for(let o of t)s.insert(J).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 i?n:new i("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(J).orderBy(drizzleOrm.desc(J.timestamp)).limit(t).all()}catch(n){throw new i("DB_ERROR","Failed to find recent request logs",n)}finally{e.close();}}};exports.BaseSqliteRepository=R;exports.RepositoryError=i;exports.RequestLogRepository=wt;exports.SpanRepository=ht;exports.TaskRepository=pt;exports.ThreadBoxRepository=mt;exports.ThreadRepository=_t;exports.ToolCallRepository=ft;exports.WorkspaceRepository=lt;exports.openDrizzleDb=m;exports.runMigrations=Q;exports.runMigrationsOnce=x;
109
+ `);}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to save user message",o)}finally{s.close();}}saveAssistantMessage(t,e,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let o=new Date().toISOString();s.db.update(u).set({last_message:e,updated_at:o}).where(drizzleOrm.eq(u.id,t)).run();}catch(o){throw o instanceof i?o:new i("DB_ERROR","Failed to save assistant message",o)}finally{s.close();}}updateThread(t,e){if(!this.dbExists())return;let n=this.openHandle(true);try{let s={updated_at:new Date().toISOString()};e.title!==void 0&&(s.title=e.title,s.title_locked=1),e.titleLocked!==void 0&&(s.title_locked=e.titleLocked?1:0),n.db.update(u).set(s).where(drizzleOrm.eq(u.id,t)).run();}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to update thread",s)}finally{n.close();}}};var ft=class extends R{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}insertSpan(t){let e=this.openHandle(true);try{e.db.insert(z).values(t).run();}catch(n){throw n instanceof i?n:new i("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(z).where(drizzleOrm.eq(z.task_id,t)).all()}catch(n){throw new i("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(z).where(drizzleOrm.eq(z.id,t)).limit(1).get()??void 0}catch(n){throw new i("DB_ERROR","Failed to find span by id",n)}finally{e.close();}}};var mt=class extends R{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}insertToolCall(t){let e=this.openHandle(true);try{e.db.insert(B).values(t).run();}catch(n){throw n instanceof i?n:new i("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(B).where(drizzleOrm.eq(B.task_id,t)).all()}catch(n){throw new i("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:B.tool_name,count:drizzleOrm.sql`count(*)`}).from(B).where(drizzleOrm.eq(B.task_id,t)).groupBy(B.tool_name).all().map(n=>({toolName:n.toolName,count:n.count}))}catch(n){throw new i("DB_ERROR","Failed to aggregate tool calls by name",n)}finally{e.close();}}};var wt=class extends R{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}ensureThreadExists(t,e){if(!t.db.select({id:u.id}).from(u).where(drizzleOrm.eq(u.id,e)).limit(1).get())throw new i("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(C).where(drizzleOrm.eq(C.thread_id,t)).orderBy(drizzleOrm.asc(C.seq)).all()}catch(n){throw n instanceof i?n:new i("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(C).where(drizzleOrm.and(drizzleOrm.eq(C.id,e),drizzleOrm.eq(C.thread_id,t))).limit(1).get()??void 0}catch(s){throw s instanceof i?s:new i("DB_ERROR","Failed to find box by id",s)}finally{n.close();}}insert(t){let e=this.openHandle(true);try{this.ensureThreadExists(e,t.threadId);try{e.db.insert(C).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(s){throw s instanceof Error&&/UNIQUE constraint failed/i.test(s.message)?new i("CONFLICT",`Duplicate seq ${String(t.seq)} for thread ${t.threadId}`,s):s}let n=e.db.select().from(C).where(drizzleOrm.eq(C.id,t.id)).limit(1).get();if(!n)throw new i("DB_ERROR","Insert did not return a row");return n}catch(n){throw n instanceof i?n:new i("DB_ERROR","Failed to insert thread box",n)}finally{e.close();}}};var kt=class extends R{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=rt.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new i("NOT_FOUND","Database not found");let n=m(e);if(t)try{x(n.db,e);}catch(s){throw n.close(),s}return n}bulkInsert(t){if(t.length===0)return;let e=this.openHandle(true);try{let n=new Date().toISOString();e.db.transaction(s=>{for(let o of t)s.insert(J).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 i?n:new i("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(J).orderBy(drizzleOrm.desc(J.timestamp)).limit(t).all()}catch(n){throw new i("DB_ERROR","Failed to find recent request logs",n)}finally{e.close();}}};exports.BaseSqliteRepository=R;exports.RepositoryError=i;exports.RequestLogRepository=kt;exports.SpanRepository=ft;exports.TaskRepository=_t;exports.ThreadBoxRepository=wt;exports.ThreadRepository=ht;exports.ToolCallRepository=mt;exports.WorkspaceRepository=ct;exports.openDrizzleDb=m;exports.runMigrations=Q;exports.runMigrationsOnce=x;
@@ -4,6 +4,8 @@ export type TaskRow = typeof tasks.$inferSelect;
4
4
  export type NewTask = typeof tasks.$inferInsert;
5
5
  export interface AgentUsageRow {
6
6
  agentId: string;
7
+ workspaceId: string | null;
8
+ workspaceName: string | null;
7
9
  totalTasks: number;
8
10
  inputTokens: number;
9
11
  outputTokens: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewx/sdk",
3
- "version": "0.8.3-rc.6",
3
+ "version": "0.8.3-rc.8",
4
4
  "license": "UNLICENSED",
5
5
  "engines": {
6
6
  "node": ">=20.19.0"
@@ -1,2 +0,0 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
2
- export declare function parseClaudeEvent(timestamp: string, parsed: Record<string, unknown>): TaskLogEntry[];
@@ -1,2 +0,0 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
2
- export declare function parseCodexEvent(timestamp: string, parsed: Record<string, unknown>): TaskLogEntry[];
@@ -1,2 +0,0 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
2
- export declare function parseCopilotEvent(timestamp: string, parsed: Record<string, unknown>): TaskLogEntry[];
@@ -1,2 +0,0 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
2
- export declare function parseGeminiEvent(timestamp: string, parsed: Record<string, unknown>): TaskLogEntry[];
@@ -1,2 +0,0 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
2
- export declare function parseOpencodeEvent(timestamp: string, parsed: Record<string, unknown>): TaskLogEntry[];
@@ -1,2 +0,0 @@
1
- import type { TaskLogEntry } from '../types/task-log.types';
2
- export declare function parseStdoutEvent(timestamp: string, message: string): TaskLogEntry[];