@crewx/sdk 0.9.0-rc.16 → 0.9.0-rc.18
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.
- package/dist/esm/plugins/index.js +5 -1
- package/dist/esm/repository/index.js +5 -1
- package/dist/plugins/index.js +14 -10
- package/dist/repository/index.d.ts +1 -1
- package/dist/repository/index.js +5 -1
- package/dist/repository/task.repository.d.ts +1 -0
- package/dist/repository/thread.repository.d.ts +2 -2
- package/package.json +1 -1
|
@@ -294,7 +294,11 @@ ${n.join(`
|
|
|
294
294
|
${e?sql`AND child.workspace_id = ${e}`:sql``}
|
|
295
295
|
ORDER BY child.started_at ASC
|
|
296
296
|
`);for(let u of l)o.has(u.id)||(o.add(u.id),i.push(u));}catch(l){throw new _("DB_ERROR","Failed to find top-level tasks",l)}finally{c.close();}}if(n!==void 0&&s.length>1){let a=new Map;for(let c of i){let l=c.agent_id??"";a.has(l)||a.set(l,[]),a.get(l).push(c);}i=[];for(let c of a.values())c.sort((l,u)=>(u.started_at??"").localeCompare(l.started_at??"")),i.push(...c.slice(0,n));i.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return i}findAllTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let i of n){if(!existsSync(i))continue;let a=R(i);try{let c=eq(r.thread_id,t),l=e?and(c,eq(r.workspace_id,e)):c,u=a.db.select().from(r).where(l).orderBy(asc(r.started_at)).all();for(let f of u)s.has(f.id)||(s.add(f.id),o.push(f));}catch(c){throw new _("DB_ERROR","Failed to find all tasks for thread",c)}finally{a.close();}}return o}findTaskById(t,e,n){let s=this.resolveDbPaths();for(let o of s){if(!existsSync(o))continue;let i=R(o);try{let a=and(eq(r.id,e),eq(r.thread_id,t)),c=n?and(a,eq(r.workspace_id,n)):a,l=i.db.select().from(r).where(c).limit(1).get();if(!l)continue;let u=i.db.select().from(r).where(eq(r.parent_task_id,l.id)).orderBy(asc(r.started_at)).all();return {task:l,children:u}}catch(a){throw new _("DB_ERROR","Failed to find task by id",a)}finally{i.close();}}}batchFetchTasksQuery(t,e){return sql`
|
|
297
|
-
SELECT child
|
|
297
|
+
SELECT child.id, child.thread_id, child.agent_id, child.status,
|
|
298
|
+
child.parent_task_id, child.started_at, child.completed_at,
|
|
299
|
+
child.duration_ms, child.input_tokens, child.output_tokens,
|
|
300
|
+
child.cost_usd, child.error
|
|
301
|
+
FROM tasks child INDEXED BY idx_tasks_thread_id
|
|
298
302
|
WHERE child.thread_id IN (${sql.join(t.map(n=>sql`${n}`),sql`, `)})
|
|
299
303
|
AND ${this.topLevelTaskPredicateSql()}
|
|
300
304
|
${e?sql`AND child.workspace_id = ${e}`:sql``}
|
|
@@ -289,7 +289,11 @@ ${n.join(`
|
|
|
289
289
|
${e?sql`AND child.workspace_id = ${e}`:sql``}
|
|
290
290
|
ORDER BY child.started_at ASC
|
|
291
291
|
`);for(let _ of c)o.has(_.id)||(o.add(_.id),i.push(_));}catch(c){throw new d("DB_ERROR","Failed to find top-level tasks",c)}finally{u.close();}}if(n!==void 0&&r.length>1){let l=new Map;for(let u of i){let c=u.agent_id??"";l.has(c)||l.set(c,[]),l.get(c).push(u);}i=[];for(let u of l.values())u.sort((c,_)=>(_.started_at??"").localeCompare(c.started_at??"")),i.push(...u.slice(0,n));i.sort((u,c)=>(u.started_at??"").localeCompare(c.started_at??""));}return i}findAllTasks(t,e){let n=this.resolveDbPaths(),r=new Set,o=[];for(let i of n){if(!existsSync(i))continue;let l=w(i);try{let u=eq(s.thread_id,t),c=e?and(u,eq(s.workspace_id,e)):u,_=l.db.select().from(s).where(c).orderBy(asc(s.started_at)).all();for(let m of _)r.has(m.id)||(r.add(m.id),o.push(m));}catch(u){throw new d("DB_ERROR","Failed to find all tasks for thread",u)}finally{l.close();}}return o}findTaskById(t,e,n){let r=this.resolveDbPaths();for(let o of r){if(!existsSync(o))continue;let i=w(o);try{let l=and(eq(s.id,e),eq(s.thread_id,t)),u=n?and(l,eq(s.workspace_id,n)):l,c=i.db.select().from(s).where(u).limit(1).get();if(!c)continue;let _=i.db.select().from(s).where(eq(s.parent_task_id,c.id)).orderBy(asc(s.started_at)).all();return {task:c,children:_}}catch(l){throw new d("DB_ERROR","Failed to find task by id",l)}finally{i.close();}}}batchFetchTasksQuery(t,e){return sql`
|
|
292
|
-
SELECT child
|
|
292
|
+
SELECT child.id, child.thread_id, child.agent_id, child.status,
|
|
293
|
+
child.parent_task_id, child.started_at, child.completed_at,
|
|
294
|
+
child.duration_ms, child.input_tokens, child.output_tokens,
|
|
295
|
+
child.cost_usd, child.error
|
|
296
|
+
FROM tasks child INDEXED BY idx_tasks_thread_id
|
|
293
297
|
WHERE child.thread_id IN (${sql.join(t.map(n=>sql`${n}`),sql`, `)})
|
|
294
298
|
AND ${this.topLevelTaskPredicateSql()}
|
|
295
299
|
${e?sql`AND child.workspace_id = ${e}`:sql``}
|
package/dist/plugins/index.js
CHANGED
|
@@ -8,7 +8,7 @@ Message: ${e.message}
|
|
|
8
8
|
`;fs.writeFileSync(s,o,{encoding:"utf8",mode:384});}catch{}}),t.on("task:output",e=>{try{let n=this.logFiles.get(e.traceId);if(!n)return;let s=new Date().toISOString();fs.appendFileSync(n,`[${s}] STDOUT: ${e.output}
|
|
9
9
|
`,"utf8");}catch{}}),t.on("task:end",e=>{try{let n=this.logFiles.get(e.traceId);if(!n)return;let s=new Date().toLocaleString(),o=e.error?`failed: ${e.error.message}`:"completed successfully",i=`[${s}] INFO: Task ${o} in ${e.durationMs}ms
|
|
10
10
|
[${s}] INFO: Process closed with exit code: ${e.error?1:0}
|
|
11
|
-
`;fs.appendFileSync(n,i,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function zt(d){let t=L__namespace.resolve(d);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 At(d){let t=zt(d);return crypto.createHash("sha256").update(t).digest("hex")}var X=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:L.join(jt__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 b(d){let t=tt("better-sqlite3"),{drizzle:e}=tt("drizzle-orm/better-sqlite3"),n=new t(d);return n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),n.exec("PRAGMA analysis_limit = 400"),n.exec("PRAGMA optimize"),{db:e(n),runRaw:(s,o=[])=>n.prepare(s).run(...o),close:()=>n.close()}}var xt=new Set,Kt={agent_id:"TEXT",status:"TEXT DEFAULT 'running'",started_at:"TEXT",trace_id:"TEXT",parent_task_id:"TEXT",crewx_version:"TEXT",pid:"INTEGER",thread_id:"TEXT",workspace_id:"TEXT",workspace_ref:"TEXT",workspace_name:"TEXT",project_id:"TEXT",project_name:"TEXT"};function pt(d,t){return (d.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function Gt(d,t){if(t>0||!pt(d,"tasks"))return;let e=d.all("PRAGMA table_info(tasks)"),n=new Set(e.map(s=>s.name));for(let[s,o]of Object.entries(Kt))n.has(s)||d.run(`ALTER TABLE tasks ADD COLUMN ${s} ${o}`);}var Xt={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"}};function Yt(d,t,e){if(!pt(d,"__drizzle_migrations")||!pt(d,"tasks"))return;let n=d.all(e`SELECT hash FROM __drizzle_migrations`),s=new Set(n.map(i=>i.hash)),o=JSON.parse(fs.readFileSync(L__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let i of o.entries){let a=Xt[i.tag];if(!a)continue;let c=L__namespace.default.join(t,`${i.tag}.sql`);if(!fs.existsSync(c))continue;let l=fs.readFileSync(c,"utf-8"),u=crypto.createHash("sha256").update(l).digest("hex");if(s.has(u))continue;let
|
|
11
|
+
`;fs.appendFileSync(n,i,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function zt(d){let t=L__namespace.resolve(d);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 At(d){let t=zt(d);return crypto.createHash("sha256").update(t).digest("hex")}var X=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:L.join(jt__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 b(d){let t=tt("better-sqlite3"),{drizzle:e}=tt("drizzle-orm/better-sqlite3"),n=new t(d);return n.exec("PRAGMA journal_mode = WAL"),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),n.exec("PRAGMA analysis_limit = 400"),n.exec("PRAGMA optimize"),{db:e(n),runRaw:(s,o=[])=>n.prepare(s).run(...o),close:()=>n.close()}}var xt=new Set,Kt={agent_id:"TEXT",status:"TEXT DEFAULT 'running'",started_at:"TEXT",trace_id:"TEXT",parent_task_id:"TEXT",crewx_version:"TEXT",pid:"INTEGER",thread_id:"TEXT",workspace_id:"TEXT",workspace_ref:"TEXT",workspace_name:"TEXT",project_id:"TEXT",project_name:"TEXT"};function pt(d,t){return (d.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function Gt(d,t){if(t>0||!pt(d,"tasks"))return;let e=d.all("PRAGMA table_info(tasks)"),n=new Set(e.map(s=>s.name));for(let[s,o]of Object.entries(Kt))n.has(s)||d.run(`ALTER TABLE tasks ADD COLUMN ${s} ${o}`);}var Xt={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"}};function Yt(d,t,e){if(!pt(d,"__drizzle_migrations")||!pt(d,"tasks"))return;let n=d.all(e`SELECT hash FROM __drizzle_migrations`),s=new Set(n.map(i=>i.hash)),o=JSON.parse(fs.readFileSync(L__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let i of o.entries){let a=Xt[i.tag];if(!a)continue;let c=L__namespace.default.join(t,`${i.tag}.sql`);if(!fs.existsSync(c))continue;let l=fs.readFileSync(c,"utf-8"),u=crypto.createHash("sha256").update(l).digest("hex");if(s.has(u))continue;let g=d.all("PRAGMA table_info(tasks)"),h=new Set(g.map(R=>R.name));for(let[R,G]of Object.entries(a))h.has(R)||(d.run(`ALTER TABLE tasks ADD COLUMN ${R} ${G}`),h.add(R));}}function Jt(d,t,e){let n=d.all(e`SELECT hash FROM __drizzle_migrations`),s=new Set(n.map(i=>i.hash)),o=JSON.parse(fs.readFileSync(L__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let i of o.entries){let a=L__namespace.default.join(t,`${i.tag}.sql`);if(!fs.existsSync(a))continue;let c=fs.readFileSync(a,"utf-8"),l=crypto.createHash("sha256").update(c).digest("hex");if(s.has(l))continue;let u=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,g=[],h;for(;(h=u.exec(c))!==null;)g.push({table:h[1],column:h[2]});if(g.length===0||!c.split(/-->\s*statement-breakpoint/).map(M=>M.trim()).filter(Boolean).every(M=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(M)))continue;g.every(({table:M,column:C})=>d.all(`PRAGMA table_info("${M}")`).some($=>$.name===C))&&d.run(e`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${i.when})`);}}function Vt(d){let{migrate:t}=tt("drizzle-orm/better-sqlite3/migrator"),{sql:e}=tt("drizzle-orm"),n=[L__namespace.default.join(__dirname,"../migrations"),L__namespace.default.join(__dirname,"migrations"),L__namespace.default.join(__dirname,"../../../../drizzle/migrations"),L__namespace.default.join(process.cwd(),"drizzle/migrations")],s=n.find(l=>fs.existsSync(L__namespace.default.join(l,"meta/_journal.json")));if(!s)throw new Error(`migrations folder not found. Searched:
|
|
12
12
|
${n.join(`
|
|
13
13
|
`)}`);let o=d.get(e`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),i=0;o?.cnt&&(i=d.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),Gt(d,i),o?.cnt&&(Jt(d,s,e),Yt(d,s,e)),t(d,{migrationsFolder:s});let c=(d.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-i;if(c>0){let l=o?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${l} (${c} migration${c>1?"s":""} applied).`);}}function nt(d,t){xt.has(t)||(Vt(d),xt.add(t));}var _=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);}};var Y=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"),trace_id:sqliteCore.text("trace_id"),parent_task_id:sqliteCore.text("parent_task_id"),caller_agent_id:sqliteCore.text("caller_agent_id"),model:sqliteCore.text("model"),platform:sqliteCore.text("platform").default("cli"),crewx_version:sqliteCore.text("crewx_version"),input_tokens:sqliteCore.integer("input_tokens").default(0),output_tokens:sqliteCore.integer("output_tokens").default(0),cost_usd:sqliteCore.real("cost_usd").default(0),pid:sqliteCore.integer("pid"),rendered_prompt:sqliteCore.text("rendered_prompt"),command:sqliteCore.text("command"),coding_agent_command:sqliteCore.text("coding_agent_command"),exit_code:sqliteCore.integer("exit_code"),logs:sqliteCore.text("logs"),thread_id:sqliteCore.text("thread_id"),workspace_ref:sqliteCore.text("workspace_ref"),project_id:sqliteCore.text("project_id"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0),run_epoch:sqliteCore.integer("run_epoch").default(0)},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 p=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>Y.id,{onDelete:"set null"}),platform:sqliteCore.text("platform").notNull().default("cli"),title:sqliteCore.text("title"),first_message:sqliteCore.text("first_message"),last_message:sqliteCore.text("last_message"),message_count:sqliteCore.integer("message_count").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),metadata:sqliteCore.text("metadata"),title_locked:sqliteCore.integer("title_locked").notNull().default(0),pinned:sqliteCore.integer("pinned").notNull().default(0),starred:sqliteCore.integer("starred").notNull().default(0)},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),idx_threads_ws_updated:sqliteCore.index("idx_threads_ws_updated").on(d.workspace_id,d.updated_at)}));var oe=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(()=>oe.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").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()},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(()=>p.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)}));sqliteCore.sqliteTable("usage_limit_snapshots",{id:sqliteCore.text("id").primaryKey(),provider:sqliteCore.text("provider").notNull(),account_ref:sqliteCore.text("account_ref").notNull().default("default"),limit_window:sqliteCore.text("limit_window").notNull(),bucket_start:sqliteCore.text("bucket_start").notNull(),captured_at:sqliteCore.text("captured_at").notNull(),used_percent:sqliteCore.integer("used_percent").notNull(),remaining_percent:sqliteCore.integer("remaining_percent").notNull(),resets_at:sqliteCore.text("resets_at"),source:sqliteCore.text("source").notNull(),metadata:sqliteCore.text("metadata")},d=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(d.provider,d.account_ref,d.limit_window,d.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(d.limit_window,d.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(d.provider,d.limit_window,d.bucket_start)}));sqliteCore.sqliteTable("usage_reports",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),month:sqliteCore.text("month").notNull(),generated_at:sqliteCore.text("generated_at").notNull(),source_range:sqliteCore.text("source_range").notNull(),tier:sqliteCore.text("tier").notNull(),total_tokens:sqliteCore.integer("total_tokens").notNull(),total_cost_usd:sqliteCore.real("total_cost_usd").notNull(),payload:sqliteCore.text("payload").notNull(),payload_hash:sqliteCore.text("payload_hash"),signature:sqliteCore.text("signature"),signed_at:sqliteCore.text("signed_at"),issuer:sqliteCore.text("issuer")},d=>({uniq_usage_reports_ws_month:sqliteCore.uniqueIndex("uniq_usage_reports_ws_month").on(d.workspace_id,d.month)}));function Lt(d){let t=d.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let e=t.lastIndexOf("/");return e>=0&&(t=t.slice(e+1)),t=t.replace(/-\d{8}$/,""),t}var B="2026-05-09",Te="0.8.9-rc.13",F=10,z=parseInt(Te.split("rc.")[1]),ye=new Set(["workflow","mcp"]),Ae=600*1e3,dt=class extends X{dbPath;pidNullObservedSince=new Map;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=L.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=L.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new _("NOT_FOUND","Database not found");let n=b(e);if(t)try{nt(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,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null}).onConflictDoUpdate({target:r.id,set:{pid:drizzleOrm.sql`COALESCE(excluded.pid, ${r.pid})`},setWhere:drizzleOrm.eq(r.status,"running")}).run();}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to start task",n)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{let n=t.runEpoch??null;e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
|
|
14
14
|
exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
|
|
@@ -34,7 +34,7 @@ ${n.join(`
|
|
|
34
34
|
FROM tasks
|
|
35
35
|
GROUP BY workspace_id
|
|
36
36
|
ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
|
|
37
|
-
`)}catch(n){throw new _("DB_ERROR","Failed to get workspace usage summary",n)}finally{e.close();}}getThreadTokenUsage(t,e){let n=this.resolveDbPaths(),s=new Set,o=0,i=0,a=0;for(let c of n){if(!fs.existsSync(c))continue;let l=b(c);try{let u=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),
|
|
37
|
+
`)}catch(n){throw new _("DB_ERROR","Failed to get workspace usage summary",n)}finally{e.close();}}getThreadTokenUsage(t,e){let n=this.resolveDbPaths(),s=new Set,o=0,i=0,a=0;for(let c of n){if(!fs.existsSync(c))continue;let l=b(c);try{let u=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(u,drizzleOrm.eq(r.workspace_id,e)):u,h=l.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 R of h)s.has(R.id)||(s.add(R.id),o+=R.input_tokens??0,i+=R.output_tokens??0,a+=R.cost_usd??0);}catch(u){throw new _("DB_ERROR","Failed to get thread token usage",u)}finally{l.close();}}return {inputTokens:o,outputTokens:i,costUsd:a}}findTasksByThread(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let i of n){if(!fs.existsSync(i))continue;let a=b(i);try{let c=drizzleOrm.or(drizzleOrm.eq(r.thread_id,t),drizzleOrm.and(drizzleOrm.isNull(r.thread_id),drizzleOrm.like(r.command,`%--thread=${t}%`))),l=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,u=a.db.select().from(r).where(l).orderBy(drizzleOrm.asc(r.started_at)).all();for(let g of u)s.has(g.id)||(s.add(g.id),o.push(g));}catch(c){throw new _("DB_ERROR","Failed to find tasks by thread",c)}finally{a.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 i=t.q??t.search;i&&n.push(drizzleOrm.like(r.prompt,`%${i}%`)),t.from&&n.push(drizzleOrm.gte(r.started_at,t.from)),t.to&&n.push(drizzleOrm.lt(r.started_at,t.to));let a=n.length>0?drizzleOrm.and(...n):void 0,c=e.db.select({count:drizzleOrm.sql`count(*)`}).from(r).where(a).get(),l=(t.sortDir??"DESC")==="ASC"?drizzleOrm.asc(r.started_at):drizzleOrm.desc(r.started_at);return {rows:e.db.select().from(r).where(a).orderBy(l).limit(t.limit).offset(t.offset).all(),total:c?.count??0}}catch(n){throw new _("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`
|
|
38
38
|
SELECT
|
|
39
39
|
t.agent_id,
|
|
40
40
|
t.workspace_id,
|
|
@@ -244,7 +244,7 @@ ${n.join(`
|
|
|
244
244
|
FROM ${r}
|
|
245
245
|
${a}
|
|
246
246
|
GROUP BY ${r.model}
|
|
247
|
-
`),l=new Map;for(let u of c){let
|
|
247
|
+
`),l=new Map;for(let u of c){let g=Lt(u.model??""),h=l.get(g);h?(h.totalTasks+=u.total_tasks,h.inputTokens+=u.input_tokens,h.outputTokens+=u.output_tokens,h.cachedInputTokens+=u.cached_input_tokens,h.costUsd+=u.cost_usd,h.totalTokens+=u.input_tokens+u.output_tokens,h.activeDurationMs+=u.active_duration_ms??0,u.last_active_at&&(!h.lastActiveAt||u.last_active_at>h.lastActiveAt)&&(h.lastActiveAt=u.last_active_at)):l.set(g,{model:g,provider:u.provider,totalTasks:u.total_tasks,inputTokens:u.input_tokens,outputTokens:u.output_tokens,cachedInputTokens:u.cached_input_tokens,costUsd:u.cost_usd,totalTokens:u.input_tokens+u.output_tokens,activeDurationMs:u.active_duration_ms??0,lastActiveAt:u.last_active_at??null});}return Array.from(l.values()).sort((u,g)=>g.costUsd-u.costUsd)}catch(o){throw new _("DB_ERROR","Failed to get model usage",o)}finally{s.close();}}getTasksForReport(t,e,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{let o=n?drizzleOrm.sql`WHERE ${r.started_at} >= ${t} AND ${r.started_at} < ${e} AND ${r.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${r.started_at} >= ${t} AND ${r.started_at} < ${e}`;return s.db.all(drizzleOrm.sql`
|
|
248
248
|
SELECT
|
|
249
249
|
${r.thread_id} AS thread_id,
|
|
250
250
|
${r.agent_id} AS agent_id,
|
|
@@ -255,11 +255,11 @@ ${n.join(`
|
|
|
255
255
|
FROM ${r}
|
|
256
256
|
${o}
|
|
257
257
|
ORDER BY ${r.started_at} ASC
|
|
258
|
-
`).map(a=>({threadId:a.thread_id,agentId:a.agent_id,startedAt:a.started_at,status:a.status,error:a.error,exitCode:a.exit_code}))}catch(o){throw new _("DB_ERROR","Failed to get tasks for report",o)}finally{s.close();}}};var wt=class extends U{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=L.join(t?.dbRoot??jt.homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let e=new dt({dbPath:this.dbPath}),n=process.cwd(),o=fs.existsSync(L.join(n,"crewx.yaml"))||fs.existsSync(L.join(n,"crewx.yml"))?At(n):null,i=process.argv.join(" ");this.unsubs.push(t.on("task:start",a=>{try{let c=a.callerAgentId??null,l=a.parentTaskId??null,u=a.rootTraceId??a.traceId,
|
|
258
|
+
`).map(a=>({threadId:a.thread_id,agentId:a.agent_id,startedAt:a.started_at,status:a.status,error:a.error,exitCode:a.exit_code}))}catch(o){throw new _("DB_ERROR","Failed to get tasks for report",o)}finally{s.close();}}};var wt=class extends U{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=L.join(t?.dbRoot??jt.homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let e=new dt({dbPath:this.dbPath}),n=process.cwd(),o=fs.existsSync(L.join(n,"crewx.yaml"))||fs.existsSync(L.join(n,"crewx.yml"))?At(n):null,i=process.argv.join(" ");this.unsubs.push(t.on("task:start",a=>{try{let c=a.callerAgentId??null,l=a.parentTaskId??null,u=a.rootTraceId??a.traceId,g=a.metadata?JSON.stringify(a.metadata):JSON.stringify({provider:a.provider??"cli/claude"});e.startTask({id:a.traceId,agentId:a.agentRef.replace(/^@/,""),prompt:a.message,mode:a.mode,status:"running",pid:a.pid??null,startedAt:a.timestamp.toISOString(),crewxVersion:this.version,platform:a.platform??"cli",model:a.model??null,renderedPrompt:a.renderedPrompt??null,command:i,codingAgentCommand:a.codingAgentCommand??null,workspaceId:a.workspaceId??o,callerAgentId:c,parentTaskId:l,traceId:u,metadata:g,threadId:a.threadId??null});}catch{}}),t.on("task:output",a=>{try{e.appendLog(a.traceId,{timestamp:a.timestamp.toISOString(),level:a.level??"stdout",message:a.output});}catch{}}),t.on("task:end",a=>{try{let c=typeof a.metadata?.runEpoch=="number"?a.metadata.runEpoch:null;e.finishTask({id:a.traceId,status:a.error?"failed":"success",result:a.result??null,error:a.error?JSON.stringify(a.error):null,completedAt:a.timestamp.toISOString(),durationMs:a.durationMs,exitCode:a.exitCode??null,inputTokens:a.inputTokens??0,outputTokens:a.outputTokens??0,cachedInputTokens:a.cachedInputTokens??0,costUsd:a.costUsd??0,model:a.model??null,runEpoch:c});}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[];}};var lt=class extends X{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=L.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=L.dirname(e);fs.existsSync(s)||fs.mkdirSync(s,{recursive:true});}else if(!fs.existsSync(e))throw new _("NOT_FOUND","Database not found");let n=b(e);if(t)try{nt(n.db,e);}catch(s){throw n.close(),s}return n}validateWorkspaceId(t,e){return t.db.select({id:Y.id}).from(Y).where(drizzleOrm.eq(Y.id,e)).limit(1).get()?e:null}topLevelTaskPredicateSql(t="child"){return drizzleOrm.sql.raw(`NOT EXISTS (
|
|
259
259
|
SELECT 1 FROM tasks parent
|
|
260
260
|
WHERE parent.id = ${t}.parent_task_id
|
|
261
261
|
AND parent.thread_id = ${t}.thread_id
|
|
262
|
-
)`)}findAllThreads(t){let e=this.resolveDbPaths(),n=new Set,s=[];for(let o of e){if(!fs.existsSync(o))continue;let i=b(o);try{let a=t?drizzleOrm.eq(p.workspace_id,t):void 0,c=i.db.select().from(p).where(a).orderBy(drizzleOrm.desc(p.updated_at)).all();for(let l of c)n.has(l.id)||(n.add(l.id),s.push(l));}catch(a){throw new _("DB_ERROR","Failed to find all threads",a)}finally{i.close();}}return s}findThreadById(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=b(s);try{let i=drizzleOrm.eq(p.id,t),a=e?drizzleOrm.and(i,drizzleOrm.eq(p.workspace_id,e)):i,c=o.db.select().from(p).where(a).limit(1).get()??void 0;if(c)return c}catch(i){throw new _("DB_ERROR","Failed to find thread by id",i)}finally{o.close();}}}threadExists(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=b(s);try{let i=drizzleOrm.eq(p.id,t),a=e?drizzleOrm.and(i,drizzleOrm.eq(p.workspace_id,e)):i;if(o.db.select({id:p.id}).from(p).where(a).limit(1).get())return !0}catch(i){throw new _("DB_ERROR","Failed to check thread existence",i)}finally{o.close();}}return false}aggregateTaskStats(t,e){let n=this.resolveDbPaths(),s=0,o=0,i=0,a=0,c=0,l=new Set;for(let u of n){if(!fs.existsSync(u))continue;let
|
|
262
|
+
)`)}findAllThreads(t){let e=this.resolveDbPaths(),n=new Set,s=[];for(let o of e){if(!fs.existsSync(o))continue;let i=b(o);try{let a=t?drizzleOrm.eq(p.workspace_id,t):void 0,c=i.db.select().from(p).where(a).orderBy(drizzleOrm.desc(p.updated_at)).all();for(let l of c)n.has(l.id)||(n.add(l.id),s.push(l));}catch(a){throw new _("DB_ERROR","Failed to find all threads",a)}finally{i.close();}}return s}findThreadById(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=b(s);try{let i=drizzleOrm.eq(p.id,t),a=e?drizzleOrm.and(i,drizzleOrm.eq(p.workspace_id,e)):i,c=o.db.select().from(p).where(a).limit(1).get()??void 0;if(c)return c}catch(i){throw new _("DB_ERROR","Failed to find thread by id",i)}finally{o.close();}}}threadExists(t,e){let n=this.resolveDbPaths();for(let s of n){if(!fs.existsSync(s))continue;let o=b(s);try{let i=drizzleOrm.eq(p.id,t),a=e?drizzleOrm.and(i,drizzleOrm.eq(p.workspace_id,e)):i;if(o.db.select({id:p.id}).from(p).where(a).limit(1).get())return !0}catch(i){throw new _("DB_ERROR","Failed to check thread existence",i)}finally{o.close();}}return false}aggregateTaskStats(t,e){let n=this.resolveDbPaths(),s=0,o=0,i=0,a=0,c=0,l=new Set;for(let u of n){if(!fs.existsSync(u))continue;let g=b(u);try{let h=g.db.get(drizzleOrm.sql`
|
|
263
263
|
SELECT
|
|
264
264
|
count(*) AS cnt,
|
|
265
265
|
COALESCE(SUM(child.input_tokens), 0) AS total_input,
|
|
@@ -270,13 +270,13 @@ ${n.join(`
|
|
|
270
270
|
WHERE child.thread_id = ${t}
|
|
271
271
|
AND ${this.topLevelTaskPredicateSql()}
|
|
272
272
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
273
|
-
`);
|
|
273
|
+
`);h&&(s+=h.cnt,o+=h.total_input,i+=h.total_output,a+=h.total_cached,c+=h.total_cost);let R=g.db.all(drizzleOrm.sql`
|
|
274
274
|
SELECT DISTINCT child.agent_id FROM tasks child
|
|
275
275
|
WHERE child.thread_id = ${t}
|
|
276
276
|
AND child.agent_id IS NOT NULL AND child.agent_id != ''
|
|
277
277
|
AND ${this.topLevelTaskPredicateSql()}
|
|
278
278
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
279
|
-
`);for(let G of R)l.add(G.agent_id);}catch(
|
|
279
|
+
`);for(let G of R)l.add(G.agent_id);}catch(h){throw new _("DB_ERROR","Failed to aggregate task stats",h)}finally{g.close();}}return {taskCount:s,inputTokens:o,outputTokens:i,cachedInputTokens:a,costUsd:c,agentIds:Array.from(l)}}findTopLevelTasks(t,e,n){let s=this.resolveDbPaths(),o=new Set,i=[];for(let a of s){if(!fs.existsSync(a))continue;let c=b(a);try{let l;n!==void 0?l=c.db.all(drizzleOrm.sql`
|
|
280
280
|
SELECT * FROM (
|
|
281
281
|
SELECT child.*,
|
|
282
282
|
ROW_NUMBER() OVER (PARTITION BY child.agent_id ORDER BY child.started_at DESC) AS rn
|
|
@@ -293,8 +293,12 @@ ${n.join(`
|
|
|
293
293
|
AND ${this.topLevelTaskPredicateSql()}
|
|
294
294
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
295
295
|
ORDER BY child.started_at ASC
|
|
296
|
-
`);for(let u of l)o.has(u.id)||(o.add(u.id),i.push(u));}catch(l){throw new _("DB_ERROR","Failed to find top-level tasks",l)}finally{c.close();}}if(n!==void 0&&s.length>1){let a=new Map;for(let c of i){let l=c.agent_id??"";a.has(l)||a.set(l,[]),a.get(l).push(c);}i=[];for(let c of a.values())c.sort((l,u)=>(u.started_at??"").localeCompare(l.started_at??"")),i.push(...c.slice(0,n));i.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return i}findAllTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let i of n){if(!fs.existsSync(i))continue;let a=b(i);try{let c=drizzleOrm.eq(r.thread_id,t),l=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,u=a.db.select().from(r).where(l).orderBy(drizzleOrm.asc(r.started_at)).all();for(let
|
|
297
|
-
SELECT child
|
|
296
|
+
`);for(let u of l)o.has(u.id)||(o.add(u.id),i.push(u));}catch(l){throw new _("DB_ERROR","Failed to find top-level tasks",l)}finally{c.close();}}if(n!==void 0&&s.length>1){let a=new Map;for(let c of i){let l=c.agent_id??"";a.has(l)||a.set(l,[]),a.get(l).push(c);}i=[];for(let c of a.values())c.sort((l,u)=>(u.started_at??"").localeCompare(l.started_at??"")),i.push(...c.slice(0,n));i.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return i}findAllTasks(t,e){let n=this.resolveDbPaths(),s=new Set,o=[];for(let i of n){if(!fs.existsSync(i))continue;let a=b(i);try{let c=drizzleOrm.eq(r.thread_id,t),l=e?drizzleOrm.and(c,drizzleOrm.eq(r.workspace_id,e)):c,u=a.db.select().from(r).where(l).orderBy(drizzleOrm.asc(r.started_at)).all();for(let g of u)s.has(g.id)||(s.add(g.id),o.push(g));}catch(c){throw new _("DB_ERROR","Failed to find all tasks for thread",c)}finally{a.close();}}return o}findTaskById(t,e,n){let s=this.resolveDbPaths();for(let o of s){if(!fs.existsSync(o))continue;let i=b(o);try{let a=drizzleOrm.and(drizzleOrm.eq(r.id,e),drizzleOrm.eq(r.thread_id,t)),c=n?drizzleOrm.and(a,drizzleOrm.eq(r.workspace_id,n)):a,l=i.db.select().from(r).where(c).limit(1).get();if(!l)continue;let u=i.db.select().from(r).where(drizzleOrm.eq(r.parent_task_id,l.id)).orderBy(drizzleOrm.asc(r.started_at)).all();return {task:l,children:u}}catch(a){throw new _("DB_ERROR","Failed to find task by id",a)}finally{i.close();}}}batchFetchTasksQuery(t,e){return drizzleOrm.sql`
|
|
297
|
+
SELECT child.id, child.thread_id, child.agent_id, child.status,
|
|
298
|
+
child.parent_task_id, child.started_at, child.completed_at,
|
|
299
|
+
child.duration_ms, child.input_tokens, child.output_tokens,
|
|
300
|
+
child.cost_usd, child.error
|
|
301
|
+
FROM tasks child INDEXED BY idx_tasks_thread_id
|
|
298
302
|
WHERE child.thread_id IN (${drizzleOrm.sql.join(t.map(n=>drizzleOrm.sql`${n}`),drizzleOrm.sql`, `)})
|
|
299
303
|
AND ${this.topLevelTaskPredicateSql()}
|
|
300
304
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
@@ -307,7 +311,7 @@ ${n.join(`
|
|
|
307
311
|
message_count = message_count + 1,
|
|
308
312
|
updated_at = ${o}
|
|
309
313
|
WHERE id = ${t}
|
|
310
|
-
`),l},{behavior:"immediate"})}}catch(o){throw o instanceof _?o:new _("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(p).set({last_message:e,updated_at:o}).where(drizzleOrm.eq(p.id,t)).run();}catch(o){throw o instanceof _?o:new _("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(p).set(s).where(drizzleOrm.eq(p.id,t)).run();}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to update thread",s)}finally{n.close();}}togglePin(t,e){let n=this.openHandle(true);try{let s=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t),o=n.db.select({pinned:p.pinned,metadata:p.metadata}).from(p).where(s).get();if(!o)return null;let i=o.pinned?0:1,a=o.metadata?JSON.parse(o.metadata):{};if(i){let c=e?drizzleOrm.and(drizzleOrm.eq(p.pinned,1),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.pinned,1),l=n.db.select({metadata:p.metadata}).from(p).where(c).all(),u=0;for(let
|
|
314
|
+
`),l},{behavior:"immediate"})}}catch(o){throw o instanceof _?o:new _("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(p).set({last_message:e,updated_at:o}).where(drizzleOrm.eq(p.id,t)).run();}catch(o){throw o instanceof _?o:new _("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(p).set(s).where(drizzleOrm.eq(p.id,t)).run();}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to update thread",s)}finally{n.close();}}togglePin(t,e){let n=this.openHandle(true);try{let s=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t),o=n.db.select({pinned:p.pinned,metadata:p.metadata}).from(p).where(s).get();if(!o)return null;let i=o.pinned?0:1,a=o.metadata?JSON.parse(o.metadata):{};if(i){let c=e?drizzleOrm.and(drizzleOrm.eq(p.pinned,1),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.pinned,1),l=n.db.select({metadata:p.metadata}).from(p).where(c).all(),u=0;for(let g of l){let h=g.metadata?JSON.parse(g.metadata):{};typeof h.pinOrder=="number"&&h.pinOrder>u&&(u=h.pinOrder);}a.pinOrder=u+1;}else delete a.pinOrder;return n.db.update(p).set({pinned:i,metadata:Object.keys(a).length>0?JSON.stringify(a):null}).where(s).run(),{pinned:!!i}}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to toggle pin",s)}finally{n.close();}}reorderPins(t,e){let n=this.openHandle(true);try{for(let s=0;s<t.length;s++){let o=e?drizzleOrm.and(drizzleOrm.eq(p.id,t[s]),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t[s]),i=n.db.select({metadata:p.metadata}).from(p).where(o).get();if(!i)continue;let a=i.metadata?JSON.parse(i.metadata):{};a.pinOrder=s+1,n.db.update(p).set({metadata:JSON.stringify(a)}).where(o).run();}}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to reorder pins",s)}finally{n.close();}}toggleStar(t,e){let n=this.openHandle(true);try{let s=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t),o=n.db.select({starred:p.starred}).from(p).where(s).get();if(!o)return null;let i=o.starred?0:1;return n.db.update(p).set({starred:i}).where(s).run(),{starred:!!i}}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to toggle star",s)}finally{n.close();}}resolveOverdriveForRequest(t,e,n,s){let i=this.openHandle(true);try{let a=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t);return i.db.transaction(l=>{let u=l.select({metadata:p.metadata}).from(p).where(a).get();if(!u)return null;let g=u.metadata?JSON.parse(u.metadata):{},h=g.overdrive??{},R=s?.defaultTurns??h.defaultTurns??3,G=s?.updatedBy??"ui",M=new Date().toISOString(),C,v,$,V;switch(n){case "enable-count":{let Q=s?.turns??R,Z=s?.consumeCurrent?Math.max(Q-1,0):Q;C=Z>0?"count":"off",v=Z,$=!0,V="count";break}case "enable-latch":{C="latch",v=0,$=!0,V="latch";break}case "disable":{C="off",v=0,$=!1;break}default:{let Q=h.state??"off",Z=typeof h.remaining=="number"?h.remaining:0;if(Q==="count"&&Z>0){let St=Z-1;St<=0?(C="off",v=0):(C="count",v=St),$=!0,V="count";}else Q==="latch"?(C="latch",v=0,$=!0,V="latch"):(C="off",v=0,$=!1);break}}return g.overdrive={state:C,remaining:v,defaultTurns:R,updatedAt:M,updatedBy:G},l.update(p).set({metadata:JSON.stringify(g),updated_at:M}).where(a).run(),{applied:$,appliedMode:V,state:C,remaining:v}},{behavior:"immediate"})}catch(a){throw a instanceof _?a:new _("DB_ERROR","Failed to resolve overdrive",a)}finally{i.close();}}};function Le(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
|
|
311
315
|
`).filter(s=>!(s.startsWith("Loaded ")&&s.includes("layouts from")||s.includes("[dotenv@")||s.includes("[Nest]")&&s.includes("DEBUG")||s.startsWith("Registered custom layout:")||s.startsWith("Updated custom layout:"))).join(`
|
|
312
316
|
`).trim()}function Ie(d){if(!d)return "";let t=d;try{let e=JSON.parse(t);Array.isArray(e)?t=e.filter(n=>n?.type==="text"&&n?.text).map(n=>n.text).join(`
|
|
313
317
|
`):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=Le(t);}return t}var ct=class{dbPath;constructor(t){this.dbPath=t??L.join(jt.homedir(),".crewx","crewx.db");}getThreadRepo(){return new lt({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,n){let s=this.getThreadRepo(),o=s.findThreadById(t);if(o){if(o.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${o.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return {created:false}}return s.ensureThread(t,e,n),{created:true}}async fetchHistory(t,e){let n=e?.limit??100,s=this.getThreadRepo(),o=s.findThreadById(t),i=s.findTopLevelTasks(t,void 0,n),a=new Set(["queued","cancelled"]);i=i.filter(u=>(!u.status||!a.has(u.status))&&(!e?.currentTraceId||u.trace_id!==e.currentTraceId));let c=o?.platform??"cli",l=this.rowsToMessages(i);return {threadId:t,platform:c,messages:l,metadata:{title:o?.title??void 0,firstMessage:o?.first_message??void 0,lastMessage:o?.last_message??void 0,messageCount:o?.message_count??0,updatedAt:o?.updated_at?new Date(o.updated_at).getTime():void 0}}}async saveUserMessage(t,e,n,s){let{firstMessage:o}=this.getThreadRepo().saveUserMessage(t,e);return {id:t,firstMessage:o}}async saveAssistantMessage(t,e,n,s){return this.getThreadRepo().saveAssistantMessage(t,e),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let e=[];for(let n of t){n.prompt&&e.push({id:`${n.id}-user`,text:n.prompt,isAssistant:false,timestamp:new Date(n.started_at).getTime(),metadata:{caller_agent_id:n.caller_agent_id}});let s=Ie(n.result),o=this.normalizeStatus(n.status);if(s||o==="running"||o==="failed"){let i={agent_id:n.agent_id,task_id:n.id};o&&(i.status=o),o==="failed"&&n.error&&(i.reason=n.error.split(`
|
|
@@ -11,7 +11,7 @@ export type { PushResult } from './push.js';
|
|
|
11
11
|
export type { Workspace, NewWorkspace } from '../schema/index.js';
|
|
12
12
|
export { tasks } from '../schema/index.js';
|
|
13
13
|
export { TaskRepository } from './task.repository.js';
|
|
14
|
-
export type { TaskRow, NewTask, AgentUsageRow, TrendRow, ProviderUsageRow, ModelUsageRow, ReportTaskRow, } from './task.repository.js';
|
|
14
|
+
export type { TaskRow, TaskListRow, NewTask, AgentUsageRow, TrendRow, ProviderUsageRow, ModelUsageRow, ReportTaskRow, } from './task.repository.js';
|
|
15
15
|
export { ThreadRepository } from './thread.repository.js';
|
|
16
16
|
export type { ThreadRow, NewThread } from './thread.repository.js';
|
|
17
17
|
export { SpanRepository } from './span.repository.js';
|
package/dist/repository/index.js
CHANGED
|
@@ -289,7 +289,11 @@ ${n.join(`
|
|
|
289
289
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
290
290
|
ORDER BY child.started_at ASC
|
|
291
291
|
`);for(let _ of c)o.has(_.id)||(o.add(_.id),i.push(_));}catch(c){throw new d("DB_ERROR","Failed to find top-level tasks",c)}finally{u.close();}}if(n!==void 0&&r.length>1){let l=new Map;for(let u of i){let c=u.agent_id??"";l.has(c)||l.set(c,[]),l.get(c).push(u);}i=[];for(let u of l.values())u.sort((c,_)=>(_.started_at??"").localeCompare(c.started_at??"")),i.push(...u.slice(0,n));i.sort((u,c)=>(u.started_at??"").localeCompare(c.started_at??""));}return i}findAllTasks(t,e){let n=this.resolveDbPaths(),r=new Set,o=[];for(let i of n){if(!Qt.existsSync(i))continue;let l=w(i);try{let u=drizzleOrm.eq(s.thread_id,t),c=e?drizzleOrm.and(u,drizzleOrm.eq(s.workspace_id,e)):u,_=l.db.select().from(s).where(c).orderBy(drizzleOrm.asc(s.started_at)).all();for(let m of _)r.has(m.id)||(r.add(m.id),o.push(m));}catch(u){throw new d("DB_ERROR","Failed to find all tasks for thread",u)}finally{l.close();}}return o}findTaskById(t,e,n){let r=this.resolveDbPaths();for(let o of r){if(!Qt.existsSync(o))continue;let i=w(o);try{let l=drizzleOrm.and(drizzleOrm.eq(s.id,e),drizzleOrm.eq(s.thread_id,t)),u=n?drizzleOrm.and(l,drizzleOrm.eq(s.workspace_id,n)):l,c=i.db.select().from(s).where(u).limit(1).get();if(!c)continue;let _=i.db.select().from(s).where(drizzleOrm.eq(s.parent_task_id,c.id)).orderBy(drizzleOrm.asc(s.started_at)).all();return {task:c,children:_}}catch(l){throw new d("DB_ERROR","Failed to find task by id",l)}finally{i.close();}}}batchFetchTasksQuery(t,e){return drizzleOrm.sql`
|
|
292
|
-
SELECT child
|
|
292
|
+
SELECT child.id, child.thread_id, child.agent_id, child.status,
|
|
293
|
+
child.parent_task_id, child.started_at, child.completed_at,
|
|
294
|
+
child.duration_ms, child.input_tokens, child.output_tokens,
|
|
295
|
+
child.cost_usd, child.error
|
|
296
|
+
FROM tasks child INDEXED BY idx_tasks_thread_id
|
|
293
297
|
WHERE child.thread_id IN (${drizzleOrm.sql.join(t.map(n=>drizzleOrm.sql`${n}`),drizzleOrm.sql`, `)})
|
|
294
298
|
AND ${this.topLevelTaskPredicateSql()}
|
|
295
299
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
@@ -2,6 +2,7 @@ import { BaseSqliteRepository } from './base-sqlite-repository.js';
|
|
|
2
2
|
import { tasks } from '../schema/index.js';
|
|
3
3
|
export type TaskRow = typeof tasks.$inferSelect;
|
|
4
4
|
export type NewTask = typeof tasks.$inferInsert;
|
|
5
|
+
export type TaskListRow = Pick<TaskRow, 'id' | 'thread_id' | 'agent_id' | 'status' | 'parent_task_id' | 'started_at' | 'completed_at' | 'duration_ms' | 'input_tokens' | 'output_tokens' | 'cost_usd' | 'error'>;
|
|
5
6
|
export interface AgentUsageRow {
|
|
6
7
|
agentId: string;
|
|
7
8
|
workspaceId: string | null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseSqliteRepository } from './base-sqlite-repository.js';
|
|
2
2
|
import { threads } from '../schema/index.js';
|
|
3
|
-
import type { TaskRow } from './task.repository.js';
|
|
3
|
+
import type { TaskRow, TaskListRow } from './task.repository.js';
|
|
4
4
|
export type ThreadRow = typeof threads.$inferSelect;
|
|
5
5
|
export type NewThread = typeof threads.$inferInsert;
|
|
6
6
|
export declare class ThreadRepository extends BaseSqliteRepository {
|
|
@@ -31,7 +31,7 @@ export declare class ThreadRepository extends BaseSqliteRepository {
|
|
|
31
31
|
children: TaskRow[];
|
|
32
32
|
} | undefined;
|
|
33
33
|
private batchFetchTasksQuery;
|
|
34
|
-
batchFetchTasks(threadIds: string[], workspaceId?: string): Map<string,
|
|
34
|
+
batchFetchTasks(threadIds: string[], workspaceId?: string): Map<string, TaskListRow[]>;
|
|
35
35
|
explainBatchFetchTasksPlan(threadIds: string[], workspaceId?: string): string[];
|
|
36
36
|
updateThreadTitle(threadId: string, title: string, workspaceId?: string): void;
|
|
37
37
|
upsertThread(threadId: string, opts: {
|