@crewx/sdk 0.9.0-rc.53 → 0.9.0-rc.55

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,19 +1,19 @@
1
- import*as F from'path';import F__default,{join,dirname}from'path';import {fileURLToPath}from'url';import {existsSync,mkdirSync,writeFileSync,appendFileSync,readFileSync}from'fs';import ae,{homedir}from'os';import {createHash}from'crypto';import {sql,eq,desc,and,isNull,lt,or,notLike,like,asc,inArray,gte,isNotNull,ne}from'drizzle-orm';import {sqliteTable,text,integer,real,index,unique,uniqueIndex,primaryKey}from'drizzle-orm/sqlite-core';var dt=(d=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(d,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):d)(function(d){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+d+'" is not supported')});var Vt=()=>fileURLToPath(import.meta.url),Qt=()=>F__default.dirname(Vt()),k=Qt();var K=class{detach(t){}};function Nt(d){let t=n=>String(n).padStart(2,"0");return `${d.getFullYear()}${t(d.getMonth()+1)}${t(d.getDate())}T${t(d.getHours())}${t(d.getMinutes())}${t(d.getSeconds())}`}var wt=class extends K{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",n=>{try{existsSync(this.logsDir)||mkdirSync(this.logsDir,{recursive:!0});let s=Nt(n.timestamp),r=join(this.logsDir,`${s}_${n.traceId}.log`);this.logFiles.set(n.traceId,r);let o=`=== TASK LOG: ${n.traceId} ===
1
+ import*as F from'path';import F__default,{join,dirname}from'path';import {fileURLToPath}from'url';import {existsSync,mkdirSync,writeFileSync,appendFileSync,readFileSync}from'fs';import ae,{homedir}from'os';import {createHash}from'crypto';import {sql,eq,desc,and,isNull,lt,or,notLike,like,asc,inArray,gte,isNotNull,ne}from'drizzle-orm';import {sqliteTable,text,integer,real,index,unique,uniqueIndex,primaryKey}from'drizzle-orm/sqlite-core';var dt=(d=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(d,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):d)(function(d){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+d+'" is not supported')});var Qt=()=>fileURLToPath(import.meta.url),Zt=()=>F__default.dirname(Qt()),k=Zt();var j=class{detach(t){}};function Ot(d){let t=n=>String(n).padStart(2,"0");return `${d.getFullYear()}${t(d.getMonth()+1)}${t(d.getDate())}T${t(d.getHours())}${t(d.getMinutes())}${t(d.getSeconds())}`}function wt(d){let t=d.toISOString();return `${t.slice(0,10)} ${t.slice(11,19)} UTC`}var Et=class extends j{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",n=>{try{existsSync(this.logsDir)||mkdirSync(this.logsDir,{recursive:!0});let s=Ot(n.timestamp),r=join(this.logsDir,`${s}_${n.traceId}.log`);this.logFiles.set(n.traceId,r);let o=`=== TASK LOG: ${n.traceId} ===
2
2
  CrewX Version: ${this.version}
3
3
  Mode: ${n.mode}
4
4
  Agent: ${n.agentRef}
5
- Started: ${n.timestamp.toLocaleString()}
5
+ Started: ${wt(n.timestamp)}
6
6
  Message: ${n.message}
7
7
 
8
8
  `;writeFileSync(r,o,{encoding:"utf8",mode:384});}catch{}}),t.on("task:output",n=>{try{let s=this.logFiles.get(n.traceId);if(!s)return;let r=new Date().toISOString();appendFileSync(s,`[${r}] STDOUT: ${n.output}
9
- `,"utf8");}catch{}}),t.on("task:end",n=>{try{let s=this.logFiles.get(n.traceId);if(!s)return;let r=new Date().toLocaleString(),o=n.error?`failed: ${n.error.message}`:"completed successfully",a=`[${r}] INFO: Task ${o} in ${n.durationMs}ms
9
+ `,"utf8");}catch{}}),t.on("task:end",n=>{try{let s=this.logFiles.get(n.traceId);if(!s)return;let r=wt(new Date),o=n.error?`failed: ${n.error.message}`:"completed successfully",i=`[${r}] INFO: Task ${o} in ${n.durationMs}ms
10
10
  [${r}] INFO: Process closed with exit code: ${n.error?1:0}
11
- `;appendFileSync(s,a,"utf8"),this.logFiles.delete(n.traceId);}catch{}}));}detach(t){this.unsubs.forEach(n=>n()),this.unsubs=[],this.logFiles.clear();}};function se(d){let t=F.resolve(d);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(n,s)=>`${s.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function $t(d){let t=se(d);return createHash("sha256").update(t).digest("hex")}var nt=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:join(ae.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(t){return t instanceof Error&&/no such table:/i.test(t.message)}dbExists(t){return existsSync(t??this.resolveDbPath())}};function R(d){let t=dt("better-sqlite3"),{drizzle:n}=dt("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"),s.exec("PRAGMA analysis_limit = 400"),s.exec("PRAGMA optimize"),{db:n(s),runRaw:(r,o=[])=>s.prepare(r).run(...o),close:()=>s.close()}}var It=new Set,ie={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 Et(d,t){return (d.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function de(d,t){if(t>0||!Et(d,"tasks"))return;let n=d.all("PRAGMA table_info(tasks)"),s=new Set(n.map(r=>r.name));for(let[r,o]of Object.entries(ie))s.has(r)||d.run(`ALTER TABLE tasks ADD COLUMN ${r} ${o}`);}var le={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"}};function ce(d,t,n){if(!Et(d,"__drizzle_migrations")||!Et(d,"tasks"))return;let s=d.all(n`SELECT hash FROM __drizzle_migrations`),r=new Set(s.map(a=>a.hash)),o=JSON.parse(readFileSync(F__default.join(t,"meta/_journal.json"),"utf-8"));for(let a of o.entries){let i=le[a.tag];if(!i)continue;let c=F__default.join(t,`${a.tag}.sql`);if(!existsSync(c))continue;let l=readFileSync(c,"utf-8"),u=createHash("sha256").update(l).digest("hex");if(r.has(u))continue;let h=d.all("PRAGMA table_info(tasks)"),f=new Set(h.map(y=>y.name));for(let[y,C]of Object.entries(i))f.has(y)||(d.run(`ALTER TABLE tasks ADD COLUMN ${y} ${C}`),f.add(y));}}function ue(d,t,n){let s=d.all(n`SELECT hash FROM __drizzle_migrations`),r=new Set(s.map(a=>a.hash)),o=JSON.parse(readFileSync(F__default.join(t,"meta/_journal.json"),"utf-8"));for(let a of o.entries){let i=F__default.join(t,`${a.tag}.sql`);if(!existsSync(i))continue;let c=readFileSync(i,"utf-8"),l=createHash("sha256").update(c).digest("hex");if(r.has(l))continue;let u=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,h=[],f;for(;(f=u.exec(c))!==null;)h.push({table:f[1],column:f[2]});if(h.length===0||!c.split(/-->\s*statement-breakpoint/).map(N=>N.trim()).filter(Boolean).every(N=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(N)))continue;h.every(({table:N,column:I})=>d.all(`PRAGMA table_info("${N}")`).some(B=>B.name===I))&&d.run(n`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${a.when})`);}}function _e(d){let{migrate:t}=dt("drizzle-orm/better-sqlite3/migrator"),{sql:n}=dt("drizzle-orm"),s=[F__default.join(k,"../migrations"),F__default.join(k,"migrations"),F__default.join(k,"../../../../drizzle/migrations"),F__default.join(process.cwd(),"drizzle/migrations")],r=s.find(l=>existsSync(F__default.join(l,"meta/_journal.json")));if(!r)throw new Error(`migrations folder not found. Searched:
11
+ `;appendFileSync(s,i,"utf8"),this.logFiles.delete(n.traceId);}catch{}}));}detach(t){this.unsubs.forEach(n=>n()),this.unsubs=[],this.logFiles.clear();}};function re(d){let t=F.resolve(d);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(n,s)=>`${s.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function $t(d){let t=re(d);return createHash("sha256").update(t).digest("hex")}var nt=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:join(ae.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(t){return t instanceof Error&&/no such table:/i.test(t.message)}dbExists(t){return existsSync(t??this.resolveDbPath())}};function b(d){let t=dt("better-sqlite3"),{drizzle:n}=dt("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"),s.exec("PRAGMA analysis_limit = 400"),s.exec("PRAGMA optimize"),{db:n(s),runRaw:(r,o=[])=>s.prepare(r).run(...o),close:()=>s.close()}}var Lt=new Set,de={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 St(d,t){return (d.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function le(d,t){if(t>0||!St(d,"tasks"))return;let n=d.all("PRAGMA table_info(tasks)"),s=new Set(n.map(r=>r.name));for(let[r,o]of Object.entries(de))s.has(r)||d.run(`ALTER TABLE tasks ADD COLUMN ${r} ${o}`);}var ce={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"}};function ue(d,t,n){if(!St(d,"__drizzle_migrations")||!St(d,"tasks"))return;let s=d.all(n`SELECT hash FROM __drizzle_migrations`),r=new Set(s.map(i=>i.hash)),o=JSON.parse(readFileSync(F__default.join(t,"meta/_journal.json"),"utf-8"));for(let i of o.entries){let a=ce[i.tag];if(!a)continue;let c=F__default.join(t,`${i.tag}.sql`);if(!existsSync(c))continue;let l=readFileSync(c,"utf-8"),u=createHash("sha256").update(l).digest("hex");if(r.has(u))continue;let h=d.all("PRAGMA table_info(tasks)"),g=new Set(h.map(y=>y.name));for(let[y,C]of Object.entries(a))g.has(y)||(d.run(`ALTER TABLE tasks ADD COLUMN ${y} ${C}`),g.add(y));}}function pe(d,t,n){let s=d.all(n`SELECT hash FROM __drizzle_migrations`),r=new Set(s.map(i=>i.hash)),o=JSON.parse(readFileSync(F__default.join(t,"meta/_journal.json"),"utf-8"));for(let i of o.entries){let a=F__default.join(t,`${i.tag}.sql`);if(!existsSync(a))continue;let c=readFileSync(a,"utf-8"),l=createHash("sha256").update(c).digest("hex");if(r.has(l))continue;let u=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,h=[],g;for(;(g=u.exec(c))!==null;)h.push({table:g[1],column:g[2]});if(h.length===0||!c.split(/-->\s*statement-breakpoint/).map(N=>N.trim()).filter(Boolean).every(N=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(N)))continue;h.every(({table:N,column:$})=>d.all(`PRAGMA table_info("${N}")`).some(B=>B.name===$))&&d.run(n`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${i.when})`);}}function _e(d){let{migrate:t}=dt("drizzle-orm/better-sqlite3/migrator"),{sql:n}=dt("drizzle-orm"),s=[F__default.join(k,"../migrations"),F__default.join(k,"migrations"),F__default.join(k,"../../../../drizzle/migrations"),F__default.join(process.cwd(),"drizzle/migrations")],r=s.find(l=>existsSync(F__default.join(l,"meta/_journal.json")));if(!r)throw new Error(`migrations folder not found. Searched:
12
12
  ${s.join(`
13
- `)}`);let o=d.get(n`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;o?.cnt&&(a=d.get(n`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),de(d,a),o?.cnt&&(ue(d,r,n),ce(d,r,n)),t(d,{migrationsFolder:r});let c=(d.get(n`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-a;if(c>0){let l=o?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${l} (${c} migration${c>1?"s":""} applied).`);}}function ct(d,t){It.has(t)||(_e(d),It.add(t));}var p=class extends Error{code;cause;constructor(t,n,s){super(n),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var st=sqliteTable("workspaces",{id:text("id").primaryKey(),slug:text("slug").notNull().unique(),name:text("name").notNull(),workspace_path:text("workspace_path"),description:text("description"),is_active:integer("is_active").notNull().default(1),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()});var e=sqliteTable("tasks",{id:text("id").primaryKey(),agent_id:text("agent_id").notNull(),user_id:text("user_id"),prompt:text("prompt").notNull(),mode:text("mode").notNull().default("execute"),status:text("status").notNull().default("running"),result:text("result"),error:text("error"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),metadata:text("metadata"),workspace_id:text("workspace_id"),trace_id:text("trace_id"),parent_task_id:text("parent_task_id"),caller_agent_id:text("caller_agent_id"),model:text("model"),platform:text("platform").default("cli"),crewx_version:text("crewx_version"),input_tokens:integer("input_tokens").default(0),output_tokens:integer("output_tokens").default(0),cost_usd:real("cost_usd").default(0),pid:integer("pid"),rendered_prompt:text("rendered_prompt"),command:text("command"),coding_agent_command:text("coding_agent_command"),exit_code:integer("exit_code"),logs:text("logs"),thread_id:text("thread_id"),workspace_ref:text("workspace_ref"),project_id:text("project_id"),project_ref:text("project_ref"),cached_input_tokens:integer("cached_input_tokens").default(0),run_epoch:integer("run_epoch").default(0)},d=>({idx_tasks_agent_id:index("idx_tasks_agent_id").on(d.agent_id),idx_tasks_status:index("idx_tasks_status").on(d.status),idx_tasks_started_at:index("idx_tasks_started_at").on(d.started_at),idx_tasks_trace_id:index("idx_tasks_trace_id").on(d.trace_id),idx_tasks_parent_task_id:index("idx_tasks_parent_task_id").on(d.parent_task_id),idx_tasks_crewx_version:index("idx_tasks_crewx_version").on(d.crewx_version),idx_tasks_pid:index("idx_tasks_pid").on(d.pid),idx_tasks_thread_id:index("idx_tasks_thread_id").on(d.thread_id),idx_tasks_workspace_id:index("idx_tasks_workspace_id").on(d.workspace_id),idx_tasks_workspace_ref:index("idx_tasks_workspace_ref").on(d.workspace_ref),idx_tasks_project_id:index("idx_tasks_project_id").on(d.project_id),idx_tasks_ws_started:index("idx_tasks_ws_started").on(d.workspace_id,d.started_at)}));var _=sqliteTable("threads",{id:text("id").primaryKey(),workspace_id:text("workspace_id").references(()=>st.id,{onDelete:"set null"}),platform:text("platform").notNull().default("cli"),title:text("title"),first_message:text("first_message"),last_message:text("last_message"),message_count:integer("message_count").notNull().default(0),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull(),metadata:text("metadata"),title_locked:integer("title_locked").notNull().default(0),pinned:integer("pinned").notNull().default(0),starred:integer("starred").notNull().default(0)},d=>({idx_threads_updated_at:index("idx_threads_updated_at").on(d.updated_at),idx_threads_workspace_id:index("idx_threads_workspace_id").on(d.workspace_id),idx_threads_ws_updated:index("idx_threads_ws_updated").on(d.workspace_id,d.updated_at),idx_threads_title:index("idx_threads_title").on(d.title)}));var Ee=sqliteTable("spans",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>e.id,{onDelete:"set null"}),parent_span_id:text("parent_span_id").references(()=>Ee.id,{onDelete:"set null"}),name:text("name").notNull(),kind:text("kind").notNull().default("internal"),status:text("status").notNull().default("ok"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),input:text("input"),output:text("output"),error:text("error"),attributes:text("attributes")},d=>({idx_spans_task_id:index("idx_spans_task_id").on(d.task_id),idx_spans_parent_span_id:index("idx_spans_parent_span_id").on(d.parent_span_id)}));sqliteTable("tool_calls",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>e.id,{onDelete:"cascade"}),session_id:text("session_id"),tool_name:text("tool_name").notNull(),files:text("files"),input:text("input"),output:text("output"),duration_ms:integer("duration_ms"),timestamp:text("timestamp").notNull()},d=>({idx_tool_calls_task_id:index("idx_tool_calls_task_id").on(d.task_id),idx_tool_calls_tool_name:index("idx_tool_calls_tool_name").on(d.tool_name),idx_tool_calls_timestamp:index("idx_tool_calls_timestamp").on(d.timestamp)}));sqliteTable("thread_boxes",{id:text("id").primaryKey(),thread_id:text("thread_id").notNull().references(()=>_.id,{onDelete:"cascade"}),seq:integer("seq").notNull(),first_task_id:text("first_task_id").notNull(),mid_task_id:text("mid_task_id").notNull(),last_task_id:text("last_task_id").notNull(),task_count:integer("task_count").notNull(),summary:text("summary"),source_tokens:integer("source_tokens").notNull(),summary_tokens:integer("summary_tokens"),created_at:text("created_at").notNull()},d=>({idx_thread_boxes_thread_id:index("idx_thread_boxes_thread_id").on(d.thread_id),idx_thread_boxes_seq:index("idx_thread_boxes_seq").on(d.thread_id,d.seq),uniq_thread_boxes_thread_seq:unique().on(d.thread_id,d.seq)}));sqliteTable("request_logs",{id:text("id").primaryKey(),path:text("path").notNull(),method:text("method").notNull(),status_code:integer("status_code").notNull(),duration_ms:integer("duration_ms").notNull(),ip:text("ip"),request_headers:text("request_headers"),response_headers:text("response_headers"),request_body:text("request_body"),response_body:text("response_body"),query:text("query"),user_id:text("user_id"),project_id:text("project_id"),partition_key:text("partition_key").notNull(),timestamp:text("timestamp").notNull().default(sql`(datetime('now'))`),metadata:text("metadata")},d=>({idx_request_logs_timestamp:index("idx_request_logs_timestamp").on(d.timestamp),idx_request_logs_path:index("idx_request_logs_path").on(d.path),idx_request_logs_status_code:index("idx_request_logs_status_code").on(d.status_code),idx_request_logs_partition_key:index("idx_request_logs_partition_key").on(d.partition_key)}));sqliteTable("usage_limit_snapshots",{id:text("id").primaryKey(),provider:text("provider").notNull(),account_ref:text("account_ref").notNull().default("default"),limit_window:text("limit_window").notNull(),bucket_start:text("bucket_start").notNull(),captured_at:text("captured_at").notNull(),used_percent:integer("used_percent").notNull(),remaining_percent:integer("remaining_percent").notNull(),resets_at:text("resets_at"),source:text("source").notNull(),metadata:text("metadata")},d=>({uniq_usage_limit_snapshots_bucket:uniqueIndex("uniq_usage_limit_snapshots_bucket").on(d.provider,d.account_ref,d.limit_window,d.bucket_start),idx_usage_limit_snapshots_window_bucket:index("idx_usage_limit_snapshots_window_bucket").on(d.limit_window,d.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:index("idx_usage_limit_snapshots_provider_window_bucket").on(d.provider,d.limit_window,d.bucket_start)}));sqliteTable("usage_reports",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),month:text("month").notNull(),generated_at:text("generated_at").notNull(),source_range:text("source_range").notNull(),tier:text("tier").notNull(),total_tokens:integer("total_tokens").notNull(),total_cost_usd:real("total_cost_usd").notNull(),payload:text("payload").notNull(),payload_hash:text("payload_hash"),signature:text("signature"),signed_at:text("signed_at"),issuer:text("issuer")},d=>({uniq_usage_reports_ws_month:uniqueIndex("uniq_usage_reports_ws_month").on(d.workspace_id,d.month)}));sqliteTable("notifications",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),agent_id:text("agent_id"),task_id:text("task_id"),thread_id:text("thread_id"),source:text("source").notNull().default("agent"),level:text("level").notNull().default("info"),title:text("title").notNull(),body:text("body"),target_user_id:text("target_user_id"),created_at:text("created_at").notNull(),metadata:text("metadata")},d=>({idx_notifications_ws_created:index("idx_notifications_ws_created").on(d.workspace_id,sql`${d.created_at} DESC`)}));sqliteTable("notification_reads",{notification_id:text("notification_id").notNull(),user_id:text("user_id").notNull(),read_at:text("read_at").notNull()},d=>({pk:primaryKey({columns:[d.notification_id,d.user_id]})}));sqliteTable("agent_suggestions",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),agent_id:text("agent_id").notNull(),task_id:text("task_id"),type:text("type").notNull(),status:text("status").notNull().default("pending"),payload:text("payload").notNull(),applied_commit_sha:text("applied_commit_sha"),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()},d=>({idx_agent_suggestions_ws_agent:index("idx_agent_suggestions_ws_agent").on(d.workspace_id,d.agent_id),idx_agent_suggestions_ws_created:index("idx_agent_suggestions_ws_created").on(d.workspace_id,d.created_at)}));function zt(d){let t=d.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let n=t.lastIndexOf("/");return n>=0&&(t=t.slice(n+1)),t=t.replace(/-\d{8}$/,""),t}var G="2026-05-09",ze="0.8.9-rc.13",X=10,Y=parseInt(ze.split("rc.")[1]),We=new Set(["workflow","mcp"]),Wt=600*1e3,mt=class extends nt{dbPath;pidNullObservedSince=new Map;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let n=this.resolveDbPath();if(t){let r=dirname(n);existsSync(r)||mkdirSync(r,{recursive:true});}else if(!existsSync(n))throw new p("NOT_FOUND","Database not found");let s=R(n);if(t)try{ct(s.db,n);}catch(r){throw s.close(),r}return s}startTask(t){let n=this.openHandle(true);try{n.db.insert(e).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null}).onConflictDoUpdate({target:e.id,set:{pid:sql`COALESCE(excluded.pid, ${e.pid})`},setWhere:eq(e.status,"running")}).run();}catch(s){throw s instanceof p?s:new p("DB_ERROR","Failed to start task",s)}finally{n.close();}}finishTask(t){let n=this.openHandle(true);try{let s=t.runEpoch??null;n.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
13
+ `)}`);let o=d.get(n`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),i=0;o?.cnt&&(i=d.get(n`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),le(d,i),o?.cnt&&(pe(d,r,n),ue(d,r,n)),t(d,{migrationsFolder:r});let c=(d.get(n`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 ct(d,t){Lt.has(t)||(_e(d),Lt.add(t));}var _=class extends Error{code;cause;constructor(t,n,s){super(n),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var st=sqliteTable("workspaces",{id:text("id").primaryKey(),slug:text("slug").notNull().unique(),name:text("name").notNull(),workspace_path:text("workspace_path"),description:text("description"),is_active:integer("is_active").notNull().default(1),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()});var e=sqliteTable("tasks",{id:text("id").primaryKey(),agent_id:text("agent_id").notNull(),user_id:text("user_id"),prompt:text("prompt").notNull(),mode:text("mode").notNull().default("execute"),status:text("status").notNull().default("running"),result:text("result"),error:text("error"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),metadata:text("metadata"),workspace_id:text("workspace_id"),trace_id:text("trace_id"),parent_task_id:text("parent_task_id"),caller_agent_id:text("caller_agent_id"),model:text("model"),platform:text("platform").default("cli"),crewx_version:text("crewx_version"),input_tokens:integer("input_tokens").default(0),output_tokens:integer("output_tokens").default(0),cost_usd:real("cost_usd").default(0),pid:integer("pid"),rendered_prompt:text("rendered_prompt"),command:text("command"),coding_agent_command:text("coding_agent_command"),exit_code:integer("exit_code"),logs:text("logs"),thread_id:text("thread_id"),workspace_ref:text("workspace_ref"),project_id:text("project_id"),project_ref:text("project_ref"),cached_input_tokens:integer("cached_input_tokens").default(0),run_epoch:integer("run_epoch").default(0)},d=>({idx_tasks_agent_id:index("idx_tasks_agent_id").on(d.agent_id),idx_tasks_status:index("idx_tasks_status").on(d.status),idx_tasks_started_at:index("idx_tasks_started_at").on(d.started_at),idx_tasks_trace_id:index("idx_tasks_trace_id").on(d.trace_id),idx_tasks_parent_task_id:index("idx_tasks_parent_task_id").on(d.parent_task_id),idx_tasks_crewx_version:index("idx_tasks_crewx_version").on(d.crewx_version),idx_tasks_pid:index("idx_tasks_pid").on(d.pid),idx_tasks_thread_id:index("idx_tasks_thread_id").on(d.thread_id),idx_tasks_workspace_id:index("idx_tasks_workspace_id").on(d.workspace_id),idx_tasks_workspace_ref:index("idx_tasks_workspace_ref").on(d.workspace_ref),idx_tasks_project_id:index("idx_tasks_project_id").on(d.project_id),idx_tasks_ws_started:index("idx_tasks_ws_started").on(d.workspace_id,d.started_at)}));var p=sqliteTable("threads",{id:text("id").primaryKey(),workspace_id:text("workspace_id").references(()=>st.id,{onDelete:"set null"}),platform:text("platform").notNull().default("cli"),title:text("title"),first_message:text("first_message"),last_message:text("last_message"),message_count:integer("message_count").notNull().default(0),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull(),metadata:text("metadata"),title_locked:integer("title_locked").notNull().default(0),pinned:integer("pinned").notNull().default(0),starred:integer("starred").notNull().default(0)},d=>({idx_threads_updated_at:index("idx_threads_updated_at").on(d.updated_at),idx_threads_workspace_id:index("idx_threads_workspace_id").on(d.workspace_id),idx_threads_ws_updated:index("idx_threads_ws_updated").on(d.workspace_id,d.updated_at),idx_threads_title:index("idx_threads_title").on(d.title)}));var Se=sqliteTable("spans",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>e.id,{onDelete:"set null"}),parent_span_id:text("parent_span_id").references(()=>Se.id,{onDelete:"set null"}),name:text("name").notNull(),kind:text("kind").notNull().default("internal"),status:text("status").notNull().default("ok"),started_at:text("started_at").notNull(),completed_at:text("completed_at"),duration_ms:integer("duration_ms"),input:text("input"),output:text("output"),error:text("error"),attributes:text("attributes")},d=>({idx_spans_task_id:index("idx_spans_task_id").on(d.task_id),idx_spans_parent_span_id:index("idx_spans_parent_span_id").on(d.parent_span_id)}));sqliteTable("tool_calls",{id:text("id").primaryKey(),task_id:text("task_id").references(()=>e.id,{onDelete:"cascade"}),session_id:text("session_id"),tool_name:text("tool_name").notNull(),files:text("files"),input:text("input"),output:text("output"),duration_ms:integer("duration_ms"),timestamp:text("timestamp").notNull()},d=>({idx_tool_calls_task_id:index("idx_tool_calls_task_id").on(d.task_id),idx_tool_calls_tool_name:index("idx_tool_calls_tool_name").on(d.tool_name),idx_tool_calls_timestamp:index("idx_tool_calls_timestamp").on(d.timestamp)}));sqliteTable("thread_boxes",{id:text("id").primaryKey(),thread_id:text("thread_id").notNull().references(()=>p.id,{onDelete:"cascade"}),seq:integer("seq").notNull(),first_task_id:text("first_task_id").notNull(),mid_task_id:text("mid_task_id").notNull(),last_task_id:text("last_task_id").notNull(),task_count:integer("task_count").notNull(),summary:text("summary"),source_tokens:integer("source_tokens").notNull(),summary_tokens:integer("summary_tokens"),created_at:text("created_at").notNull()},d=>({idx_thread_boxes_thread_id:index("idx_thread_boxes_thread_id").on(d.thread_id),idx_thread_boxes_seq:index("idx_thread_boxes_seq").on(d.thread_id,d.seq),uniq_thread_boxes_thread_seq:unique().on(d.thread_id,d.seq)}));sqliteTable("request_logs",{id:text("id").primaryKey(),path:text("path").notNull(),method:text("method").notNull(),status_code:integer("status_code").notNull(),duration_ms:integer("duration_ms").notNull(),ip:text("ip"),request_headers:text("request_headers"),response_headers:text("response_headers"),request_body:text("request_body"),response_body:text("response_body"),query:text("query"),user_id:text("user_id"),project_id:text("project_id"),partition_key:text("partition_key").notNull(),timestamp:text("timestamp").notNull().default(sql`(datetime('now'))`),metadata:text("metadata")},d=>({idx_request_logs_timestamp:index("idx_request_logs_timestamp").on(d.timestamp),idx_request_logs_path:index("idx_request_logs_path").on(d.path),idx_request_logs_status_code:index("idx_request_logs_status_code").on(d.status_code),idx_request_logs_partition_key:index("idx_request_logs_partition_key").on(d.partition_key)}));sqliteTable("usage_limit_snapshots",{id:text("id").primaryKey(),provider:text("provider").notNull(),account_ref:text("account_ref").notNull().default("default"),limit_window:text("limit_window").notNull(),bucket_start:text("bucket_start").notNull(),captured_at:text("captured_at").notNull(),used_percent:integer("used_percent").notNull(),remaining_percent:integer("remaining_percent").notNull(),resets_at:text("resets_at"),source:text("source").notNull(),metadata:text("metadata")},d=>({uniq_usage_limit_snapshots_bucket:uniqueIndex("uniq_usage_limit_snapshots_bucket").on(d.provider,d.account_ref,d.limit_window,d.bucket_start),idx_usage_limit_snapshots_window_bucket:index("idx_usage_limit_snapshots_window_bucket").on(d.limit_window,d.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:index("idx_usage_limit_snapshots_provider_window_bucket").on(d.provider,d.limit_window,d.bucket_start)}));sqliteTable("usage_reports",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),month:text("month").notNull(),generated_at:text("generated_at").notNull(),source_range:text("source_range").notNull(),tier:text("tier").notNull(),total_tokens:integer("total_tokens").notNull(),total_cost_usd:real("total_cost_usd").notNull(),payload:text("payload").notNull(),payload_hash:text("payload_hash"),signature:text("signature"),signed_at:text("signed_at"),issuer:text("issuer")},d=>({uniq_usage_reports_ws_month:uniqueIndex("uniq_usage_reports_ws_month").on(d.workspace_id,d.month)}));sqliteTable("notifications",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),agent_id:text("agent_id"),task_id:text("task_id"),thread_id:text("thread_id"),source:text("source").notNull().default("agent"),level:text("level").notNull().default("info"),title:text("title").notNull(),body:text("body"),target_user_id:text("target_user_id"),created_at:text("created_at").notNull(),metadata:text("metadata")},d=>({idx_notifications_ws_created:index("idx_notifications_ws_created").on(d.workspace_id,sql`${d.created_at} DESC`)}));sqliteTable("notification_reads",{notification_id:text("notification_id").notNull(),user_id:text("user_id").notNull(),read_at:text("read_at").notNull()},d=>({pk:primaryKey({columns:[d.notification_id,d.user_id]})}));sqliteTable("agent_suggestions",{id:text("id").primaryKey(),workspace_id:text("workspace_id").notNull(),agent_id:text("agent_id").notNull(),task_id:text("task_id"),type:text("type").notNull(),status:text("status").notNull().default("pending"),payload:text("payload").notNull(),applied_commit_sha:text("applied_commit_sha"),created_at:text("created_at").notNull(),updated_at:text("updated_at").notNull()},d=>({idx_agent_suggestions_ws_agent:index("idx_agent_suggestions_ws_agent").on(d.workspace_id,d.agent_id),idx_agent_suggestions_ws_created:index("idx_agent_suggestions_ws_created").on(d.workspace_id,d.created_at)}));function Wt(d){let t=d.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let n=t.lastIndexOf("/");return n>=0&&(t=t.slice(n+1)),t=t.replace(/-\d{8}$/,""),t}var G="2026-05-09",je="0.8.9-rc.13",X=10,Y=parseInt(je.split("rc.")[1]),Ke=new Set(["workflow","mcp"]),jt=600*1e3,ft=class extends nt{dbPath;pidNullObservedSince=new Map;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let n=this.resolveDbPath();if(t){let r=dirname(n);existsSync(r)||mkdirSync(r,{recursive:true});}else if(!existsSync(n))throw new _("NOT_FOUND","Database not found");let s=b(n);if(t)try{ct(s.db,n);}catch(r){throw s.close(),r}return s}startTask(t){let n=this.openHandle(true);try{n.db.insert(e).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null}).onConflictDoUpdate({target:e.id,set:{pid:sql`COALESCE(excluded.pid, ${e.pid})`},setWhere:eq(e.status,"running")}).run();}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to start task",s)}finally{n.close();}}finishTask(t){let n=this.openHandle(true);try{let s=t.runEpoch??null;n.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
14
14
  exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
15
15
  model=COALESCE(?, model)
16
- WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[t.status,t.result??null,t.error??null,t.completedAt,t.durationMs??null,t.exitCode??null,t.inputTokens??0,t.outputTokens??0,t.cachedInputTokens??0,t.costUsd??0,t.model??null,t.id,s]);}catch(s){throw s instanceof p?s:new p("DB_ERROR","Failed to finish task",s)}finally{n.close();}}appendLog(t,n){let s=this.openHandle(true);try{s.db.transaction(r=>{let o=r.select({logs:e.logs}).from(e).where(eq(e.id,t)).limit(1).get(),a=o?.logs?JSON.parse(o.logs):[];a.push(n),r.update(e).set({logs:JSON.stringify(a)}).where(eq(e.id,t)).run();},{behavior:"immediate"});}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to append log",r)}finally{s.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(e).where(eq(e.status,"running")).orderBy(desc(e.started_at)).all()}catch(n){throw new p("DB_ERROR","Failed to get running tasks",n)}finally{t.close();}}getAllTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(e).orderBy(desc(e.started_at)).limit(100).all()}catch(n){throw new p("DB_ERROR","Failed to get all tasks",n)}finally{t.close();}}getTask(t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(e).where(eq(e.id,t)).limit(1).get()??void 0}catch(s){throw new p("DB_ERROR","Failed to get task",s)}finally{n.close();}}killTask(t){if(!this.dbExists())return {killed:false};let n=this.openHandle(true);try{let s=n.db.select({id:e.id,status:e.status,pid:e.pid}).from(e).where(eq(e.id,t)).limit(1).get();if(!s||s.status!=="running")return {killed:!1};if(s.pid)try{process.kill(s.pid,"SIGTERM");}catch{}return n.db.update(e).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(and(eq(e.id,t),eq(e.status,"running"))).run(),{killed:!0,pid:s.pid??void 0}}catch(s){throw s instanceof p?s:new p("DB_ERROR","Failed to kill task",s)}finally{n.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let n=t.db.select({id:e.id,pid:e.pid,platform:e.platform,run_epoch:e.run_epoch}).from(e).where(eq(e.status,"running")).all(),s=Date.now(),r=new Set,o=0;for(let a of n){if(a.pid){let l=!1;try{process.kill(a.pid,0),l=!0;}catch{}l||(t.db.update(e).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(and(eq(e.id,a.id),eq(e.status,"running"))).run(),o++);continue}if(We.has(a.platform??"cli"))continue;let i=`${a.id}:${a.run_epoch??0}`;r.add(i);let c=this.pidNullObservedSince.get(i);if(c===void 0){this.pidNullObservedSince.set(i,s);continue}s-c>=Wt&&(t.db.update(e).set({status:"failed",error:"Reaped: pid never recorded after resume (stale running_instruction)",completed_at:new Date().toISOString()}).where(and(eq(e.id,a.id),eq(e.status,"running"))).run(),o++,this.pidNullObservedSince.delete(i));}for(let a of Array.from(this.pidNullObservedSince.keys()))r.has(a)||this.pidNullObservedSince.delete(a);return o}finally{t.close();}}reapRunningWorkflowTasks(t=Wt){if(!this.dbExists())return 0;let n=this.openHandle(true);try{let s=new Date(Date.now()-t).toISOString();return n.db.update(e).set({status:"failed",error:"Reaped: stale workflow run (finally not executed)",completed_at:new Date().toISOString()}).where(and(eq(e.status,"running"),eq(e.platform,"workflow"),isNull(e.pid),lt(e.started_at,s),or(isNull(e.metadata),notLike(e.metadata,'%"kind":"workflow_card"%')))).run().changes??0}finally{n.close();}}findTaskStatus(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=R(r);try{let a=n?eq(e.workspace_id,n):void 0,i=a?and(eq(e.id,t),a):eq(e.id,t),c=o.db.select().from(e).where(i).limit(1).get()??void 0;if(!c){let l=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),u=a?and(l,a):l;c=o.db.select().from(e).where(u).orderBy(desc(e.started_at)).limit(1).get()??void 0;}if(c)return c}catch(a){throw new p("DB_ERROR","Failed to find task status",a)}finally{o.close();}}}findChildTasks(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let a of s){if(!existsSync(a))continue;let i=R(a);try{let c=n?and(eq(e.parent_task_id,t),eq(e.workspace_id,n)):eq(e.parent_task_id,t),l=i.db.select().from(e).where(c).orderBy(asc(e.started_at)).all();for(let u of l)r.has(u.id)||(r.add(u.id),o.push(u));}catch(c){throw new p("DB_ERROR","Failed to find child tasks",c)}finally{i.close();}}return o}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(t?sql`
16
+ WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[t.status,t.result??null,t.error??null,t.completedAt,t.durationMs??null,t.exitCode??null,t.inputTokens??0,t.outputTokens??0,t.cachedInputTokens??0,t.costUsd??0,t.model??null,t.id,s]);}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to finish task",s)}finally{n.close();}}appendLog(t,n){let s=this.openHandle(true);try{s.db.transaction(r=>{let o=r.select({logs:e.logs}).from(e).where(eq(e.id,t)).limit(1).get(),i=o?.logs?JSON.parse(o.logs):[];i.push(n),r.update(e).set({logs:JSON.stringify(i)}).where(eq(e.id,t)).run();},{behavior:"immediate"});}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to append log",r)}finally{s.close();}}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(e).where(eq(e.status,"running")).orderBy(desc(e.started_at)).all()}catch(n){throw new _("DB_ERROR","Failed to get running tasks",n)}finally{t.close();}}getAllTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(e).orderBy(desc(e.started_at)).limit(100).all()}catch(n){throw new _("DB_ERROR","Failed to get all tasks",n)}finally{t.close();}}getTask(t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(e).where(eq(e.id,t)).limit(1).get()??void 0}catch(s){throw new _("DB_ERROR","Failed to get task",s)}finally{n.close();}}killTask(t){if(!this.dbExists())return {killed:false};let n=this.openHandle(true);try{let s=n.db.select({id:e.id,status:e.status,pid:e.pid}).from(e).where(eq(e.id,t)).limit(1).get();if(!s||s.status!=="running")return {killed:!1};if(s.pid)try{process.kill(s.pid,"SIGTERM");}catch{}return n.db.update(e).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(and(eq(e.id,t),eq(e.status,"running"))).run(),{killed:!0,pid:s.pid??void 0}}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to kill task",s)}finally{n.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let n=t.db.select({id:e.id,pid:e.pid,platform:e.platform,run_epoch:e.run_epoch}).from(e).where(eq(e.status,"running")).all(),s=Date.now(),r=new Set,o=0;for(let i of n){if(i.pid){let l=!1;try{process.kill(i.pid,0),l=!0;}catch{}l||(t.db.update(e).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(and(eq(e.id,i.id),eq(e.status,"running"))).run(),o++);continue}if(Ke.has(i.platform??"cli"))continue;let a=`${i.id}:${i.run_epoch??0}`;r.add(a);let c=this.pidNullObservedSince.get(a);if(c===void 0){this.pidNullObservedSince.set(a,s);continue}s-c>=jt&&(t.db.update(e).set({status:"failed",error:"Reaped: pid never recorded after resume (stale running_instruction)",completed_at:new Date().toISOString()}).where(and(eq(e.id,i.id),eq(e.status,"running"))).run(),o++,this.pidNullObservedSince.delete(a));}for(let i of Array.from(this.pidNullObservedSince.keys()))r.has(i)||this.pidNullObservedSince.delete(i);return o}finally{t.close();}}reapRunningWorkflowTasks(t=jt){if(!this.dbExists())return 0;let n=this.openHandle(true);try{let s=new Date(Date.now()-t).toISOString();return n.db.update(e).set({status:"failed",error:"Reaped: stale workflow run (finally not executed)",completed_at:new Date().toISOString()}).where(and(eq(e.status,"running"),eq(e.platform,"workflow"),isNull(e.pid),lt(e.started_at,s),or(isNull(e.metadata),notLike(e.metadata,'%"kind":"workflow_card"%')))).run().changes??0}finally{n.close();}}findTaskStatus(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=b(r);try{let i=n?eq(e.workspace_id,n):void 0,a=i?and(eq(e.id,t),i):eq(e.id,t),c=o.db.select().from(e).where(a).limit(1).get()??void 0;if(!c){let l=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),u=i?and(l,i):l;c=o.db.select().from(e).where(u).orderBy(desc(e.started_at)).limit(1).get()??void 0;}if(c)return c}catch(i){throw new _("DB_ERROR","Failed to find task status",i)}finally{o.close();}}}findChildTasks(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let i of s){if(!existsSync(i))continue;let a=b(i);try{let c=n?and(eq(e.parent_task_id,t),eq(e.workspace_id,n)):eq(e.parent_task_id,t),l=a.db.select().from(e).where(c).orderBy(asc(e.started_at)).all();for(let u of l)r.has(u.id)||(r.add(u.id),o.push(u));}catch(c){throw new _("DB_ERROR","Failed to find child tasks",c)}finally{a.close();}}return o}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.all(t?sql`
17
17
  SELECT
18
18
  COALESCE(workspace_id, 'unknown') AS workspace_id,
19
19
  COALESCE(SUM(input_tokens), 0) AS input_tokens,
@@ -34,7 +34,7 @@ ${s.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(s){throw new p("DB_ERROR","Failed to get workspace usage summary",s)}finally{n.close();}}getThreadTokenUsage(t,n){let s=this.resolveDbPaths(),r=new Set,o=0,a=0,i=0;for(let c of s){if(!existsSync(c))continue;let l=R(c);try{let u=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),h=n?and(u,eq(e.workspace_id,n)):u,f=l.db.select({id:e.id,input_tokens:e.input_tokens,output_tokens:e.output_tokens,cost_usd:e.cost_usd}).from(e).where(h).all();for(let y of f)r.has(y.id)||(r.add(y.id),o+=y.input_tokens??0,a+=y.output_tokens??0,i+=y.cost_usd??0);}catch(u){throw new p("DB_ERROR","Failed to get thread token usage",u)}finally{l.close();}}return {inputTokens:o,outputTokens:a,costUsd:i}}findTasksByThread(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let a of s){if(!existsSync(a))continue;let i=R(a);try{let c=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),l=n?and(c,eq(e.workspace_id,n)):c,u=i.db.select().from(e).where(l).orderBy(asc(e.started_at)).all();for(let h of u)r.has(h.id)||(r.add(h.id),o.push(h));}catch(c){throw new p("DB_ERROR","Failed to find tasks by thread",c)}finally{i.close();}}return o}parseWorkflowCardMetadata(t){if(!t)return {};try{let n=JSON.parse(t);return {kind:typeof n.kind=="string"?n.kind:void 0,workflowRunId:typeof n.workflowRunId=="string"?n.workflowRunId:void 0}}catch{return {}}}extractThreadIdFromCommand(t){return t?/--thread=(\S+)/.exec(t)?.[1]??null:null}findRunningWorkflowParentTasks(){if(!this.dbExists())return [];let t=[];for(let n of this.resolveDbPaths()){if(!existsSync(n))continue;let s=R(n);try{t.push(...s.db.select({id:e.id,agent_id:e.agent_id,thread_id:e.thread_id,workspace_id:e.workspace_id,platform:e.platform,status:e.status,error:e.error,completed_at:e.completed_at,duration_ms:e.duration_ms,started_at:e.started_at,metadata:e.metadata}).from(e).where(and(eq(e.platform,"workflow"),like(e.metadata,'%"kind":"workflow_card"%'))).orderBy(desc(e.started_at)).all());}catch(r){throw new p("DB_ERROR","Failed to find workflow parent tasks",r)}finally{s.close();}}return t}batchFetchWorkflowCards(t,n){let s=new Map;if(t.length===0)return s;let r=new Set(t),o=new Map,a=n?eq(e.workspace_id,n):void 0,i=(c,l)=>{if(!c)return;let u=o.get(c);if(u&&l.started_at<=u)return;let h=this.parseWorkflowCardMetadata(l.metadata);h.kind==="workflow_card"&&(o.set(c,l.started_at),s.set(c,{taskId:l.id,workflowRunId:h.workflowRunId,raw:l.result??void 0}));};for(let c of this.resolveDbPaths()){if(!existsSync(c))continue;let l=R(c);try{let u=and(inArray(e.thread_id,t),like(e.metadata,'%"kind":"workflow_card"%')),h=l.db.select({id:e.id,thread_id:e.thread_id,metadata:e.metadata,result:e.result,started_at:e.started_at}).from(e).where(a?and(u,a):u).all();for(let C of h)i(C.thread_id,C);let f=and(isNull(e.thread_id),like(e.metadata,'%"kind":"workflow_card"%')),y=l.db.select({id:e.id,command:e.command,metadata:e.metadata,result:e.result,started_at:e.started_at}).from(e).where(a?and(f,a):f).all();for(let C of y){let N=this.extractThreadIdFromCommand(C.command);!N||!r.has(N)||i(N,C);}}catch(u){throw new p("DB_ERROR","Failed to batch fetch workflow cards",u)}finally{l.close();}}return s}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let n=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(e.workspace_id,t.workspaceId));let r=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;r&&s.push(inArray(e.agent_id,r));let o=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;o&&s.push(inArray(e.status,o));let a=t.q??t.search;a&&s.push(like(e.prompt,`%${a}%`)),t.from&&s.push(gte(e.started_at,t.from)),t.to&&s.push(lt(e.started_at,t.to));let i=s.length>0?and(...s):void 0,c=n.db.select({count:sql`count(*)`}).from(e).where(i).get(),l=(t.sortDir??"DESC")==="ASC"?asc(e.started_at):desc(e.started_at);return {rows:n.db.select().from(e).where(i).orderBy(l).limit(t.limit).offset(t.offset).all(),total:c?.count??0}}catch(s){throw new p("DB_ERROR","Failed to find all tasks",s)}finally{n.close();}}getAgentUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(s?sql`
37
+ `)}catch(s){throw new _("DB_ERROR","Failed to get workspace usage summary",s)}finally{n.close();}}getThreadTokenUsage(t,n){let s=this.resolveDbPaths(),r=new Set,o=0,i=0,a=0;for(let c of s){if(!existsSync(c))continue;let l=b(c);try{let u=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),h=n?and(u,eq(e.workspace_id,n)):u,g=l.db.select({id:e.id,input_tokens:e.input_tokens,output_tokens:e.output_tokens,cost_usd:e.cost_usd}).from(e).where(h).all();for(let y of g)r.has(y.id)||(r.add(y.id),o+=y.input_tokens??0,i+=y.output_tokens??0,a+=y.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,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let i of s){if(!existsSync(i))continue;let a=b(i);try{let c=or(eq(e.thread_id,t),and(isNull(e.thread_id),like(e.command,`%--thread=${t}%`))),l=n?and(c,eq(e.workspace_id,n)):c,u=a.db.select().from(e).where(l).orderBy(asc(e.started_at)).all();for(let h of u)r.has(h.id)||(r.add(h.id),o.push(h));}catch(c){throw new _("DB_ERROR","Failed to find tasks by thread",c)}finally{a.close();}}return o}parseWorkflowCardMetadata(t){if(!t)return {};try{let n=JSON.parse(t);return {kind:typeof n.kind=="string"?n.kind:void 0,workflowRunId:typeof n.workflowRunId=="string"?n.workflowRunId:void 0}}catch{return {}}}extractThreadIdFromCommand(t){return t?/--thread=(\S+)/.exec(t)?.[1]??null:null}findRunningWorkflowParentTasks(){if(!this.dbExists())return [];let t=[];for(let n of this.resolveDbPaths()){if(!existsSync(n))continue;let s=b(n);try{t.push(...s.db.select({id:e.id,agent_id:e.agent_id,thread_id:e.thread_id,workspace_id:e.workspace_id,platform:e.platform,status:e.status,error:e.error,completed_at:e.completed_at,duration_ms:e.duration_ms,started_at:e.started_at,metadata:e.metadata}).from(e).where(and(eq(e.platform,"workflow"),like(e.metadata,'%"kind":"workflow_card"%'))).orderBy(desc(e.started_at)).all());}catch(r){throw new _("DB_ERROR","Failed to find workflow parent tasks",r)}finally{s.close();}}return t}batchFetchWorkflowCards(t,n){let s=new Map;if(t.length===0)return s;let r=new Set(t),o=new Map,i=n?eq(e.workspace_id,n):void 0,a=(c,l)=>{if(!c)return;let u=o.get(c);if(u&&l.started_at<=u)return;let h=this.parseWorkflowCardMetadata(l.metadata);h.kind==="workflow_card"&&(o.set(c,l.started_at),s.set(c,{taskId:l.id,workflowRunId:h.workflowRunId,raw:l.result??void 0}));};for(let c of this.resolveDbPaths()){if(!existsSync(c))continue;let l=b(c);try{let u=and(inArray(e.thread_id,t),like(e.metadata,'%"kind":"workflow_card"%')),h=l.db.select({id:e.id,thread_id:e.thread_id,metadata:e.metadata,result:e.result,started_at:e.started_at}).from(e).where(i?and(u,i):u).all();for(let C of h)a(C.thread_id,C);let g=and(isNull(e.thread_id),like(e.metadata,'%"kind":"workflow_card"%')),y=l.db.select({id:e.id,command:e.command,metadata:e.metadata,result:e.result,started_at:e.started_at}).from(e).where(i?and(g,i):g).all();for(let C of y){let N=this.extractThreadIdFromCommand(C.command);!N||!r.has(N)||a(N,C);}}catch(u){throw new _("DB_ERROR","Failed to batch fetch workflow cards",u)}finally{l.close();}}return s}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let n=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(e.workspace_id,t.workspaceId));let r=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;r&&s.push(inArray(e.agent_id,r));let o=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;o&&s.push(inArray(e.status,o));let i=t.q??t.search;i&&s.push(like(e.prompt,`%${i}%`)),t.from&&s.push(gte(e.started_at,t.from)),t.to&&s.push(lt(e.started_at,t.to));let a=s.length>0?and(...s):void 0,c=n.db.select({count:sql`count(*)`}).from(e).where(a).get(),l=(t.sortDir??"DESC")==="ASC"?asc(e.started_at):desc(e.started_at);return {rows:n.db.select().from(e).where(a).orderBy(l).limit(t.limit).offset(t.offset).all(),total:c?.count??0}}catch(s){throw new _("DB_ERROR","Failed to find all tasks",s)}finally{n.close();}}getAgentUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(s?sql`
38
38
  SELECT
39
39
  t.agent_id,
40
40
  t.workspace_id,
@@ -119,7 +119,7 @@ ${s.join(`
119
119
  ), 0)
120
120
  + COALESCE(SUM(t.output_tokens), 0)
121
121
  ) DESC
122
- `).map(a=>({agentId:a.agent_id,workspaceId:a.workspace_id??null,totalTasks:a.total_tasks,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd,totalTokens:a.input_tokens+a.output_tokens}))}catch(o){throw new p("DB_ERROR","Failed to get agent usage",o)}finally{r.close();}}getAgentUsageTrendRaw(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(s?sql`
122
+ `).map(i=>({agentId:i.agent_id,workspaceId:i.workspace_id??null,totalTasks:i.total_tasks,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd,totalTokens:i.input_tokens+i.output_tokens}))}catch(o){throw new _("DB_ERROR","Failed to get agent usage",o)}finally{r.close();}}getAgentUsageTrendRaw(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.all(s?sql`
123
123
  SELECT
124
124
  date(t.started_at) AS date,
125
125
  t.agent_id,
@@ -172,7 +172,7 @@ ${s.join(`
172
172
  AND t.started_at < ${n}
173
173
  GROUP BY date(t.started_at), t.agent_id
174
174
  ORDER BY date(t.started_at) ASC
175
- `).map(a=>({date:a.date,agentId:a.agent_id,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd,totalTokens:a.input_tokens+a.output_tokens}))}catch(o){throw new p("DB_ERROR","Failed to get agent usage trend",o)}finally{r.close();}}findTaskForStop(t,n){if(!this.dbExists())return;let s=this.openHandle(false);try{return s.db.select().from(e).where(and(eq(e.id,t),eq(e.workspace_id,n))).limit(1).get()??void 0}catch(r){throw new p("DB_ERROR","Failed to find task for stop",r)}finally{s.close();}}findLatestTaskByMetadata(t){if(!this.dbExists())return null;let n=this.openHandle(false);try{return n.db.select({id:e.id,thread_id:e.thread_id,status:e.status,result:e.result,error:e.error,started_at:e.started_at,completed_at:e.completed_at}).from(e).where(and(eq(e.agent_id,t.agentId),eq(e.workspace_id,t.workspaceId),sql`${e.metadata} IS NOT NULL AND json_valid(${e.metadata}) AND json_extract(${e.metadata}, '$.' || ${t.metaKey}) = ${t.metaValue}`)).orderBy(desc(e.started_at)).limit(1).get()??null}catch(s){throw new p("DB_ERROR","Failed to find latest task by metadata",s)}finally{n.close();}}markTaskFailed(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=new Date().toISOString(),a=s?and(eq(e.id,t),eq(e.status,"running"),eq(e.workspace_id,s)):and(eq(e.id,t),eq(e.status,"running"));r.db.update(e).set({status:"failed",error:n,completed_at:o}).where(a).run();}catch(o){throw o instanceof p?o:new p("DB_ERROR","Failed to mark task failed",o)}finally{r.close();}}findTasksByPromptHint(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let a of s){if(!existsSync(a))continue;let i=R(a);try{let c=n?and(like(e.prompt,`%${t}%`),eq(e.workspace_id,n)):like(e.prompt,`%${t}%`),l=i.db.select().from(e).where(c).orderBy(asc(e.started_at)).all();for(let u of l)r.has(u.id)||(r.add(u.id),o.push(u));}catch(c){throw new p("DB_ERROR","Failed to find tasks by prompt hint",c)}finally{i.close();}}return o}getProviderUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=sql`
175
+ `).map(i=>({date:i.date,agentId:i.agent_id,inputTokens:i.input_tokens,outputTokens:i.output_tokens,cachedInputTokens:i.cached_input_tokens,costUsd:i.cost_usd,totalTokens:i.input_tokens+i.output_tokens}))}catch(o){throw new _("DB_ERROR","Failed to get agent usage trend",o)}finally{r.close();}}findTaskForStop(t,n){if(!this.dbExists())return;let s=this.openHandle(false);try{return s.db.select().from(e).where(and(eq(e.id,t),eq(e.workspace_id,n))).limit(1).get()??void 0}catch(r){throw new _("DB_ERROR","Failed to find task for stop",r)}finally{s.close();}}findLatestTaskByMetadata(t){if(!this.dbExists())return null;let n=this.openHandle(false);try{return n.db.select({id:e.id,thread_id:e.thread_id,status:e.status,result:e.result,error:e.error,started_at:e.started_at,completed_at:e.completed_at}).from(e).where(and(eq(e.agent_id,t.agentId),eq(e.workspace_id,t.workspaceId),sql`${e.metadata} IS NOT NULL AND json_valid(${e.metadata}) AND json_extract(${e.metadata}, '$.' || ${t.metaKey}) = ${t.metaValue}`)).orderBy(desc(e.started_at)).limit(1).get()??null}catch(s){throw new _("DB_ERROR","Failed to find latest task by metadata",s)}finally{n.close();}}markTaskFailed(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=new Date().toISOString(),i=s?and(eq(e.id,t),eq(e.status,"running"),eq(e.workspace_id,s)):and(eq(e.id,t),eq(e.status,"running"));r.db.update(e).set({status:"failed",error:n,completed_at:o}).where(i).run();}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to mark task failed",o)}finally{r.close();}}findTasksByPromptHint(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let i of s){if(!existsSync(i))continue;let a=b(i);try{let c=n?and(like(e.prompt,`%${t}%`),eq(e.workspace_id,n)):like(e.prompt,`%${t}%`),l=a.db.select().from(e).where(c).orderBy(asc(e.started_at)).all();for(let u of l)r.has(u.id)||(r.add(u.id),o.push(u));}catch(c){throw new _("DB_ERROR","Failed to find tasks by prompt hint",c)}finally{a.close();}}return o}getProviderUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=sql`
176
176
  CASE
177
177
  WHEN ${e.model} LIKE 'claude-%' OR ${e.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
178
178
  WHEN ${e.model} LIKE 'gpt-%' OR ${e.model} LIKE 'codex-%' THEN 'codex'
@@ -182,7 +182,7 @@ ${s.join(`
182
182
  WHEN ${e.model} LIKE 'qwen%' THEN 'qwen'
183
183
  ELSE 'unknown'
184
184
  END
185
- `,a=sql`
185
+ `,i=sql`
186
186
  COALESCE(${e.input_tokens}, 0)
187
187
  + CASE
188
188
  WHEN ${e.started_at} >= ${G}
@@ -194,21 +194,21 @@ ${s.join(`
194
194
  THEN COALESCE(${e.cached_input_tokens}, 0)
195
195
  ELSE 0
196
196
  END
197
- `,i=s?sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`;return r.db.all(sql`
197
+ `,a=s?sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`;return r.db.all(sql`
198
198
  SELECT
199
199
  ${o} AS provider,
200
200
  COUNT(*) AS total_tasks,
201
- COALESCE(SUM(${a}), 0) AS input_tokens,
201
+ COALESCE(SUM(${i}), 0) AS input_tokens,
202
202
  COALESCE(SUM(${e.output_tokens}), 0) AS output_tokens,
203
203
  COALESCE(SUM(${e.cached_input_tokens}), 0) AS cached_input_tokens,
204
204
  COALESCE(SUM(${e.cost_usd}), 0) AS cost_usd,
205
205
  COALESCE(SUM(${e.duration_ms}), 0) AS active_duration_ms,
206
206
  MAX(${e.completed_at}) AS last_active_at
207
207
  FROM ${e}
208
- ${i}
208
+ ${a}
209
209
  GROUP BY provider
210
- ORDER BY (COALESCE(SUM(${a}), 0) + COALESCE(SUM(${e.output_tokens}), 0)) DESC
211
- `).map(l=>({provider:l.provider,totalTasks:l.total_tasks,inputTokens:l.input_tokens,outputTokens:l.output_tokens,cachedInputTokens:l.cached_input_tokens,costUsd:l.cost_usd,totalTokens:l.input_tokens+l.output_tokens,activeDurationMs:l.active_duration_ms??0,lastActiveAt:l.last_active_at??null}))}catch(o){throw new p("DB_ERROR","Failed to get provider usage",o)}finally{r.close();}}getModelUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=sql`
210
+ ORDER BY (COALESCE(SUM(${i}), 0) + COALESCE(SUM(${e.output_tokens}), 0)) DESC
211
+ `).map(l=>({provider:l.provider,totalTasks:l.total_tasks,inputTokens:l.input_tokens,outputTokens:l.output_tokens,cachedInputTokens:l.cached_input_tokens,costUsd:l.cost_usd,totalTokens:l.input_tokens+l.output_tokens,activeDurationMs:l.active_duration_ms??0,lastActiveAt:l.last_active_at??null}))}catch(o){throw new _("DB_ERROR","Failed to get provider usage",o)}finally{r.close();}}getModelUsage(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=sql`
212
212
  CASE
213
213
  WHEN ${e.model} LIKE 'claude-%' OR ${e.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
214
214
  WHEN ${e.model} LIKE 'gpt-%' OR ${e.model} LIKE 'codex-%' THEN 'codex'
@@ -218,7 +218,7 @@ ${s.join(`
218
218
  WHEN ${e.model} LIKE 'qwen%' THEN 'qwen'
219
219
  ELSE 'unknown'
220
220
  END
221
- `,a=sql`
221
+ `,i=sql`
222
222
  COALESCE(${e.input_tokens}, 0)
223
223
  + CASE
224
224
  WHEN ${e.started_at} >= ${G}
@@ -230,21 +230,21 @@ ${s.join(`
230
230
  THEN COALESCE(${e.cached_input_tokens}, 0)
231
231
  ELSE 0
232
232
  END
233
- `,i=s?sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`,c=r.db.all(sql`
233
+ `,a=s?sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.status} IN ('completed', 'success') AND ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`,c=r.db.all(sql`
234
234
  SELECT
235
235
  ${e.model} AS model,
236
236
  ${o} AS provider,
237
237
  COUNT(*) AS total_tasks,
238
- COALESCE(SUM(${a}), 0) AS input_tokens,
238
+ COALESCE(SUM(${i}), 0) AS input_tokens,
239
239
  COALESCE(SUM(${e.output_tokens}), 0) AS output_tokens,
240
240
  COALESCE(SUM(${e.cached_input_tokens}), 0) AS cached_input_tokens,
241
241
  COALESCE(SUM(${e.cost_usd}), 0) AS cost_usd,
242
242
  COALESCE(SUM(${e.duration_ms}), 0) AS active_duration_ms,
243
243
  MAX(${e.completed_at}) AS last_active_at
244
244
  FROM ${e}
245
- ${i}
245
+ ${a}
246
246
  GROUP BY ${e.model}
247
- `),l=new Map;for(let u of c){let h=zt(u.model??""),f=l.get(h);f?(f.totalTasks+=u.total_tasks,f.inputTokens+=u.input_tokens,f.outputTokens+=u.output_tokens,f.cachedInputTokens+=u.cached_input_tokens,f.costUsd+=u.cost_usd,f.totalTokens+=u.input_tokens+u.output_tokens,f.activeDurationMs+=u.active_duration_ms??0,u.last_active_at&&(!f.lastActiveAt||u.last_active_at>f.lastActiveAt)&&(f.lastActiveAt=u.last_active_at)):l.set(h,{model:h,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,h)=>h.costUsd-u.costUsd)}catch(o){throw new p("DB_ERROR","Failed to get model usage",o)}finally{r.close();}}getTasksForReport(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=s?sql`WHERE ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`;return r.db.all(sql`
247
+ `),l=new Map;for(let u of c){let h=Wt(u.model??""),g=l.get(h);g?(g.totalTasks+=u.total_tasks,g.inputTokens+=u.input_tokens,g.outputTokens+=u.output_tokens,g.cachedInputTokens+=u.cached_input_tokens,g.costUsd+=u.cost_usd,g.totalTokens+=u.input_tokens+u.output_tokens,g.activeDurationMs+=u.active_duration_ms??0,u.last_active_at&&(!g.lastActiveAt||u.last_active_at>g.lastActiveAt)&&(g.lastActiveAt=u.last_active_at)):l.set(h,{model:h,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,h)=>h.costUsd-u.costUsd)}catch(o){throw new _("DB_ERROR","Failed to get model usage",o)}finally{r.close();}}getTasksForReport(t,n,s){if(!this.dbExists())return [];let r=this.openHandle(false);try{let o=s?sql`WHERE ${e.started_at} >= ${t} AND ${e.started_at} < ${n} AND ${e.workspace_id} = ${s}`:sql`WHERE ${e.started_at} >= ${t} AND ${e.started_at} < ${n}`;return r.db.all(sql`
248
248
  SELECT
249
249
  ${e.thread_id} AS thread_id,
250
250
  ${e.agent_id} AS agent_id,
@@ -255,11 +255,11 @@ ${s.join(`
255
255
  FROM ${e}
256
256
  ${o}
257
257
  ORDER BY ${e.started_at} ASC
258
- `).map(i=>({threadId:i.thread_id,agentId:i.agent_id,startedAt:i.started_at,status:i.status,error:i.error,exitCode:i.exit_code}))}catch(o){throw new p("DB_ERROR","Failed to get tasks for report",o)}finally{r.close();}}findTaskEvidence(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(e.workspace_id,t.workspaceId)),t.agents&&t.agents.length>0&&s.push(inArray(e.agent_id,t.agents)),t.statuses&&t.statuses.length>0&&s.push(inArray(e.status,t.statuses)),t.from&&s.push(gte(e.started_at,t.from)),t.to&&s.push(lt(e.started_at,t.to));let r=s.length>0?and(...s):void 0,o=(t.order??"DESC")==="ASC"?asc(e.started_at):desc(e.started_at),a={id:e.id,agent_id:e.agent_id,status:e.status,prompt:e.prompt,started_at:e.started_at,completed_at:e.completed_at,thread_id:e.thread_id};return t.limit?n.db.select(a).from(e).where(r).orderBy(o).limit(t.limit).all():n.db.select(a).from(e).where(r).orderBy(o).all()}catch(s){throw new p("DB_ERROR","Failed to find task evidence",s)}finally{n.close();}}findThreadChains(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let s=t.maxThreads??8,r=t.maxTurnsPerThread??4,o=[isNotNull(e.thread_id),isNull(e.parent_task_id),isNull(e.caller_agent_id),or(isNull(e.platform),ne(e.platform,"workflow")),or(isNull(e.metadata),notLike(e.metadata,'%"kind":"workflow_card"%')),or(isNull(e.metadata),notLike(e.metadata,'%"retriedFromTaskId"%'))];t.workspaceId&&o.push(eq(e.workspace_id,t.workspaceId)),t.from&&o.push(gte(e.started_at,t.from)),t.to&&o.push(lt(e.started_at,t.to));let a=n.db.select({id:e.id,agent_id:e.agent_id,status:e.status,prompt:e.prompt,started_at:e.started_at,completed_at:e.completed_at,thread_id:e.thread_id}).from(e).where(and(...o)).orderBy(asc(e.started_at),asc(e.id)).all(),i=new Map;for(let l of a){if(!l.thread_id)continue;let u={id:l.id,agentId:l.agent_id,status:l.status,prompt:l.prompt,startedAt:l.started_at,completedAt:l.completed_at},h=i.get(l.thread_id);h?h.push(u):i.set(l.thread_id,[u]);}let c=[];for(let[l,u]of i){let h=u.filter(f=>f.agentId===t.targetAgentId).length;h<2||c.push({threadId:l,targetAgentTurnCount:h,turns:u});}return c.sort((l,u)=>{let h=l.turns[l.turns.length-1].startedAt,f=u.turns[u.turns.length-1].startedAt;return h<f?1:h>f?-1:0}),c.slice(0,s).map(l=>({threadId:l.threadId,targetAgentTurnCount:l.targetAgentTurnCount,turns:l.turns.slice(-r)}))}catch(s){throw new p("DB_ERROR","Failed to find thread chains",s)}finally{n.close();}}};var xt=class extends K{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=join(t?.dbRoot??homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let n=new mt({dbPath:this.dbPath}),s=process.cwd(),o=existsSync(join(s,"crewx.yaml"))||existsSync(join(s,"crewx.yml"))?$t(s):null,a=process.argv.join(" ");this.unsubs.push(t.on("task:start",i=>{try{let c=i.callerAgentId??null,l=i.parentTaskId??null,u=i.rootTraceId??i.traceId,h=i.metadata?JSON.stringify(i.metadata):JSON.stringify({provider:i.provider??"cli/claude"});n.startTask({id:i.traceId,agentId:i.agentRef.replace(/^@/,""),prompt:i.message,mode:i.mode,status:"running",pid:i.pid??null,startedAt:i.timestamp.toISOString(),crewxVersion:this.version,platform:i.platform??"cli",model:i.model??null,renderedPrompt:i.renderedPrompt??null,command:a,codingAgentCommand:i.codingAgentCommand??null,workspaceId:i.workspaceId??o,callerAgentId:c,parentTaskId:l,traceId:u,metadata:h,threadId:i.threadId??null});}catch{}}),t.on("task:output",i=>{try{n.appendLog(i.traceId,{timestamp:i.timestamp.toISOString(),level:i.level??"stdout",message:i.output});}catch{}}),t.on("task:end",i=>{try{let c=typeof i.metadata?.runEpoch=="number"?i.metadata.runEpoch:null,l=i.error?JSON.stringify({code:i.error.code,message:i.error.message,...i.error.providerCode?{providerCode:i.error.providerCode}:{}}):null;n.finishTask({id:i.traceId,status:i.error?"failed":"success",result:i.result??null,error:l,completedAt:i.timestamp.toISOString(),durationMs:i.durationMs,exitCode:i.exitCode??null,inputTokens:i.inputTokens??0,outputTokens:i.outputTokens??0,cachedInputTokens:i.cachedInputTokens??0,costUsd:i.costUsd??0,model:i.model??null,runEpoch:c});}catch{}}));}detach(t){this.unsubs.forEach(n=>n()),this.unsubs=[];}};var gt=class extends nt{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let n=this.resolveDbPath();if(t){let r=dirname(n);existsSync(r)||mkdirSync(r,{recursive:true});}else if(!existsSync(n))throw new p("NOT_FOUND","Database not found");let s=R(n);if(t)try{ct(s.db,n);}catch(r){throw s.close(),r}return s}validateWorkspaceId(t,n){return t.db.select({id:st.id}).from(st).where(eq(st.id,n)).limit(1).get()?n:null}topLevelTaskPredicateSql(t="child"){return sql.raw(`NOT EXISTS (
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{r.close();}}findTaskEvidence(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let s=[];t.workspaceId&&s.push(eq(e.workspace_id,t.workspaceId)),t.agents&&t.agents.length>0&&s.push(inArray(e.agent_id,t.agents)),t.statuses&&t.statuses.length>0&&s.push(inArray(e.status,t.statuses)),t.from&&s.push(gte(e.started_at,t.from)),t.to&&s.push(lt(e.started_at,t.to));let r=s.length>0?and(...s):void 0,o=(t.order??"DESC")==="ASC"?asc(e.started_at):desc(e.started_at),i={id:e.id,agent_id:e.agent_id,status:e.status,prompt:e.prompt,started_at:e.started_at,completed_at:e.completed_at,thread_id:e.thread_id};return t.limit?n.db.select(i).from(e).where(r).orderBy(o).limit(t.limit).all():n.db.select(i).from(e).where(r).orderBy(o).all()}catch(s){throw new _("DB_ERROR","Failed to find task evidence",s)}finally{n.close();}}findThreadChains(t){if(!this.dbExists())return [];let n=this.openHandle(false);try{let s=t.maxThreads??8,r=t.maxTurnsPerThread??4,o=[isNotNull(e.thread_id),isNull(e.parent_task_id),isNull(e.caller_agent_id),or(isNull(e.platform),ne(e.platform,"workflow")),or(isNull(e.metadata),notLike(e.metadata,'%"kind":"workflow_card"%')),or(isNull(e.metadata),notLike(e.metadata,'%"retriedFromTaskId"%'))];t.workspaceId&&o.push(eq(e.workspace_id,t.workspaceId)),t.from&&o.push(gte(e.started_at,t.from)),t.to&&o.push(lt(e.started_at,t.to));let i=n.db.select({id:e.id,agent_id:e.agent_id,status:e.status,prompt:e.prompt,started_at:e.started_at,completed_at:e.completed_at,thread_id:e.thread_id}).from(e).where(and(...o)).orderBy(asc(e.started_at),asc(e.id)).all(),a=new Map;for(let l of i){if(!l.thread_id)continue;let u={id:l.id,agentId:l.agent_id,status:l.status,prompt:l.prompt,startedAt:l.started_at,completedAt:l.completed_at},h=a.get(l.thread_id);h?h.push(u):a.set(l.thread_id,[u]);}let c=[];for(let[l,u]of a){let h=u.filter(g=>g.agentId===t.targetAgentId).length;h<2||c.push({threadId:l,targetAgentTurnCount:h,turns:u});}return c.sort((l,u)=>{let h=l.turns[l.turns.length-1].startedAt,g=u.turns[u.turns.length-1].startedAt;return h<g?1:h>g?-1:0}),c.slice(0,s).map(l=>({threadId:l.threadId,targetAgentTurnCount:l.targetAgentTurnCount,turns:l.turns.slice(-r)}))}catch(s){throw new _("DB_ERROR","Failed to find thread chains",s)}finally{n.close();}}};var At=class extends j{name="sqlite-tracing";unsubs=[];dbPath;version;constructor(t){super(),this.dbPath=join(t?.dbRoot??homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let n=new ft({dbPath:this.dbPath}),s=process.cwd(),o=existsSync(join(s,"crewx.yaml"))||existsSync(join(s,"crewx.yml"))?$t(s):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,h=a.metadata?JSON.stringify(a.metadata):JSON.stringify({provider:a.provider??"cli/claude"});n.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:h,threadId:a.threadId??null});}catch{}}),t.on("task:output",a=>{try{n.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,l=a.error?JSON.stringify({code:a.error.code,message:a.error.message,...a.error.providerCode?{providerCode:a.error.providerCode}:{}}):null;n.finishTask({id:a.traceId,status:a.error?"failed":"success",result:a.result??null,error:l,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(n=>n()),this.unsubs=[];}};var mt=class extends nt{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let n=this.resolveDbPath();if(t){let r=dirname(n);existsSync(r)||mkdirSync(r,{recursive:true});}else if(!existsSync(n))throw new _("NOT_FOUND","Database not found");let s=b(n);if(t)try{ct(s.db,n);}catch(r){throw s.close(),r}return s}validateWorkspaceId(t,n){return t.db.select({id:st.id}).from(st).where(eq(st.id,n)).limit(1).get()?n:null}topLevelTaskPredicateSql(t="child"){return 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 n=this.resolveDbPaths(),s=new Set,r=[];for(let o of n){if(!existsSync(o))continue;let a=R(o);try{let i=t?eq(_.workspace_id,t):void 0,c=a.db.select().from(_).where(i).orderBy(desc(_.updated_at)).all();for(let l of c)s.has(l.id)||(s.add(l.id),r.push(l));}catch(i){throw new p("DB_ERROR","Failed to find all threads",i)}finally{a.close();}}return r}findThreadsByIdsOrTitles(t,n){if(t.length===0)return [];let s=this.resolveDbPaths(),r=new Set,o=[];for(let a of s){if(!existsSync(a))continue;let i=R(a);try{let c=or(inArray(_.id,t),inArray(_.title,t)),l=n?and(c,eq(_.workspace_id,n)):c,u=i.db.select().from(_).where(l).orderBy(desc(_.updated_at)).all();for(let h of u)r.has(h.id)||(r.add(h.id),o.push(h));}catch(c){throw new p("DB_ERROR","Failed to find threads by ids or titles",c)}finally{i.close();}}return o}findThreadById(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=R(r);try{let a=eq(_.id,t),i=n?and(a,eq(_.workspace_id,n)):a,c=o.db.select().from(_).where(i).limit(1).get()??void 0;if(c)return c}catch(a){throw new p("DB_ERROR","Failed to find thread by id",a)}finally{o.close();}}}threadExists(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=R(r);try{let a=eq(_.id,t),i=n?and(a,eq(_.workspace_id,n)):a;if(o.db.select({id:_.id}).from(_).where(i).limit(1).get())return !0}catch(a){throw new p("DB_ERROR","Failed to check thread existence",a)}finally{o.close();}}return false}aggregateTaskStats(t,n){let s=this.resolveDbPaths(),r=0,o=0,a=0,i=0,c=0,l=new Set;for(let u of s){if(!existsSync(u))continue;let h=R(u);try{let f=h.db.get(sql`
262
+ )`)}findAllThreads(t){let n=this.resolveDbPaths(),s=new Set,r=[];for(let o of n){if(!existsSync(o))continue;let i=b(o);try{let a=t?eq(p.workspace_id,t):void 0,c=i.db.select().from(p).where(a).orderBy(desc(p.updated_at)).all();for(let l of c)s.has(l.id)||(s.add(l.id),r.push(l));}catch(a){throw new _("DB_ERROR","Failed to find all threads",a)}finally{i.close();}}return r}findThreadsByIdsOrTitles(t,n){if(t.length===0)return [];let s=this.resolveDbPaths(),r=new Set,o=[];for(let i of s){if(!existsSync(i))continue;let a=b(i);try{let c=or(inArray(p.id,t),inArray(p.title,t)),l=n?and(c,eq(p.workspace_id,n)):c,u=a.db.select().from(p).where(l).orderBy(desc(p.updated_at)).all();for(let h of u)r.has(h.id)||(r.add(h.id),o.push(h));}catch(c){throw new _("DB_ERROR","Failed to find threads by ids or titles",c)}finally{a.close();}}return o}findThreadById(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=b(r);try{let i=eq(p.id,t),a=n?and(i,eq(p.workspace_id,n)):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,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=b(r);try{let i=eq(p.id,t),a=n?and(i,eq(p.workspace_id,n)):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,n){let s=this.resolveDbPaths(),r=0,o=0,i=0,a=0,c=0,l=new Set;for(let u of s){if(!existsSync(u))continue;let h=b(u);try{let g=h.db.get(sql`
263
263
  SELECT
264
264
  count(*) AS cnt,
265
265
  COALESCE(SUM(child.input_tokens), 0) AS total_input,
@@ -270,13 +270,13 @@ ${s.join(`
270
270
  WHERE child.thread_id = ${t}
271
271
  AND ${this.topLevelTaskPredicateSql()}
272
272
  ${n?sql`AND child.workspace_id = ${n}`:sql``}
273
- `);f&&(r+=f.cnt,o+=f.total_input,a+=f.total_output,i+=f.total_cached,c+=f.total_cost);let y=h.db.all(sql`
273
+ `);g&&(r+=g.cnt,o+=g.total_input,i+=g.total_output,a+=g.total_cached,c+=g.total_cost);let y=h.db.all(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
  ${n?sql`AND child.workspace_id = ${n}`:sql``}
279
- `);for(let C of y)l.add(C.agent_id);}catch(f){throw new p("DB_ERROR","Failed to aggregate task stats",f)}finally{h.close();}}return {taskCount:r,inputTokens:o,outputTokens:a,cachedInputTokens:i,costUsd:c,agentIds:Array.from(l)}}findTopLevelTasks(t,n,s){let r=this.resolveDbPaths(),o=new Set,a=[];for(let i of r){if(!existsSync(i))continue;let c=R(i);try{let l;s!==void 0?l=c.db.all(sql`
279
+ `);for(let C of y)l.add(C.agent_id);}catch(g){throw new _("DB_ERROR","Failed to aggregate task stats",g)}finally{h.close();}}return {taskCount:r,inputTokens:o,outputTokens:i,cachedInputTokens:a,costUsd:c,agentIds:Array.from(l)}}findTopLevelTasks(t,n,s){let r=this.resolveDbPaths(),o=new Set,i=[];for(let a of r){if(!existsSync(a))continue;let c=b(a);try{let l;s!==void 0?l=c.db.all(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,7 +293,7 @@ ${s.join(`
293
293
  AND ${this.topLevelTaskPredicateSql()}
294
294
  ${n?sql`AND child.workspace_id = ${n}`:sql``}
295
295
  ORDER BY child.started_at ASC
296
- `);for(let u of l)o.has(u.id)||(o.add(u.id),a.push(u));}catch(l){throw new p("DB_ERROR","Failed to find top-level tasks",l)}finally{c.close();}}if(s!==void 0&&r.length>1){let i=new Map;for(let c of a){let l=c.agent_id??"";i.has(l)||i.set(l,[]),i.get(l).push(c);}a=[];for(let c of i.values())c.sort((l,u)=>(u.started_at??"").localeCompare(l.started_at??"")),a.push(...c.slice(0,s));a.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return a}findAllTasks(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let a of s){if(!existsSync(a))continue;let i=R(a);try{let c=eq(e.thread_id,t),l=n?and(c,eq(e.workspace_id,n)):c,u=i.db.select().from(e).where(l).orderBy(asc(e.started_at)).all();for(let h of u)r.has(h.id)||(r.add(h.id),o.push(h));}catch(c){throw new p("DB_ERROR","Failed to find all tasks for thread",c)}finally{i.close();}}return o}findTaskById(t,n,s){let r=this.resolveDbPaths();for(let o of r){if(!existsSync(o))continue;let a=R(o);try{let i=and(eq(e.id,n),eq(e.thread_id,t)),c=s?and(i,eq(e.workspace_id,s)):i,l=a.db.select().from(e).where(c).limit(1).get();if(!l)continue;let u=a.db.select().from(e).where(eq(e.parent_task_id,l.id)).orderBy(asc(e.started_at)).all();return {task:l,children:u}}catch(i){throw new p("DB_ERROR","Failed to find task by id",i)}finally{a.close();}}}batchFetchTasksQuery(t,n){return sql`
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(s!==void 0&&r.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,s));i.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return i}findAllTasks(t,n){let s=this.resolveDbPaths(),r=new Set,o=[];for(let i of s){if(!existsSync(i))continue;let a=b(i);try{let c=eq(e.thread_id,t),l=n?and(c,eq(e.workspace_id,n)):c,u=a.db.select().from(e).where(l).orderBy(asc(e.started_at)).all();for(let h of u)r.has(h.id)||(r.add(h.id),o.push(h));}catch(c){throw new _("DB_ERROR","Failed to find all tasks for thread",c)}finally{a.close();}}return o}findTaskById(t,n,s){let r=this.resolveDbPaths();for(let o of r){if(!existsSync(o))continue;let i=b(o);try{let a=and(eq(e.id,n),eq(e.thread_id,t)),c=s?and(a,eq(e.workspace_id,s)):a,l=i.db.select().from(e).where(c).limit(1).get();if(!l)continue;let u=i.db.select().from(e).where(eq(e.parent_task_id,l.id)).orderBy(asc(e.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,n){return sql`
297
297
  SELECT child.id, child.thread_id, child.agent_id, child.status,
298
298
  child.parent_task_id, child.started_at, child.completed_at,
299
299
  child.duration_ms, child.input_tokens, child.output_tokens,
@@ -303,7 +303,7 @@ ${s.join(`
303
303
  AND ${this.topLevelTaskPredicateSql()}
304
304
  ${n?sql`AND child.workspace_id = ${n}`:sql``}
305
305
  ORDER BY child.started_at ASC
306
- `}batchFetchTasks(t,n){let s=new Map;if(t.length===0)return s;let r=this.resolveDbPaths();for(let o of r){if(!existsSync(o))continue;let a=R(o);try{let i=a.db.all(this.batchFetchTasksQuery(t,n));for(let c of i){let l=c.thread_id;s.has(l)||s.set(l,[]),s.get(l).push(c);}}catch(i){throw new p("DB_ERROR","Failed to batch fetch tasks",i)}finally{a.close();}}return s}explainBatchFetchTasksPlan(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=R(r);try{return o.db.all(sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(t,n)}`).map(i=>i.detail)}finally{o.close();}}return []}updateThreadTitle(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=eq(_.id,t),a=s?and(o,eq(_.workspace_id,s)):o;if(!r.db.select({id:_.id}).from(_).where(a).limit(1).get())return;r.db.update(_).set({title:n,title_locked:1,updated_at:new Date().toISOString()}).where(eq(_.id,t)).run();}catch(o){throw o instanceof p?o:new p("DB_ERROR","Failed to update thread title",o)}finally{r.close();}}upsertThread(t,n){let s=this.openHandle(true);try{let r=n.workspaceId?this.validateWorkspaceId(s,n.workspaceId):null,o=new Date().toISOString();if(s.db.select({id:_.id,message_count:_.message_count}).from(_).where(eq(_.id,t)).limit(1).get()){let i={updated_at:o};n.title!==void 0&&(i.title=n.title),n.titleLocked!==void 0&&(i.title_locked=n.titleLocked?1:0),s.db.update(_).set(i).where(eq(_.id,t)).run();}else s.db.insert(_).values({id:t,platform:n.platform,workspace_id:r,title:n.title??null,title_locked:n.titleLocked?1:0,message_count:0,created_at:o,updated_at:o}).run();}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to upsert thread",r)}finally{s.close();}}ensureThread(t,n,s){let r=this.openHandle(true);try{let o=s?this.validateWorkspaceId(r,s):null,a=r.db.select({id:_.id,platform:_.platform,workspace_id:_.workspace_id}).from(_).where(eq(_.id,t)).limit(1).get();if(a){o&&!a.workspace_id&&r.db.update(_).set({workspace_id:o}).where(eq(_.id,t)).run();return}let i=new Date().toISOString();r.db.insert(_).values({id:t,platform:n,workspace_id:o,message_count:0,created_at:i,updated_at:i}).run();}catch(o){throw o instanceof p?o:new p("DB_ERROR","Failed to ensure thread",o)}finally{r.close();}}saveUserMessage(t,n,s){if(!this.dbExists())return {firstMessage:false};let r=this.openHandle(true);try{let o=new Date().toISOString();return {firstMessage:r.db.transaction(i=>{let l=i.select({message_count:_.message_count}).from(_).where(eq(_.id,t)).limit(1).get()?.message_count===0;return i.run(sql`
306
+ `}batchFetchTasks(t,n){let s=new Map;if(t.length===0)return s;let r=this.resolveDbPaths();for(let o of r){if(!existsSync(o))continue;let i=b(o);try{let a=i.db.all(this.batchFetchTasksQuery(t,n));for(let c of a){let l=c.thread_id;s.has(l)||s.set(l,[]),s.get(l).push(c);}}catch(a){throw new _("DB_ERROR","Failed to batch fetch tasks",a)}finally{i.close();}}return s}explainBatchFetchTasksPlan(t,n){let s=this.resolveDbPaths();for(let r of s){if(!existsSync(r))continue;let o=b(r);try{return o.db.all(sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(t,n)}`).map(a=>a.detail)}finally{o.close();}}return []}updateThreadTitle(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=eq(p.id,t),i=s?and(o,eq(p.workspace_id,s)):o;if(!r.db.select({id:p.id}).from(p).where(i).limit(1).get())return;r.db.update(p).set({title:n,title_locked:1,updated_at:new Date().toISOString()}).where(eq(p.id,t)).run();}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to update thread title",o)}finally{r.close();}}upsertThread(t,n){let s=this.openHandle(true);try{let r=n.workspaceId?this.validateWorkspaceId(s,n.workspaceId):null,o=new Date().toISOString();if(s.db.select({id:p.id,message_count:p.message_count}).from(p).where(eq(p.id,t)).limit(1).get()){let a={updated_at:o};n.title!==void 0&&(a.title=n.title),n.titleLocked!==void 0&&(a.title_locked=n.titleLocked?1:0),s.db.update(p).set(a).where(eq(p.id,t)).run();}else s.db.insert(p).values({id:t,platform:n.platform,workspace_id:r,title:n.title??null,title_locked:n.titleLocked?1:0,message_count:0,created_at:o,updated_at:o}).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to upsert thread",r)}finally{s.close();}}ensureThread(t,n,s){let r=this.openHandle(true);try{let o=s?this.validateWorkspaceId(r,s):null,i=r.db.select({id:p.id,platform:p.platform,workspace_id:p.workspace_id}).from(p).where(eq(p.id,t)).limit(1).get();if(i){o&&!i.workspace_id&&r.db.update(p).set({workspace_id:o}).where(eq(p.id,t)).run();return}let a=new Date().toISOString();r.db.insert(p).values({id:t,platform:n,workspace_id:o,message_count:0,created_at:a,updated_at:a}).run();}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to ensure thread",o)}finally{r.close();}}saveUserMessage(t,n,s){if(!this.dbExists())return {firstMessage:false};let r=this.openHandle(true);try{let o=new Date().toISOString();return {firstMessage:r.db.transaction(a=>{let l=a.select({message_count:p.message_count}).from(p).where(eq(p.id,t)).limit(1).get()?.message_count===0;return a.run(sql`
307
307
  UPDATE threads
308
308
  SET first_message = COALESCE(first_message, ${n}),
309
309
  title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${n}, 1, 60) ELSE title END,
@@ -311,8 +311,8 @@ ${s.join(`
311
311
  message_count = message_count + 1,
312
312
  updated_at = ${o}
313
313
  WHERE id = ${t}
314
- `),l},{behavior:"immediate"})}}catch(o){throw o instanceof p?o:new p("DB_ERROR","Failed to save user message",o)}finally{r.close();}}saveAssistantMessage(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=new Date().toISOString();r.db.update(_).set({last_message:n,updated_at:o}).where(eq(_.id,t)).run();}catch(o){throw o instanceof p?o:new p("DB_ERROR","Failed to save assistant message",o)}finally{r.close();}}updateThread(t,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let r={updated_at:new Date().toISOString()};n.title!==void 0&&(r.title=n.title,r.title_locked=1),n.titleLocked!==void 0&&(r.title_locked=n.titleLocked?1:0),s.db.update(_).set(r).where(eq(_.id,t)).run();}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to update thread",r)}finally{s.close();}}togglePin(t,n){let s=this.openHandle(true);try{let r=n?and(eq(_.id,t),eq(_.workspace_id,n)):eq(_.id,t),o=s.db.select({pinned:_.pinned,metadata:_.metadata}).from(_).where(r).get();if(!o)return null;let a=o.pinned?0:1,i=o.metadata?JSON.parse(o.metadata):{};if(a){let c=n?and(eq(_.pinned,1),eq(_.workspace_id,n)):eq(_.pinned,1),l=s.db.select({metadata:_.metadata}).from(_).where(c).all(),u=null;for(let h of l){let f=h.metadata?JSON.parse(h.metadata):{};typeof f.pinOrder=="number"&&(u===null||f.pinOrder<u)&&(u=f.pinOrder);}i.pinOrder=u===null?0:u-1;}else delete i.pinOrder;return s.db.update(_).set({pinned:a,metadata:Object.keys(i).length>0?JSON.stringify(i):null}).where(r).run(),{pinned:!!a}}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to toggle pin",r)}finally{s.close();}}reorderPins(t,n){let s=this.openHandle(true);try{for(let r=0;r<t.length;r++){let o=n?and(eq(_.id,t[r]),eq(_.workspace_id,n)):eq(_.id,t[r]),a=s.db.select({metadata:_.metadata}).from(_).where(o).get();if(!a)continue;let i=a.metadata?JSON.parse(a.metadata):{};i.pinOrder=r+1,s.db.update(_).set({metadata:JSON.stringify(i)}).where(o).run();}}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to reorder pins",r)}finally{s.close();}}toggleStar(t,n){let s=this.openHandle(true);try{let r=n?and(eq(_.id,t),eq(_.workspace_id,n)):eq(_.id,t),o=s.db.select({starred:_.starred}).from(_).where(r).get();if(!o)return null;let a=o.starred?0:1;return s.db.update(_).set({starred:a}).where(r).run(),{starred:!!a}}catch(r){throw r instanceof p?r:new p("DB_ERROR","Failed to toggle star",r)}finally{s.close();}}resolveOverdriveForRequest(t,n,s,r){let a=this.openHandle(true);try{let i=n?and(eq(_.id,t),eq(_.workspace_id,n)):eq(_.id,t);return a.db.transaction(l=>{let u=l.select({metadata:_.metadata}).from(_).where(i).get();if(!u)return null;let h=u.metadata?JSON.parse(u.metadata):{},f=h.overdrive??{},y=r?.defaultTurns??f.defaultTurns??3,C=r?.updatedBy??"ui",N=new Date().toISOString(),I,M,B,rt;switch(s){case "enable-count":{let ot=r?.turns??y,at=r?.consumeCurrent?Math.max(ot-1,0):ot;I=at>0?"count":"off",M=at,B=!0,rt="count";break}case "enable-latch":{I="latch",M=0,B=!0,rt="latch";break}case "disable":{I="off",M=0,B=!1;break}default:{let ot=f.state??"off",at=typeof f.remaining=="number"?f.remaining:0;if(ot==="count"&&at>0){let Ct=at-1;Ct<=0?(I="off",M=0):(I="count",M=Ct),B=!0,rt="count";}else ot==="latch"?(I="latch",M=0,B=!0,rt="latch"):(I="off",M=0,B=!1);break}}return h.overdrive={state:I,remaining:M,defaultTurns:y,updatedAt:N,updatedBy:C},l.update(_).set({metadata:JSON.stringify(h),updated_at:N}).where(i).run(),{applied:B,appliedMode:rt,state:I,remaining:M}},{behavior:"immediate"})}catch(i){throw i instanceof p?i:new p("DB_ERROR","Failed to resolve overdrive",i)}finally{a.close();}}};function Qe(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
314
+ `),l},{behavior:"immediate"})}}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to save user message",o)}finally{r.close();}}saveAssistantMessage(t,n,s){if(!this.dbExists())return;let r=this.openHandle(true);try{let o=new Date().toISOString();r.db.update(p).set({last_message:n,updated_at:o}).where(eq(p.id,t)).run();}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to save assistant message",o)}finally{r.close();}}updateThread(t,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let r={updated_at:new Date().toISOString()};n.title!==void 0&&(r.title=n.title,r.title_locked=1),n.titleLocked!==void 0&&(r.title_locked=n.titleLocked?1:0),s.db.update(p).set(r).where(eq(p.id,t)).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to update thread",r)}finally{s.close();}}togglePin(t,n){let s=this.openHandle(true);try{let r=n?and(eq(p.id,t),eq(p.workspace_id,n)):eq(p.id,t),o=s.db.select({pinned:p.pinned,metadata:p.metadata}).from(p).where(r).get();if(!o)return null;let i=o.pinned?0:1,a=o.metadata?JSON.parse(o.metadata):{};if(i){let c=n?and(eq(p.pinned,1),eq(p.workspace_id,n)):eq(p.pinned,1),l=s.db.select({metadata:p.metadata}).from(p).where(c).all(),u=null;for(let h of l){let g=h.metadata?JSON.parse(h.metadata):{};typeof g.pinOrder=="number"&&(u===null||g.pinOrder<u)&&(u=g.pinOrder);}a.pinOrder=u===null?0:u-1;}else delete a.pinOrder;return s.db.update(p).set({pinned:i,metadata:Object.keys(a).length>0?JSON.stringify(a):null}).where(r).run(),{pinned:!!i}}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to toggle pin",r)}finally{s.close();}}reorderPins(t,n){let s=this.openHandle(true);try{for(let r=0;r<t.length;r++){let o=n?and(eq(p.id,t[r]),eq(p.workspace_id,n)):eq(p.id,t[r]),i=s.db.select({metadata:p.metadata}).from(p).where(o).get();if(!i)continue;let a=i.metadata?JSON.parse(i.metadata):{};a.pinOrder=r+1,s.db.update(p).set({metadata:JSON.stringify(a)}).where(o).run();}}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to reorder pins",r)}finally{s.close();}}toggleStar(t,n){let s=this.openHandle(true);try{let r=n?and(eq(p.id,t),eq(p.workspace_id,n)):eq(p.id,t),o=s.db.select({starred:p.starred}).from(p).where(r).get();if(!o)return null;let i=o.starred?0:1;return s.db.update(p).set({starred:i}).where(r).run(),{starred:!!i}}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to toggle star",r)}finally{s.close();}}resolveOverdriveForRequest(t,n,s,r){let i=this.openHandle(true);try{let a=n?and(eq(p.id,t),eq(p.workspace_id,n)):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 h=u.metadata?JSON.parse(u.metadata):{},g=h.overdrive??{},y=r?.defaultTurns??g.defaultTurns??3,C=r?.updatedBy??"ui",N=new Date().toISOString(),$,M,B,rt;switch(s){case "enable-count":{let ot=r?.turns??y,it=r?.consumeCurrent?Math.max(ot-1,0):ot;$=it>0?"count":"off",M=it,B=!0,rt="count";break}case "enable-latch":{$="latch",M=0,B=!0,rt="latch";break}case "disable":{$="off",M=0,B=!1;break}default:{let ot=g.state??"off",it=typeof g.remaining=="number"?g.remaining:0;if(ot==="count"&&it>0){let Nt=it-1;Nt<=0?($="off",M=0):($="count",M=Nt),B=!0,rt="count";}else ot==="latch"?($="latch",M=0,B=!0,rt="latch"):($="off",M=0,B=!1);break}}return h.overdrive={state:$,remaining:M,defaultTurns:y,updatedAt:N,updatedBy:C},l.update(p).set({metadata:JSON.stringify(h),updated_at:N}).where(a).run(),{applied:B,appliedMode:rt,state:$,remaining:M}},{behavior:"immediate"})}catch(a){throw a instanceof _?a:new _("DB_ERROR","Failed to resolve overdrive",a)}finally{i.close();}}};function tn(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
315
315
  `).filter(r=>!(r.startsWith("Loaded ")&&r.includes("layouts from")||r.includes("[dotenv@")||r.includes("[Nest]")&&r.includes("DEBUG")||r.startsWith("Registered custom layout:")||r.startsWith("Updated custom layout:"))).join(`
316
- `).trim()}function Ze(d){if(!d)return "";let t=d;try{let n=JSON.parse(t);Array.isArray(n)?t=n.filter(s=>s?.type==="text"&&s?.text).map(s=>s.text).join(`
317
- `):n&&typeof n=="object"&&n.result!==void 0&&(t=n.result||"");}catch{t=Qe(t);}return t}var kt=class{dbPath;constructor(t){this.dbPath=t??join(homedir(),".crewx","crewx.db");}getThreadRepo(){return new gt({dbPath:this.dbPath})}updateThread(t,n){this.getThreadRepo().updateThread(t,{title:n.title});}async ensureThread(t,n,s){let r=this.getThreadRepo(),o=r.findThreadById(t);if(o){if(o.platform!==n)throw new Error(`Thread '${t}' already exists with platform '${o.platform}' \u2014 cannot change to '${n}' (platform is immutable)`);return {created:false}}return r.ensureThread(t,n,s),{created:true}}async fetchHistory(t,n){let s=n?.limit??100,r=this.getThreadRepo(),o=r.findThreadById(t),a=r.findTopLevelTasks(t,void 0,s),i=new Set(["queued","cancelled"]);a=a.filter(u=>(!u.status||!i.has(u.status))&&(!n?.currentTraceId||u.trace_id!==n.currentTraceId));let c=o?.platform??"cli",l=this.rowsToMessages(a);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,n,s,r){let{firstMessage:o}=this.getThreadRepo().saveUserMessage(t,n);return {id:t,firstMessage:o}}async saveAssistantMessage(t,n,s,r){return this.getThreadRepo().saveAssistantMessage(t,n),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let n=[];for(let s of t){s.prompt&&n.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime(),metadata:{caller_agent_id:s.caller_agent_id}});let r=Ze(s.result),o=this.normalizeStatus(s.status);if(r||o==="running"||o==="failed"){let a={agent_id:s.agent_id,task_id:s.id};o&&(a.status=o),o==="failed"&&s.error&&(a.reason=s.error.split(`
318
- `)[0].slice(0,200)),n.push({id:`${s.id}-assistant`,text:r,isAssistant:true,timestamp:new Date(s.started_at).getTime(),metadata:a});}}return n}};var At=class extends K{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new kt(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,n,s,r){}async afterAssistantMessage(t,n,s){}attach(t){this.unsubStart=t.on("task:start",async n=>{if(!n.threadId)return;let s=n.platform??"cli";try{let r=await this._provider.ensureThread(n.threadId,s,n.workspaceId),o=await this._provider.saveUserMessage(n.threadId,n.message??"");await this.afterUserMessage(n.threadId,o.id,r.created||o.firstMessage,n);}catch{}}),this.unsubEnd=t.on("task:end",async n=>{if(!n.result)return;let s=n.metadata?.threadId;if(!s)return;let r=n.agentRef?.replace(/^@/,"")??"";try{let{id:o}=await this._provider.saveAssistantMessage(s,n.result,r);await this.afterAssistantMessage(s,o,n);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{At as ConversationPlugin,wt as FileLoggerPlugin,xt as SqliteTracingPlugin};
316
+ `).trim()}function en(d){if(!d)return "";let t=d;try{let n=JSON.parse(t);Array.isArray(n)?t=n.filter(s=>s?.type==="text"&&s?.text).map(s=>s.text).join(`
317
+ `):n&&typeof n=="object"&&n.result!==void 0&&(t=n.result||"");}catch{t=tn(t);}return t}var kt=class{dbPath;constructor(t){this.dbPath=t??join(homedir(),".crewx","crewx.db");}getThreadRepo(){return new mt({dbPath:this.dbPath})}updateThread(t,n){this.getThreadRepo().updateThread(t,{title:n.title});}async ensureThread(t,n,s){let r=this.getThreadRepo(),o=r.findThreadById(t);if(o){if(o.platform!==n)throw new Error(`Thread '${t}' already exists with platform '${o.platform}' \u2014 cannot change to '${n}' (platform is immutable)`);return {created:false}}return r.ensureThread(t,n,s),{created:true}}async fetchHistory(t,n){let s=n?.limit??100,r=this.getThreadRepo(),o=r.findThreadById(t),i=r.findTopLevelTasks(t,void 0,s),a=new Set(["queued","cancelled"]);i=i.filter(u=>(!u.status||!a.has(u.status))&&(!n?.currentTraceId||u.trace_id!==n.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,n,s,r){let{firstMessage:o}=this.getThreadRepo().saveUserMessage(t,n);return {id:t,firstMessage:o}}async saveAssistantMessage(t,n,s,r){return this.getThreadRepo().saveAssistantMessage(t,n),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let n=[];for(let s of t){s.prompt&&n.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime(),metadata:{caller_agent_id:s.caller_agent_id}});let r=en(s.result),o=this.normalizeStatus(s.status);if(r||o==="running"||o==="failed"){let i={agent_id:s.agent_id,task_id:s.id};o&&(i.status=o),o==="failed"&&s.error&&(i.reason=s.error.split(`
318
+ `)[0].slice(0,200)),n.push({id:`${s.id}-assistant`,text:r,isAssistant:true,timestamp:new Date(s.started_at).getTime(),metadata:i});}}return n}};var Ct=class extends j{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new kt(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,n,s,r){}async afterAssistantMessage(t,n,s){}attach(t){this.unsubStart=t.on("task:start",async n=>{if(!n.threadId)return;let s=n.platform??"cli";try{let r=await this._provider.ensureThread(n.threadId,s,n.workspaceId),o=await this._provider.saveUserMessage(n.threadId,n.message??"");await this.afterUserMessage(n.threadId,o.id,r.created||o.firstMessage,n);}catch{}}),this.unsubEnd=t.on("task:end",async n=>{if(!n.result)return;let s=n.metadata?.threadId;if(!s)return;let r=n.agentRef?.replace(/^@/,"")??"";try{let{id:o}=await this._provider.saveAssistantMessage(s,n.result,r);await this.afterAssistantMessage(s,o,n);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{Ct as ConversationPlugin,Et as FileLoggerPlugin,At as SqliteTracingPlugin};
@@ -1 +1 @@
1
- import*as b from'path';import {join}from'path';import*as g from'fs';import {existsSync,readFileSync}from'fs';import*as q from'crypto';import*as W from'js-yaml';import*as N from'os';import*as Q from'tar';import {gunzipSync,gzipSync}from'zlib';function ce(e){let t=n=>n.replace(/[.+^${}()|[\]\\]/g,"\\$&"),s=e.split("/").map(n=>n==="**"?".*":n.split("*").map(t).join("[^/]*"));return new RegExp(`^${s.join("\\/")}$`)}function A(e,t){try{return ce(t).test(e)}catch{return false}}function U(e,...t){let r=e.split("/");if(r.length<t.length)return false;let s=r.length-t.length;return t.every((n,i)=>A(r[s+i],n))}function ue(e,t){return e.split("/").some(r=>A(r,t))}var D=[{label:".env*",test:e=>A(e,".env*")},{label:".git/",test:(e,t,r)=>r&&e===".git"},{label:"memory/",test:(e,t,r)=>r&&e==="memory"},{label:"*.key",test:e=>A(e,"*.key")},{label:"*.pem",test:e=>A(e,"*.pem")},{label:"auth.json",test:e=>e==="auth.json"},{label:"node_modules/",test:(e,t,r)=>r&&e==="node_modules"},{label:"conversations/",test:(e,t,r)=>r&&e==="conversations"},{label:".crewx/threads/",test:(e,t,r)=>r&&U(t,".crewx","threads")},{label:".crewx/crewx.db",test:(e,t,r)=>!r&&U(t,".crewx","crewx.db")},{label:".crewx/*.log",test:(e,t,r)=>!r&&U(t,".crewx","*.log")},{label:".crewx/publish/",test:(e,t,r)=>r&&U(t,".crewx","publish")},{label:".crewx/",test:(e,t)=>ue(t,".crewx")}];function k(e,t,r){for(let s of D)if(s.test(e,t,r))return s.label;return null}function K(e){let t=[],r=[];function s(n,i,a){let m;try{m=g.readdirSync(n,{withFileTypes:!0});}catch{return}m.sort((c,u)=>c.name.localeCompare(u.name));for(let c of m){let u=i?`${i}/${c.name}`:c.name,l=b.join(n,c.name);if(c.isSymbolicLink()){let p;try{p=g.statSync(l);}catch{continue}if(p.isDirectory()){r.push({path:u,rule:a??"symlink-dir"});continue}let P=a??k(c.name,u,false);P?r.push({path:u,rule:P}):t.push(u);continue}if(c.isDirectory()){let p=a??k(c.name,u,true);s(l,u,p);continue}if(c.isFile()){let p=a??k(c.name,u,false);p?r.push({path:u,rule:p}):t.push(u);}}}return s(e,"",null),t.sort(),r.sort((n,i)=>n.path<i.path?-1:n.path>i.path?1:0),{included:t,excluded:r}}var le=[{rule:"token-prefix",regex:/\b(?:sk-|ghp_|xoxb-)[A-Za-z0-9_-]{10,}/},{rule:"private-key",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----/},{rule:"aws-access-key",regex:/\bAKIA[0-9A-Z]{16}\b/}];function pe(e){return e.includes(0)}function X(e,t){let r=[];for(let s of t){let n=b.join(e,s),i;try{i=g.readFileSync(n);}catch{continue}if(pe(i))continue;i.toString("utf8").split(/\r\n|\r|\n/).forEach((m,c)=>{for(let{rule:u,regex:l}of le)l.test(m)&&r.push({path:s,line:c+1,rule:u});});}return r}var G=/^[a-z0-9-]+$/,fe=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/,me=/^[A-Za-z_][A-Za-z0-9_]*$/;function he(e){let t=b.join(e,"crewx.yaml");if(!g.existsSync(t))return {};let r;try{r=W.load(g.readFileSync(t,"utf8"));}catch{return {}}if(!r||typeof r!="object")return {};let s=r.metadata;if(!s||typeof s!="object")return {};let n=s;return {name:typeof n.name=="string"?n.name:void 0,version:typeof n.version=="string"?n.version:void 0,description:typeof n.description=="string"?n.description:void 0,requiredEnv:n.requiredEnv,crewxMinVersion:typeof n.crewxMinVersion=="string"?n.crewxMinVersion:void 0}}function de(e){return q.createHash("sha256").update(new Uint8Array(g.readFileSync(e))).digest("hex")}function Z(e,t,r={}){let s=he(e),n=s.name??b.basename(e);if(!G.test(n))throw new Error(`publish: invalid name "${n}" \u2014 must match ${G} (lowercase letters, numbers, hyphen only)`);let i=r.version??s.version;if(!i)throw new Error("publish: version is required \u2014 set crewx.yaml metadata.version or pass opts.version");if(!fe.test(i))throw new Error(`publish: invalid version "${i}" \u2014 must be semver (e.g. 1.0.0)`);let a=Array.isArray(s.requiredEnv)?s.requiredEnv:[],m=[];for(let l of a){if(typeof l!="string"||!me.test(l))throw new Error(`publish: requiredEnv must contain names only (no values), got "${String(l)}"`);m.push(l);}let c=t.map(l=>({path:l,sha256:de(b.join(e,l))})).sort((l,p)=>l.path<p.path?-1:l.path>p.path?1:0),u={name:n,version:i,type:"template",description:s.description??"",files:c,requiredEnv:m};return s.crewxMinVersion&&(u.crewxMinVersion=s.crewxMinVersion),u}async function ee(e,t){let r=b.join(e,".crewx","publish");g.mkdirSync(r,{recursive:true});let s=b.join(r,`${t.name}-${t.version}.tgz`),n=g.mkdtempSync(b.join(N.tmpdir(),"crewx-publish-"));try{g.writeFileSync(b.join(n,"manifest.json"),JSON.stringify(t,null,2));for(let i of t.files){let a=b.join(n,i.path);g.mkdirSync(b.dirname(a),{recursive:!0}),g.copyFileSync(b.join(e,i.path),a);}await Q.create({gzip:!0,file:s,cwd:n,portable:!0,noMtime:!0},["manifest.json",...t.files.map(i=>i.path)]);}finally{g.rmSync(n,{recursive:true,force:true});}return s}var S="/api/v1";var be=201,we=409,O=401;function Ee(){return process.env.WI013_FAKE_UPLOAD==="1"}function Ae(e){let t=gunzipSync(new Uint8Array(e)),r=gzipSync(new Uint8Array(t),{level:1});if(Buffer.compare(new Uint8Array(r),new Uint8Array(e))===0)throw new Error("WI013_FAKE_UPLOAD: re-gzipped bytes are identical to the original \u2014 tamper is a no-op");return r}function Se(e){return e.replace(/\/+$/,"")}async function C(e){try{return await e.json()}catch{return null}}function w(e){let t=e?.message;return typeof t=="string"?t:void 0}function te(e,t,r){let s=e;if(!s||s.success!==true||s.data===void 0)throw new Error(`publish: ${t} response envelope malformed (expected { success: true, data }) \u2014 HTTP ${r}`);return s.data}async function xe(e){let t=Se(e.baseUrl),r=e.accessPolicy??"private",s=e.manifest.name,n;try{n=await fetch(`${t}${S}/publisher/items`,{method:"POST",headers:{Authorization:`Bearer ${e.accessToken}`,"Content-Type":"application/json"},body:JSON.stringify({slug:s,displayName:s,description:e.manifest.description,type:"template",version:e.manifest.version,accessPolicy:r})});}catch(o){throw new Error(`publish: submit \uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (\uB124\uD2B8\uC6CC\uD06C) \u2014 ${o instanceof Error?o.message:String(o)}`)}let i;if(n.status===be)i="created";else if(n.status===we)i="existing";else {if(n.status===O)throw new Error("publish: \uC778\uC99D\uC774 \uB9CC\uB8CC\uB418\uC5C8\uAC70\uB098 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uC2DC \uB85C\uADF8\uC778\uD558\uC138\uC694");{let o=await C(n);throw new Error(`publish: submit \uC2E4\uD328 \u2014 HTTP ${n.status}${w(o)?` ${w(o)}`:""}`)}}let a="not-needed",m=null;if(i==="existing"){let o;try{o=await fetch(`${t}${S}/publisher/items`,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}});}catch(f){throw new Error(`publish: version \uC870\uD68C \uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (\uB124\uD2B8\uC6CC\uD06C) \u2014 ${f instanceof Error?f.message:String(f)}`)}let $=await C(o);if(o.status!==200)throw new Error(`publish: publisher items \uC870\uD68C \uC2E4\uD328 \u2014 HTTP ${o.status}${w($)?` ${w($)}`:""}`);let z=te($,"publisher items",o.status)?.items;if(!Array.isArray(z))throw new Error(`publish: publisher items response malformed (expected data.items[]) \u2014 HTTP ${o.status}`);let I=z.find(f=>!f||typeof f!="object"?false:f.slug===s);if(!I||typeof I.version!="string")throw new Error(`publish: publisher items response does not contain slug "${s}" \u2014 HTTP ${o.status}`);if(m=I.version,m!==e.manifest.version){let f;try{f=await fetch(`${t}${S}/publisher/items/${encodeURIComponent(s)}`,{method:"PUT",headers:{Authorization:`Bearer ${e.accessToken}`,"Content-Type":"application/json"},body:JSON.stringify({version:e.manifest.version})});}catch(_){throw new Error(`publish: version update \uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (\uB124\uD2B8\uC6CC\uD06C) \u2014 ${_ instanceof Error?_.message:String(_)}`)}if(!f.ok){let _=await C(f),E=w(_);throw f.status===O?new Error(`publish: version update \uC778\uC99D\uC774 \uB9CC\uB8CC\uB418\uC5C8\uAC70\uB098 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uC2DC \uB85C\uADF8\uC778\uD558\uC138\uC694 (HTTP ${f.status})${E?` ${E}`:""}`):f.status===403?new Error(`publish: version update \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uAE30\uC874 \uD56D\uBAA9\uC758 \uC18C\uC720\uC790\uB9CC \uBC84\uC804\uC744 \uAC31\uC2E0\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4 (HTTP ${f.status})${E?` ${E}`:""}`):new Error(`publish: version update \uC2E4\uD328 \u2014 HTTP ${f.status}${E?` ${E}`:""}`)}a="applied";}}let c=g.readFileSync(e.tgzPath),u=Ee()?Ae(c):c,l=new FormData;l.set("archive",new Blob([new Uint8Array(u)],{type:"application/gzip"}),`${s}-${e.manifest.version}.tgz`);let p;try{p=await fetch(`${t}${S}/publisher/items/${encodeURIComponent(s)}/upload`,{method:"POST",headers:{Authorization:`Bearer ${e.accessToken}`},body:l});}catch(o){throw new Error(`publish: upload \uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (\uB124\uD2B8\uC6CC\uD06C) \u2014 ${o instanceof Error?o.message:String(o)}`)}if(p.status===O)throw new Error("publish: \uC778\uC99D\uC774 \uB9CC\uB8CC\uB418\uC5C8\uAC70\uB098 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uC2DC \uB85C\uADF8\uC778\uD558\uC138\uC694");if(!p.ok){let o=await C(p);throw new Error(`publish: upload \uC2E4\uD328 \u2014 HTTP ${p.status}${w(o)?` ${w(o)}`:""}`)}let P=await C(p),H=te(P,"upload",p.status);return {slug:s,version:e.manifest.version,artifactChecksum:H.artifactChecksum,artifactSizeBytes:H.artifactSizeBytes,submitOutcome:i,versionUpdate:a,serverVersionBefore:m}}function se(){if(process.env.CREWX_HOME)try{return g.realpathSync(process.env.CREWX_HOME)}catch{return b.join(N.homedir(),".crewx")}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?b.join(process.env.XDG_CONFIG_HOME,"crewx"):b.join(N.homedir(),".crewx")}var y=class extends Error{code;constructor(t,r){super(r),this.name="AccountAuthBoundaryError",this.code=t;}};function j(e=process.env){let t=e.CREWX_ACCOUNT_ISSUER?.trim(),r=e.CREWX_ACCOUNT_ANON_KEY?.trim();if(!t&&!r)throw new y("ACCOUNT_USER_PAIR_MISSING","CrewX user-realm issuer and anon/publishable key pair are not configured");if(!t)throw new y("ACCOUNT_USER_ISSUER_MISSING","CrewX user-realm issuer is not configured");if(!r)throw new y("ACCOUNT_USER_ANON_KEY_MISSING","CrewX user-realm anon/publishable key is not configured");return {issuer:t,anonKey:r}}function x(){throw new y("ACCOUNT_ACCESS_TOKEN_INVALID","Account access token could not be verified")}function ie(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf8"))}catch{return x()}}function oe(e){if(typeof e!="string")return x();let t=e.split(".");if(t.length!==3||t.some(i=>i.length===0))return x();let r=ie(t[0]),s=ie(t[1]);if(!r||typeof r!="object"||!s||typeof s!="object")return x();let n=s;return typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0?x():{issuer:n.iss,sub:n.sub}}function ae(e,t,r){let s=oe(e);if(s.issuer!==t.issuer)throw new y("ACCOUNT_TOKEN_ISSUER_MISMATCH","Account access token does not match the configured user realm");if(r!==void 0&&s.sub!==r)throw new y("ACCOUNT_TOKEN_SUB_MISMATCH","Account access token subject does not match the expected identity");return s}function B(e,t){if(e.issuer!==t.issuer)throw new y("ACCOUNT_AUTH_JSON_ISSUER_MISMATCH","auth.json does not match the configured user realm");let r=ae(e.access_token,t);if(r.sub!==e.sub)throw new y("ACCOUNT_AUTH_JSON_SUB_MISMATCH","auth.json subject does not match the access token identity");return r}function Ce(e){if(!e||typeof e!="object")return false;let t=e;return t.version===1&&typeof t.sub=="string"&&typeof t.email=="string"&&typeof t.access_token=="string"&&typeof t.refresh_token=="string"&&typeof t.expires_at=="number"&&typeof t.issuer=="string"&&typeof t.updated_at=="string"}function Pe(){let e=join(se(),"auth.json");if(!existsSync(e))throw new Error(`Login required \u2014 ${e} was not found (please log in first)`);let t;try{t=readFileSync(e,"utf8");}catch(n){throw new Error(`Could not read auth.json (${e}): ${n instanceof Error?n.message:String(n)}`)}let r;try{r=JSON.parse(t);}catch(n){throw new Error(`Failed to parse auth.json (${e}): ${n instanceof Error?n.message:String(n)}`)}if(!Ce(r))throw new Error(`auth.json is malformed (${e}) \u2014 please log in again`);let s=j();return B(r,s),r}async function Ue(e,t={}){let r=b.resolve(e),{included:s,excluded:n}=K(r),i=Z(r,s,{version:t.version}),a=X(r,s);return {manifest:i,included:s,excluded:n,secretFindings:a}}async function ft(e,t={}){let r=await Ue(e,t);if(r.secretFindings.length>0){let i=r.secretFindings.map(a=>`${a.path}:${a.line} (${a.rule})`).join(", ");throw new Error(`publish: aborted \u2014 secret findings must be resolved before packing: ${i}`)}let s=b.resolve(e),n=await ee(s,r.manifest);return {manifest:r.manifest,tgzPath:n}}export{y as AccountAuthBoundaryError,D as EXCLUDE_RULES,S as MARKETPLACE_API_PREFIX,B as assertAuthJsonUserRealm,ae as assertUserRealmAccessToken,oe as decodeAccessTokenIdentity,ft as packTemplate,Ue as planPublish,Pe as readAuthJson,j as resolveUserAccountConfig,xe as uploadToMarketplace};
1
+ import*as E from'path';import {join}from'path';import*as g from'fs';import {existsSync,readFileSync}from'fs';import*as W from'crypto';import*as G from'js-yaml';import*as N from'os';import*as Q from'tar';import {gunzipSync,gzipSync}from'zlib';function ce(e){let t=n=>n.replace(/[.+^${}()|[\]\\]/g,"\\$&"),s=e.split("/").map(n=>n==="**"?".*":n.split("*").map(t).join("[^/]*"));return new RegExp(`^${s.join("\\/")}$`)}function A(e,t){try{return ce(t).test(e)}catch{return false}}function v(e,...t){let r=e.split("/");if(r.length<t.length)return false;let s=r.length-t.length;return t.every((n,i)=>A(r[s+i],n))}function ue(e,t){return e.split("/").some(r=>A(r,t))}var z=[{label:".env*",test:e=>A(e,".env*")},{label:".git/",test:(e,t,r)=>r&&e===".git"},{label:"memory/",test:(e,t,r)=>r&&e==="memory"},{label:"*.key",test:e=>A(e,"*.key")},{label:"*.pem",test:e=>A(e,"*.pem")},{label:"auth.json",test:e=>e==="auth.json"},{label:"node_modules/",test:(e,t,r)=>r&&e==="node_modules"},{label:"conversations/",test:(e,t,r)=>r&&e==="conversations"},{label:".crewx/threads/",test:(e,t,r)=>r&&v(t,".crewx","threads")},{label:".crewx/crewx.db",test:(e,t,r)=>!r&&v(t,".crewx","crewx.db")},{label:".crewx/*.log",test:(e,t,r)=>!r&&v(t,".crewx","*.log")},{label:".crewx/publish/",test:(e,t,r)=>r&&v(t,".crewx","publish")},{label:".crewx/",test:(e,t)=>ue(t,".crewx")}];function R(e,t,r){for(let s of z)if(s.test(e,t,r))return s.label;return null}function K(e){let t=[],r=[];function s(n,i,a){let d;try{d=g.readdirSync(n,{withFileTypes:!0});}catch{return}d.sort((c,u)=>c.name.localeCompare(u.name));for(let c of d){let u=i?`${i}/${c.name}`:c.name,l=E.join(n,c.name);if(c.isSymbolicLink()){let p;try{p=g.statSync(l);}catch{continue}if(p.isDirectory()){r.push({path:u,rule:a??"symlink-dir"});continue}let C=a??R(c.name,u,false);C?r.push({path:u,rule:C}):t.push(u);continue}if(c.isDirectory()){let p=a??R(c.name,u,true);s(l,u,p);continue}if(c.isFile()){let p=a??R(c.name,u,false);p?r.push({path:u,rule:p}):t.push(u);}}}return s(e,"",null),t.sort(),r.sort((n,i)=>n.path<i.path?-1:n.path>i.path?1:0),{included:t,excluded:r}}var le=[{rule:"token-prefix",regex:/\b(?:sk-|ghp_|xoxb-)[A-Za-z0-9_-]{10,}/},{rule:"private-key",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----/},{rule:"aws-access-key",regex:/\bAKIA[0-9A-Z]{16}\b/}];function pe(e){return e.includes(0)}function V(e,t){let r=[];for(let s of t){let n=E.join(e,s),i;try{i=g.readFileSync(n);}catch{continue}if(pe(i))continue;i.toString("utf8").split(/\r\n|\r|\n/).forEach((d,c)=>{for(let{rule:u,regex:l}of le)l.test(d)&&r.push({path:s,line:c+1,rule:u});});}return r}var X=/^[a-z0-9-]+$/,fe=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/,de=/^[A-Za-z_][A-Za-z0-9_]*$/;function me(e){let t=E.join(e,"crewx.yaml");if(!g.existsSync(t))return {};let r;try{r=G.load(g.readFileSync(t,"utf8"));}catch{return {}}if(!r||typeof r!="object")return {};let s=r.metadata;if(!s||typeof s!="object")return {};let n=s;return {name:typeof n.name=="string"?n.name:void 0,version:typeof n.version=="string"?n.version:void 0,description:typeof n.description=="string"?n.description:void 0,requiredEnv:n.requiredEnv,crewxMinVersion:typeof n.crewxMinVersion=="string"?n.crewxMinVersion:void 0}}function he(e){return W.createHash("sha256").update(new Uint8Array(g.readFileSync(e))).digest("hex")}function Z(e,t,r={}){let s=me(e),n=s.name??E.basename(e);if(!X.test(n))throw new Error(`publish: invalid name "${n}" \u2014 must match ${X} (lowercase letters, numbers, hyphen only)`);let i=r.version??s.version;if(!i)throw new Error("publish: version is required \u2014 set crewx.yaml metadata.version or pass opts.version");if(!fe.test(i))throw new Error(`publish: invalid version "${i}" \u2014 must be semver (e.g. 1.0.0)`);let a=Array.isArray(s.requiredEnv)?s.requiredEnv:[],d=[];for(let l of a){if(typeof l!="string"||!de.test(l))throw new Error(`publish: requiredEnv must contain names only (no values), got "${String(l)}"`);d.push(l);}let c=t.map(l=>({path:l,sha256:he(E.join(e,l))})).sort((l,p)=>l.path<p.path?-1:l.path>p.path?1:0),u={name:n,version:i,type:"template",description:s.description??"",files:c,requiredEnv:d};return s.crewxMinVersion&&(u.crewxMinVersion=s.crewxMinVersion),u}async function ee(e,t){let r=E.join(e,".crewx","publish");g.mkdirSync(r,{recursive:true});let s=E.join(r,`${t.name}-${t.version}.tgz`),n=g.mkdtempSync(E.join(N.tmpdir(),"crewx-publish-"));try{g.writeFileSync(E.join(n,"manifest.json"),JSON.stringify(t,null,2));for(let i of t.files){let a=E.join(n,i.path);g.mkdirSync(E.dirname(a),{recursive:!0}),g.copyFileSync(E.join(e,i.path),a);}await Q.create({gzip:!0,file:s,cwd:n,portable:!0,noMtime:!0},["manifest.json",...t.files.map(i=>i.path)]);}finally{g.rmSync(n,{recursive:true,force:true});}return s}var _="/api/v1";var Ee=201,be=409,I=401;function we(){return process.env.WI013_FAKE_UPLOAD==="1"}function Ae(e){let t=gunzipSync(new Uint8Array(e)),r=gzipSync(new Uint8Array(t),{level:1});if(Buffer.compare(new Uint8Array(r),new Uint8Array(e))===0)throw new Error("publish: [E_MALFORMED] Re-gzipped upload bytes are identical to the original \u2014 tamper is a no-op");return r}function _e(e){return e.replace(/\/+$/,"")}async function U(e){try{return await e.json()}catch{return null}}function b(e){let t=e?.message;return typeof t=="string"?t:void 0}function te(e,t,r){let s=e;if(!s||s.success!==true||s.data===void 0)throw new Error(`publish: [E_MALFORMED] ${t} response envelope is malformed (expected { success: true, data }) \u2014 HTTP ${r}`);return s.data}async function Te(e){let t=_e(e.baseUrl),r=e.accessPolicy??"private",s=e.manifest.name,n;try{n=await fetch(`${t}${_}/publisher/items`,{method:"POST",headers:{Authorization:`Bearer ${e.accessToken}`,"Content-Type":"application/json"},body:JSON.stringify({slug:s,displayName:s,description:e.manifest.description,type:"template",version:e.manifest.version,accessPolicy:r})});}catch(o){throw new Error(`publish: [E_NETWORK] Submit request failed (network) \u2014 ${o instanceof Error?o.message:String(o)}`)}let i;if(n.status===Ee)i="created";else if(n.status===be)i="existing";else {if(n.status===I)throw new Error("publish: [E_AUTH_EXPIRED] Authentication is expired or missing \u2014 please log in again (HTTP 401)");{let o=await U(n);throw new Error(`publish: [E_HTTP] Submit request failed \u2014 HTTP ${n.status}${b(o)?` ${b(o)}`:""}`)}}let a="not-needed",d=null;if(i==="existing"){let o;try{o=await fetch(`${t}${_}/publisher/items`,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}});}catch(f){throw new Error(`publish: [E_NETWORK] Publisher items request failed (network) \u2014 ${f instanceof Error?f.message:String(f)}`)}let O=await U(o);if(o.status!==200)throw new Error(`publish: [E_HTTP] Publisher items request failed \u2014 HTTP ${o.status}${b(O)?` ${b(O)}`:""}`);let D=te(O,"publisher items",o.status)?.items;if(!Array.isArray(D))throw new Error(`publish: [E_MALFORMED] Publisher items response is malformed (expected data.items[]) \u2014 HTTP ${o.status}`);let $=D.find(f=>!f||typeof f!="object"?false:f.slug===s);if(!$||typeof $.version!="string")throw new Error(`publish: [E_MALFORMED] Publisher items response does not contain slug "${s}" \u2014 HTTP ${o.status}`);if(d=$.version,d!==e.manifest.version){let f;try{f=await fetch(`${t}${_}/publisher/items/${encodeURIComponent(s)}`,{method:"PUT",headers:{Authorization:`Bearer ${e.accessToken}`,"Content-Type":"application/json"},body:JSON.stringify({version:e.manifest.version})});}catch(x){throw new Error(`publish: [E_NETWORK] Version update request failed (network) \u2014 ${x instanceof Error?x.message:String(x)}`)}if(!f.ok){let x=await U(f),w=b(x);throw f.status===I?new Error(`publish: [E_AUTH_EXPIRED] Authentication is expired or missing \u2014 please log in again (HTTP ${f.status})${w?` ${w}`:""}`):f.status===403?new Error(`publish: [E_FORBIDDEN] Version update is forbidden; only the item owner can update an existing item (HTTP ${f.status})${w?` ${w}`:""}`):new Error(`publish: [E_HTTP] Version update failed \u2014 HTTP ${f.status}${w?` ${w}`:""}`)}a="applied";}}let c=g.readFileSync(e.tgzPath),u=we()?Ae(c):c,l=new FormData;l.set("archive",new Blob([new Uint8Array(u)],{type:"application/gzip"}),`${s}-${e.manifest.version}.tgz`);let p;try{p=await fetch(`${t}${_}/publisher/items/${encodeURIComponent(s)}/upload`,{method:"POST",headers:{Authorization:`Bearer ${e.accessToken}`},body:l});}catch(o){throw new Error(`publish: [E_NETWORK] Upload request failed (network) \u2014 ${o instanceof Error?o.message:String(o)}`)}if(p.status===I)throw new Error("publish: [E_AUTH_EXPIRED] Authentication is expired or missing \u2014 please log in again (HTTP 401)");if(!p.ok){let o=await U(p);throw new Error(`publish: [E_HTTP] Upload request failed \u2014 HTTP ${p.status}${b(o)?` ${b(o)}`:""}`)}let C=await U(p),B=te(C,"upload",p.status);return {slug:s,version:e.manifest.version,artifactChecksum:B.artifactChecksum,artifactSizeBytes:B.artifactSizeBytes,submitOutcome:i,versionUpdate:a,serverVersionBefore:d}}function se(){if(process.env.CREWX_HOME)try{return g.realpathSync(process.env.CREWX_HOME)}catch{return E.join(N.homedir(),".crewx")}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?E.join(process.env.XDG_CONFIG_HOME,"crewx"):E.join(N.homedir(),".crewx")}var y=class extends Error{code;constructor(t,r){super(r),this.name="AccountAuthBoundaryError",this.code=t;}};function H(e=process.env){let t=e.CREWX_ACCOUNT_ISSUER?.trim(),r=e.CREWX_ACCOUNT_ANON_KEY?.trim();if(!t&&!r)throw new y("ACCOUNT_USER_PAIR_MISSING","CrewX user-realm issuer and anon/publishable key pair are not configured");if(!t)throw new y("ACCOUNT_USER_ISSUER_MISSING","CrewX user-realm issuer is not configured");if(!r)throw new y("ACCOUNT_USER_ANON_KEY_MISSING","CrewX user-realm anon/publishable key is not configured");return {issuer:t,anonKey:r}}function T(){throw new y("ACCOUNT_ACCESS_TOKEN_INVALID","Account access token could not be verified")}function ie(e){try{return JSON.parse(Buffer.from(e,"base64url").toString("utf8"))}catch{return T()}}function oe(e){if(typeof e!="string")return T();let t=e.split(".");if(t.length!==3||t.some(i=>i.length===0))return T();let r=ie(t[0]),s=ie(t[1]);if(!r||typeof r!="object"||!s||typeof s!="object")return T();let n=s;return typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0?T():{issuer:n.iss,sub:n.sub}}function ae(e,t,r){let s=oe(e);if(s.issuer!==t.issuer)throw new y("ACCOUNT_TOKEN_ISSUER_MISMATCH","Account access token does not match the configured user realm");if(r!==void 0&&s.sub!==r)throw new y("ACCOUNT_TOKEN_SUB_MISMATCH","Account access token subject does not match the expected identity");return s}function F(e,t){if(e.issuer!==t.issuer)throw new y("ACCOUNT_AUTH_JSON_ISSUER_MISMATCH","auth.json does not match the configured user realm");let r=ae(e.access_token,t);if(r.sub!==e.sub)throw new y("ACCOUNT_AUTH_JSON_SUB_MISMATCH","auth.json subject does not match the access token identity");return r}function Ue(e){if(!e||typeof e!="object")return false;let t=e;return t.version===1&&typeof t.sub=="string"&&typeof t.email=="string"&&typeof t.access_token=="string"&&typeof t.refresh_token=="string"&&typeof t.expires_at=="number"&&typeof t.issuer=="string"&&typeof t.updated_at=="string"}function Ce(){let e=join(se(),"auth.json");if(!existsSync(e))throw new Error(`Login required \u2014 ${e} was not found (please log in first)`);let t;try{t=readFileSync(e,"utf8");}catch(n){throw new Error(`Could not read auth.json (${e}): ${n instanceof Error?n.message:String(n)}`)}let r;try{r=JSON.parse(t);}catch(n){throw new Error(`Failed to parse auth.json (${e}): ${n instanceof Error?n.message:String(n)}`)}if(!Ue(r))throw new Error(`auth.json is malformed (${e}) \u2014 please log in again`);let s=H();return F(r,s),r}async function ve(e,t={}){let r=E.resolve(e),{included:s,excluded:n}=K(r),i=Z(r,s,{version:t.version}),a=V(r,s);return {manifest:i,included:s,excluded:n,secretFindings:a}}async function ft(e,t={}){let r=await ve(e,t);if(r.secretFindings.length>0){let i=r.secretFindings.map(a=>`${a.path}:${a.line} (${a.rule})`).join(", ");throw new Error(`publish: aborted \u2014 secret findings must be resolved before packing: ${i}`)}let s=E.resolve(e),n=await ee(s,r.manifest);return {manifest:r.manifest,tgzPath:n}}export{y as AccountAuthBoundaryError,z as EXCLUDE_RULES,_ as MARKETPLACE_API_PREFIX,F as assertAuthJsonUserRealm,ae as assertUserRealmAccessToken,oe as decodeAccessTokenIdentity,ft as packTemplate,ve as planPublish,Ce as readAuthJson,H as resolveUserAccountConfig,Te as uploadToMarketplace};