@crewx/sdk 0.9.0-rc.78 → 0.9.0-rc.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context-budget/continuity.d.ts +9 -1
- package/dist/context-budget/index.d.ts +2 -1
- package/dist/conversation/sqlite-provider.d.ts +2 -1
- package/dist/conversation/types.d.ts +13 -0
- package/dist/esm/index.js +113 -106
- package/dist/esm/plugins/index.js +113 -113
- package/dist/esm/repository/index.js +15 -15
- package/dist/facade/Crewx.d.ts +3 -3
- package/dist/highlight/thread-highlight-prompt.d.ts +1 -0
- package/dist/highlight/thread-highlighter.d.ts +12 -1
- package/dist/index.browser.js +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +114 -107
- package/dist/layout/types.d.ts +2 -0
- package/dist/plugins/index.js +113 -113
- package/dist/repository/index.js +15 -15
- package/dist/repository/thread-history.repository.d.ts +1 -0
- package/package.json +1 -1
- package/templates/agents/default.yaml +17 -10
package/dist/plugins/index.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
'use strict';var fs=require('fs'),
|
|
1
|
+
'use strict';var fs$1=require('fs'),dt=require('path'),Qn=require('os'),crypto=require('crypto'),drizzleOrm=require('drizzle-orm'),sqliteCore=require('drizzle-orm/sqlite-core');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var dt__namespace=/*#__PURE__*/_interopNamespace(dt);var Qn__default=/*#__PURE__*/_interopDefault(Qn);var Xt=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var kt=class{detach(t){}};function je(n){let t=e=>String(e).padStart(2,"0");return `${n.getFullYear()}${t(n.getMonth()+1)}${t(n.getDate())}T${t(n.getHours())}${t(n.getMinutes())}${t(n.getSeconds())}`}function ge(n){let t=n.toISOString();return `${t.slice(0,10)} ${t.slice(11,19)} UTC`}var fe=class extends kt{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(t){super(),this.logsDir=dt.join(t?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=t?.version??"unknown";}attach(t){this.unsubs.push(t.on("task:start",e=>{try{fs$1.existsSync(this.logsDir)||fs$1.mkdirSync(this.logsDir,{recursive:!0});let r=je(e.timestamp),s=dt.join(this.logsDir,`${r}_${e.traceId}.log`);this.logFiles.set(e.traceId,s);let i=`=== TASK LOG: ${e.traceId} ===
|
|
2
2
|
CrewX Version: ${this.version}
|
|
3
3
|
Mode: ${e.mode}
|
|
4
4
|
Agent: ${e.agentRef}
|
|
5
|
-
Started: ${
|
|
5
|
+
Started: ${ge(e.timestamp)}
|
|
6
6
|
Message: ${e.message}
|
|
7
7
|
|
|
8
|
-
`;fs.writeFileSync(i,
|
|
9
|
-
`,"utf8");}catch{}}),t.on("task:end",e=>{try{let r=this.logFiles.get(e.traceId);if(!r)return;let
|
|
10
|
-
[${
|
|
11
|
-
`;fs.appendFileSync(r,a,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function
|
|
8
|
+
`;fs$1.writeFileSync(s,i,{encoding:"utf8",mode:384});}catch{}}),t.on("task:output",e=>{try{let r=this.logFiles.get(e.traceId);if(!r)return;let s=new Date().toISOString();fs$1.appendFileSync(r,`[${s}] STDOUT: ${e.output}
|
|
9
|
+
`,"utf8");}catch{}}),t.on("task:end",e=>{try{let r=this.logFiles.get(e.traceId);if(!r)return;let s=ge(new Date),i=e.error?`failed: ${e.error.message}`:"completed successfully",a=`[${s}] INFO: Task ${i} in ${e.durationMs}ms
|
|
10
|
+
[${s}] INFO: Process closed with exit code: ${e.error?1:0}
|
|
11
|
+
`;fs$1.appendFileSync(r,a,"utf8"),this.logFiles.delete(e.traceId);}catch{}}));}detach(t){this.unsubs.forEach(e=>e()),this.unsubs=[],this.logFiles.clear();}};function Xn(n){let t=dt__namespace.resolve(n);return process.platform==="win32"&&(t=t.replace(/\\/g,"/"),t=t.replace(/^([A-Z]):/,(e,r)=>`${r.toLowerCase()}:`)),t.length>1&&!/^[a-zA-Z]:\/$/.test(t)&&(t=t.replace(/\/+$/,"")),t}function We(n){let t=Xn(n);return crypto.createHash("sha256").update(t).digest("hex")}var u=class extends Error{code;cause;constructor(t,e,r){super(e),this.name="RepositoryError",this.code=t,this.cause=r,Object.setPrototypeOf(this,new.target.prototype);}};var X=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:dt.join(Qn__default.default.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(t){return t instanceof Error&&/no such table:/i.test(t.message)}dbExists(t){return fs$1.existsSync(t??this.resolveDbPath())}};var tr=32*1024*1024;function N(n){let t=Xt("better-sqlite3"),{drizzle:e}=Xt("drizzle-orm/better-sqlite3"),r=new t(n);return r.exec("PRAGMA journal_mode = WAL"),r.exec(`PRAGMA journal_size_limit = ${tr}`),r.exec("PRAGMA busy_timeout = 5000"),r.exec("PRAGMA foreign_keys = ON"),r.exec("PRAGMA analysis_limit = 400"),{db:e(r),runRaw:(s,i=[])=>r.prepare(s).run(...i),close:()=>r.close()}}var Ge=new Set,er={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",command:"TEXT"};function me(n,t){return (n.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${t}'`)?.cnt??0)>0}function nr(n,t){if(t>0||!me(n,"tasks"))return;let e=n.all("PRAGMA table_info(tasks)"),r=new Set(e.map(s=>s.name));for(let[s,i]of Object.entries(er))r.has(s)||n.run(`ALTER TABLE tasks ADD COLUMN ${s} ${i}`);}var rr={"0002_normalize_task_names":{workspace_name:"TEXT",project_name:"TEXT"},"0015_panoramic_gorilla_man":{project_id:"TEXT",workspace_id:"TEXT"},"0019_backfill_task_thread_ids":{command:"TEXT",thread_id:"TEXT"}};function sr(n,t,e){if(!me(n,"__drizzle_migrations")||!me(n,"tasks"))return;let r=n.all(e`SELECT hash FROM __drizzle_migrations`),s=new Set(r.map(a=>a.hash)),i=JSON.parse(fs$1.readFileSync(dt__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let a of i.entries){let d=rr[a.tag];if(!d)continue;let c=dt__namespace.default.join(t,`${a.tag}.sql`);if(!fs$1.existsSync(c))continue;let l=fs$1.readFileSync(c,"utf-8"),_=crypto.createHash("sha256").update(l).digest("hex");if(s.has(_))continue;let p=n.all("PRAGMA table_info(tasks)"),g=new Set(p.map(f=>f.name));for(let[f,b]of Object.entries(d))g.has(f)||(n.run(`ALTER TABLE tasks ADD COLUMN ${f} ${b}`),g.add(f));}}function or(n,t,e){let r=n.all(e`SELECT hash FROM __drizzle_migrations`),s=new Set(r.map(a=>a.hash)),i=JSON.parse(fs$1.readFileSync(dt__namespace.default.join(t,"meta/_journal.json"),"utf-8"));for(let a of i.entries){let d=dt__namespace.default.join(t,`${a.tag}.sql`);if(!fs$1.existsSync(d))continue;let c=fs$1.readFileSync(d,"utf-8"),l=crypto.createHash("sha256").update(c).digest("hex");if(s.has(l))continue;let _=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,p=[],g;for(;(g=_.exec(c))!==null;)p.push({table:g[1],column:g[2]});if(p.length===0||!c.split(/-->\s*statement-breakpoint/).map(x=>x.trim()).filter(Boolean).every(x=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(x)))continue;p.every(({table:x,column:v})=>n.all(`PRAGMA table_info("${x}")`).some(j=>j.name===v))&&n.run(e`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${a.when})`);}}function ir(n){let{migrate:t}=Xt("drizzle-orm/better-sqlite3/migrator"),{sql:e}=Xt("drizzle-orm"),r=[dt__namespace.default.join(__dirname,"../migrations"),dt__namespace.default.join(__dirname,"migrations"),dt__namespace.default.join(__dirname,"../../../../drizzle/migrations"),dt__namespace.default.join(process.cwd(),"drizzle/migrations")],s=r.find(l=>fs$1.existsSync(dt__namespace.default.join(l,"meta/_journal.json")));if(!s)throw new Error(`migrations folder not found. Searched:
|
|
12
12
|
${r.join(`
|
|
13
|
-
`)}`);let o=n.get(e`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;o?.cnt&&(a=n.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),qn(n,a),o?.cnt&&(Un(n,i,e),Bn(n,i,e)),t(n,{migrationsFolder:i});let c=(n.get(e`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 ht(n,t){Le.has(t)||(Fn(n),Le.add(t));}var St=sqliteCore.sqliteTable("workspaces",{id:sqliteCore.text("id").primaryKey(),slug:sqliteCore.text("slug").notNull().unique(),name:sqliteCore.text("name").notNull(),workspace_path:sqliteCore.text("workspace_path"),description:sqliteCore.text("description"),is_active:sqliteCore.integer("is_active").notNull().default(1),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()});var s=sqliteCore.sqliteTable("tasks",{id:sqliteCore.text("id").primaryKey(),agent_id:sqliteCore.text("agent_id").notNull(),user_id:sqliteCore.text("user_id"),prompt:sqliteCore.text("prompt").notNull(),mode:sqliteCore.text("mode").notNull().default("execute"),status:sqliteCore.text("status").notNull().default("running"),result:sqliteCore.text("result"),error:sqliteCore.text("error"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),metadata:sqliteCore.text("metadata"),workspace_id:sqliteCore.text("workspace_id"),trace_id:sqliteCore.text("trace_id"),parent_task_id:sqliteCore.text("parent_task_id"),caller_agent_id:sqliteCore.text("caller_agent_id"),model:sqliteCore.text("model"),platform:sqliteCore.text("platform").default("cli"),crewx_version:sqliteCore.text("crewx_version"),input_tokens:sqliteCore.integer("input_tokens").default(0),output_tokens:sqliteCore.integer("output_tokens").default(0),cost_usd:sqliteCore.real("cost_usd").default(0),pid:sqliteCore.integer("pid"),rendered_prompt:sqliteCore.text("rendered_prompt"),command:sqliteCore.text("command"),coding_agent_command:sqliteCore.text("coding_agent_command"),exit_code:sqliteCore.integer("exit_code"),logs:sqliteCore.text("logs"),log_storage:sqliteCore.text("log_storage",{enum:["blob","events"]}).notNull().default("blob"),last_log_seq:sqliteCore.integer("last_log_seq").notNull().default(0),log_revision:sqliteCore.integer("log_revision").notNull().default(0),thread_id:sqliteCore.text("thread_id"),workspace_ref:sqliteCore.text("workspace_ref"),project_id:sqliteCore.text("project_id"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0),run_epoch:sqliteCore.integer("run_epoch").default(0)},n=>({log_storage_check:sqliteCore.check("tasks_log_storage_ck",drizzleOrm.sql`${n.log_storage} IN ('blob', 'events')`),idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(n.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(n.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(n.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(n.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(n.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(n.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(n.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(n.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(n.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(n.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(n.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(n.workspace_id,n.started_at)}));var J=sqliteCore.sqliteTable("task_log_events",{id:sqliteCore.integer("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>s.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),timestamp:sqliteCore.text("timestamp").notNull(),level:sqliteCore.text("level").notNull(),message:sqliteCore.text("message").notNull()},n=>({taskSeqUnique:sqliteCore.uniqueIndex("task_log_events_task_seq_uq").on(n.task_id,n.seq)}));var Zn="json_extract(metadata, '$.threadTitle.state')",tr="json_extract(metadata, '$.threadTitle.priority')",p=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>St.id,{onDelete:"set null"}),platform:sqliteCore.text("platform").notNull().default("cli"),title:sqliteCore.text("title"),first_message:sqliteCore.text("first_message"),last_message:sqliteCore.text("last_message"),message_count:sqliteCore.integer("message_count").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),metadata:sqliteCore.text("metadata"),title_locked:sqliteCore.integer("title_locked").notNull().default(0),pinned:sqliteCore.integer("pinned").notNull().default(0),starred:sqliteCore.integer("starred").notNull().default(0)},n=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(n.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(n.workspace_id),idx_threads_ws_updated:sqliteCore.index("idx_threads_ws_updated").on(n.workspace_id,n.updated_at),idx_threads_title:sqliteCore.index("idx_threads_title").on(n.title),idx_threads_workspace_thread_state:sqliteCore.index("idx_threads_workspace_thread_state").on(n.workspace_id,drizzleOrm.sql.raw(Zn)),idx_threads_workspace_thread_priority:sqliteCore.index("idx_threads_workspace_thread_priority").on(n.workspace_id,drizzleOrm.sql.raw(tr))}));var rr=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>s.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>rr.id,{onDelete:"set null"}),name:sqliteCore.text("name").notNull(),kind:sqliteCore.text("kind").notNull().default("internal"),status:sqliteCore.text("status").notNull().default("ok"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),error:sqliteCore.text("error"),attributes:sqliteCore.text("attributes")},n=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(n.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(n.parent_span_id)}));sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>s.id,{onDelete:"cascade"}),session_id:sqliteCore.text("session_id"),tool_name:sqliteCore.text("tool_name").notNull(),files:sqliteCore.text("files"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),duration_ms:sqliteCore.integer("duration_ms"),timestamp:sqliteCore.text("timestamp").notNull()},n=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(n.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(n.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(n.timestamp)}));sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>p.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),first_task_id:sqliteCore.text("first_task_id").notNull(),mid_task_id:sqliteCore.text("mid_task_id").notNull(),last_task_id:sqliteCore.text("last_task_id").notNull(),task_count:sqliteCore.integer("task_count").notNull(),summary:sqliteCore.text("summary"),source_tokens:sqliteCore.integer("source_tokens").notNull(),summary_tokens:sqliteCore.integer("summary_tokens"),created_at:sqliteCore.text("created_at").notNull()},n=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(n.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(n.thread_id,n.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(n.thread_id,n.seq)}));sqliteCore.sqliteTable("request_logs",{id:sqliteCore.text("id").primaryKey(),path:sqliteCore.text("path").notNull(),method:sqliteCore.text("method").notNull(),status_code:sqliteCore.integer("status_code").notNull(),duration_ms:sqliteCore.integer("duration_ms").notNull(),ip:sqliteCore.text("ip"),request_headers:sqliteCore.text("request_headers"),response_headers:sqliteCore.text("response_headers"),request_body:sqliteCore.text("request_body"),response_body:sqliteCore.text("response_body"),query:sqliteCore.text("query"),user_id:sqliteCore.text("user_id"),project_id:sqliteCore.text("project_id"),partition_key:sqliteCore.text("partition_key").notNull(),timestamp:sqliteCore.text("timestamp").notNull().default(drizzleOrm.sql`(datetime('now'))`),metadata:sqliteCore.text("metadata")},n=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(n.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(n.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(n.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(n.partition_key)}));sqliteCore.sqliteTable("usage_limit_snapshots",{id:sqliteCore.text("id").primaryKey(),provider:sqliteCore.text("provider").notNull(),account_ref:sqliteCore.text("account_ref").notNull().default("default"),limit_window:sqliteCore.text("limit_window").notNull(),bucket_start:sqliteCore.text("bucket_start").notNull(),captured_at:sqliteCore.text("captured_at").notNull(),used_percent:sqliteCore.integer("used_percent").notNull(),remaining_percent:sqliteCore.integer("remaining_percent").notNull(),resets_at:sqliteCore.text("resets_at"),source:sqliteCore.text("source").notNull(),metadata:sqliteCore.text("metadata")},n=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(n.provider,n.account_ref,n.limit_window,n.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(n.limit_window,n.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(n.provider,n.limit_window,n.bucket_start)}));sqliteCore.sqliteTable("usage_reports",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),month:sqliteCore.text("month").notNull(),generated_at:sqliteCore.text("generated_at").notNull(),source_range:sqliteCore.text("source_range").notNull(),tier:sqliteCore.text("tier").notNull(),total_tokens:sqliteCore.integer("total_tokens").notNull(),total_cost_usd:sqliteCore.real("total_cost_usd").notNull(),payload:sqliteCore.text("payload").notNull(),payload_hash:sqliteCore.text("payload_hash"),signature:sqliteCore.text("signature"),signed_at:sqliteCore.text("signed_at"),issuer:sqliteCore.text("issuer")},n=>({uniq_usage_reports_ws_month:sqliteCore.uniqueIndex("uniq_usage_reports_ws_month").on(n.workspace_id,n.month)}));sqliteCore.sqliteTable("notifications",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id"),task_id:sqliteCore.text("task_id"),thread_id:sqliteCore.text("thread_id"),source:sqliteCore.text("source").notNull().default("agent"),level:sqliteCore.text("level").notNull().default("info"),title:sqliteCore.text("title").notNull(),body:sqliteCore.text("body"),target_user_id:sqliteCore.text("target_user_id"),created_at:sqliteCore.text("created_at").notNull(),metadata:sqliteCore.text("metadata")},n=>({idx_notifications_ws_created:sqliteCore.index("idx_notifications_ws_created").on(n.workspace_id,drizzleOrm.sql`${n.created_at} DESC`)}));sqliteCore.sqliteTable("notification_reads",{notification_id:sqliteCore.text("notification_id").notNull(),user_id:sqliteCore.text("user_id").notNull(),read_at:sqliteCore.text("read_at").notNull()},n=>({pk:sqliteCore.primaryKey({columns:[n.notification_id,n.user_id]})}));sqliteCore.sqliteTable("agent_suggestions",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id").notNull(),task_id:sqliteCore.text("task_id"),type:sqliteCore.text("type").notNull(),status:sqliteCore.text("status").notNull().default("pending"),payload:sqliteCore.text("payload").notNull(),applied_commit_sha:sqliteCore.text("applied_commit_sha"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},n=>({idx_agent_suggestions_ws_agent:sqliteCore.index("idx_agent_suggestions_ws_agent").on(n.workspace_id,n.agent_id),idx_agent_suggestions_ws_created:sqliteCore.index("idx_agent_suggestions_ws_created").on(n.workspace_id,n.created_at)}));sqliteCore.sqliteTable("ui_instances",{id:sqliteCore.text("id").primaryKey().notNull(),definition_id:sqliteCore.text("definition_id").notNull(),definition_version:sqliteCore.integer("definition_version").notNull(),definition_hash:sqliteCore.text("definition_hash").notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),thread_id:sqliteCore.text("thread_id").notNull(),anchor_task_id:sqliteCore.text("anchor_task_id"),domain_ref_json:sqliteCore.text("domain_ref_json").notNull(),state_json:sqliteCore.text("state_json").notNull(),revision:sqliteCore.integer("revision").notNull().default(0),status:sqliteCore.text("status").notNull().default("active"),granted_capabilities_json:sqliteCore.text("granted_capabilities_json").notNull().default("[]"),created_at:sqliteCore.integer("created_at").notNull(),updated_at:sqliteCore.integer("updated_at").notNull()},n=>({idCheck:sqliteCore.check("ui_instances_id_ck",drizzleOrm.sql`length(${n.id}) BETWEEN 5 AND 128 AND ${n.id} GLOB 'uic_*'`),definitionIdCheck:sqliteCore.check("ui_instances_definition_id_ck",drizzleOrm.sql`length(${n.definition_id}) BETWEEN 1 AND 128`),definitionVersionCheck:sqliteCore.check("ui_instances_definition_version_ck",drizzleOrm.sql`${n.definition_version} >= 1`),definitionHashCheck:sqliteCore.check("ui_instances_definition_hash_ck",drizzleOrm.sql`length(${n.definition_hash}) = 64 AND ${n.definition_hash} NOT GLOB '*[^0-9a-f]*'`),workspaceIdCheck:sqliteCore.check("ui_instances_workspace_id_ck",drizzleOrm.sql`length(${n.workspace_id}) BETWEEN 1 AND 256`),threadIdCheck:sqliteCore.check("ui_instances_thread_id_ck",drizzleOrm.sql`length(${n.thread_id}) BETWEEN 1 AND 256`),domainRefJsonCheck:sqliteCore.check("ui_instances_domain_ref_json_ck",drizzleOrm.sql`json_valid(${n.domain_ref_json}) AND json_type(${n.domain_ref_json}) = 'object'`),stateJsonCheck:sqliteCore.check("ui_instances_state_json_ck",drizzleOrm.sql`json_valid(${n.state_json}) AND json_type(${n.state_json}) = 'object'`),revisionCheck:sqliteCore.check("ui_instances_revision_ck",drizzleOrm.sql`${n.revision} >= 0`),statusCheck:sqliteCore.check("ui_instances_status_ck",drizzleOrm.sql`${n.status} IN ('active', 'completed', 'expired', 'revoked', 'unsupported')`),grantedCapabilitiesJsonCheck:sqliteCore.check("ui_instances_granted_capabilities_json_ck",drizzleOrm.sql`json_valid(${n.granted_capabilities_json}) AND json_type(${n.granted_capabilities_json}) = 'array'`),createdAtCheck:sqliteCore.check("ui_instances_created_at_ck",drizzleOrm.sql`${n.created_at} >= 0`),updatedAtCheck:sqliteCore.check("ui_instances_updated_at_ck",drizzleOrm.sql`${n.updated_at} >= ${n.created_at}`),workspaceThreadIdx:sqliteCore.index("ui_instances_workspace_thread_idx").on(n.workspace_id,n.thread_id)}));sqliteCore.sqliteTable("ui_action_receipts",{id:sqliteCore.text("id").primaryKey().notNull(),instance_id:sqliteCore.text("instance_id").notNull(),request_id:sqliteCore.text("request_id").notNull(),action_id:sqliteCore.text("action_id").notNull(),actor_json:sqliteCore.text("actor_json").notNull(),source:sqliteCore.text("source").notNull(),expected_revision:sqliteCore.integer("expected_revision").notNull(),before_revision:sqliteCore.integer("before_revision").notNull(),after_revision:sqliteCore.integer("after_revision"),status:sqliteCore.text("status").notNull(),outcome:sqliteCore.text("outcome"),input_json:sqliteCore.text("input_json").notNull(),result_json:sqliteCore.text("result_json"),error_code:sqliteCore.text("error_code"),requested_at:sqliteCore.integer("requested_at").notNull(),settled_at:sqliteCore.integer("settled_at")},n=>({idCheck:sqliteCore.check("ui_action_receipts_id_ck",drizzleOrm.sql`length(${n.id}) BETWEEN 5 AND 128`),instanceIdCheck:sqliteCore.check("ui_action_receipts_instance_id_ck",drizzleOrm.sql`length(${n.instance_id}) BETWEEN 1 AND 128`),requestIdCheck:sqliteCore.check("ui_action_receipts_request_id_ck",drizzleOrm.sql`length(${n.request_id}) BETWEEN 1 AND 128`),actionIdCheck:sqliteCore.check("ui_action_receipts_action_id_ck",drizzleOrm.sql`length(${n.action_id}) BETWEEN 1 AND 128`),actorJsonCheck:sqliteCore.check("ui_action_receipts_actor_json_ck",drizzleOrm.sql`json_valid(${n.actor_json}) AND json_type(${n.actor_json}) = 'object'`),sourceCheck:sqliteCore.check("ui_action_receipts_source_ck",drizzleOrm.sql`${n.source} IN ('ui_host', 'cli', 'system')`),expectedRevisionCheck:sqliteCore.check("ui_action_receipts_expected_revision_ck",drizzleOrm.sql`${n.expected_revision} >= 0`),beforeRevisionCheck:sqliteCore.check("ui_action_receipts_before_revision_ck",drizzleOrm.sql`${n.before_revision} >= 0`),afterRevisionCheck:sqliteCore.check("ui_action_receipts_after_revision_ck",drizzleOrm.sql`${n.after_revision} IS NULL OR ${n.after_revision} >= 0`),statusCheck:sqliteCore.check("ui_action_receipts_status_ck",drizzleOrm.sql`${n.status} IN ('requested', 'settled')`),outcomeCheck:sqliteCore.check("ui_action_receipts_outcome_ck",drizzleOrm.sql`${n.outcome} IS NULL OR ${n.outcome} IN ('succeeded', 'rejected', 'failed', 'conflicted', 'expired')`),inputJsonCheck:sqliteCore.check("ui_action_receipts_input_json_ck",drizzleOrm.sql`json_valid(${n.input_json}) AND json_type(${n.input_json}) = 'object'`),resultJsonCheck:sqliteCore.check("ui_action_receipts_result_json_ck",drizzleOrm.sql`${n.result_json} IS NULL OR (json_valid(${n.result_json}) AND json_type(${n.result_json}) = 'object')`),requestedAtCheck:sqliteCore.check("ui_action_receipts_requested_at_ck",drizzleOrm.sql`${n.requested_at} >= 0`),settledAtCheck:sqliteCore.check("ui_action_receipts_settled_at_ck",drizzleOrm.sql`${n.settled_at} IS NULL OR ${n.settled_at} >= ${n.requested_at}`),statusTransitionCheck:sqliteCore.check("ui_action_receipts_status_transition_ck",drizzleOrm.sql`(
|
|
13
|
+
`)}`);let i=n.get(e`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;i?.cnt&&(a=n.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),nr(n,a),i?.cnt&&(or(n,s,e),sr(n,s,e)),t(n,{migrationsFolder:s});let c=(n.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-a;if(c>0){let l=i?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${l} (${c} migration${c>1?"s":""} applied).`);}}function et(n,t){Ge.has(t)||(ir(n),Ge.add(t));}var At=sqliteCore.sqliteTable("workspaces",{id:sqliteCore.text("id").primaryKey(),slug:sqliteCore.text("slug").notNull().unique(),name:sqliteCore.text("name").notNull(),workspace_path:sqliteCore.text("workspace_path"),description:sqliteCore.text("description"),is_active:sqliteCore.integer("is_active").notNull().default(1),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()});var o=sqliteCore.sqliteTable("tasks",{id:sqliteCore.text("id").primaryKey(),agent_id:sqliteCore.text("agent_id").notNull(),user_id:sqliteCore.text("user_id"),prompt:sqliteCore.text("prompt").notNull(),mode:sqliteCore.text("mode").notNull().default("execute"),status:sqliteCore.text("status").notNull().default("running"),result:sqliteCore.text("result"),error:sqliteCore.text("error"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),metadata:sqliteCore.text("metadata"),workspace_id:sqliteCore.text("workspace_id"),trace_id:sqliteCore.text("trace_id"),parent_task_id:sqliteCore.text("parent_task_id"),caller_agent_id:sqliteCore.text("caller_agent_id"),model:sqliteCore.text("model"),platform:sqliteCore.text("platform").default("cli"),crewx_version:sqliteCore.text("crewx_version"),input_tokens:sqliteCore.integer("input_tokens").default(0),output_tokens:sqliteCore.integer("output_tokens").default(0),cost_usd:sqliteCore.real("cost_usd").default(0),pid:sqliteCore.integer("pid"),rendered_prompt:sqliteCore.text("rendered_prompt"),command:sqliteCore.text("command"),coding_agent_command:sqliteCore.text("coding_agent_command"),exit_code:sqliteCore.integer("exit_code"),logs:sqliteCore.text("logs"),log_storage:sqliteCore.text("log_storage",{enum:["blob","events"]}).notNull().default("blob"),last_log_seq:sqliteCore.integer("last_log_seq").notNull().default(0),log_revision:sqliteCore.integer("log_revision").notNull().default(0),thread_id:sqliteCore.text("thread_id"),workspace_ref:sqliteCore.text("workspace_ref"),project_id:sqliteCore.text("project_id"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0),run_epoch:sqliteCore.integer("run_epoch").default(0)},n=>({log_storage_check:sqliteCore.check("tasks_log_storage_ck",drizzleOrm.sql`${n.log_storage} IN ('blob', 'events')`),idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(n.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(n.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(n.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(n.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(n.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(n.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(n.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(n.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(n.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(n.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(n.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(n.workspace_id,n.started_at)}));var nt=sqliteCore.sqliteTable("task_log_events",{id:sqliteCore.integer("id").primaryKey(),task_id:sqliteCore.text("task_id").notNull().references(()=>o.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),timestamp:sqliteCore.text("timestamp").notNull(),level:sqliteCore.text("level").notNull(),message:sqliteCore.text("message").notNull()},n=>({taskSeqUnique:sqliteCore.uniqueIndex("task_log_events_task_seq_uq").on(n.task_id,n.seq)}));var fr="json_extract(metadata, '$.threadTitle.state')",mr="json_extract(metadata, '$.threadTitle.priority')",h=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>At.id,{onDelete:"set null"}),platform:sqliteCore.text("platform").notNull().default("cli"),title:sqliteCore.text("title"),first_message:sqliteCore.text("first_message"),last_message:sqliteCore.text("last_message"),message_count:sqliteCore.integer("message_count").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),metadata:sqliteCore.text("metadata"),title_locked:sqliteCore.integer("title_locked").notNull().default(0),pinned:sqliteCore.integer("pinned").notNull().default(0),starred:sqliteCore.integer("starred").notNull().default(0)},n=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(n.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(n.workspace_id),idx_threads_ws_updated:sqliteCore.index("idx_threads_ws_updated").on(n.workspace_id,n.updated_at),idx_threads_title:sqliteCore.index("idx_threads_title").on(n.title),idx_threads_workspace_thread_state:sqliteCore.index("idx_threads_workspace_thread_state").on(n.workspace_id,drizzleOrm.sql.raw(fr)),idx_threads_workspace_thread_priority:sqliteCore.index("idx_threads_workspace_thread_priority").on(n.workspace_id,drizzleOrm.sql.raw(mr))}));var wr=sqliteCore.sqliteTable("spans",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>o.id,{onDelete:"set null"}),parent_span_id:sqliteCore.text("parent_span_id").references(()=>wr.id,{onDelete:"set null"}),name:sqliteCore.text("name").notNull(),kind:sqliteCore.text("kind").notNull().default("internal"),status:sqliteCore.text("status").notNull().default("ok"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),error:sqliteCore.text("error"),attributes:sqliteCore.text("attributes")},n=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(n.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(n.parent_span_id)}));sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>o.id,{onDelete:"cascade"}),session_id:sqliteCore.text("session_id"),tool_name:sqliteCore.text("tool_name").notNull(),files:sqliteCore.text("files"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),duration_ms:sqliteCore.integer("duration_ms"),timestamp:sqliteCore.text("timestamp").notNull()},n=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(n.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(n.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(n.timestamp)}));sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>h.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),first_task_id:sqliteCore.text("first_task_id").notNull(),mid_task_id:sqliteCore.text("mid_task_id").notNull(),last_task_id:sqliteCore.text("last_task_id").notNull(),task_count:sqliteCore.integer("task_count").notNull(),summary:sqliteCore.text("summary"),source_tokens:sqliteCore.integer("source_tokens").notNull(),summary_tokens:sqliteCore.integer("summary_tokens"),created_at:sqliteCore.text("created_at").notNull()},n=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(n.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(n.thread_id,n.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(n.thread_id,n.seq)}));sqliteCore.sqliteTable("request_logs",{id:sqliteCore.text("id").primaryKey(),path:sqliteCore.text("path").notNull(),method:sqliteCore.text("method").notNull(),status_code:sqliteCore.integer("status_code").notNull(),duration_ms:sqliteCore.integer("duration_ms").notNull(),ip:sqliteCore.text("ip"),request_headers:sqliteCore.text("request_headers"),response_headers:sqliteCore.text("response_headers"),request_body:sqliteCore.text("request_body"),response_body:sqliteCore.text("response_body"),query:sqliteCore.text("query"),user_id:sqliteCore.text("user_id"),project_id:sqliteCore.text("project_id"),partition_key:sqliteCore.text("partition_key").notNull(),timestamp:sqliteCore.text("timestamp").notNull().default(drizzleOrm.sql`(datetime('now'))`),metadata:sqliteCore.text("metadata")},n=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(n.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(n.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(n.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(n.partition_key)}));sqliteCore.sqliteTable("usage_limit_snapshots",{id:sqliteCore.text("id").primaryKey(),provider:sqliteCore.text("provider").notNull(),account_ref:sqliteCore.text("account_ref").notNull().default("default"),limit_window:sqliteCore.text("limit_window").notNull(),bucket_start:sqliteCore.text("bucket_start").notNull(),captured_at:sqliteCore.text("captured_at").notNull(),used_percent:sqliteCore.integer("used_percent").notNull(),remaining_percent:sqliteCore.integer("remaining_percent").notNull(),resets_at:sqliteCore.text("resets_at"),source:sqliteCore.text("source").notNull(),metadata:sqliteCore.text("metadata")},n=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(n.provider,n.account_ref,n.limit_window,n.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(n.limit_window,n.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(n.provider,n.limit_window,n.bucket_start)}));sqliteCore.sqliteTable("usage_reports",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),month:sqliteCore.text("month").notNull(),generated_at:sqliteCore.text("generated_at").notNull(),source_range:sqliteCore.text("source_range").notNull(),tier:sqliteCore.text("tier").notNull(),total_tokens:sqliteCore.integer("total_tokens").notNull(),total_cost_usd:sqliteCore.real("total_cost_usd").notNull(),payload:sqliteCore.text("payload").notNull(),payload_hash:sqliteCore.text("payload_hash"),signature:sqliteCore.text("signature"),signed_at:sqliteCore.text("signed_at"),issuer:sqliteCore.text("issuer")},n=>({uniq_usage_reports_ws_month:sqliteCore.uniqueIndex("uniq_usage_reports_ws_month").on(n.workspace_id,n.month)}));sqliteCore.sqliteTable("notifications",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id"),task_id:sqliteCore.text("task_id"),thread_id:sqliteCore.text("thread_id"),source:sqliteCore.text("source").notNull().default("agent"),level:sqliteCore.text("level").notNull().default("info"),title:sqliteCore.text("title").notNull(),body:sqliteCore.text("body"),target_user_id:sqliteCore.text("target_user_id"),created_at:sqliteCore.text("created_at").notNull(),metadata:sqliteCore.text("metadata")},n=>({idx_notifications_ws_created:sqliteCore.index("idx_notifications_ws_created").on(n.workspace_id,drizzleOrm.sql`${n.created_at} DESC`)}));sqliteCore.sqliteTable("notification_reads",{notification_id:sqliteCore.text("notification_id").notNull(),user_id:sqliteCore.text("user_id").notNull(),read_at:sqliteCore.text("read_at").notNull()},n=>({pk:sqliteCore.primaryKey({columns:[n.notification_id,n.user_id]})}));sqliteCore.sqliteTable("agent_suggestions",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").notNull(),agent_id:sqliteCore.text("agent_id").notNull(),task_id:sqliteCore.text("task_id"),type:sqliteCore.text("type").notNull(),status:sqliteCore.text("status").notNull().default("pending"),payload:sqliteCore.text("payload").notNull(),applied_commit_sha:sqliteCore.text("applied_commit_sha"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},n=>({idx_agent_suggestions_ws_agent:sqliteCore.index("idx_agent_suggestions_ws_agent").on(n.workspace_id,n.agent_id),idx_agent_suggestions_ws_created:sqliteCore.index("idx_agent_suggestions_ws_created").on(n.workspace_id,n.created_at)}));sqliteCore.sqliteTable("ui_instances",{id:sqliteCore.text("id").primaryKey().notNull(),definition_id:sqliteCore.text("definition_id").notNull(),definition_version:sqliteCore.integer("definition_version").notNull(),definition_hash:sqliteCore.text("definition_hash").notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),thread_id:sqliteCore.text("thread_id").notNull(),anchor_task_id:sqliteCore.text("anchor_task_id"),domain_ref_json:sqliteCore.text("domain_ref_json").notNull(),state_json:sqliteCore.text("state_json").notNull(),revision:sqliteCore.integer("revision").notNull().default(0),status:sqliteCore.text("status").notNull().default("active"),granted_capabilities_json:sqliteCore.text("granted_capabilities_json").notNull().default("[]"),created_at:sqliteCore.integer("created_at").notNull(),updated_at:sqliteCore.integer("updated_at").notNull()},n=>({idCheck:sqliteCore.check("ui_instances_id_ck",drizzleOrm.sql`length(${n.id}) BETWEEN 5 AND 128 AND ${n.id} GLOB 'uic_*'`),definitionIdCheck:sqliteCore.check("ui_instances_definition_id_ck",drizzleOrm.sql`length(${n.definition_id}) BETWEEN 1 AND 128`),definitionVersionCheck:sqliteCore.check("ui_instances_definition_version_ck",drizzleOrm.sql`${n.definition_version} >= 1`),definitionHashCheck:sqliteCore.check("ui_instances_definition_hash_ck",drizzleOrm.sql`length(${n.definition_hash}) = 64 AND ${n.definition_hash} NOT GLOB '*[^0-9a-f]*'`),workspaceIdCheck:sqliteCore.check("ui_instances_workspace_id_ck",drizzleOrm.sql`length(${n.workspace_id}) BETWEEN 1 AND 256`),threadIdCheck:sqliteCore.check("ui_instances_thread_id_ck",drizzleOrm.sql`length(${n.thread_id}) BETWEEN 1 AND 256`),domainRefJsonCheck:sqliteCore.check("ui_instances_domain_ref_json_ck",drizzleOrm.sql`json_valid(${n.domain_ref_json}) AND json_type(${n.domain_ref_json}) = 'object'`),stateJsonCheck:sqliteCore.check("ui_instances_state_json_ck",drizzleOrm.sql`json_valid(${n.state_json}) AND json_type(${n.state_json}) = 'object'`),revisionCheck:sqliteCore.check("ui_instances_revision_ck",drizzleOrm.sql`${n.revision} >= 0`),statusCheck:sqliteCore.check("ui_instances_status_ck",drizzleOrm.sql`${n.status} IN ('active', 'completed', 'expired', 'revoked', 'unsupported')`),grantedCapabilitiesJsonCheck:sqliteCore.check("ui_instances_granted_capabilities_json_ck",drizzleOrm.sql`json_valid(${n.granted_capabilities_json}) AND json_type(${n.granted_capabilities_json}) = 'array'`),createdAtCheck:sqliteCore.check("ui_instances_created_at_ck",drizzleOrm.sql`${n.created_at} >= 0`),updatedAtCheck:sqliteCore.check("ui_instances_updated_at_ck",drizzleOrm.sql`${n.updated_at} >= ${n.created_at}`),workspaceThreadIdx:sqliteCore.index("ui_instances_workspace_thread_idx").on(n.workspace_id,n.thread_id)}));sqliteCore.sqliteTable("ui_action_receipts",{id:sqliteCore.text("id").primaryKey().notNull(),instance_id:sqliteCore.text("instance_id").notNull(),request_id:sqliteCore.text("request_id").notNull(),action_id:sqliteCore.text("action_id").notNull(),actor_json:sqliteCore.text("actor_json").notNull(),source:sqliteCore.text("source").notNull(),expected_revision:sqliteCore.integer("expected_revision").notNull(),before_revision:sqliteCore.integer("before_revision").notNull(),after_revision:sqliteCore.integer("after_revision"),status:sqliteCore.text("status").notNull(),outcome:sqliteCore.text("outcome"),input_json:sqliteCore.text("input_json").notNull(),result_json:sqliteCore.text("result_json"),error_code:sqliteCore.text("error_code"),requested_at:sqliteCore.integer("requested_at").notNull(),settled_at:sqliteCore.integer("settled_at")},n=>({idCheck:sqliteCore.check("ui_action_receipts_id_ck",drizzleOrm.sql`length(${n.id}) BETWEEN 5 AND 128`),instanceIdCheck:sqliteCore.check("ui_action_receipts_instance_id_ck",drizzleOrm.sql`length(${n.instance_id}) BETWEEN 1 AND 128`),requestIdCheck:sqliteCore.check("ui_action_receipts_request_id_ck",drizzleOrm.sql`length(${n.request_id}) BETWEEN 1 AND 128`),actionIdCheck:sqliteCore.check("ui_action_receipts_action_id_ck",drizzleOrm.sql`length(${n.action_id}) BETWEEN 1 AND 128`),actorJsonCheck:sqliteCore.check("ui_action_receipts_actor_json_ck",drizzleOrm.sql`json_valid(${n.actor_json}) AND json_type(${n.actor_json}) = 'object'`),sourceCheck:sqliteCore.check("ui_action_receipts_source_ck",drizzleOrm.sql`${n.source} IN ('ui_host', 'cli', 'system')`),expectedRevisionCheck:sqliteCore.check("ui_action_receipts_expected_revision_ck",drizzleOrm.sql`${n.expected_revision} >= 0`),beforeRevisionCheck:sqliteCore.check("ui_action_receipts_before_revision_ck",drizzleOrm.sql`${n.before_revision} >= 0`),afterRevisionCheck:sqliteCore.check("ui_action_receipts_after_revision_ck",drizzleOrm.sql`${n.after_revision} IS NULL OR ${n.after_revision} >= 0`),statusCheck:sqliteCore.check("ui_action_receipts_status_ck",drizzleOrm.sql`${n.status} IN ('requested', 'settled')`),outcomeCheck:sqliteCore.check("ui_action_receipts_outcome_ck",drizzleOrm.sql`${n.outcome} IS NULL OR ${n.outcome} IN ('succeeded', 'rejected', 'failed', 'conflicted', 'expired')`),inputJsonCheck:sqliteCore.check("ui_action_receipts_input_json_ck",drizzleOrm.sql`json_valid(${n.input_json}) AND json_type(${n.input_json}) = 'object'`),resultJsonCheck:sqliteCore.check("ui_action_receipts_result_json_ck",drizzleOrm.sql`${n.result_json} IS NULL OR (json_valid(${n.result_json}) AND json_type(${n.result_json}) = 'object')`),requestedAtCheck:sqliteCore.check("ui_action_receipts_requested_at_ck",drizzleOrm.sql`${n.requested_at} >= 0`),settledAtCheck:sqliteCore.check("ui_action_receipts_settled_at_ck",drizzleOrm.sql`${n.settled_at} IS NULL OR ${n.settled_at} >= ${n.requested_at}`),statusTransitionCheck:sqliteCore.check("ui_action_receipts_status_transition_ck",drizzleOrm.sql`(
|
|
14
14
|
(${n.status} = 'requested' AND ${n.after_revision} IS NULL AND ${n.outcome} IS NULL AND ${n.settled_at} IS NULL)
|
|
15
15
|
OR
|
|
16
16
|
(${n.status} = 'settled' AND ${n.after_revision} IS NOT NULL AND ${n.outcome} IS NOT NULL AND ${n.settled_at} IS NOT NULL)
|
|
17
|
-
)`),instanceRequestUnique:sqliteCore.uniqueIndex("ui_action_receipts_instance_request_uq").on(n.instance_id,n.request_id),instanceIdIdx:sqliteCore.index("ui_action_receipts_instance_id_idx").on(n.instance_id),requestedAtIdx:sqliteCore.index("ui_action_receipts_requested_at_idx").on(n.requested_at)}));var Ge=sqliteCore.sqliteTable("projects",{id:sqliteCore.text("id").primaryKey().notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),name:sqliteCore.text("name").notNull(),outcome:sqliteCore.text("outcome").notNull(),due_date:sqliteCore.text("due_date"),scene:sqliteCore.text("scene").notNull().default("planning"),stages_json:sqliteCore.text("stages_json").notNull(),stage_index:sqliteCore.integer("stage_index").notNull(),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),accepted_at:sqliteCore.text("accepted_at"),archived_at:sqliteCore.text("archived_at")},n=>({idCheck:sqliteCore.check("projects_id_ck",drizzleOrm.sql`${n.id} GLOB 'prj_*'`),sceneCheck:sqliteCore.check("projects_scene_ck",drizzleOrm.sql`${n.scene} IN ('planning', 'plan_review', 'running', 'human_wait', 'limit_wait', 'failed_stop', 'analyzing_feedback', 'replanned', 'awaiting_review', 'accepted')`),stagesJsonCheck:sqliteCore.check("projects_stages_json_ck",drizzleOrm.sql`json_valid(${n.stages_json}) AND json_type(${n.stages_json}) = 'array'`),stageIndexCheck:sqliteCore.check("projects_stage_index_ck",drizzleOrm.sql`${n.stage_index} >= 1`)}));sqliteCore.sqliteTable("project_criteria",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>Ge.id,{onDelete:"cascade"}),position:sqliteCore.integer("position").notNull(),statement:sqliteCore.text("statement").notNull(),verify_status:sqliteCore.text("verify_status").notNull().default("pending"),verified_at:sqliteCore.text("verified_at"),evidence_json:sqliteCore.text("evidence_json").notNull().default("[]"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},n=>({idCheck:sqliteCore.check("project_criteria_id_ck",drizzleOrm.sql`${n.id} GLOB 'pjc_*'`),verifyStatusCheck:sqliteCore.check("project_criteria_verify_status_ck",drizzleOrm.sql`${n.verify_status} IN ('pending', 'verifying', 'passed', 'failed')`),evidenceJsonCheck:sqliteCore.check("project_criteria_evidence_json_ck",drizzleOrm.sql`json_valid(${n.evidence_json}) AND json_type(${n.evidence_json}) = 'array'`),projectPositionUnique:sqliteCore.uniqueIndex("project_criteria_project_position_uq").on(n.project_id,n.position)}));sqliteCore.sqliteTable("project_events",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>Ge.id,{onDelete:"restrict"}),seq:sqliteCore.integer("seq").notNull(),actor_type:sqliteCore.text("actor_type").notNull(),actor_id:sqliteCore.text("actor_id"),type:sqliteCore.text("type").notNull(),title:sqliteCore.text("title").notNull(),summary:sqliteCore.text("summary"),payload_json:sqliteCore.text("payload_json").notNull().default("{}"),created_at:sqliteCore.text("created_at").notNull()},n=>({idCheck:sqliteCore.check("project_events_id_ck",drizzleOrm.sql`${n.id} GLOB 'pje_*'`),actorTypeCheck:sqliteCore.check("project_events_actor_type_ck",drizzleOrm.sql`${n.actor_type} IN ('user', 'project_manager', 'system')`),payloadJsonCheck:sqliteCore.check("project_events_payload_json_ck",drizzleOrm.sql`json_valid(${n.payload_json}) AND json_type(${n.payload_json}) = 'object'`),projectSeqUnique:sqliteCore.uniqueIndex("project_events_project_seq_uq").on(n.project_id,n.seq)}));sqliteCore.sqliteTable("common_codes",{code_group:sqliteCore.text("code_group").notNull(),code:sqliteCore.text("code").notNull(),code_name:sqliteCore.text("code_name"),color:sqliteCore.text("color").notNull().default("gray"),sort_order:sqliteCore.integer("sort_order").notNull(),workspace_id:sqliteCore.text("workspace_id"),is_builtin:sqliteCore.integer("is_builtin").notNull().default(0),is_archived:sqliteCore.integer("is_archived").notNull().default(0),metadata:sqliteCore.text("metadata"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},n=>({pk:sqliteCore.primaryKey({columns:[n.code_group,n.code]}),metadataCheck:sqliteCore.check("common_codes_metadata_ck",drizzleOrm.sql`${n.metadata} IS NULL OR (json_valid(${n.metadata}) AND json_type(${n.metadata}) = 'object')`),builtinCheck:sqliteCore.check("common_codes_builtin_ck",drizzleOrm.sql`${n.is_builtin} IN (0, 1)`),archivedCheck:sqliteCore.check("common_codes_archived_ck",drizzleOrm.sql`${n.is_archived} IN (0, 1)`),idxCommonCodesSelection:sqliteCore.index("idx_common_codes_group_archived_order").on(n.code_group,n.is_archived,n.sort_order)}));var Je=["thread.snapshot.imported","thread.title.changed","thread.priority.changed","thread.state.changed","thread.highlight.created","thread.highlight.updated","thread.highlight.deleted"],Qe=["user","agent","system"],Ze=["auto","manual"],tn=["decision","judgment","issue","result","pivot"];var E=sqliteCore.sqliteTable("thread_events",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>p.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),type:sqliteCore.text("type").notNull(),actor_type:sqliteCore.text("actor_type").notNull(),payload_json:sqliteCore.text("payload_json").notNull(),created_at:sqliteCore.text("created_at").notNull(),actor_id:sqliteCore.text("actor_id"),task_id:sqliteCore.text("task_id"),highlight_id:sqliteCore.text("highlight_id")},n=>({typeCheck:sqliteCore.check("thread_events_type_ck",drizzleOrm.sql`${n.type} IN ('thread.snapshot.imported', 'thread.title.changed', 'thread.priority.changed', 'thread.state.changed', 'thread.highlight.created', 'thread.highlight.updated', 'thread.highlight.deleted')`),actorTypeCheck:sqliteCore.check("thread_events_actor_type_ck",drizzleOrm.sql`${n.actor_type} IN ('user', 'agent', 'system')`),payloadJsonCheck:sqliteCore.check("thread_events_payload_json_ck",drizzleOrm.sql`json_valid(${n.payload_json}) AND json_type(${n.payload_json}) = 'object'`),threadSeqIndex:sqliteCore.index("idx_thread_events_thread_seq").on(n.thread_id,n.seq),threadCreatedIndex:sqliteCore.index("idx_thread_events_thread_created").on(n.thread_id,n.created_at),threadSeqUnique:sqliteCore.uniqueIndex("thread_events_thread_seq_uq").on(n.thread_id,n.seq)})),y=sqliteCore.sqliteTable("thread_highlights",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>p.id,{onDelete:"cascade"}),source:sqliteCore.text("source").notNull(),kind:sqliteCore.text("kind").notNull(),status:sqliteCore.text("status").notNull().default("active"),text:sqliteCore.text("text"),covers_from_task_id:sqliteCore.text("covers_from_task_id").notNull(),covers_to_task_id:sqliteCore.text("covers_to_task_id").notNull(),revision:sqliteCore.integer("revision").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),agent_id:sqliteCore.text("agent_id"),source_task_id:sqliteCore.text("source_task_id"),detector_version:sqliteCore.text("detector_version"),content_fingerprint:sqliteCore.text("content_fingerprint"),dismissed_at:sqliteCore.text("dismissed_at")},n=>({sourceCheck:sqliteCore.check("thread_highlights_source_ck",drizzleOrm.sql`${n.source} IN ('auto', 'manual')`),kindCheck:sqliteCore.check("thread_highlights_kind_ck",drizzleOrm.sql`${n.kind} IN ('decision', 'judgment', 'issue', 'result', 'pivot')`),statusCheck:sqliteCore.check("thread_highlights_status_ck",drizzleOrm.sql`${n.status} IN ('active', 'dismissed')`),activeTextCheck:sqliteCore.check("thread_highlights_active_text_ck",drizzleOrm.sql`${n.status} = 'dismissed' OR (${n.text} IS NOT NULL AND length(${n.text}) > 0)`),coversCheck:sqliteCore.check("thread_highlights_covers_ck",drizzleOrm.sql`length(${n.covers_from_task_id}) > 0 AND length(${n.covers_to_task_id}) > 0`),autoKeyCheck:sqliteCore.check("thread_highlights_auto_key_ck",drizzleOrm.sql`${n.source} = 'manual' OR (${n.source} = 'auto' AND ${n.source_task_id} IS NOT NULL AND ${n.detector_version} IS NOT NULL AND ${n.content_fingerprint} IS NOT NULL AND length(${n.source_task_id}) > 0 AND length(${n.detector_version}) > 0 AND length(${n.content_fingerprint}) > 0)`),threadStatusCreatedIndex:sqliteCore.index("idx_thread_highlights_thread_status_created").on(n.thread_id,n.status,n.created_at),threadCoversIndex:sqliteCore.index("idx_thread_highlights_thread_covers").on(n.thread_id,n.covers_from_task_id,n.covers_to_task_id),autoIdempotencyUnique:sqliteCore.uniqueIndex("thread_highlights_auto_idempotency_uq").on(n.thread_id,n.source_task_id,n.detector_version,n.content_fingerprint).where(drizzleOrm.sql`${n.source} = 'auto'`)}));function en(n){let t=n.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let e=t.lastIndexOf("/");return e>=0&&(t=t.slice(e+1)),t=t.replace(/-\d{8}$/,""),t}function an(n,t){let e=t===void 0?"":` at index ${t}`;if(!n||typeof n!="object")throw new _("VALIDATION",`Task log entry${e} must be an object`);if(typeof n.timestamp!="string"||typeof n.level!="string"||typeof n.message!="string")throw new _("VALIDATION",`Task log entry${e} must contain string timestamp, level, and message fields`);return {timestamp:n.timestamp,level:n.level,message:n.message}}function sn(n,t){if(t===null||t.trim()==="")return [];let e;try{e=JSON.parse(t);}catch(r){throw new _("DB_ERROR",`Malformed legacy task logs: ${n}`,r)}if(!Array.isArray(e))throw new _("DB_ERROR",`Malformed legacy task logs: ${n} (expected an array)`);try{return e.map((r,i)=>an(r,i))}catch(r){throw r instanceof _?new _("DB_ERROR",`Malformed legacy task logs: ${n}`,r):r}}function dn(n){if(n.log_storage!=="blob"&&n.log_storage!=="events")throw new _("DB_ERROR",`Invalid task log storage for task: ${n.id}`);if(!Number.isInteger(n.last_log_seq)||n.last_log_seq<0)throw new _("DB_ERROR",`Invalid task log sequence for task: ${n.id}`);if(!Number.isInteger(n.log_revision)||n.log_revision<0)throw new _("DB_ERROR",`Invalid task log revision for task: ${n.id}`);return n.log_storage}function on(n){return {taskId:n.id,source:dn(n),revision:n.log_revision,lastSeq:n.last_log_seq}}function Lr(n){if(!Number.isInteger(n)||n<0)throw new _("VALIDATION","Task log tail limit must be a non-negative integer")}var Vt=class extends Y{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let i=rt.dirname(e);fs.existsSync(i)||fs.mkdirSync(i,{recursive:true});}else if(!fs.existsSync(e))throw new _("NOT_FOUND","Database not found");let r=b(e);if(t)try{ht(r.db,e);}catch(i){throw r.close(),i}return r}findStateRow(t,e){return t.db.select({id:s.id,log_storage:s.log_storage,last_log_seq:s.last_log_seq,log_revision:s.log_revision,logs:s.logs}).from(s).where(drizzleOrm.eq(s.id,e)).limit(1).get()}findStateRowInTransaction(t,e){return t.select({id:s.id,log_storage:s.log_storage,last_log_seq:s.last_log_seq,log_revision:s.log_revision,logs:s.logs}).from(s).where(drizzleOrm.eq(s.id,e)).limit(1).get()}requireStateRowInTransaction(t,e){let r=this.findStateRowInTransaction(t,e);if(!r)throw new _("NOT_FOUND",`Task not found: ${e}`);return r}appendLog(t,e){return this.appendLogs(t,[e])}appendLogs(t,e){let r=e.map((o,a)=>an(o,a));if(r.length===0){let o=this.getLogState(t);if(!o)throw new _("NOT_FOUND",`Task not found: ${t}`);return o}let i=this.openHandle(true);try{return i.db.transaction(a=>{let d=this.requireStateRowInTransaction(a,t),c=dn(d);if(c==="blob"){let g=sn(t,d.logs);if(a.update(s).set({logs:JSON.stringify([...g,...r]),log_revision:drizzleOrm.sql`${s.log_revision} + 1`}).where(drizzleOrm.eq(s.id,t)).run().changes!==1)throw new _("NOT_FOUND",`Task not found: ${t}`);return {taskId:t,source:c,revision:d.log_revision+1,lastSeq:d.last_log_seq}}let l=d.last_log_seq+1,u=d.last_log_seq+r.length;if(a.insert(J).values(r.map((g,f)=>({task_id:t,seq:l+f,timestamp:g.timestamp,level:g.level,message:g.message}))).run(),a.update(s).set({last_log_seq:u,log_revision:drizzleOrm.sql`${s.log_revision} + 1`}).where(drizzleOrm.eq(s.id,t)).run().changes!==1)throw new _("NOT_FOUND",`Task not found: ${t}`);return {taskId:t,source:c,revision:d.log_revision+1,lastSeq:u}},{behavior:"immediate"})}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to append task log",o)}finally{i.close();}}getLogState(t){if(!this.dbExists())return;let e=this.openHandle(false);try{let r=this.findStateRow(e,t);return r?on(r):void 0}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to read task log state",r)}finally{e.close();}}readLogs(t){return this.readLogsInternal(t)}readLogsTail(t,e){return Lr(e),this.readLogsInternal(t,e)}readTail(t,e){return this.readLogsTail(t,e)}readLogsInternal(t,e){if(!this.dbExists())return;let r=this.openHandle(false);try{return r.db.transaction(i=>{let o=this.findStateRowInTransaction(i,t);if(!o)return;let a=on(o);if(a.source==="blob"){let u=sn(t,o.logs);return {...a,entries:e===void 0?u:u.slice(Math.max(0,u.length-e))}}let d=i.select({seq:J.seq,timestamp:J.timestamp,level:J.level,message:J.message}).from(J).where(drizzleOrm.eq(J.task_id,t)).orderBy(e===void 0?drizzleOrm.asc(J.seq):drizzleOrm.desc(J.seq)),l=(e===void 0?d.all():d.limit(e).all()).map(({timestamp:u,level:h,message:g})=>({timestamp:u,level:h,message:g}));return e!==void 0&&l.reverse(),{...a,entries:l}},{behavior:"deferred"})}catch(i){throw i instanceof _?i:new _("DB_ERROR","Failed to read task logs",i)}finally{r.close();}}};var me=40,lt="2026-05-09",jr="0.8.9-rc.13",ut=10,_t=parseInt(jr.split("rc.")[1]);function cn(){let n=drizzleOrm.sql`
|
|
17
|
+
)`),instanceRequestUnique:sqliteCore.uniqueIndex("ui_action_receipts_instance_request_uq").on(n.instance_id,n.request_id),instanceIdIdx:sqliteCore.index("ui_action_receipts_instance_id_idx").on(n.instance_id),requestedAtIdx:sqliteCore.index("ui_action_receipts_requested_at_idx").on(n.requested_at)}));var on=sqliteCore.sqliteTable("projects",{id:sqliteCore.text("id").primaryKey().notNull(),workspace_id:sqliteCore.text("workspace_id").notNull(),name:sqliteCore.text("name").notNull(),outcome:sqliteCore.text("outcome").notNull(),due_date:sqliteCore.text("due_date"),scene:sqliteCore.text("scene").notNull().default("planning"),stages_json:sqliteCore.text("stages_json").notNull(),stage_index:sqliteCore.integer("stage_index").notNull(),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),accepted_at:sqliteCore.text("accepted_at"),archived_at:sqliteCore.text("archived_at")},n=>({idCheck:sqliteCore.check("projects_id_ck",drizzleOrm.sql`${n.id} GLOB 'prj_*'`),sceneCheck:sqliteCore.check("projects_scene_ck",drizzleOrm.sql`${n.scene} IN ('planning', 'plan_review', 'running', 'human_wait', 'limit_wait', 'failed_stop', 'analyzing_feedback', 'replanned', 'awaiting_review', 'accepted')`),stagesJsonCheck:sqliteCore.check("projects_stages_json_ck",drizzleOrm.sql`json_valid(${n.stages_json}) AND json_type(${n.stages_json}) = 'array'`),stageIndexCheck:sqliteCore.check("projects_stage_index_ck",drizzleOrm.sql`${n.stage_index} >= 1`)}));sqliteCore.sqliteTable("project_criteria",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>on.id,{onDelete:"cascade"}),position:sqliteCore.integer("position").notNull(),statement:sqliteCore.text("statement").notNull(),verify_status:sqliteCore.text("verify_status").notNull().default("pending"),verified_at:sqliteCore.text("verified_at"),evidence_json:sqliteCore.text("evidence_json").notNull().default("[]"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},n=>({idCheck:sqliteCore.check("project_criteria_id_ck",drizzleOrm.sql`${n.id} GLOB 'pjc_*'`),verifyStatusCheck:sqliteCore.check("project_criteria_verify_status_ck",drizzleOrm.sql`${n.verify_status} IN ('pending', 'verifying', 'passed', 'failed')`),evidenceJsonCheck:sqliteCore.check("project_criteria_evidence_json_ck",drizzleOrm.sql`json_valid(${n.evidence_json}) AND json_type(${n.evidence_json}) = 'array'`),projectPositionUnique:sqliteCore.uniqueIndex("project_criteria_project_position_uq").on(n.project_id,n.position)}));sqliteCore.sqliteTable("project_events",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>on.id,{onDelete:"restrict"}),seq:sqliteCore.integer("seq").notNull(),actor_type:sqliteCore.text("actor_type").notNull(),actor_id:sqliteCore.text("actor_id"),type:sqliteCore.text("type").notNull(),title:sqliteCore.text("title").notNull(),summary:sqliteCore.text("summary"),payload_json:sqliteCore.text("payload_json").notNull().default("{}"),created_at:sqliteCore.text("created_at").notNull()},n=>({idCheck:sqliteCore.check("project_events_id_ck",drizzleOrm.sql`${n.id} GLOB 'pje_*'`),actorTypeCheck:sqliteCore.check("project_events_actor_type_ck",drizzleOrm.sql`${n.actor_type} IN ('user', 'project_manager', 'system')`),payloadJsonCheck:sqliteCore.check("project_events_payload_json_ck",drizzleOrm.sql`json_valid(${n.payload_json}) AND json_type(${n.payload_json}) = 'object'`),projectSeqUnique:sqliteCore.uniqueIndex("project_events_project_seq_uq").on(n.project_id,n.seq)}));var Ie=["THREAD_STATE","THREAD_PRIORITY"],ve=["gray","blue","violet","green","amber","orange","red","pink"],m=sqliteCore.sqliteTable("common_codes",{code_group:sqliteCore.text("code_group").notNull(),code:sqliteCore.text("code").notNull(),code_name:sqliteCore.text("code_name"),color:sqliteCore.text("color").notNull().default("gray"),sort_order:sqliteCore.integer("sort_order").notNull(),workspace_id:sqliteCore.text("workspace_id"),is_builtin:sqliteCore.integer("is_builtin").notNull().default(0),is_archived:sqliteCore.integer("is_archived").notNull().default(0),metadata:sqliteCore.text("metadata"),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull()},n=>({pk:sqliteCore.primaryKey({columns:[n.code_group,n.code]}),metadataCheck:sqliteCore.check("common_codes_metadata_ck",drizzleOrm.sql`${n.metadata} IS NULL OR (json_valid(${n.metadata}) AND json_type(${n.metadata}) = 'object')`),builtinCheck:sqliteCore.check("common_codes_builtin_ck",drizzleOrm.sql`${n.is_builtin} IN (0, 1)`),archivedCheck:sqliteCore.check("common_codes_archived_ck",drizzleOrm.sql`${n.is_archived} IN (0, 1)`),idxCommonCodesSelection:sqliteCore.index("idx_common_codes_group_archived_order").on(n.code_group,n.is_archived,n.sort_order)}));var ln=["thread.snapshot.imported","thread.title.changed","thread.priority.changed","thread.state.changed","thread.highlight.created","thread.highlight.updated","thread.highlight.deleted"],un=["user","agent","system"],_n=["auto","manual"],hn=["decision","judgment","issue","result","pivot"];var R=sqliteCore.sqliteTable("thread_events",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>h.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),type:sqliteCore.text("type").notNull(),actor_type:sqliteCore.text("actor_type").notNull(),payload_json:sqliteCore.text("payload_json").notNull(),created_at:sqliteCore.text("created_at").notNull(),actor_id:sqliteCore.text("actor_id"),task_id:sqliteCore.text("task_id"),highlight_id:sqliteCore.text("highlight_id")},n=>({typeCheck:sqliteCore.check("thread_events_type_ck",drizzleOrm.sql`${n.type} IN ('thread.snapshot.imported', 'thread.title.changed', 'thread.priority.changed', 'thread.state.changed', 'thread.highlight.created', 'thread.highlight.updated', 'thread.highlight.deleted')`),actorTypeCheck:sqliteCore.check("thread_events_actor_type_ck",drizzleOrm.sql`${n.actor_type} IN ('user', 'agent', 'system')`),payloadJsonCheck:sqliteCore.check("thread_events_payload_json_ck",drizzleOrm.sql`json_valid(${n.payload_json}) AND json_type(${n.payload_json}) = 'object'`),threadSeqIndex:sqliteCore.index("idx_thread_events_thread_seq").on(n.thread_id,n.seq),threadCreatedIndex:sqliteCore.index("idx_thread_events_thread_created").on(n.thread_id,n.created_at),threadSeqUnique:sqliteCore.uniqueIndex("thread_events_thread_seq_uq").on(n.thread_id,n.seq)})),E=sqliteCore.sqliteTable("thread_highlights",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>h.id,{onDelete:"cascade"}),source:sqliteCore.text("source").notNull(),kind:sqliteCore.text("kind").notNull(),status:sqliteCore.text("status").notNull().default("active"),text:sqliteCore.text("text"),covers_from_task_id:sqliteCore.text("covers_from_task_id").notNull(),covers_to_task_id:sqliteCore.text("covers_to_task_id").notNull(),revision:sqliteCore.integer("revision").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),agent_id:sqliteCore.text("agent_id"),source_task_id:sqliteCore.text("source_task_id"),detector_version:sqliteCore.text("detector_version"),content_fingerprint:sqliteCore.text("content_fingerprint"),dismissed_at:sqliteCore.text("dismissed_at")},n=>({sourceCheck:sqliteCore.check("thread_highlights_source_ck",drizzleOrm.sql`${n.source} IN ('auto', 'manual')`),kindCheck:sqliteCore.check("thread_highlights_kind_ck",drizzleOrm.sql`${n.kind} IN ('decision', 'judgment', 'issue', 'result', 'pivot')`),statusCheck:sqliteCore.check("thread_highlights_status_ck",drizzleOrm.sql`${n.status} IN ('active', 'dismissed')`),activeTextCheck:sqliteCore.check("thread_highlights_active_text_ck",drizzleOrm.sql`${n.status} = 'dismissed' OR (${n.text} IS NOT NULL AND length(${n.text}) > 0)`),coversCheck:sqliteCore.check("thread_highlights_covers_ck",drizzleOrm.sql`length(${n.covers_from_task_id}) > 0 AND length(${n.covers_to_task_id}) > 0`),autoKeyCheck:sqliteCore.check("thread_highlights_auto_key_ck",drizzleOrm.sql`${n.source} = 'manual' OR (${n.source} = 'auto' AND ${n.source_task_id} IS NOT NULL AND ${n.detector_version} IS NOT NULL AND ${n.content_fingerprint} IS NOT NULL AND length(${n.source_task_id}) > 0 AND length(${n.detector_version}) > 0 AND length(${n.content_fingerprint}) > 0)`),threadStatusCreatedIndex:sqliteCore.index("idx_thread_highlights_thread_status_created").on(n.thread_id,n.status,n.created_at),threadCoversIndex:sqliteCore.index("idx_thread_highlights_thread_covers").on(n.thread_id,n.covers_from_task_id,n.covers_to_task_id),autoIdempotencyUnique:sqliteCore.uniqueIndex("thread_highlights_auto_idempotency_uq").on(n.thread_id,n.source_task_id,n.detector_version,n.content_fingerprint).where(drizzleOrm.sql`${n.source} = 'auto'`)}));function pn(n){let t=n.toLowerCase().trim();t=t.replace(/\[[^\]]*\]$/g,"");let e=t.lastIndexOf("/");return e>=0&&(t=t.slice(e+1)),t=t.replace(/-\d{8}$/,""),t}function Tn(n,t){let e=t===void 0?"":` at index ${t}`;if(!n||typeof n!="object")throw new u("VALIDATION",`Task log entry${e} must be an object`);if(typeof n.timestamp!="string"||typeof n.level!="string"||typeof n.message!="string")throw new u("VALIDATION",`Task log entry${e} must contain string timestamp, level, and message fields`);return {timestamp:n.timestamp,level:n.level,message:n.message}}function mn(n,t){if(t===null||t.trim()==="")return [];let e;try{e=JSON.parse(t);}catch(r){throw new u("DB_ERROR",`Malformed legacy task logs: ${n}`,r)}if(!Array.isArray(e))throw new u("DB_ERROR",`Malformed legacy task logs: ${n} (expected an array)`);try{return e.map((r,s)=>Tn(r,s))}catch(r){throw r instanceof u?new u("DB_ERROR",`Malformed legacy task logs: ${n}`,r):r}}function wn(n){if(n.log_storage!=="blob"&&n.log_storage!=="events")throw new u("DB_ERROR",`Invalid task log storage for task: ${n.id}`);if(!Number.isInteger(n.last_log_seq)||n.last_log_seq<0)throw new u("DB_ERROR",`Invalid task log sequence for task: ${n.id}`);if(!Number.isInteger(n.log_revision)||n.log_revision<0)throw new u("DB_ERROR",`Invalid task log revision for task: ${n.id}`);return n.log_storage}function kn(n){return {taskId:n.id,source:wn(n),revision:n.log_revision,lastSeq:n.last_log_seq}}function Jr(n){if(!Number.isInteger(n)||n<0)throw new u("VALIDATION","Task log tail limit must be a non-negative integer")}var re=class extends X{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=dt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=dt.dirname(e);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}else if(!fs$1.existsSync(e))throw new u("NOT_FOUND","Database not found");let r=N(e);if(t)try{et(r.db,e);}catch(s){throw r.close(),s}return r}findStateRow(t,e){return t.db.select({id:o.id,log_storage:o.log_storage,last_log_seq:o.last_log_seq,log_revision:o.log_revision,logs:o.logs}).from(o).where(drizzleOrm.eq(o.id,e)).limit(1).get()}findStateRowInTransaction(t,e){return t.select({id:o.id,log_storage:o.log_storage,last_log_seq:o.last_log_seq,log_revision:o.log_revision,logs:o.logs}).from(o).where(drizzleOrm.eq(o.id,e)).limit(1).get()}requireStateRowInTransaction(t,e){let r=this.findStateRowInTransaction(t,e);if(!r)throw new u("NOT_FOUND",`Task not found: ${e}`);return r}appendLog(t,e){return this.appendLogs(t,[e])}appendLogs(t,e){let r=e.map((i,a)=>Tn(i,a));if(r.length===0){let i=this.getLogState(t);if(!i)throw new u("NOT_FOUND",`Task not found: ${t}`);return i}let s=this.openHandle(true);try{return s.db.transaction(a=>{let d=this.requireStateRowInTransaction(a,t),c=wn(d);if(c==="blob"){let g=mn(t,d.logs);if(a.update(o).set({logs:JSON.stringify([...g,...r]),log_revision:drizzleOrm.sql`${o.log_revision} + 1`}).where(drizzleOrm.eq(o.id,t)).run().changes!==1)throw new u("NOT_FOUND",`Task not found: ${t}`);return {taskId:t,source:c,revision:d.log_revision+1,lastSeq:d.last_log_seq}}let l=d.last_log_seq+1,_=d.last_log_seq+r.length;if(a.insert(nt).values(r.map((g,f)=>({task_id:t,seq:l+f,timestamp:g.timestamp,level:g.level,message:g.message}))).run(),a.update(o).set({last_log_seq:_,log_revision:drizzleOrm.sql`${o.log_revision} + 1`}).where(drizzleOrm.eq(o.id,t)).run().changes!==1)throw new u("NOT_FOUND",`Task not found: ${t}`);return {taskId:t,source:c,revision:d.log_revision+1,lastSeq:_}},{behavior:"immediate"})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to append task log",i)}finally{s.close();}}getLogState(t){if(!this.dbExists())return;let e=this.openHandle(false);try{let r=this.findStateRow(e,t);return r?kn(r):void 0}catch(r){throw r instanceof u?r:new u("DB_ERROR","Failed to read task log state",r)}finally{e.close();}}readLogs(t){return this.readLogsInternal(t)}readLogsTail(t,e){return Jr(e),this.readLogsInternal(t,e)}readTail(t,e){return this.readLogsTail(t,e)}readLogsInternal(t,e){if(!this.dbExists())return;let r=this.openHandle(false);try{return r.db.transaction(s=>{let i=this.findStateRowInTransaction(s,t);if(!i)return;let a=kn(i);if(a.source==="blob"){let _=mn(t,i.logs);return {...a,entries:e===void 0?_:_.slice(Math.max(0,_.length-e))}}let d=s.select({seq:nt.seq,timestamp:nt.timestamp,level:nt.level,message:nt.message}).from(nt).where(drizzleOrm.eq(nt.task_id,t)).orderBy(e===void 0?drizzleOrm.asc(nt.seq):drizzleOrm.desc(nt.seq)),l=(e===void 0?d.all():d.limit(e).all()).map(({timestamp:_,level:p,message:g})=>({timestamp:_,level:p,message:g}));return e!==void 0&&l.reverse(),{...a,entries:l}},{behavior:"deferred"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read task logs",s)}finally{r.close();}}};var Ae=40,gt="2026-05-09",rs="0.8.9-rc.13",ft=10,mt=parseInt(rs.split("rc.")[1]);function yn(){let n=drizzleOrm.sql`
|
|
18
18
|
CASE
|
|
19
|
-
WHEN ${
|
|
20
|
-
WHEN ${
|
|
21
|
-
WHEN ${
|
|
22
|
-
WHEN ${
|
|
23
|
-
WHEN ${
|
|
24
|
-
WHEN ${
|
|
25
|
-
WHEN ${
|
|
19
|
+
WHEN ${o.model} LIKE 'claude-%' OR ${o.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
|
|
20
|
+
WHEN ${o.model} LIKE 'gpt-%' OR ${o.model} LIKE 'codex-%' THEN 'codex'
|
|
21
|
+
WHEN ${o.model} LIKE 'gemini-%' THEN 'gemini'
|
|
22
|
+
WHEN ${o.model} LIKE 'grok-%' THEN 'grok'
|
|
23
|
+
WHEN ${o.model} LIKE 'zai-%' OR ${o.model} LIKE 'openrouter/z-ai/%' THEN 'opencode'
|
|
24
|
+
WHEN ${o.model} LIKE 'minimax/%' THEN 'minimax'
|
|
25
|
+
WHEN ${o.model} LIKE 'qwen%' THEN 'qwen'
|
|
26
26
|
ELSE 'unknown'
|
|
27
27
|
END
|
|
28
|
-
`,t=drizzleOrm.sql`json_extract(${
|
|
28
|
+
`,t=drizzleOrm.sql`json_extract(${o.metadata}, '$.provider')`,e=drizzleOrm.sql`trim(${t})`,r=drizzleOrm.sql`substr(${e}, 1, instr(${e}, '/') - 1)`,s=drizzleOrm.sql`
|
|
29
29
|
CASE
|
|
30
30
|
WHEN instr(${e}, '/') > 0
|
|
31
31
|
AND ${r} IN ('cli', 'acp', 'api', 'plugin', 'remote')
|
|
@@ -34,26 +34,26 @@ ${r.join(`
|
|
|
34
34
|
END
|
|
35
35
|
`;return drizzleOrm.sql`
|
|
36
36
|
CASE
|
|
37
|
-
WHEN ${
|
|
38
|
-
WHEN json_valid(${
|
|
39
|
-
WHEN json_type(${
|
|
40
|
-
WHEN json_type(${
|
|
41
|
-
WHEN json_type(${
|
|
37
|
+
WHEN ${o.metadata} IS NULL THEN ${n}
|
|
38
|
+
WHEN json_valid(${o.metadata}) = 0 THEN 'unknown'
|
|
39
|
+
WHEN json_type(${o.metadata}, '$') IS NOT 'object' THEN 'unknown'
|
|
40
|
+
WHEN json_type(${o.metadata}, '$.provider') IS NULL THEN ${n}
|
|
41
|
+
WHEN json_type(${o.metadata}, '$.provider') IS NOT 'text' THEN 'unknown'
|
|
42
42
|
WHEN ${e} = '' THEN 'unknown'
|
|
43
|
-
WHEN trim(${
|
|
44
|
-
ELSE ${
|
|
43
|
+
WHEN trim(${s}) = '' THEN 'unknown'
|
|
44
|
+
ELSE ${s}
|
|
45
45
|
END
|
|
46
|
-
`}var
|
|
46
|
+
`}var ss=new Set(["workflow","mcp"]),En=600*1e3,oe=class extends X{dbPath;taskLogRepository;pidNullObservedSince=new Map;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=dt.join(t.dbRoot,".crewx","crewx.db")),this.taskLogRepository=new re({dbPath:this.dbPath});}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=dt.dirname(e);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}else if(!fs$1.existsSync(e))throw new u("NOT_FOUND","Database not found");let r=N(e);if(t)try{et(r.db,e);}catch(s){throw r.close(),s}return r}startTask(t){let e=this.openHandle(true);try{let r={id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,project_id:t.projectId??null,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null,log_storage:"events"},s=i=>{e.db.insert(o).values(i).onConflictDoUpdate({target:o.id,set:{pid:drizzleOrm.sql`COALESCE(excluded.pid, ${o.pid})`},setWhere:drizzleOrm.eq(o.status,"running")}).run();};try{s(r);}catch(i){let a=i instanceof Error?i.message:typeof i=="object"&&i!==null&&"message"in i?String(i.message):String(i);if(!/log_storage/i.test(a)||!/no such column|no column named/i.test(a))throw i;e.runRaw(`INSERT INTO tasks (
|
|
47
47
|
id, agent_id, prompt, mode, status, started_at, pid,
|
|
48
48
|
parent_task_id, caller_agent_id, trace_id, command, metadata,
|
|
49
49
|
workspace_id, project_id, platform, crewx_version, thread_id,
|
|
50
50
|
model, rendered_prompt, coding_agent_command
|
|
51
51
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
52
52
|
ON CONFLICT(id) DO UPDATE SET pid = COALESCE(excluded.pid, tasks.pid)
|
|
53
|
-
WHERE tasks.status = 'running'`,[r.id,r.agent_id,r.prompt,r.mode,r.status,r.started_at,r.pid,r.parent_task_id,r.caller_agent_id,r.trace_id,r.command,r.metadata,r.workspace_id,r.project_id,r.platform,r.crewx_version,r.thread_id,r.model,r.rendered_prompt,r.coding_agent_command]);}}catch(r){throw r instanceof
|
|
53
|
+
WHERE tasks.status = 'running'`,[r.id,r.agent_id,r.prompt,r.mode,r.status,r.started_at,r.pid,r.parent_task_id,r.caller_agent_id,r.trace_id,r.command,r.metadata,r.workspace_id,r.project_id,r.platform,r.crewx_version,r.thread_id,r.model,r.rendered_prompt,r.coding_agent_command]);}}catch(r){throw r instanceof u?r:new u("DB_ERROR","Failed to start task",r)}finally{e.close();}}listTasksByProjectId(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(o).where(drizzleOrm.eq(o.project_id,t)).orderBy(drizzleOrm.desc(o.started_at)).all()}catch(r){throw r instanceof u?r:new u("DB_ERROR","Failed to list tasks by project",r)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{let r=t.runEpoch??null;e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
|
|
54
54
|
exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
|
|
55
55
|
model=COALESCE(?, model)
|
|
56
|
-
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,r]);}catch(r){throw r instanceof
|
|
56
|
+
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,r]);}catch(r){throw r instanceof u?r:new u("DB_ERROR","Failed to finish task",r)}finally{e.close();}}appendLog(t,e){this.taskLogRepository.appendLog(t,e);}appendLogs(t,e){this.taskLogRepository.appendLogs(t,e);}readLogs(t){return this.taskLogRepository.readLogs(t)}readLogsTail(t,e){return this.taskLogRepository.readLogsTail(t,e)}getLogState(t){return this.taskLogRepository.getLogState(t)}getRunningTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).where(drizzleOrm.eq(o.status,"running")).orderBy(drizzleOrm.desc(o.started_at)).all()}catch(e){throw new u("DB_ERROR","Failed to get running tasks",e)}finally{t.close();}}getAllTasks(){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).orderBy(drizzleOrm.desc(o.started_at)).limit(100).all()}catch(e){throw new u("DB_ERROR","Failed to get all tasks",e)}finally{t.close();}}getTask(t){if(!this.dbExists())return;let e=this.openHandle(false);try{return e.db.select().from(o).where(drizzleOrm.eq(o.id,t)).limit(1).get()??void 0}catch(r){throw new u("DB_ERROR","Failed to get task",r)}finally{e.close();}}killTask(t){if(!this.dbExists())return {killed:false};let e=this.openHandle(true);try{let r=e.db.select({id:o.id,status:o.status,pid:o.pid}).from(o).where(drizzleOrm.eq(o.id,t)).limit(1).get();if(!r||r.status!=="running")return {killed:!1};if(r.pid)try{process.kill(r.pid,"SIGTERM");}catch{}return e.db.update(o).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"))).run(),{killed:!0,pid:r.pid??void 0}}catch(r){throw r instanceof u?r:new u("DB_ERROR","Failed to kill task",r)}finally{e.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let e=t.db.select({id:o.id,pid:o.pid,platform:o.platform,run_epoch:o.run_epoch}).from(o).where(drizzleOrm.eq(o.status,"running")).all(),r=Date.now(),s=new Set,i=0;for(let a of e){if(a.pid){let l=!1;try{process.kill(a.pid,0),l=!0;}catch{}l||(t.db.update(o).set({status:"failed",error:"Reaped: process not found (orphaned task)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(o.id,a.id),drizzleOrm.eq(o.status,"running"))).run(),i++);continue}if(ss.has(a.platform??"cli"))continue;let d=`${a.id}:${a.run_epoch??0}`;s.add(d);let c=this.pidNullObservedSince.get(d);if(c===void 0){this.pidNullObservedSince.set(d,r);continue}r-c>=En&&(t.db.update(o).set({status:"failed",error:"Reaped: pid never recorded after resume (stale running_instruction)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(o.id,a.id),drizzleOrm.eq(o.status,"running"))).run(),i++,this.pidNullObservedSince.delete(d));}for(let a of Array.from(this.pidNullObservedSince.keys()))s.has(a)||this.pidNullObservedSince.delete(a);return i}finally{t.close();}}reapRunningWorkflowTasks(t=En){if(!this.dbExists())return 0;let e=this.openHandle(true);try{let r=new Date(Date.now()-t).toISOString();return e.db.update(o).set({status:"failed",error:"Reaped: stale workflow run (finally not executed)",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(o.status,"running"),drizzleOrm.eq(o.platform,"workflow"),drizzleOrm.isNull(o.pid),drizzleOrm.lt(o.started_at,r),drizzleOrm.or(drizzleOrm.isNull(o.metadata),drizzleOrm.and(drizzleOrm.notLike(o.metadata,'%"kind":"workflow_card"%'),drizzleOrm.notLike(o.metadata,'%"kind":"workflow_ui_instance"%'))))).run().changes??0}finally{e.close();}}findTaskStatus(t,e){let r=this.resolveDbPaths();for(let s of r){if(!fs$1.existsSync(s))continue;let i=N(s);try{let a=e?drizzleOrm.eq(o.workspace_id,e):void 0,d=a?drizzleOrm.and(drizzleOrm.eq(o.id,t),a):drizzleOrm.eq(o.id,t),c=i.db.select().from(o).where(d).limit(1).get()??void 0;if(!c){let l=a?drizzleOrm.and(drizzleOrm.eq(o.thread_id,t),a):drizzleOrm.eq(o.thread_id,t);c=i.db.select().from(o).where(l).orderBy(drizzleOrm.desc(o.started_at)).limit(1).get()??void 0;}if(c)return c}catch(a){throw new u("DB_ERROR","Failed to find task status",a)}finally{i.close();}}}findChildTasks(t,e){let r=this.resolveDbPaths(),s=new Set,i=[];for(let a of r){if(!fs$1.existsSync(a))continue;let d=N(a);try{let c=e?drizzleOrm.and(drizzleOrm.eq(o.parent_task_id,t),drizzleOrm.eq(o.workspace_id,e)):drizzleOrm.eq(o.parent_task_id,t),l=d.db.select().from(o).where(c).orderBy(drizzleOrm.asc(o.started_at)).all();for(let _ of l)s.has(_.id)||(s.add(_.id),i.push(_));}catch(c){throw new u("DB_ERROR","Failed to find child tasks",c)}finally{d.close();}}return i}getWorkspaceUsageSummary(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.all(t?drizzleOrm.sql`
|
|
57
57
|
SELECT
|
|
58
58
|
COALESCE(workspace_id, 'unknown') AS workspace_id,
|
|
59
59
|
COALESCE(SUM(input_tokens), 0) AS input_tokens,
|
|
@@ -74,7 +74,7 @@ ${r.join(`
|
|
|
74
74
|
FROM tasks
|
|
75
75
|
GROUP BY workspace_id
|
|
76
76
|
ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
|
|
77
|
-
`)}catch(r){throw new
|
|
77
|
+
`)}catch(r){throw new u("DB_ERROR","Failed to get workspace usage summary",r)}finally{e.close();}}getThreadTokenUsage(t,e){let r=this.resolveDbPaths(),s=new Set,i=0,a=0,d=0;for(let c of r){if(!fs$1.existsSync(c))continue;let l=N(c);try{let _=drizzleOrm.eq(o.thread_id,t),p=e?drizzleOrm.and(_,drizzleOrm.eq(o.workspace_id,e)):_,g=l.db.select({id:o.id,input_tokens:o.input_tokens,output_tokens:o.output_tokens,cost_usd:o.cost_usd}).from(o).where(p).all();for(let f of g)s.has(f.id)||(s.add(f.id),i+=f.input_tokens??0,a+=f.output_tokens??0,d+=f.cost_usd??0);}catch(_){throw new u("DB_ERROR","Failed to get thread token usage",_)}finally{l.close();}}return {inputTokens:i,outputTokens:a,costUsd:d}}findTasksByThread(t,e,r){let s=this.resolveDbPaths(),i=new Set,a=[],d=r?.projection==="activity-log";for(let c of s){if(!fs$1.existsSync(c))continue;let l=N(c);try{let _=drizzleOrm.eq(o.thread_id,t),p=e?drizzleOrm.and(_,drizzleOrm.eq(o.workspace_id,e)):_,g=d?l.db.select({id:o.id,thread_id:o.thread_id,agent_id:o.agent_id,parent_task_id:o.parent_task_id,started_at:o.started_at,completed_at:o.completed_at}).from(o).where(p).orderBy(drizzleOrm.asc(o.started_at)).all():l.db.select().from(o).where(p).orderBy(drizzleOrm.asc(o.started_at)).all();for(let f of g)i.has(f.id)||(i.add(f.id),a.push(f));}catch(_){throw new u("DB_ERROR","Failed to find tasks by thread",_)}finally{l.close();}}return a}parseWorkflowCardMetadata(t){if(!t)return {};try{let e=JSON.parse(t);return {kind:typeof e.kind=="string"?e.kind:void 0,workflowRunId:typeof e.workflowRunId=="string"?e.workflowRunId:void 0}}catch{return {}}}extractThreadIdFromCommand(t){return t?/--thread=(\S+)/.exec(t)?.[1]??null:null}findRunningWorkflowParentTasks(){if(!this.dbExists())return [];let t=[];for(let e of this.resolveDbPaths()){if(!fs$1.existsSync(e))continue;let r=N(e);try{t.push(...r.db.select({id:o.id,agent_id:o.agent_id,thread_id:o.thread_id,workspace_id:o.workspace_id,platform:o.platform,status:o.status,error:o.error,completed_at:o.completed_at,duration_ms:o.duration_ms,started_at:o.started_at,metadata:o.metadata}).from(o).where(drizzleOrm.and(drizzleOrm.eq(o.platform,"workflow"),drizzleOrm.or(drizzleOrm.like(o.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(o.metadata,'%"kind":"workflow_ui_instance"%')))).orderBy(drizzleOrm.desc(o.started_at)).all());}catch(s){throw new u("DB_ERROR","Failed to find workflow parent tasks",s)}finally{r.close();}}return t}batchFetchWorkflowCards(t,e){let r=new Map;if(t.length===0)return r;let s=new Set(t),i=new Map,a=e?drizzleOrm.eq(o.workspace_id,e):void 0,d=(c,l)=>{if(!c)return;let _=i.get(c);if(_&&l.started_at<=_)return;let p=this.parseWorkflowCardMetadata(l.metadata);p.kind!=="workflow_card"&&p.kind!=="workflow_ui_instance"||(i.set(c,l.started_at),r.set(c,{taskId:l.id,workflowRunId:p.workflowRunId,raw:l.result??void 0}));};for(let c of this.resolveDbPaths()){if(!fs$1.existsSync(c))continue;let l=N(c);try{let _=drizzleOrm.and(drizzleOrm.inArray(o.thread_id,t),drizzleOrm.or(drizzleOrm.like(o.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(o.metadata,'%"kind":"workflow_ui_instance"%'))),p=l.db.select({id:o.id,thread_id:o.thread_id,metadata:o.metadata,result:o.result,started_at:o.started_at}).from(o).where(a?drizzleOrm.and(_,a):_).all();for(let b of p)d(b.thread_id,b);let g=drizzleOrm.and(drizzleOrm.isNull(o.thread_id),drizzleOrm.or(drizzleOrm.like(o.metadata,'%"kind":"workflow_card"%'),drizzleOrm.like(o.metadata,'%"kind":"workflow_ui_instance"%'))),f=l.db.select({id:o.id,command:o.command,metadata:o.metadata,result:o.result,started_at:o.started_at}).from(o).where(a?drizzleOrm.and(g,a):g).all();for(let b of f){let x=this.extractThreadIdFromCommand(b.command);!x||!s.has(x)||d(x,b);}}catch(_){throw new u("DB_ERROR","Failed to batch fetch workflow cards",_)}finally{l.close();}}return r}findAllTasks(t){if(!this.dbExists())return {rows:[],total:0};let e=this.openHandle(false);try{let r=[];t.workspaceId&&r.push(drizzleOrm.eq(o.workspace_id,t.workspaceId));let s=t.agents&&t.agents.length>0?t.agents:t.agentId?[t.agentId]:null;s&&r.push(drizzleOrm.inArray(o.agent_id,s));let i=t.statuses&&t.statuses.length>0?t.statuses:t.status?[t.status]:null;i&&r.push(drizzleOrm.inArray(o.status,i));let a=t.q??t.search;a&&r.push(drizzleOrm.like(o.prompt,`%${a}%`)),t.from&&r.push(drizzleOrm.gte(o.started_at,t.from)),t.to&&r.push(drizzleOrm.lt(o.started_at,t.to));let d=r.length>0?drizzleOrm.and(...r):void 0,c=e.db.select({count:drizzleOrm.sql`count(*)`}).from(o).where(d).get(),l=(t.sortDir??"DESC")==="ASC"?drizzleOrm.asc(o.started_at):drizzleOrm.desc(o.started_at);return {rows:e.db.select().from(o).where(d).orderBy(l).limit(t.limit).offset(t.offset).all(),total:c?.count??0}}catch(r){throw new u("DB_ERROR","Failed to find all tasks",r)}finally{e.close();}}getAgentUsage(t,e,r){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(r?drizzleOrm.sql`
|
|
78
78
|
SELECT
|
|
79
79
|
t.agent_id,
|
|
80
80
|
t.workspace_id,
|
|
@@ -82,11 +82,11 @@ ${r.join(`
|
|
|
82
82
|
COALESCE(SUM(
|
|
83
83
|
COALESCE(t.input_tokens, 0)
|
|
84
84
|
+ CASE
|
|
85
|
-
WHEN t.started_at >= ${
|
|
85
|
+
WHEN t.started_at >= ${gt}
|
|
86
86
|
AND (
|
|
87
87
|
t.crewx_version IS NULL
|
|
88
88
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
89
|
-
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${
|
|
89
|
+
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${ft}) AS INTEGER) < ${mt})
|
|
90
90
|
)
|
|
91
91
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
92
92
|
ELSE 0
|
|
@@ -105,11 +105,11 @@ ${r.join(`
|
|
|
105
105
|
COALESCE(SUM(
|
|
106
106
|
COALESCE(t.input_tokens, 0)
|
|
107
107
|
+ CASE
|
|
108
|
-
WHEN t.started_at >= ${
|
|
108
|
+
WHEN t.started_at >= ${gt}
|
|
109
109
|
AND (
|
|
110
110
|
t.crewx_version IS NULL
|
|
111
111
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
112
|
-
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${
|
|
112
|
+
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${ft}) AS INTEGER) < ${mt})
|
|
113
113
|
)
|
|
114
114
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
115
115
|
ELSE 0
|
|
@@ -125,11 +125,11 @@ ${r.join(`
|
|
|
125
125
|
COALESCE(SUM(
|
|
126
126
|
COALESCE(t.input_tokens, 0)
|
|
127
127
|
+ CASE
|
|
128
|
-
WHEN t.started_at >= ${
|
|
128
|
+
WHEN t.started_at >= ${gt}
|
|
129
129
|
AND (
|
|
130
130
|
t.crewx_version IS NULL
|
|
131
131
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
132
|
-
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${
|
|
132
|
+
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${ft}) AS INTEGER) < ${mt})
|
|
133
133
|
)
|
|
134
134
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
135
135
|
ELSE 0
|
|
@@ -147,11 +147,11 @@ ${r.join(`
|
|
|
147
147
|
COALESCE(SUM(
|
|
148
148
|
COALESCE(t.input_tokens, 0)
|
|
149
149
|
+ CASE
|
|
150
|
-
WHEN t.started_at >= ${
|
|
150
|
+
WHEN t.started_at >= ${gt}
|
|
151
151
|
AND (
|
|
152
152
|
t.crewx_version IS NULL
|
|
153
153
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
154
|
-
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${
|
|
154
|
+
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${ft}) AS INTEGER) < ${mt})
|
|
155
155
|
)
|
|
156
156
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
157
157
|
ELSE 0
|
|
@@ -159,18 +159,18 @@ ${r.join(`
|
|
|
159
159
|
), 0)
|
|
160
160
|
+ COALESCE(SUM(t.output_tokens), 0)
|
|
161
161
|
) DESC
|
|
162
|
-
`).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(
|
|
162
|
+
`).map(a=>({agentId:a.agent_id,workspaceId:a.workspace_id??null,totalTasks:a.total_tasks,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd,totalTokens:a.input_tokens+a.output_tokens}))}catch(i){throw new u("DB_ERROR","Failed to get agent usage",i)}finally{s.close();}}getAgentUsageTrendRaw(t,e,r){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(r?drizzleOrm.sql`
|
|
163
163
|
SELECT
|
|
164
164
|
date(t.started_at) AS date,
|
|
165
165
|
t.agent_id,
|
|
166
166
|
COALESCE(SUM(
|
|
167
167
|
COALESCE(t.input_tokens, 0)
|
|
168
168
|
+ CASE
|
|
169
|
-
WHEN t.started_at >= ${
|
|
169
|
+
WHEN t.started_at >= ${gt}
|
|
170
170
|
AND (
|
|
171
171
|
t.crewx_version IS NULL
|
|
172
172
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
173
|
-
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${
|
|
173
|
+
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${ft}) AS INTEGER) < ${mt})
|
|
174
174
|
)
|
|
175
175
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
176
176
|
ELSE 0
|
|
@@ -193,11 +193,11 @@ ${r.join(`
|
|
|
193
193
|
COALESCE(SUM(
|
|
194
194
|
COALESCE(t.input_tokens, 0)
|
|
195
195
|
+ CASE
|
|
196
|
-
WHEN t.started_at >= ${
|
|
196
|
+
WHEN t.started_at >= ${gt}
|
|
197
197
|
AND (
|
|
198
198
|
t.crewx_version IS NULL
|
|
199
199
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
200
|
-
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${
|
|
200
|
+
OR (t.crewx_version LIKE '0.8.9-rc.%' AND CAST(SUBSTR(t.crewx_version, ${ft}) AS INTEGER) < ${mt})
|
|
201
201
|
)
|
|
202
202
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
203
203
|
ELSE 0
|
|
@@ -212,98 +212,98 @@ ${r.join(`
|
|
|
212
212
|
AND t.started_at < ${e}
|
|
213
213
|
GROUP BY date(t.started_at), t.agent_id
|
|
214
214
|
ORDER BY date(t.started_at) ASC
|
|
215
|
-
`).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(
|
|
216
|
-
COALESCE(${
|
|
215
|
+
`).map(a=>({date:a.date,agentId:a.agent_id,inputTokens:a.input_tokens,outputTokens:a.output_tokens,cachedInputTokens:a.cached_input_tokens,costUsd:a.cost_usd,totalTokens:a.input_tokens+a.output_tokens}))}catch(i){throw new u("DB_ERROR","Failed to get agent usage trend",i)}finally{s.close();}}findTaskForStop(t,e){if(!this.dbExists())return;let r=this.openHandle(false);try{return r.db.select().from(o).where(drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.workspace_id,e))).limit(1).get()??void 0}catch(s){throw new u("DB_ERROR","Failed to find task for stop",s)}finally{r.close();}}findLatestTaskByMetadata(t){if(!this.dbExists())return null;let e=this.openHandle(false);try{return e.db.select({id:o.id,thread_id:o.thread_id,status:o.status,result:o.result,error:o.error,started_at:o.started_at,completed_at:o.completed_at,metadata:o.metadata}).from(o).where(drizzleOrm.and(drizzleOrm.eq(o.agent_id,t.agentId),drizzleOrm.eq(o.workspace_id,t.workspaceId),drizzleOrm.sql`${o.metadata} IS NOT NULL AND json_valid(${o.metadata}) AND json_extract(${o.metadata}, '$.' || ${t.metaKey}) = ${t.metaValue}`)).orderBy(drizzleOrm.desc(o.started_at)).limit(1).get()??null}catch(r){throw new u("DB_ERROR","Failed to find latest task by metadata",r)}finally{e.close();}}markTaskFailed(t,e,r){if(!this.dbExists())return;let s=this.openHandle(true);try{let i=new Date().toISOString(),a=r?drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"),drizzleOrm.eq(o.workspace_id,r)):drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.status,"running"));s.db.update(o).set({status:"failed",error:e,completed_at:i}).where(a).run();}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to mark task failed",i)}finally{s.close();}}findTasksByPromptHint(t,e){let r=this.resolveDbPaths(),s=new Set,i=[];for(let a of r){if(!fs$1.existsSync(a))continue;let d=N(a);try{let c=e?drizzleOrm.and(drizzleOrm.like(o.prompt,`%${t}%`),drizzleOrm.eq(o.workspace_id,e)):drizzleOrm.like(o.prompt,`%${t}%`),l=d.db.select().from(o).where(c).orderBy(drizzleOrm.asc(o.started_at)).all();for(let _ of l)s.has(_.id)||(s.add(_.id),i.push(_));}catch(c){throw new u("DB_ERROR","Failed to find tasks by prompt hint",c)}finally{d.close();}}return i}getProviderUsage(t,e,r){if(!this.dbExists())return [];let s=this.openHandle(false);try{let i=yn(),a=drizzleOrm.sql`
|
|
216
|
+
COALESCE(${o.input_tokens}, 0)
|
|
217
217
|
+ CASE
|
|
218
|
-
WHEN ${
|
|
218
|
+
WHEN ${o.started_at} >= ${gt}
|
|
219
219
|
AND (
|
|
220
|
-
${
|
|
221
|
-
OR (${
|
|
222
|
-
OR (${
|
|
220
|
+
${o.crewx_version} IS NULL
|
|
221
|
+
OR (${o.crewx_version} LIKE '0.8.%' AND ${o.crewx_version} NOT LIKE '0.8.9%')
|
|
222
|
+
OR (${o.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${o.crewx_version}, ${ft}) AS INTEGER) < ${mt})
|
|
223
223
|
)
|
|
224
|
-
THEN COALESCE(${
|
|
224
|
+
THEN COALESCE(${o.cached_input_tokens}, 0)
|
|
225
225
|
ELSE 0
|
|
226
226
|
END
|
|
227
|
-
`,d=r?drizzleOrm.sql`WHERE ${
|
|
227
|
+
`,d=r?drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e} AND ${o.workspace_id} = ${r}`:drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e}`;return s.db.all(drizzleOrm.sql`
|
|
228
228
|
SELECT
|
|
229
|
-
${
|
|
229
|
+
${i} AS provider,
|
|
230
230
|
COUNT(*) AS total_tasks,
|
|
231
231
|
COALESCE(SUM(${a}), 0) AS input_tokens,
|
|
232
|
-
COALESCE(SUM(${
|
|
233
|
-
COALESCE(SUM(${
|
|
234
|
-
COALESCE(SUM(${
|
|
235
|
-
COALESCE(SUM(${
|
|
236
|
-
MAX(${
|
|
237
|
-
FROM ${
|
|
232
|
+
COALESCE(SUM(${o.output_tokens}), 0) AS output_tokens,
|
|
233
|
+
COALESCE(SUM(${o.cached_input_tokens}), 0) AS cached_input_tokens,
|
|
234
|
+
COALESCE(SUM(${o.cost_usd}), 0) AS cost_usd,
|
|
235
|
+
COALESCE(SUM(${o.duration_ms}), 0) AS active_duration_ms,
|
|
236
|
+
MAX(${o.completed_at}) AS last_active_at
|
|
237
|
+
FROM ${o}
|
|
238
238
|
${d}
|
|
239
|
-
GROUP BY ${
|
|
240
|
-
ORDER BY (COALESCE(SUM(${a}), 0) + COALESCE(SUM(${
|
|
241
|
-
`).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(
|
|
242
|
-
COALESCE(${
|
|
239
|
+
GROUP BY ${i}
|
|
240
|
+
ORDER BY (COALESCE(SUM(${a}), 0) + COALESCE(SUM(${o.output_tokens}), 0)) DESC
|
|
241
|
+
`).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(i){throw new u("DB_ERROR","Failed to get provider usage",i)}finally{s.close();}}getModelUsage(t,e,r){if(!this.dbExists())return [];let s=this.openHandle(false);try{let i=yn(),a=drizzleOrm.sql`
|
|
242
|
+
COALESCE(${o.input_tokens}, 0)
|
|
243
243
|
+ CASE
|
|
244
|
-
WHEN ${
|
|
244
|
+
WHEN ${o.started_at} >= ${gt}
|
|
245
245
|
AND (
|
|
246
|
-
${
|
|
247
|
-
OR (${
|
|
248
|
-
OR (${
|
|
246
|
+
${o.crewx_version} IS NULL
|
|
247
|
+
OR (${o.crewx_version} LIKE '0.8.%' AND ${o.crewx_version} NOT LIKE '0.8.9%')
|
|
248
|
+
OR (${o.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${o.crewx_version}, ${ft}) AS INTEGER) < ${mt})
|
|
249
249
|
)
|
|
250
|
-
THEN COALESCE(${
|
|
250
|
+
THEN COALESCE(${o.cached_input_tokens}, 0)
|
|
251
251
|
ELSE 0
|
|
252
252
|
END
|
|
253
|
-
`,d=r?drizzleOrm.sql`WHERE ${
|
|
253
|
+
`,d=r?drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e} AND ${o.workspace_id} = ${r}`:drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e}`,c=s.db.all(drizzleOrm.sql`
|
|
254
254
|
SELECT
|
|
255
|
-
${
|
|
256
|
-
${
|
|
255
|
+
${o.model} AS model,
|
|
256
|
+
${i} AS provider,
|
|
257
257
|
COUNT(*) AS total_tasks,
|
|
258
258
|
COALESCE(SUM(${a}), 0) AS input_tokens,
|
|
259
|
-
COALESCE(SUM(${
|
|
260
|
-
COALESCE(SUM(${
|
|
261
|
-
COALESCE(SUM(${
|
|
262
|
-
COALESCE(SUM(${
|
|
263
|
-
MAX(${
|
|
264
|
-
FROM ${
|
|
259
|
+
COALESCE(SUM(${o.output_tokens}), 0) AS output_tokens,
|
|
260
|
+
COALESCE(SUM(${o.cached_input_tokens}), 0) AS cached_input_tokens,
|
|
261
|
+
COALESCE(SUM(${o.cost_usd}), 0) AS cost_usd,
|
|
262
|
+
COALESCE(SUM(${o.duration_ms}), 0) AS active_duration_ms,
|
|
263
|
+
MAX(${o.completed_at}) AS last_active_at
|
|
264
|
+
FROM ${o}
|
|
265
265
|
${d}
|
|
266
|
-
GROUP BY ${
|
|
267
|
-
`),l=new Map;for(let
|
|
266
|
+
GROUP BY ${o.model}, ${i}
|
|
267
|
+
`),l=new Map;for(let _ of c){let p=pn(_.model??""),g=JSON.stringify([_.provider,p]),f=l.get(g);f?(f.totalTasks+=_.total_tasks,f.inputTokens+=_.input_tokens,f.outputTokens+=_.output_tokens,f.cachedInputTokens+=_.cached_input_tokens,f.costUsd+=_.cost_usd,f.totalTokens+=_.input_tokens+_.output_tokens,f.activeDurationMs+=_.active_duration_ms??0,_.last_active_at&&(!f.lastActiveAt||_.last_active_at>f.lastActiveAt)&&(f.lastActiveAt=_.last_active_at)):l.set(g,{model:p,provider:_.provider,totalTasks:_.total_tasks,inputTokens:_.input_tokens,outputTokens:_.output_tokens,cachedInputTokens:_.cached_input_tokens,costUsd:_.cost_usd,totalTokens:_.input_tokens+_.output_tokens,activeDurationMs:_.active_duration_ms??0,lastActiveAt:_.last_active_at??null});}return Array.from(l.values()).sort((_,p)=>p.costUsd-_.costUsd)}catch(i){throw new u("DB_ERROR","Failed to get model usage",i)}finally{s.close();}}getTasksForReport(t,e,r){if(!this.dbExists())return [];let s=this.openHandle(false);try{let i=r?drizzleOrm.sql`WHERE ${o.started_at} >= ${t} AND ${o.started_at} < ${e} AND ${o.workspace_id} = ${r}`:drizzleOrm.sql`WHERE ${o.started_at} >= ${t} AND ${o.started_at} < ${e}`;return s.db.all(drizzleOrm.sql`
|
|
268
268
|
SELECT
|
|
269
|
-
${
|
|
270
|
-
${
|
|
271
|
-
${
|
|
272
|
-
${
|
|
273
|
-
${
|
|
274
|
-
${
|
|
275
|
-
FROM ${
|
|
276
|
-
${
|
|
277
|
-
ORDER BY ${
|
|
278
|
-
`).map(d=>({threadId:d.thread_id,agentId:d.agent_id,startedAt:d.started_at,status:d.status,error:d.error,exitCode:d.exit_code}))}catch(
|
|
279
|
-
COALESCE(${
|
|
269
|
+
${o.thread_id} AS thread_id,
|
|
270
|
+
${o.agent_id} AS agent_id,
|
|
271
|
+
${o.started_at} AS started_at,
|
|
272
|
+
${o.status} AS status,
|
|
273
|
+
${o.error} AS error,
|
|
274
|
+
${o.exit_code} AS exit_code
|
|
275
|
+
FROM ${o}
|
|
276
|
+
${i}
|
|
277
|
+
ORDER BY ${o.started_at} ASC
|
|
278
|
+
`).map(d=>({threadId:d.thread_id,agentId:d.agent_id,startedAt:d.started_at,status:d.status,error:d.error,exitCode:d.exit_code}))}catch(i){throw new u("DB_ERROR","Failed to get tasks for report",i)}finally{s.close();}}getDelegationMatrix(t,e,r){if(!this.dbExists())return {edges:[],truncated:false};let s=this.openHandle(false);try{let i=drizzleOrm.sql`
|
|
279
|
+
COALESCE(${o.input_tokens}, 0)
|
|
280
280
|
+ CASE
|
|
281
|
-
WHEN ${
|
|
281
|
+
WHEN ${o.started_at} >= ${gt}
|
|
282
282
|
AND (
|
|
283
|
-
${
|
|
284
|
-
OR (${
|
|
285
|
-
OR (${
|
|
283
|
+
${o.crewx_version} IS NULL
|
|
284
|
+
OR (${o.crewx_version} LIKE '0.8.%' AND ${o.crewx_version} NOT LIKE '0.8.9%')
|
|
285
|
+
OR (${o.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${o.crewx_version}, ${ft}) AS INTEGER) < ${mt})
|
|
286
286
|
)
|
|
287
|
-
THEN COALESCE(${
|
|
287
|
+
THEN COALESCE(${o.cached_input_tokens}, 0)
|
|
288
288
|
ELSE 0
|
|
289
289
|
END
|
|
290
|
-
`,a=r?drizzleOrm.sql`WHERE ${
|
|
290
|
+
`,a=r?drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e} AND ${o.workspace_id} = ${r}`:drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${t} AND ${o.started_at} < ${e}`,d=s.db.all(drizzleOrm.sql`
|
|
291
291
|
SELECT
|
|
292
|
-
${
|
|
293
|
-
${
|
|
292
|
+
${o.caller_agent_id} AS caller_agent_id,
|
|
293
|
+
${o.agent_id} AS agent_id,
|
|
294
294
|
COUNT(*) AS task_count,
|
|
295
|
-
COALESCE(SUM(${
|
|
296
|
-
COALESCE(SUM(${
|
|
297
|
-
FROM ${
|
|
295
|
+
COALESCE(SUM(${i}), 0) AS input_tokens,
|
|
296
|
+
COALESCE(SUM(${o.output_tokens}), 0) AS output_tokens
|
|
297
|
+
FROM ${o}
|
|
298
298
|
${a}
|
|
299
|
-
GROUP BY ${
|
|
300
|
-
ORDER BY task_count DESC, ${
|
|
301
|
-
LIMIT ${
|
|
302
|
-
`),c=d.length>
|
|
299
|
+
GROUP BY ${o.caller_agent_id}, ${o.agent_id}
|
|
300
|
+
ORDER BY task_count DESC, ${o.caller_agent_id} ASC, ${o.agent_id} ASC
|
|
301
|
+
LIMIT ${Ae+1}
|
|
302
|
+
`),c=d.length>Ae;return {edges:d.slice(0,Ae).map(_=>({callerAgentId:_.caller_agent_id??null,agentId:_.agent_id,taskCount:_.task_count,totalTokens:_.input_tokens+_.output_tokens,outputTokens:_.output_tokens})),truncated:c}}catch(i){throw new u("DB_ERROR","Failed to get delegation matrix",i)}finally{s.close();}}findTaskEvidence(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{let r=[];t.workspaceId&&r.push(drizzleOrm.eq(o.workspace_id,t.workspaceId)),t.agents&&t.agents.length>0&&r.push(drizzleOrm.inArray(o.agent_id,t.agents)),t.statuses&&t.statuses.length>0&&r.push(drizzleOrm.inArray(o.status,t.statuses)),t.from&&r.push(drizzleOrm.gte(o.started_at,t.from)),t.to&&r.push(drizzleOrm.lt(o.started_at,t.to));let s=r.length>0?drizzleOrm.and(...r):void 0,i=(t.order??"DESC")==="ASC"?drizzleOrm.asc(o.started_at):drizzleOrm.desc(o.started_at),a={id:o.id,agent_id:o.agent_id,status:o.status,prompt:o.prompt,started_at:o.started_at,completed_at:o.completed_at,thread_id:o.thread_id};return t.limit?e.db.select(a).from(o).where(s).orderBy(i).limit(t.limit).all():e.db.select(a).from(o).where(s).orderBy(i).all()}catch(r){throw new u("DB_ERROR","Failed to find task evidence",r)}finally{e.close();}}findThreadChains(t){if(!this.dbExists())return [];let e=this.openHandle(false);try{let r=t.maxThreads??8,s=t.maxTurnsPerThread??4,i=[drizzleOrm.isNotNull(o.thread_id),drizzleOrm.isNull(o.parent_task_id),drizzleOrm.isNull(o.caller_agent_id),drizzleOrm.or(drizzleOrm.isNull(o.platform),drizzleOrm.ne(o.platform,"workflow")),drizzleOrm.or(drizzleOrm.isNull(o.metadata),drizzleOrm.and(drizzleOrm.notLike(o.metadata,'%"kind":"workflow_card"%'),drizzleOrm.notLike(o.metadata,'%"kind":"workflow_ui_instance"%'))),drizzleOrm.or(drizzleOrm.isNull(o.metadata),drizzleOrm.notLike(o.metadata,'%"retriedFromTaskId"%'))];t.workspaceId&&i.push(drizzleOrm.eq(o.workspace_id,t.workspaceId)),t.from&&i.push(drizzleOrm.gte(o.started_at,t.from)),t.to&&i.push(drizzleOrm.lt(o.started_at,t.to));let a=e.db.select({id:o.id,agent_id:o.agent_id,status:o.status,prompt:o.prompt,started_at:o.started_at,completed_at:o.completed_at,thread_id:o.thread_id}).from(o).where(drizzleOrm.and(...i)).orderBy(drizzleOrm.asc(o.started_at),drizzleOrm.asc(o.id)).all(),d=new Map;for(let l of a){if(!l.thread_id)continue;let _={id:l.id,agentId:l.agent_id,status:l.status,prompt:l.prompt,startedAt:l.started_at,completedAt:l.completed_at},p=d.get(l.thread_id);p?p.push(_):d.set(l.thread_id,[_]);}let c=[];for(let[l,_]of d){let p=_.filter(g=>g.agentId===t.targetAgentId).length;p<2||c.push({threadId:l,targetAgentTurnCount:p,turns:_});}return c.sort((l,_)=>{let p=l.turns[l.turns.length-1].startedAt,g=_.turns[_.turns.length-1].startedAt;return p<g?1:p>g?-1:0}),c.slice(0,r).map(l=>({threadId:l.threadId,targetAgentTurnCount:l.targetAgentTurnCount,turns:l.turns.slice(-s)}))}catch(r){throw new u("DB_ERROR","Failed to find thread chains",r)}finally{e.close();}}};var is=200,as=200;function ds(n){if(typeof n!="object"||n===null||!("code"in n))return;let t=n.code;return typeof t=="string"&&t.length>0?t:void 0}function cs(n){let t=n instanceof u?n.code:void 0,e=n instanceof u?n.cause:n,r=ds(e);return {code:t??r??"DB_ERROR",cause:r??(e instanceof Error?e.name:t??typeof e)}}function Sn(n){return Buffer.byteLength(JSON.stringify(n),"utf8")}var be=class extends kt{name="sqlite-tracing";unsubs=[];dbPath;version;taskRepo;queues=new Map;metrics={flushCount:0,flushedEntries:0,maxQueueEntries:0,maxQueueBytes:0,appendFailureCount:0,appendFailureEntries:0,appendFailureBytes:0,appendFailureByCode:{},appendFailureByCause:{}};constructor(t){super(),this.dbPath=dt.join(t?.dbRoot??Qn.homedir(),".crewx","crewx.db"),this.version=t?.version??"unknown";}attach(t){let e=new oe({dbPath:this.dbPath});this.taskRepo=e;let r=process.cwd(),i=fs$1.existsSync(dt.join(r,"crewx.yaml"))||fs$1.existsSync(dt.join(r,"crewx.yml"))?We(r):null,a=process.argv.join(" ");this.unsubs.push(t.on("task:start",d=>{try{let c=d.callerAgentId??null,l=d.parentTaskId??null,_=d.rootTraceId??d.traceId,p=d.metadata?JSON.stringify(d.metadata):JSON.stringify({provider:d.provider??"cli/claude"});e.startTask({id:d.traceId,agentId:d.agentRef.replace(/^@/,""),prompt:d.message,mode:d.mode,status:"running",pid:d.pid??null,startedAt:d.timestamp.toISOString(),crewxVersion:this.version,platform:d.platform??"cli",model:d.model??null,renderedPrompt:d.renderedPrompt??null,command:a,codingAgentCommand:d.codingAgentCommand??null,workspaceId:d.workspaceId??i,projectId:d.projectId??null,callerAgentId:c,parentTaskId:l,traceId:_,metadata:p,threadId:d.threadId??null});}catch{}}),t.on("task:output",d=>{try{this.enqueueLog(d.traceId,{timestamp:d.timestamp.toISOString(),level:d.level??"stdout",message:d.output});}catch(c){let l={timestamp:d.timestamp.toISOString(),level:d.level??"stdout",message:d.output};this.recordAppendFailure(c,[l],Sn(l));}}),t.on("task:end",d=>{try{this.flushTaskLogs(d.traceId);let c=typeof d.metadata?.runEpoch=="number"?d.metadata.runEpoch:null,l=d.error?JSON.stringify({code:d.error.code,message:d.error.message,...d.error.providerCode?{providerCode:d.error.providerCode}:{}}):null;e.finishTask({id:d.traceId,status:d.error?"failed":"success",result:d.result??null,error:l,completedAt:d.timestamp.toISOString(),durationMs:d.durationMs,exitCode:d.exitCode??null,inputTokens:d.inputTokens??0,outputTokens:d.outputTokens??0,cachedInputTokens:d.cachedInputTokens??0,costUsd:d.costUsd??0,model:d.model??null,runEpoch:c});}catch{}}));}detach(t){try{this.flushAllTaskLogs();}finally{this.clearAllTimers(),this.unsubs.forEach(e=>e()),this.unsubs=[],this.queues.clear(),this.taskRepo=void 0;}}getMetrics(){let t=0,e=0;for(let r of this.queues.values())t+=r.entries.length,e+=r.bytes;return {...this.metrics,appendFailureByCode:{...this.metrics.appendFailureByCode},appendFailureByCause:{...this.metrics.appendFailureByCause},pendingQueueEntries:t,pendingQueueBytes:e}}enqueueLog(t,e){let r=this.queues.get(t);if(r||(r={entries:[],bytes:0},this.queues.set(t,r)),r.entries.push(e),r.bytes+=Sn(e),this.metrics.maxQueueEntries=Math.max(this.metrics.maxQueueEntries,r.entries.length),this.metrics.maxQueueBytes=Math.max(this.metrics.maxQueueBytes,r.bytes),r.entries.length>=is){this.flushTaskLogs(t);return}if(!r.timer){let s=setTimeout(()=>{let i=this.queues.get(t);!i||i.timer!==s||(i.timer=void 0,this.flushTaskLogs(t));},as);r.timer=s;}}flushTaskLogs(t){let e=this.queues.get(t);if(!e||e.entries.length===0){e?.timer&&clearTimeout(e.timer),this.queues.delete(t);return}e.timer&&(clearTimeout(e.timer),e.timer=void 0);let r=e.entries,s=e.bytes;e.entries=[],e.bytes=0,this.metrics.flushCount+=1;try{this.taskRepo?.appendLogs(t,r),this.metrics.flushedEntries+=r.length;}catch(a){this.recordAppendFailure(a,r,s);}let i=this.queues.get(t);i&&i.entries.length===0&&(i.timer&&clearTimeout(i.timer),this.queues.delete(t));}flushAllTaskLogs(){for(let t of [...this.queues.keys()])this.flushTaskLogs(t);}clearAllTimers(){for(let t of this.queues.values())t.timer&&(clearTimeout(t.timer),t.timer=void 0);}recordAppendFailure(t,e,r){let s=cs(t);this.metrics.appendFailureCount+=1,this.metrics.appendFailureEntries+=e.length,this.metrics.appendFailureBytes+=r,this.metrics.appendFailureByCode[s.code]=(this.metrics.appendFailureByCode[s.code]??0)+1,this.metrics.appendFailureByCause[s.cause]=(this.metrics.appendFailureByCause[s.cause]??0)+1,console.warn("[crewx] sqlite tracing append failed",{code:s.code,cause:s.cause,pendingEntries:e.length,pendingBytes:r});}};var bt=class extends u{reason;constructor(t,e=t){super("VALIDATION",e),this.name="ThreadTitleMetadataPatchError",this.reason=t;}};function jt(n){if(!n)return {};try{let t=JSON.parse(n);return !t||typeof t!="object"||Array.isArray(t)?{}:t}catch{return {}}}function ps(n){let e=jt(n).threadTitle;if(!e||typeof e!="object"||Array.isArray(e))return {priority:null,state:null};let r=e;return {priority:typeof r.priority=="string"?r.priority:null,state:typeof r.state=="string"?r.state:null}}var ie=class extends X{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=dt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let s=dt.dirname(e);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}else if(!fs$1.existsSync(e))throw new u("NOT_FOUND","Database not found");let r=N(e);if(t)try{et(r.db,e);}catch(s){throw r.close(),s}return r}validateWorkspaceId(t,e){return t.db.select({id:At.id}).from(At).where(drizzleOrm.eq(At.id,e)).limit(1).get()?e:null}topLevelTaskPredicateSql(t="child"){return drizzleOrm.sql.raw(`NOT EXISTS (
|
|
303
303
|
SELECT 1 FROM tasks parent
|
|
304
304
|
WHERE parent.id = ${t}.parent_task_id
|
|
305
305
|
AND parent.thread_id = ${t}.thread_id
|
|
306
|
-
)`)}findAllThreads(t){let e=this.resolveDbPaths(),r=new Set,
|
|
306
|
+
)`)}findAllThreads(t){let e=this.resolveDbPaths(),r=new Set,s=[];for(let i of e){if(!fs$1.existsSync(i))continue;let a=N(i);try{let d=t?drizzleOrm.eq(h.workspace_id,t):void 0,c=a.db.select().from(h).where(d).orderBy(drizzleOrm.desc(h.updated_at)).all();for(let l of c)r.has(l.id)||(r.add(l.id),s.push(l));}catch(d){throw new u("DB_ERROR","Failed to find all threads",d)}finally{a.close();}}return s}findThreadsByIdsOrTitles(t,e){if(t.length===0)return [];let r=this.resolveDbPaths(),s=new Set,i=[];for(let a of r){if(!fs$1.existsSync(a))continue;let d=N(a);try{let c=drizzleOrm.or(drizzleOrm.inArray(h.id,t),drizzleOrm.inArray(h.title,t)),l=e?drizzleOrm.and(c,drizzleOrm.eq(h.workspace_id,e)):c,_=d.db.select().from(h).where(l).orderBy(drizzleOrm.desc(h.updated_at)).all();for(let p of _)s.has(p.id)||(s.add(p.id),i.push(p));}catch(c){throw new u("DB_ERROR","Failed to find threads by ids or titles",c)}finally{d.close();}}return i}findThreadById(t,e){let r=this.resolveDbPaths();for(let s of r){if(!fs$1.existsSync(s))continue;let i=N(s);try{let a=drizzleOrm.eq(h.id,t),d=e?drizzleOrm.and(a,drizzleOrm.eq(h.workspace_id,e)):a,c=i.db.select().from(h).where(d).limit(1).get()??void 0;if(c)return c}catch(a){throw new u("DB_ERROR","Failed to find thread by id",a)}finally{i.close();}}}threadExists(t,e){let r=this.resolveDbPaths();for(let s of r){if(!fs$1.existsSync(s))continue;let i=N(s);try{let a=drizzleOrm.eq(h.id,t),d=e?drizzleOrm.and(a,drizzleOrm.eq(h.workspace_id,e)):a;if(i.db.select({id:h.id}).from(h).where(d).limit(1).get())return !0}catch(a){throw new u("DB_ERROR","Failed to check thread existence",a)}finally{i.close();}}return false}aggregateTaskStats(t,e){let r=this.resolveDbPaths(),s=0,i=0,a=0,d=0,c=0,l=new Set;for(let _ of r){if(!fs$1.existsSync(_))continue;let p=N(_);try{let g=p.db.get(drizzleOrm.sql`
|
|
307
307
|
SELECT
|
|
308
308
|
count(*) AS cnt,
|
|
309
309
|
COALESCE(SUM(child.input_tokens), 0) AS total_input,
|
|
@@ -314,13 +314,13 @@ ${r.join(`
|
|
|
314
314
|
WHERE child.thread_id = ${t}
|
|
315
315
|
AND ${this.topLevelTaskPredicateSql()}
|
|
316
316
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
317
|
-
`);g&&(
|
|
317
|
+
`);g&&(s+=g.cnt,i+=g.total_input,a+=g.total_output,d+=g.total_cached,c+=g.total_cost);let f=p.db.all(drizzleOrm.sql`
|
|
318
318
|
SELECT DISTINCT child.agent_id FROM tasks child
|
|
319
319
|
WHERE child.thread_id = ${t}
|
|
320
320
|
AND child.agent_id IS NOT NULL AND child.agent_id != ''
|
|
321
321
|
AND ${this.topLevelTaskPredicateSql()}
|
|
322
322
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
323
|
-
`);for(let
|
|
323
|
+
`);for(let b of f)l.add(b.agent_id);}catch(g){throw new u("DB_ERROR","Failed to aggregate task stats",g)}finally{p.close();}}return {taskCount:s,inputTokens:i,outputTokens:a,cachedInputTokens:d,costUsd:c,agentIds:Array.from(l)}}findTopLevelTasks(t,e,r){let s=this.resolveDbPaths(),i=new Set,a=[];for(let d of s){if(!fs$1.existsSync(d))continue;let c=N(d);try{let l;r!==void 0?l=c.db.all(drizzleOrm.sql`
|
|
324
324
|
SELECT * FROM (
|
|
325
325
|
SELECT child.*,
|
|
326
326
|
ROW_NUMBER() OVER (PARTITION BY child.agent_id ORDER BY child.started_at DESC) AS rn
|
|
@@ -337,7 +337,7 @@ ${r.join(`
|
|
|
337
337
|
AND ${this.topLevelTaskPredicateSql()}
|
|
338
338
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
339
339
|
ORDER BY child.started_at ASC
|
|
340
|
-
`);for(let
|
|
340
|
+
`);for(let _ of l)i.has(_.id)||(i.add(_.id),a.push(_));}catch(l){throw new u("DB_ERROR","Failed to find top-level tasks",l)}finally{c.close();}}if(r!==void 0&&s.length>1){let d=new Map;for(let c of a){let l=c.agent_id??"";d.has(l)||d.set(l,[]),d.get(l).push(c);}a=[];for(let c of d.values())c.sort((l,_)=>(_.started_at??"").localeCompare(l.started_at??"")),a.push(...c.slice(0,r));a.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return a}findAllTasks(t,e){let r=this.resolveDbPaths(),s=new Set,i=[];for(let a of r){if(!fs$1.existsSync(a))continue;let d=N(a);try{let c=drizzleOrm.eq(o.thread_id,t),l=e?drizzleOrm.and(c,drizzleOrm.eq(o.workspace_id,e)):c,_=d.db.select().from(o).where(l).orderBy(drizzleOrm.asc(o.started_at)).all();for(let p of _)s.has(p.id)||(s.add(p.id),i.push(p));}catch(c){throw new u("DB_ERROR","Failed to find all tasks for thread",c)}finally{d.close();}}return i}findTaskById(t,e,r){let s=this.resolveDbPaths();for(let i of s){if(!fs$1.existsSync(i))continue;let a=N(i);try{let d=drizzleOrm.and(drizzleOrm.eq(o.id,e),drizzleOrm.eq(o.thread_id,t)),c=r?drizzleOrm.and(d,drizzleOrm.eq(o.workspace_id,r)):d,l=a.db.select().from(o).where(c).limit(1).get();if(!l)continue;let _=a.db.select().from(o).where(drizzleOrm.eq(o.parent_task_id,l.id)).orderBy(drizzleOrm.asc(o.started_at)).all();return {task:l,children:_}}catch(d){throw new u("DB_ERROR","Failed to find task by id",d)}finally{a.close();}}}batchFetchTasksQuery(t,e){return drizzleOrm.sql`
|
|
341
341
|
SELECT child.id, child.thread_id, child.agent_id, child.status,
|
|
342
342
|
child.parent_task_id, child.started_at, child.completed_at,
|
|
343
343
|
child.duration_ms, child.input_tokens, child.output_tokens,
|
|
@@ -347,19 +347,19 @@ ${r.join(`
|
|
|
347
347
|
AND ${this.topLevelTaskPredicateSql()}
|
|
348
348
|
${e?drizzleOrm.sql`AND child.workspace_id = ${e}`:drizzleOrm.sql``}
|
|
349
349
|
ORDER BY child.started_at ASC
|
|
350
|
-
`}batchFetchTasks(t,e){let r=new Map;if(t.length===0)return r;let
|
|
350
|
+
`}batchFetchTasks(t,e){let r=new Map;if(t.length===0)return r;let s=this.resolveDbPaths();for(let i of s){if(!fs$1.existsSync(i))continue;let a=N(i);try{let d=a.db.all(this.batchFetchTasksQuery(t,e));for(let c of d){let l=c.thread_id;r.has(l)||r.set(l,[]),r.get(l).push(c);}}catch(d){throw new u("DB_ERROR","Failed to batch fetch tasks",d)}finally{a.close();}}return r}explainBatchFetchTasksPlan(t,e){let r=this.resolveDbPaths();for(let s of r){if(!fs$1.existsSync(s))continue;let i=N(s);try{return i.db.all(drizzleOrm.sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(t,e)}`).map(d=>d.detail)}finally{i.close();}}return []}updateThreadTitle(t,e,r){if(!this.dbExists())return;let s=this.openHandle(true);try{let i=drizzleOrm.eq(h.id,t),a=r?drizzleOrm.and(i,drizzleOrm.eq(h.workspace_id,r)):i;if(!s.db.select({id:h.id}).from(h).where(a).limit(1).get())return;s.db.update(h).set({title:e,title_locked:1,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(h.id,t)).run();}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to update thread title",i)}finally{s.close();}}upsertThread(t,e){let r=this.openHandle(true);try{let s=e.workspaceId?this.validateWorkspaceId(r,e.workspaceId):null,i=new Date().toISOString();if(r.db.select({id:h.id,message_count:h.message_count}).from(h).where(drizzleOrm.eq(h.id,t)).limit(1).get()){let d={updated_at:i};e.title!==void 0&&(d.title=e.title),e.titleLocked!==void 0&&(d.title_locked=e.titleLocked?1:0),r.db.update(h).set(d).where(drizzleOrm.eq(h.id,t)).run();}else r.db.insert(h).values({id:t,platform:e.platform,workspace_id:s,title:e.title??null,title_locked:e.titleLocked?1:0,message_count:0,created_at:i,updated_at:i}).run();}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to upsert thread",s)}finally{r.close();}}ensureThread(t,e,r){let s=this.openHandle(true);try{let i=r?this.validateWorkspaceId(s,r):null,a=s.db.select({id:h.id,platform:h.platform,workspace_id:h.workspace_id}).from(h).where(drizzleOrm.eq(h.id,t)).limit(1).get();if(a){i&&!a.workspace_id&&s.db.update(h).set({workspace_id:i}).where(drizzleOrm.eq(h.id,t)).run();return}let d=new Date().toISOString();s.db.insert(h).values({id:t,platform:e,workspace_id:i,message_count:0,created_at:d,updated_at:d}).run();}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to ensure thread",i)}finally{s.close();}}saveUserMessage(t,e,r){if(!this.dbExists())return {firstMessage:false};let s=this.openHandle(true);try{let i=new Date().toISOString();return {firstMessage:s.db.transaction(d=>{let l=d.select({message_count:h.message_count}).from(h).where(drizzleOrm.eq(h.id,t)).limit(1).get()?.message_count===0;return d.run(drizzleOrm.sql`
|
|
351
351
|
UPDATE threads
|
|
352
352
|
SET first_message = COALESCE(first_message, ${e}),
|
|
353
353
|
title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${e}, 1, 60) ELSE title END,
|
|
354
354
|
last_message = ${e},
|
|
355
355
|
message_count = message_count + 1,
|
|
356
|
-
updated_at = ${
|
|
356
|
+
updated_at = ${i}
|
|
357
357
|
WHERE id = ${t}
|
|
358
|
-
`),l},{behavior:"immediate"})}}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to save user message",o)}finally{i.close();}}saveAssistantMessage(t,e,r){if(!this.dbExists())return;let i=this.openHandle(true);try{let o=new Date().toISOString();i.db.update(p).set({last_message:e,updated_at:o}).where(drizzleOrm.eq(p.id,t)).run();}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to save assistant message",o)}finally{i.close();}}updateThread(t,e){if(!this.dbExists())return;let r=this.openHandle(true);try{let i={updated_at:new Date().toISOString()};e.title!==void 0&&(i.title=e.title,i.title_locked=1),e.titleLocked!==void 0&&(i.title_locked=e.titleLocked?1:0),r.db.update(p).set(i).where(drizzleOrm.eq(p.id,t)).run();}catch(i){throw i instanceof _?i:new _("DB_ERROR","Failed to update thread",i)}finally{r.close();}}patchThreadTitleMetadata(t,e,r){let i=e;if(!i||typeof i!="object"||Array.isArray(i))return new vt("THREAD_TITLE_PATCH_INVALID","Thread-title metadata patch must be an object");if(Object.keys(i).some(c=>c!=="priority"&&c!=="state"))return new vt("THREAD_TITLE_PATCH_INVALID","Thread-title metadata patch only supports priority and state");let a=i;if(a.priority===void 0&&a.state===void 0)return new vt("THREAD_TITLE_PATCH_EMPTY","Thread-title metadata patch must change priority or state");for(let c of [a.priority,a.state])if(c!=null&&(typeof c!="string"||c.length===0))return new vt("THREAD_TITLE_PATCH_INVALID","Thread-title metadata values must be non-empty strings or null");let d=this.openHandle(true);try{let c=r?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,r)):drizzleOrm.eq(p.id,t);return d.db.transaction(l=>{let u=l.select({metadata:p.metadata}).from(p).where(c).get();if(!u)return null;let h=Pt(u.metadata),g=h.threadTitle,f=g&&typeof g=="object"&&!Array.isArray(g)?{...g}:{};a.priority===null?delete f.priority:a.priority!==void 0&&(f.priority=a.priority),a.state===null?delete f.state:a.state!==void 0&&(f.state=a.state),Object.keys(f).length>0?h.threadTitle=f:delete h.threadTitle;let x=Object.keys(h).length>0?JSON.stringify(h):null,A=new Date().toISOString();l.update(p).set({metadata:x,updated_at:A}).where(c).run();let v=l.select({metadata:p.metadata}).from(p).where(c).get();if(!v)throw new _("DB_ERROR","Thread-title metadata update could not be read back");let $=Jr(v.metadata);return {threadId:t,priority:$.priority,state:$.state}},{behavior:"immediate"})}catch(c){throw c instanceof _?c:new _("DB_ERROR","Failed to patch thread-title metadata",c)}finally{d.close();}}togglePin(t,e){let r=this.openHandle(true);try{let i=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t);return r.db.transaction(o=>{let a=o.select({pinned:p.pinned,metadata:p.metadata}).from(p).where(i).get();if(!a)return null;let d=a.pinned?0:1,c=Pt(a.metadata);if(d){let l=e?drizzleOrm.and(drizzleOrm.eq(p.pinned,1),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.pinned,1),u=o.select({metadata:p.metadata}).from(p).where(l).all(),h=null;for(let g of u){let f=Pt(g.metadata);typeof f.pinOrder=="number"&&(h===null||f.pinOrder<h)&&(h=f.pinOrder);}c.pinOrder=h===null?0:h-1;}else delete c.pinOrder;return o.update(p).set({pinned:d,metadata:Object.keys(c).length>0?JSON.stringify(c):null}).where(i).run(),{pinned:!!d}},{behavior:"immediate"})}catch(i){throw i instanceof _?i:new _("DB_ERROR","Failed to toggle pin",i)}finally{r.close();}}reorderPins(t,e){let r=this.openHandle(true);try{r.db.transaction(i=>{for(let o=0;o<t.length;o++){let a=e?drizzleOrm.and(drizzleOrm.eq(p.id,t[o]),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t[o]),d=i.select({metadata:p.metadata}).from(p).where(a).get();if(!d)continue;let c=Pt(d.metadata);c.pinOrder=o+1,i.update(p).set({metadata:JSON.stringify(c)}).where(a).run();}},{behavior:"immediate"});}catch(i){throw i instanceof _?i:new _("DB_ERROR","Failed to reorder pins",i)}finally{r.close();}}toggleStar(t,e){let r=this.openHandle(true);try{let i=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t),o=r.db.select({starred:p.starred}).from(p).where(i).get();if(!o)return null;let a=o.starred?0:1;return r.db.update(p).set({starred:a}).where(i).run(),{starred:!!a}}catch(i){throw i instanceof _?i:new _("DB_ERROR","Failed to toggle star",i)}finally{r.close();}}resolveOverdriveForRequest(t,e,r,i){let a=this.openHandle(true);try{let d=e?drizzleOrm.and(drizzleOrm.eq(p.id,t),drizzleOrm.eq(p.workspace_id,e)):drizzleOrm.eq(p.id,t);return a.db.transaction(l=>{let u=l.select({metadata:p.metadata}).from(p).where(d).get();if(!u)return null;let h=u.metadata?JSON.parse(u.metadata):{},g=h.overdrive??{},f=i?.defaultTurns??g.defaultTurns??3,x=i?.updatedBy??"ui",A=new Date().toISOString(),v,$,M,At;switch(r){case "enable-count":{let Nt=i?.turns??f,Ct=i?.consumeCurrent?Math.max(Nt-1,0):Nt;v=Ct>0?"count":"off",$=Ct,M=!0,At="count";break}case "enable-latch":{v="latch",$=0,M=!0,At="latch";break}case "disable":{v="off",$=0,M=!1;break}default:{let Nt=g.state??"off",Ct=typeof g.remaining=="number"?g.remaining:0;if(Nt==="count"&&Ct>0){let be=Ct-1;be<=0?(v="off",$=0):(v="count",$=be),M=!0,At="count";}else Nt==="latch"?(v="latch",$=0,M=!0,At="latch"):(v="off",$=0,M=!1);break}}return h.overdrive={state:v,remaining:$,defaultTurns:f,updatedAt:A,updatedBy:x},l.update(p).set({metadata:JSON.stringify(h),updated_at:A}).where(d).run(),{applied:M,appliedMode:At,state:v,remaining:$}},{behavior:"immediate"})}catch(d){throw d instanceof _?d:new _("DB_ERROR","Failed to resolve overdrive",d)}finally{a.close();}}};var mn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Qr(n){let t=crypto.randomBytes(n*2),e="";for(let r=0;r<t.length&&e.length<n;r++){let i=t[r];i<248&&(e+=mn[i%62]);}for(;e.length<n;)e+=mn[crypto.randomBytes(1)[0]%62];return e}function we(n){return `${n}_${Qr(8)}`}var Zr=["urgent","high","medium","low"],ts=["investigating","in-progress","in-review","on-hold","done"],kn="custom:";var es=new Set(Zr),ns=new Set(ts);function ye(n){return typeof n=="string"&&es.has(n)}function Ee(n){if(typeof n!="string")return false;if(ns.has(n))return true;if(n.startsWith("c_"))return n.length>2;if(!n.startsWith(kn))return false;let t=n.slice(kn.length);return t.length>=1&&t.length<=20}function Tn(n){if(!n)return null;try{let t=JSON.parse(n);return !t||typeof t!="object"||Array.isArray(t)?null:t}catch{return null}}function Se(n){let t=Tn(n);if(!t)return {};let e=t.threadTitle;if(!e||typeof e!="object"||Array.isArray(e))return {};let r=e,i={};return ye(r.priority)&&(i.priority=r.priority),Ee(r.state)&&(i.state=r.state),i}function wn(n,t){let e=Tn(n)??{},r={...Se(n)};return t.priority===null?delete r.priority:t.priority!==void 0&&(r.priority=t.priority),t.state===null?delete r.state:t.state!==void 0&&(r.state=t.state),r.priority===void 0&&r.state===void 0?delete e.threadTitle:e.threadTitle=r,Object.keys(e).length===0?null:JSON.stringify(e)}var Ie=class extends _{threadId;highlightId;expectedRevision;currentRevision;constructor(t,e,r,i){super("CONFLICT",`Highlight revision conflict: expected ${r}, current ${i}`),this.name="ThreadHistoryConflictError",this.threadId=t,this.highlightId=e,this.expectedRevision=r,this.currentRevision=i;}},qt=class extends Ie{},os=new Set(Qe),as=new Set(Je),ds=new Set(Ze),cs=new Set(tn),ls=50,Rn=100,vn=280;function D(n){throw new _("VALIDATION",n)}function xt(n){throw new _("NOT_FOUND",n)}function L(n,t){(typeof n!="string"||n.trim().length===0)&&D(`${t} is required`);}function Zt(n={}){let t=n.actor??n,e=t.actorType??"system";return os.has(e)||D(`invalid actorType: ${String(e)}`),t.actorId!==void 0&&t.actorId!==null&&typeof t.actorId!="string"&&D("actorId must be a string or null"),{actorType:e,actorId:t.actorId??null}}function us(n){L(n.threadId,"threadId"),n.workspaceId!==void 0&&n.workspaceId!==null&&L(n.workspaceId,"workspaceId"),n.title!==void 0&&n.title!==null&&((typeof n.title!="string"||n.title.trim().length===0)&&D("title must not be empty"),n.title.length>120&&D("title must be at most 120 characters")),n.priority!==void 0&&n.priority!==null&&!ye(n.priority)&&D(`invalid priority: ${String(n.priority)}`),n.state!==void 0&&n.state!==null&&!Ee(n.state)&&D(`invalid state: ${String(n.state)}`);}function _s(n){n.beforeSeq!==void 0&&n.afterSeq!==void 0&&D("beforeSeq and afterSeq cannot be used together");for(let[e,r]of [["beforeSeq",n.beforeSeq],["afterSeq",n.afterSeq]])r!==void 0&&(!Number.isInteger(r)||r<0)&&D(`${e} must be a non-negative integer`);let t=n.limit??ls;return (!Number.isInteger(t)||t<1||t>Rn)&&D(`limit must be between 1 and ${Rn}`),t}function In(n){typeof n!="string"&&D("text is required");let t=n.trim();return t.length===0&&D("text must not be empty"),t.length>vn&&D(`text must be at most ${vn} characters`),t}function bt(n,t){return L(n??"",t),n}function xn(n){cs.has(n)||D(`invalid highlight kind: ${String(n)}`);}function ps(n){ds.has(n)||D(`invalid highlight source: ${String(n)}`);}function hs(n){L(n.threadId,"threadId"),L(n.workspaceId,"workspaceId");let t=n.source??"manual";ps(t),xn(n.kind);let e=In(n.text),r=n.coversFromTaskId??n.fromTaskId??n.taskId,i=n.coversToTaskId??n.toTaskId??n.taskId;if(t==="manual"){let u=n.taskId??(r&&i&&r===i?r:void 0),h=bt(u,"taskId");return (r!==h||i!==h)&&D("manual highlights must cover exactly one task"),{source:t,kind:n.kind,text:e,coversFromTaskId:h,coversToTaskId:h,agentId:n.agentId??null,sourceTaskId:null,detectorVersion:null,contentFingerprint:null}}let o=bt(r,"coversFromTaskId"),a=bt(i,"coversToTaskId"),d=n.sourceTaskId??o,c=n.detectorVersion??(n.idempotencyKey!==void 0?"default":null),l=n.contentFingerprint??n.idempotencyKey??null;return bt(d??void 0,"sourceTaskId"),bt(c??void 0,"detectorVersion"),bt(l??void 0,"contentFingerprint"),{source:t,kind:n.kind,text:e,coversFromTaskId:o,coversToTaskId:a,agentId:n.agentId??null,sourceTaskId:d,detectorVersion:c,contentFingerprint:l}}function re(n){let t=Se(n.metadata);return {threadId:n.id,workspaceId:n.workspace_id,title:n.title,priority:t.priority??null,state:t.state??null,metadata:n.metadata,titleLocked:n.title_locked===1,updatedAt:n.updated_at}}function gs(n){try{let t=JSON.stringify(n);return (!t||t==="null"||t.startsWith("["))&&D("event payload must be a JSON object"),t}catch(t){throw new _("VALIDATION","event payload must be JSON serializable",t)}}function te(n,t){return n.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${E.seq}), 0)`}).from(E).where(drizzleOrm.eq(E.thread_id,t)).get()?.maxSeq??0}function ee(n,t){return !!n.select({id:E.id}).from(E).where(drizzleOrm.eq(E.thread_id,t)).limit(1).get()}function jt(n,t){as.has(t.type)||D(`invalid thread event type: ${String(t.type)}`);let e=we("the");n.insert(E).values({id:e,thread_id:t.threadId,seq:t.seq,type:t.type,actor_type:t.actorType,actor_id:t.actorId,task_id:t.taskId??null,highlight_id:t.highlightId??null,payload_json:gs(t.payload),created_at:t.createdAt}).run();let r=n.select().from(E).where(drizzleOrm.eq(E.id,e)).get();if(!r)throw new _("DB_ERROR","Thread event insert did not return a row");return r}function ne(n,t,e,r,i){let o=re(t);jt(n,{threadId:t.id,seq:i,type:"thread.snapshot.imported",actorType:e.actorType,actorId:e.actorId,createdAt:r,payload:{title:o.title,priority:o.priority,state:o.state}});}function Re(n){return {highlightId:n.id,source:n.source,kind:n.kind,status:n.status,coversFromTaskId:n.covers_from_task_id,coversToTaskId:n.covers_to_task_id,revision:n.revision,...n.dismissed_at===null?{}:{dismissedAt:n.dismissed_at}}}function ve(n,t,e,r,i,o,a){let d=i==="thread.highlight.created"?Re(t):{before:a?Re({...t,...a,id:t.id}):void 0,after:Re(t)};return jt(n,{threadId:t.thread_id,seq:o,type:i,actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.source==="manual"?t.covers_from_task_id:t.source_task_id??t.covers_from_task_id,highlightId:t.id,payload:d})}var se=class extends Y{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=rt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(!t&&!fs.existsSync(e))throw new _("NOT_FOUND","Database not found");if(t){let i=rt.dirname(e);fs.existsSync(i)||fs.mkdirSync(i,{recursive:true});}let r=b(e);if(t)try{ht(r.db,e);}catch(i){throw r.close(),i}return r}findThread(t,e,r){let i=drizzleOrm.eq(p.id,e),o=r===void 0?i:r===null?drizzleOrm.and(i,drizzleOrm.isNull(p.workspace_id)):drizzleOrm.and(i,drizzleOrm.eq(p.workspace_id,r));return t.select().from(p).where(o).limit(1).get()}resolveWorkspaceId(t){if(L(t,"threadId"),!fs.existsSync(this.resolveDbPath()))return null;let e=this.openHandle(false);try{return e.db.select({workspaceId:p.workspace_id}).from(p).where(drizzleOrm.eq(p.id,t)).limit(1).get()?.workspaceId??null}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to resolve thread workspace",r)}finally{e.close();}}updateSnapshot(t){us(t);let e=Zt(t),r=new Date().toISOString(),i=this.openHandle(true);try{return i.db.transaction(o=>{let a=this.findThread(o,t.threadId,t.workspaceId);a||xt(`Thread ${t.threadId} not found`);let d=re(a),c=t.title!==void 0,l=c&&t.title!==d.title,u=c&&a.title_locked!==1,h=t.priority!==void 0&&t.priority!==d.priority,g=t.state!==void 0&&t.state!==d.state,f=l||h||g;if(!f&&!u)return d;let x=a.metadata;(h||g)&&(x=wn(a.metadata,{priority:t.priority,state:t.state}));let A={};if(f&&(A.metadata=x,A.updated_at=r),l&&(A.title=t.title),c&&(A.title_locked=1),o.update(p).set(A).where(t.workspaceId===void 0?drizzleOrm.eq(p.id,t.threadId):t.workspaceId===null?drizzleOrm.and(drizzleOrm.eq(p.id,t.threadId),drizzleOrm.isNull(p.workspace_id)):drizzleOrm.and(drizzleOrm.eq(p.id,t.threadId),drizzleOrm.eq(p.workspace_id,t.workspaceId))).run(),!f){let M={...a,title_locked:1};return re(M)}let v=te(o,a.id)+1;ee(o,a.id)||(ne(o,a,e,r,v),v+=1),l&&(jt(o,{threadId:a.id,seq:v,type:"thread.title.changed",actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.taskId,payload:{before:d.title,after:t.title}}),v+=1),h&&(jt(o,{threadId:a.id,seq:v,type:"thread.priority.changed",actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.taskId,payload:{before:d.priority,after:t.priority}}),v+=1),g&&jt(o,{threadId:a.id,seq:v,type:"thread.state.changed",actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.taskId,payload:{before:d.state,after:t.state}});let $={...a,title:l?t.title:a.title,metadata:x,title_locked:c?1:a.title_locked,updated_at:r};return re($)},{behavior:"immediate"})}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to update thread snapshot",o)}finally{i.close();}}mutateSnapshot(t){return this.updateSnapshot(t)}updateThreadSnapshot(t){return this.updateSnapshot(t)}getLatestSeq(t,e){if(L(t,"threadId"),!fs.existsSync(this.resolveDbPath()))return null;let r=this.openHandle(false);try{return this.findThread(r.db,t,e)?r.db.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${E.seq}), 0)`}).from(E).where(drizzleOrm.eq(E.thread_id,t)).get()?.maxSeq??0:null}catch(i){throw i instanceof _?i:new _("DB_ERROR","Failed to read latest thread event sequence",i)}finally{r.close();}}listTimeline(t,e,r={}){let i=typeof t=="string"?{...r,threadId:t,workspaceId:e}:t;L(i.threadId,"threadId"),L(i.workspaceId,"workspaceId");let o=_s(i);if(!fs.existsSync(this.resolveDbPath()))return null;let a=this.openHandle(false);try{if(!this.findThread(a.db,i.threadId,i.workspaceId))return null;let d=a.db.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${E.seq}), 0)`}).from(E).where(drizzleOrm.eq(E.thread_id,i.threadId)).get()?.maxSeq??0,c;i.beforeSeq!==void 0?c=a.db.select().from(E).where(drizzleOrm.and(drizzleOrm.eq(E.thread_id,i.threadId),drizzleOrm.lt(E.seq,i.beforeSeq))).orderBy(drizzleOrm.desc(E.seq)).limit(o+1).all().reverse():i.afterSeq!==void 0?c=a.db.select().from(E).where(drizzleOrm.and(drizzleOrm.eq(E.thread_id,i.threadId),drizzleOrm.sql`${E.seq} > ${i.afterSeq}`)).orderBy(drizzleOrm.asc(E.seq)).limit(o+1).all():c=a.db.select().from(E).where(drizzleOrm.eq(E.thread_id,i.threadId)).orderBy(drizzleOrm.desc(E.seq)).limit(o+1).all().reverse();let l=c.length>o,u=i.afterSeq!==void 0?c.slice(0,o):l?c.slice(1):c,h=!1,g=u[0];return g&&(h=!!a.db.select({id:E.id}).from(E).where(drizzleOrm.and(drizzleOrm.eq(E.thread_id,i.threadId),drizzleOrm.lt(E.seq,g.seq))).limit(1).get()),{items:u,latestSeq:d,hasMoreOlder:h}}catch(d){throw d instanceof _?d:new _("DB_ERROR","Failed to list thread timeline",d)}finally{a.close();}}listEvents(t,e,r){return this.listTimeline(t,e,r)}getTimeline(t,e,r){return this.listTimeline(t,e,r)}createHighlight(t){let e=hs(t),r=Zt(t),i=new Date().toISOString(),o=this.openHandle(true);try{return o.db.transaction(a=>{let d=this.findThread(a,t.threadId,t.workspaceId);if(d||xt(`Thread ${t.threadId} not found`),e.source==="auto"){let g=a.select().from(y).where(drizzleOrm.and(drizzleOrm.eq(y.thread_id,t.threadId),drizzleOrm.eq(y.source_task_id,e.sourceTaskId),drizzleOrm.eq(y.detector_version,e.detectorVersion),drizzleOrm.eq(y.content_fingerprint,e.contentFingerprint))).orderBy(drizzleOrm.asc(y.created_at),drizzleOrm.asc(y.id)).limit(1).get();if(g)return g}let c=t.id??we("thl"),l={id:c,thread_id:t.threadId,source:e.source,kind:e.kind,status:"active",text:e.text,covers_from_task_id:e.coversFromTaskId,covers_to_task_id:e.coversToTaskId,revision:0,created_at:i,updated_at:i,agent_id:e.agentId,source_task_id:e.sourceTaskId,detector_version:e.detectorVersion,content_fingerprint:e.contentFingerprint,dismissed_at:null};a.insert(y).values(l).run();let u=a.select().from(y).where(drizzleOrm.eq(y.id,c)).get();if(!u)throw new _("DB_ERROR","Highlight insert did not return a row");let h=te(a,d.id)+1;return ee(a,d.id)||(ne(a,d,r,i,h),h+=1),ve(a,u,r,i,"thread.highlight.created",h),u},{behavior:"immediate"})}catch(a){throw a instanceof _?a:new _("DB_ERROR","Failed to create thread highlight",a)}finally{o.close();}}updateHighlight(t){L(t.threadId,"threadId"),L(t.workspaceId,"workspaceId"),L(t.highlightId,"highlightId"),(!Number.isInteger(t.expectedRevision)||t.expectedRevision<0)&&D("expectedRevision must be a non-negative integer"),t.text===void 0&&t.kind===void 0&&t.coversFromTaskId===void 0&&t.coversToTaskId===void 0&&D("highlight update requires at least one field"),t.kind!==void 0&&xn(t.kind);let e=t.text===void 0?void 0:In(t.text),r=Zt(t),i=new Date().toISOString(),o=this.openHandle(true);try{return o.db.transaction(a=>{let d=this.findThread(a,t.threadId,t.workspaceId);d||xt(`Thread ${t.threadId} not found`);let c=a.select().from(y).where(drizzleOrm.and(drizzleOrm.eq(y.id,t.highlightId),drizzleOrm.eq(y.thread_id,d.id))).limit(1).get();if(c||xt(`Highlight ${t.highlightId} not found`),c.revision!==t.expectedRevision)throw new qt(d.id,c.id,t.expectedRevision,c.revision);if(c.status!=="active")throw new qt(d.id,c.id,t.expectedRevision,c.revision);let l=t.kind??c.kind,u=e??c.text,h=t.coversFromTaskId??c.covers_from_task_id,g=t.coversToTaskId??c.covers_to_task_id;(!u||h.length===0||g.length===0)&&D("highlight projection is incomplete");let f=l!==c.kind||u!==c.text||h!==c.covers_from_task_id||g!==c.covers_to_task_id,x=r.actorType==="user"&&c.source==="auto"&&f?"manual":c.source;if(!(f||x!==c.source))return c;let v=c.revision+1;a.update(y).set({source:x,kind:l,text:u,covers_from_task_id:h,covers_to_task_id:g,revision:v,updated_at:i}).where(drizzleOrm.and(drizzleOrm.eq(y.id,c.id),drizzleOrm.eq(y.revision,c.revision))).run();let $=a.select().from(y).where(drizzleOrm.eq(y.id,c.id)).get();if(!$)throw new _("DB_ERROR","Highlight update did not return a row");let M=te(a,d.id)+1;return ee(a,d.id)||(ne(a,d,r,i,M),M+=1),ve(a,$,r,i,"thread.highlight.updated",M,c),$},{behavior:"immediate"})}catch(a){throw a instanceof _?a:new _("DB_ERROR","Failed to update thread highlight",a)}finally{o.close();}}dismissHighlight(t){L(t.threadId,"threadId"),L(t.workspaceId,"workspaceId"),L(t.highlightId,"highlightId"),(!Number.isInteger(t.expectedRevision)||t.expectedRevision<0)&&D("expectedRevision must be a non-negative integer");let e=Zt(t),r=new Date().toISOString(),i=this.openHandle(true);try{return i.db.transaction(o=>{let a=this.findThread(o,t.threadId,t.workspaceId);a||xt(`Thread ${t.threadId} not found`);let d=o.select().from(y).where(drizzleOrm.and(drizzleOrm.eq(y.id,t.highlightId),drizzleOrm.eq(y.thread_id,a.id))).limit(1).get();if(d||xt(`Highlight ${t.highlightId} not found`),d.revision!==t.expectedRevision)throw new qt(a.id,d.id,t.expectedRevision,d.revision);if(d.status==="dismissed")return d;let c=d.revision+1;o.update(y).set({status:"dismissed",text:null,revision:c,updated_at:r,dismissed_at:r}).where(drizzleOrm.and(drizzleOrm.eq(y.id,d.id),drizzleOrm.eq(y.revision,d.revision))).run();let l=o.select().from(y).where(drizzleOrm.eq(y.id,d.id)).get();if(!l)throw new _("DB_ERROR","Highlight dismissal did not return a row");let u=te(o,a.id)+1;return ee(o,a.id)||(ne(o,a,e,r,u),u+=1),ve(o,l,e,r,"thread.highlight.deleted",u,d),l},{behavior:"immediate"})}catch(o){throw o instanceof _?o:new _("DB_ERROR","Failed to dismiss thread highlight",o)}finally{i.close();}}listActiveHighlights(t,e,r={}){if(L(t,"threadId"),L(e,"workspaceId"),r.taskId!==void 0&&L(r.taskId,"taskId"),r.coversFromTaskId!==void 0&&L(r.coversFromTaskId,"coversFromTaskId"),r.coversToTaskId!==void 0&&L(r.coversToTaskId,"coversToTaskId"),!fs.existsSync(this.resolveDbPath()))return null;let i=this.openHandle(false);try{if(!this.findThread(i.db,t,e))return null;let a=i.db.select().from(y).where(drizzleOrm.and(drizzleOrm.eq(y.thread_id,t),drizzleOrm.eq(y.status,"active"))).orderBy(drizzleOrm.asc(y.created_at),drizzleOrm.asc(y.id)).all();if(r.taskId===void 0&&r.coversFromTaskId===void 0&&r.coversToTaskId===void 0)return a;let d=i.db.all(drizzleOrm.sql`
|
|
358
|
+
`),l},{behavior:"immediate"})}}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to save user message",i)}finally{s.close();}}saveAssistantMessage(t,e,r){if(!this.dbExists())return;let s=this.openHandle(true);try{let i=new Date().toISOString();s.db.update(h).set({last_message:e,updated_at:i}).where(drizzleOrm.eq(h.id,t)).run();}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to save assistant message",i)}finally{s.close();}}updateThread(t,e){if(!this.dbExists())return;let r=this.openHandle(true);try{let s={updated_at:new Date().toISOString()};e.title!==void 0&&(s.title=e.title,s.title_locked=1),e.titleLocked!==void 0&&(s.title_locked=e.titleLocked?1:0),r.db.update(h).set(s).where(drizzleOrm.eq(h.id,t)).run();}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to update thread",s)}finally{r.close();}}patchThreadTitleMetadata(t,e,r){let s=e;if(!s||typeof s!="object"||Array.isArray(s))return new bt("THREAD_TITLE_PATCH_INVALID","Thread-title metadata patch must be an object");if(Object.keys(s).some(c=>c!=="priority"&&c!=="state"))return new bt("THREAD_TITLE_PATCH_INVALID","Thread-title metadata patch only supports priority and state");let a=s;if(a.priority===void 0&&a.state===void 0)return new bt("THREAD_TITLE_PATCH_EMPTY","Thread-title metadata patch must change priority or state");for(let c of [a.priority,a.state])if(c!=null&&(typeof c!="string"||c.length===0))return new bt("THREAD_TITLE_PATCH_INVALID","Thread-title metadata values must be non-empty strings or null");let d=this.openHandle(true);try{let c=r?drizzleOrm.and(drizzleOrm.eq(h.id,t),drizzleOrm.eq(h.workspace_id,r)):drizzleOrm.eq(h.id,t);return d.db.transaction(l=>{let _=l.select({metadata:h.metadata}).from(h).where(c).get();if(!_)return null;let p=jt(_.metadata),g=p.threadTitle,f=g&&typeof g=="object"&&!Array.isArray(g)?{...g}:{};a.priority===null?delete f.priority:a.priority!==void 0&&(f.priority=a.priority),a.state===null?delete f.state:a.state!==void 0&&(f.state=a.state),Object.keys(f).length>0?p.threadTitle=f:delete p.threadTitle;let b=Object.keys(p).length>0?JSON.stringify(p):null,x=new Date().toISOString();l.update(h).set({metadata:b,updated_at:x}).where(c).run();let v=l.select({metadata:h.metadata}).from(h).where(c).get();if(!v)throw new u("DB_ERROR","Thread-title metadata update could not be read back");let M=ps(v.metadata);return {threadId:t,priority:M.priority,state:M.state}},{behavior:"immediate"})}catch(c){throw c instanceof u?c:new u("DB_ERROR","Failed to patch thread-title metadata",c)}finally{d.close();}}togglePin(t,e){let r=this.openHandle(true);try{let s=e?drizzleOrm.and(drizzleOrm.eq(h.id,t),drizzleOrm.eq(h.workspace_id,e)):drizzleOrm.eq(h.id,t);return r.db.transaction(i=>{let a=i.select({pinned:h.pinned,metadata:h.metadata}).from(h).where(s).get();if(!a)return null;let d=a.pinned?0:1,c=jt(a.metadata);if(d){let l=e?drizzleOrm.and(drizzleOrm.eq(h.pinned,1),drizzleOrm.eq(h.workspace_id,e)):drizzleOrm.eq(h.pinned,1),_=i.select({metadata:h.metadata}).from(h).where(l).all(),p=null;for(let g of _){let f=jt(g.metadata);typeof f.pinOrder=="number"&&(p===null||f.pinOrder<p)&&(p=f.pinOrder);}c.pinOrder=p===null?0:p-1;}else delete c.pinOrder;return i.update(h).set({pinned:d,metadata:Object.keys(c).length>0?JSON.stringify(c):null}).where(s).run(),{pinned:!!d}},{behavior:"immediate"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to toggle pin",s)}finally{r.close();}}reorderPins(t,e){let r=this.openHandle(true);try{r.db.transaction(s=>{for(let i=0;i<t.length;i++){let a=e?drizzleOrm.and(drizzleOrm.eq(h.id,t[i]),drizzleOrm.eq(h.workspace_id,e)):drizzleOrm.eq(h.id,t[i]),d=s.select({metadata:h.metadata}).from(h).where(a).get();if(!d)continue;let c=jt(d.metadata);c.pinOrder=i+1,s.update(h).set({metadata:JSON.stringify(c)}).where(a).run();}},{behavior:"immediate"});}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to reorder pins",s)}finally{r.close();}}toggleStar(t,e){let r=this.openHandle(true);try{let s=e?drizzleOrm.and(drizzleOrm.eq(h.id,t),drizzleOrm.eq(h.workspace_id,e)):drizzleOrm.eq(h.id,t),i=r.db.select({starred:h.starred}).from(h).where(s).get();if(!i)return null;let a=i.starred?0:1;return r.db.update(h).set({starred:a}).where(s).run(),{starred:!!a}}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to toggle star",s)}finally{r.close();}}resolveOverdriveForRequest(t,e,r,s){let a=this.openHandle(true);try{let d=e?drizzleOrm.and(drizzleOrm.eq(h.id,t),drizzleOrm.eq(h.workspace_id,e)):drizzleOrm.eq(h.id,t);return a.db.transaction(l=>{let _=l.select({metadata:h.metadata}).from(h).where(d).get();if(!_)return null;let p=_.metadata?JSON.parse(_.metadata):{},g=p.overdrive??{},f=s?.defaultTurns??g.defaultTurns??3,b=s?.updatedBy??"ui",x=new Date().toISOString(),v,M,j,Lt;switch(r){case "enable-count":{let $t=s?.turns??f,Pt=s?.consumeCurrent?Math.max($t-1,0):$t;v=Pt>0?"count":"off",M=Pt,j=!0,Lt="count";break}case "enable-latch":{v="latch",M=0,j=!0,Lt="latch";break}case "disable":{v="off",M=0,j=!1;break}default:{let $t=g.state??"off",Pt=typeof g.remaining=="number"?g.remaining:0;if($t==="count"&&Pt>0){let Be=Pt-1;Be<=0?(v="off",M=0):(v="count",M=Be),j=!0,Lt="count";}else $t==="latch"?(v="latch",M=0,j=!0,Lt="latch"):(v="off",M=0,j=!1);break}}return p.overdrive={state:v,remaining:M,defaultTurns:f,updatedAt:x,updatedBy:b},l.update(h).set({metadata:JSON.stringify(p),updated_at:x}).where(d).run(),{applied:j,appliedMode:Lt,state:v,remaining:M}},{behavior:"immediate"})}catch(d){throw d instanceof u?d:new u("DB_ERROR","Failed to resolve overdrive",d)}finally{a.close();}}};var Cn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function gs(n){let t=crypto.randomBytes(n*2),e="";for(let r=0;r<t.length&&e.length<n;r++){let s=t[r];s<248&&(e+=Cn[s%62]);}for(;e.length<n;)e+=Cn[crypto.randomBytes(1)[0]%62];return e}function xe(n){return `${n}_${gs(8)}`}var fs=["urgent","high","medium","low"],ms=["investigating","in-progress","in-review","on-hold","done"],bn="custom:";var ks=new Set(fs),Ts=new Set(ms);function Oe(n){return typeof n=="string"&&ks.has(n)}function De(n){if(typeof n!="string")return false;if(Ts.has(n))return true;if(n.startsWith("c_"))return n.length>2;if(!n.startsWith(bn))return false;let t=n.slice(bn.length);return t.length>=1&&t.length<=20}function xn(n){if(!n)return null;try{let t=JSON.parse(n);return !t||typeof t!="object"||Array.isArray(t)?null:t}catch{return null}}function Le(n){let t=xn(n);if(!t)return {};let e=t.threadTitle;if(!e||typeof e!="object"||Array.isArray(e))return {};let r=e,s={};return Oe(r.priority)&&(s.priority=r.priority),De(r.state)&&(s.state=r.state),s}function On(n,t){let e=xn(n)??{},r={...Le(n)};return t.priority===null?delete r.priority:t.priority!==void 0&&(r.priority=t.priority),t.state===null?delete r.state:t.state!==void 0&&(r.state=t.state),r.priority===void 0&&r.state===void 0?delete e.threadTitle:e.threadTitle=r,Object.keys(e).length===0?null:JSON.stringify(e)}var Me=class extends u{threadId;highlightId;expectedRevision;currentRevision;constructor(t,e,r,s){super("CONFLICT",`Highlight revision conflict: expected ${r}, current ${s}`),this.name="ThreadHistoryConflictError",this.threadId=t,this.highlightId=e,this.expectedRevision=r,this.currentRevision=s;}},Wt=class extends Me{},Rs=new Set(un),Ss=new Set(ln),Is=new Set(_n),vs=new Set(hn),Ns=50,Pn=100,Mn=280;function L(n){throw new u("VALIDATION",n)}function xt(n){throw new u("NOT_FOUND",n)}function P(n,t){(typeof n!="string"||n.trim().length===0)&&L(`${t} is required`);}function ae(n={}){let t=n.actor??n,e=t.actorType??"system";return Rs.has(e)||L(`invalid actorType: ${String(e)}`),t.actorId!==void 0&&t.actorId!==null&&typeof t.actorId!="string"&&L("actorId must be a string or null"),{actorType:e,actorId:t.actorId??null}}function As(n){P(n.threadId,"threadId"),n.workspaceId!==void 0&&n.workspaceId!==null&&P(n.workspaceId,"workspaceId"),n.title!==void 0&&n.title!==null&&((typeof n.title!="string"||n.title.trim().length===0)&&L("title must not be empty"),n.title.length>120&&L("title must be at most 120 characters")),n.priority!==void 0&&n.priority!==null&&!Oe(n.priority)&&L(`invalid priority: ${String(n.priority)}`),n.state!==void 0&&n.state!==null&&!De(n.state)&&L(`invalid state: ${String(n.state)}`);}function Cs(n){n.beforeSeq!==void 0&&n.afterSeq!==void 0&&L("beforeSeq and afterSeq cannot be used together");for(let[e,r]of [["beforeSeq",n.beforeSeq],["afterSeq",n.afterSeq]])r!==void 0&&(!Number.isInteger(r)||r<0)&&L(`${e} must be a non-negative integer`);let t=n.limit??Ns;return (!Number.isInteger(t)||t<1||t>Pn)&&L(`limit must be between 1 and ${Pn}`),t}function Hn(n){typeof n!="string"&&L("text is required");let t=n.trim();return t.length===0&&L("text must not be empty"),t.length>Mn&&L(`text must be at most ${Mn} characters`),t}function Ot(n,t){return P(n??"",t),n}function qn(n){vs.has(n)||L(`invalid highlight kind: ${String(n)}`);}function bs(n){Is.has(n)||L(`invalid highlight source: ${String(n)}`);}function xs(n){P(n.threadId,"threadId"),P(n.workspaceId,"workspaceId");let t=n.source??"manual";bs(t),qn(n.kind);let e=Hn(n.text),r=n.coversFromTaskId??n.fromTaskId??n.taskId,s=n.coversToTaskId??n.toTaskId??n.taskId;if(t==="manual"){let _=n.taskId??(r&&s&&r===s?r:void 0),p=Ot(_,"taskId");return (r!==p||s!==p)&&L("manual highlights must cover exactly one task"),{source:t,kind:n.kind,text:e,coversFromTaskId:p,coversToTaskId:p,agentId:n.agentId??null,sourceTaskId:null,detectorVersion:null,contentFingerprint:null}}let i=Ot(r,"coversFromTaskId"),a=Ot(s,"coversToTaskId"),d=n.sourceTaskId??i,c=n.detectorVersion??(n.idempotencyKey!==void 0?"default":null),l=n.contentFingerprint??n.idempotencyKey??null;return Ot(d??void 0,"sourceTaskId"),Ot(c??void 0,"detectorVersion"),Ot(l??void 0,"contentFingerprint"),{source:t,kind:n.kind,text:e,coversFromTaskId:i,coversToTaskId:a,agentId:n.agentId??null,sourceTaskId:d,detectorVersion:c,contentFingerprint:l}}function zt(n){let t=Le(n.metadata);return {threadId:n.id,workspaceId:n.workspace_id,title:n.title,priority:t.priority??null,state:t.state??null,metadata:n.metadata,titleLocked:n.title_locked===1,updatedAt:n.updated_at}}function Os(n){try{let t=JSON.stringify(n);return (!t||t==="null"||t.startsWith("["))&&L("event payload must be a JSON object"),t}catch(t){throw new u("VALIDATION","event payload must be JSON serializable",t)}}function de(n,t){return n.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${R.seq}), 0)`}).from(R).where(drizzleOrm.eq(R.thread_id,t)).get()?.maxSeq??0}function ce(n,t){return !!n.select({id:R.id}).from(R).where(drizzleOrm.eq(R.thread_id,t)).limit(1).get()}function Gt(n,t){Ss.has(t.type)||L(`invalid thread event type: ${String(t.type)}`);let e=xe("the");n.insert(R).values({id:e,thread_id:t.threadId,seq:t.seq,type:t.type,actor_type:t.actorType,actor_id:t.actorId,task_id:t.taskId??null,highlight_id:t.highlightId??null,payload_json:Os(t.payload),created_at:t.createdAt}).run();let r=n.select().from(R).where(drizzleOrm.eq(R.id,e)).get();if(!r)throw new u("DB_ERROR","Thread event insert did not return a row");return r}function le(n,t,e,r,s){let i=zt(t);Gt(n,{threadId:t.id,seq:s,type:"thread.snapshot.imported",actorType:e.actorType,actorId:e.actorId,createdAt:r,payload:{title:i.title,priority:i.priority,state:i.state}});}function $e(n){return {highlightId:n.id,source:n.source,kind:n.kind,status:n.status,coversFromTaskId:n.covers_from_task_id,coversToTaskId:n.covers_to_task_id,revision:n.revision,...n.dismissed_at===null?{}:{dismissedAt:n.dismissed_at}}}function Pe(n,t,e,r,s,i,a){let d=s==="thread.highlight.created"?$e(t):{before:a?$e({...t,...a,id:t.id}):void 0,after:$e(t)};return Gt(n,{threadId:t.thread_id,seq:i,type:s,actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.source==="manual"?t.covers_from_task_id:t.source_task_id??t.covers_from_task_id,highlightId:t.id,payload:d})}var ue=class extends X{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=dt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(!t&&!fs$1.existsSync(e))throw new u("NOT_FOUND","Database not found");if(t){let s=dt.dirname(e);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}let r=N(e);if(t)try{et(r.db,e);}catch(s){throw r.close(),s}return r}findThread(t,e,r){let s=drizzleOrm.eq(h.id,e),i=r===void 0?s:r===null?drizzleOrm.and(s,drizzleOrm.isNull(h.workspace_id)):drizzleOrm.and(s,drizzleOrm.eq(h.workspace_id,r));return t.select().from(h).where(i).limit(1).get()}resolveWorkspaceId(t){if(P(t,"threadId"),!fs$1.existsSync(this.resolveDbPath()))return null;let e=this.openHandle(false);try{return e.db.select({workspaceId:h.workspace_id}).from(h).where(drizzleOrm.eq(h.id,t)).limit(1).get()?.workspaceId??null}catch(r){throw r instanceof u?r:new u("DB_ERROR","Failed to resolve thread workspace",r)}finally{e.close();}}getSnapshot(t,e){if(P(t,"threadId"),!fs$1.existsSync(this.resolveDbPath()))return null;let r=this.openHandle(false);try{let s=this.findThread(r.db,t,e);return s?zt(s):null}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read thread snapshot",s)}finally{r.close();}}updateSnapshot(t){As(t);let e=ae(t),r=new Date().toISOString(),s=this.openHandle(true);try{return s.db.transaction(i=>{let a=this.findThread(i,t.threadId,t.workspaceId);a||xt(`Thread ${t.threadId} not found`);let d=zt(a),c=t.title!==void 0,l=c&&t.title!==d.title,_=c&&a.title_locked!==1,p=t.priority!==void 0&&t.priority!==d.priority,g=t.state!==void 0&&t.state!==d.state,f=l||p||g;if(!f&&!_)return d;let b=a.metadata;(p||g)&&(b=On(a.metadata,{priority:t.priority,state:t.state}));let x={};if(f&&(x.metadata=b,x.updated_at=r),l&&(x.title=t.title),c&&(x.title_locked=1),i.update(h).set(x).where(t.workspaceId===void 0?drizzleOrm.eq(h.id,t.threadId):t.workspaceId===null?drizzleOrm.and(drizzleOrm.eq(h.id,t.threadId),drizzleOrm.isNull(h.workspace_id)):drizzleOrm.and(drizzleOrm.eq(h.id,t.threadId),drizzleOrm.eq(h.workspace_id,t.workspaceId))).run(),!f){let j={...a,title_locked:1};return zt(j)}let v=de(i,a.id)+1;ce(i,a.id)||(le(i,a,e,r,v),v+=1),l&&(Gt(i,{threadId:a.id,seq:v,type:"thread.title.changed",actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.taskId,payload:{before:d.title,after:t.title}}),v+=1),p&&(Gt(i,{threadId:a.id,seq:v,type:"thread.priority.changed",actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.taskId,payload:{before:d.priority,after:t.priority}}),v+=1),g&&Gt(i,{threadId:a.id,seq:v,type:"thread.state.changed",actorType:e.actorType,actorId:e.actorId,createdAt:r,taskId:t.taskId,payload:{before:d.state,after:t.state}});let M={...a,title:l?t.title:a.title,metadata:b,title_locked:c?1:a.title_locked,updated_at:r};return zt(M)},{behavior:"immediate"})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to update thread snapshot",i)}finally{s.close();}}mutateSnapshot(t){return this.updateSnapshot(t)}updateThreadSnapshot(t){return this.updateSnapshot(t)}getLatestSeq(t,e){if(P(t,"threadId"),!fs$1.existsSync(this.resolveDbPath()))return null;let r=this.openHandle(false);try{return this.findThread(r.db,t,e)?r.db.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${R.seq}), 0)`}).from(R).where(drizzleOrm.eq(R.thread_id,t)).get()?.maxSeq??0:null}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read latest thread event sequence",s)}finally{r.close();}}listTimeline(t,e,r={}){let s=typeof t=="string"?{...r,threadId:t,workspaceId:e}:t;P(s.threadId,"threadId"),P(s.workspaceId,"workspaceId");let i=Cs(s);if(!fs$1.existsSync(this.resolveDbPath()))return null;let a=this.openHandle(false);try{if(!this.findThread(a.db,s.threadId,s.workspaceId))return null;let d=a.db.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${R.seq}), 0)`}).from(R).where(drizzleOrm.eq(R.thread_id,s.threadId)).get()?.maxSeq??0,c;s.beforeSeq!==void 0?c=a.db.select().from(R).where(drizzleOrm.and(drizzleOrm.eq(R.thread_id,s.threadId),drizzleOrm.lt(R.seq,s.beforeSeq))).orderBy(drizzleOrm.desc(R.seq)).limit(i+1).all().reverse():s.afterSeq!==void 0?c=a.db.select().from(R).where(drizzleOrm.and(drizzleOrm.eq(R.thread_id,s.threadId),drizzleOrm.sql`${R.seq} > ${s.afterSeq}`)).orderBy(drizzleOrm.asc(R.seq)).limit(i+1).all():c=a.db.select().from(R).where(drizzleOrm.eq(R.thread_id,s.threadId)).orderBy(drizzleOrm.desc(R.seq)).limit(i+1).all().reverse();let l=c.length>i,_=s.afterSeq!==void 0?c.slice(0,i):l?c.slice(1):c,p=!1,g=_[0];return g&&(p=!!a.db.select({id:R.id}).from(R).where(drizzleOrm.and(drizzleOrm.eq(R.thread_id,s.threadId),drizzleOrm.lt(R.seq,g.seq))).limit(1).get()),{items:_,latestSeq:d,hasMoreOlder:p}}catch(d){throw d instanceof u?d:new u("DB_ERROR","Failed to list thread timeline",d)}finally{a.close();}}listEvents(t,e,r){return this.listTimeline(t,e,r)}getTimeline(t,e,r){return this.listTimeline(t,e,r)}createHighlight(t){let e=xs(t),r=ae(t),s=new Date().toISOString(),i=this.openHandle(true);try{return i.db.transaction(a=>{let d=this.findThread(a,t.threadId,t.workspaceId);if(d||xt(`Thread ${t.threadId} not found`),e.source==="auto"){let g=a.select().from(E).where(drizzleOrm.and(drizzleOrm.eq(E.thread_id,t.threadId),drizzleOrm.eq(E.source_task_id,e.sourceTaskId),drizzleOrm.eq(E.detector_version,e.detectorVersion),drizzleOrm.eq(E.content_fingerprint,e.contentFingerprint))).orderBy(drizzleOrm.asc(E.created_at),drizzleOrm.asc(E.id)).limit(1).get();if(g)return g}let c=t.id??xe("thl"),l={id:c,thread_id:t.threadId,source:e.source,kind:e.kind,status:"active",text:e.text,covers_from_task_id:e.coversFromTaskId,covers_to_task_id:e.coversToTaskId,revision:0,created_at:s,updated_at:s,agent_id:e.agentId,source_task_id:e.sourceTaskId,detector_version:e.detectorVersion,content_fingerprint:e.contentFingerprint,dismissed_at:null};a.insert(E).values(l).run();let _=a.select().from(E).where(drizzleOrm.eq(E.id,c)).get();if(!_)throw new u("DB_ERROR","Highlight insert did not return a row");let p=de(a,d.id)+1;return ce(a,d.id)||(le(a,d,r,s,p),p+=1),Pe(a,_,r,s,"thread.highlight.created",p),_},{behavior:"immediate"})}catch(a){throw a instanceof u?a:new u("DB_ERROR","Failed to create thread highlight",a)}finally{i.close();}}updateHighlight(t){P(t.threadId,"threadId"),P(t.workspaceId,"workspaceId"),P(t.highlightId,"highlightId"),(!Number.isInteger(t.expectedRevision)||t.expectedRevision<0)&&L("expectedRevision must be a non-negative integer"),t.text===void 0&&t.kind===void 0&&t.coversFromTaskId===void 0&&t.coversToTaskId===void 0&&L("highlight update requires at least one field"),t.kind!==void 0&&qn(t.kind);let e=t.text===void 0?void 0:Hn(t.text),r=ae(t),s=new Date().toISOString(),i=this.openHandle(true);try{return i.db.transaction(a=>{let d=this.findThread(a,t.threadId,t.workspaceId);d||xt(`Thread ${t.threadId} not found`);let c=a.select().from(E).where(drizzleOrm.and(drizzleOrm.eq(E.id,t.highlightId),drizzleOrm.eq(E.thread_id,d.id))).limit(1).get();if(c||xt(`Highlight ${t.highlightId} not found`),c.revision!==t.expectedRevision)throw new Wt(d.id,c.id,t.expectedRevision,c.revision);if(c.status!=="active")throw new Wt(d.id,c.id,t.expectedRevision,c.revision);let l=t.kind??c.kind,_=e??c.text,p=t.coversFromTaskId??c.covers_from_task_id,g=t.coversToTaskId??c.covers_to_task_id;(!_||p.length===0||g.length===0)&&L("highlight projection is incomplete");let f=l!==c.kind||_!==c.text||p!==c.covers_from_task_id||g!==c.covers_to_task_id,b=r.actorType==="user"&&c.source==="auto"&&f?"manual":c.source;if(!(f||b!==c.source))return c;let v=c.revision+1;a.update(E).set({source:b,kind:l,text:_,covers_from_task_id:p,covers_to_task_id:g,revision:v,updated_at:s}).where(drizzleOrm.and(drizzleOrm.eq(E.id,c.id),drizzleOrm.eq(E.revision,c.revision))).run();let M=a.select().from(E).where(drizzleOrm.eq(E.id,c.id)).get();if(!M)throw new u("DB_ERROR","Highlight update did not return a row");let j=de(a,d.id)+1;return ce(a,d.id)||(le(a,d,r,s,j),j+=1),Pe(a,M,r,s,"thread.highlight.updated",j,c),M},{behavior:"immediate"})}catch(a){throw a instanceof u?a:new u("DB_ERROR","Failed to update thread highlight",a)}finally{i.close();}}dismissHighlight(t){P(t.threadId,"threadId"),P(t.workspaceId,"workspaceId"),P(t.highlightId,"highlightId"),(!Number.isInteger(t.expectedRevision)||t.expectedRevision<0)&&L("expectedRevision must be a non-negative integer");let e=ae(t),r=new Date().toISOString(),s=this.openHandle(true);try{return s.db.transaction(i=>{let a=this.findThread(i,t.threadId,t.workspaceId);a||xt(`Thread ${t.threadId} not found`);let d=i.select().from(E).where(drizzleOrm.and(drizzleOrm.eq(E.id,t.highlightId),drizzleOrm.eq(E.thread_id,a.id))).limit(1).get();if(d||xt(`Highlight ${t.highlightId} not found`),d.revision!==t.expectedRevision)throw new Wt(a.id,d.id,t.expectedRevision,d.revision);if(d.status==="dismissed")return d;let c=d.revision+1;i.update(E).set({status:"dismissed",text:null,revision:c,updated_at:r,dismissed_at:r}).where(drizzleOrm.and(drizzleOrm.eq(E.id,d.id),drizzleOrm.eq(E.revision,d.revision))).run();let l=i.select().from(E).where(drizzleOrm.eq(E.id,d.id)).get();if(!l)throw new u("DB_ERROR","Highlight dismissal did not return a row");let _=de(i,a.id)+1;return ce(i,a.id)||(le(i,a,e,r,_),_+=1),Pe(i,l,e,r,"thread.highlight.deleted",_,d),l},{behavior:"immediate"})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to dismiss thread highlight",i)}finally{s.close();}}listActiveHighlights(t,e,r={}){if(P(t,"threadId"),P(e,"workspaceId"),r.taskId!==void 0&&P(r.taskId,"taskId"),r.coversFromTaskId!==void 0&&P(r.coversFromTaskId,"coversFromTaskId"),r.coversToTaskId!==void 0&&P(r.coversToTaskId,"coversToTaskId"),!fs$1.existsSync(this.resolveDbPath()))return null;let s=this.openHandle(false);try{if(!this.findThread(s.db,t,e))return null;let a=s.db.select().from(E).where(drizzleOrm.and(drizzleOrm.eq(E.thread_id,t),drizzleOrm.eq(E.status,"active"))).orderBy(drizzleOrm.asc(E.created_at),drizzleOrm.asc(E.id)).all();if(r.taskId===void 0&&r.coversFromTaskId===void 0&&r.coversToTaskId===void 0)return a;let d=s.db.all(drizzleOrm.sql`
|
|
359
359
|
SELECT id, started_at FROM tasks WHERE thread_id = ${t}
|
|
360
360
|
ORDER BY started_at ASC, id ASC
|
|
361
|
-
`),c=new Map(d.map((g,f)=>[g.id,f])),l=r.taskId===void 0?void 0:c.get(r.taskId),
|
|
362
|
-
`).filter(
|
|
363
|
-
`).trim()}function
|
|
364
|
-
`):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=
|
|
365
|
-
`)[0].slice(0,200)),e.push({id:`${r.id}-assistant`,text:
|
|
361
|
+
`),c=new Map(d.map((g,f)=>[g.id,f])),l=r.taskId===void 0?void 0:c.get(r.taskId),_=r.coversFromTaskId===void 0?void 0:c.get(r.coversFromTaskId),p=r.coversToTaskId===void 0?void 0:c.get(r.coversToTaskId);return a.filter(g=>{let f=c.get(g.covers_from_task_id),b=c.get(g.covers_to_task_id);if(f===void 0||b===void 0)return !1;let x=Math.min(f,b),v=Math.max(f,b);return !(l!==void 0&&(l<x||l>v)||_!==void 0&&v<_||p!==void 0&&x>p)})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to list active thread highlights",i)}finally{s.close();}}listHighlights(t,e,r){return this.listActiveHighlights(t,e,r)}getActiveHighlights(t,e,r){return this.listActiveHighlights(t,e,r)}};var H=class extends u{reason;constructor(t,e="VALIDATION",r=t,s){super(e,r,s),this.name="CommonCodeRepositoryError",this.reason=t;}},jn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function js(){let n=crypto.randomBytes(16),t="";for(let e of n)t+=jn[e%jn.length];return t.slice(0,12)}function Un(){return `c_${js()}`}function Us(n){return typeof n=="string"&&Ie.includes(n)}function Fs(n){return typeof n=="string"&&ve.includes(n)}function Kt(n){if(!Us(n))throw new H("COMMON_CODE_GROUP_INVALID","VALIDATION",`Unsupported common-code group: ${n}`)}function Fn(n){if(!Fs(n))throw new H("COMMON_CODE_COLOR_INVALID","VALIDATION",`Unsupported common-code color: ${n}`)}function zn(n){let t=typeof n=="string"?n.trim():"",e=[...t].length;if(e<1||e>20)throw new H("COMMON_CODE_NAME_INVALID","VALIDATION","Common-code names must contain 1 to 20 Unicode characters");return t}function Vt(n){if(typeof n!="string"||n.trim().length===0)throw new H("COMMON_CODE_WORKSPACE_INVALID","VALIDATION","Workspace id is required for a user common code")}function He(n){if(typeof n!="string"||n.trim().length===0)throw new H("COMMON_CODE_CODE_INVALID","VALIDATION","Common-code code is required")}function Dt(n,t){return drizzleOrm.and(drizzleOrm.eq(m.code_group,n),drizzleOrm.or(drizzleOrm.isNull(m.workspace_id),drizzleOrm.eq(m.workspace_id,t)))}var he=class extends X{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=dt.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(!t&&!fs$1.existsSync(e))throw new u("NOT_FOUND","Database not found");t&&fs$1.mkdirSync(dt.dirname(e),{recursive:true});let r=N(e);if(t)try{et(r.db,e);}catch(s){throw r.close(),s}return r}listSelectable(t,e){if(Kt(t),Vt(e),!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.select().from(m).where(drizzleOrm.and(Dt(t,e),drizzleOrm.eq(m.is_archived,0))).orderBy(drizzleOrm.asc(m.sort_order),drizzleOrm.asc(m.code)).all()}catch(s){throw new u("DB_ERROR","Failed to list selectable common codes",s)}finally{r.close();}}listForHistory(t,e){if(Kt(t),Vt(e),!this.dbExists())return [];let r=this.openHandle(false);try{return r.db.select().from(m).where(Dt(t,e)).orderBy(drizzleOrm.asc(m.sort_order),drizzleOrm.asc(m.code)).all()}catch(s){throw new u("DB_ERROR","Failed to list common-code history",s)}finally{r.close();}}resolve(t,e){if(Kt(t),He(e),!this.dbExists())return null;let r=this.openHandle(false);try{return r.db.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t),drizzleOrm.eq(m.code,e))).limit(1).get()??null}catch(s){throw new u("DB_ERROR","Failed to resolve common code",s)}finally{r.close();}}createThreadState(t){Vt(t.workspaceId);let e=zn(t.name);Fn(t.color);let r=this.openHandle(true);try{return r.db.transaction(s=>{if(s.select({code:m.code}).from(m).where(drizzleOrm.and(Dt("THREAD_STATE",t.workspaceId),drizzleOrm.eq(m.is_archived,0),drizzleOrm.eq(m.code_name,e))).limit(1).get())throw new H("COMMON_CODE_NAME_CONFLICT","CONFLICT",`Common-code name is already in use: ${e}`);let a=s.select({maxSortOrder:drizzleOrm.sql`max(${m.sort_order})`}).from(m).where(Dt("THREAD_STATE",t.workspaceId)).get(),d=new Date().toISOString(),c=Un();for(;s.select({code:m.code}).from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,"THREAD_STATE"),drizzleOrm.eq(m.code,c))).limit(1).get();)c=Un();s.insert(m).values({code_group:"THREAD_STATE",code:c,code_name:e,color:t.color,sort_order:(a?.maxSortOrder??-1)+1,workspace_id:t.workspaceId,is_builtin:0,is_archived:0,metadata:null,created_at:d,updated_at:d}).run();let l=s.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,"THREAD_STATE"),drizzleOrm.eq(m.code,c))).limit(1).get();if(!l)throw new u("DB_ERROR","Created common code could not be read back");return l},{behavior:"immediate"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to create thread state common code",s)}finally{r.close();}}updateDisplay(t){if(Kt(t.group),He(t.code),Vt(t.workspaceId),t.name===void 0&&t.color===void 0)throw new H("COMMON_CODE_UPDATE_EMPTY","VALIDATION","At least one display value is required");let e=t.name===void 0||t.name===null?t.name:zn(t.name);t.color!==void 0&&Fn(t.color);let r=this.openHandle(true);try{return r.db.transaction(s=>{let i=s.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t.group),drizzleOrm.eq(m.code,t.code))).limit(1).get();if(!i)throw new H("COMMON_CODE_NOT_FOUND","NOT_FOUND",`Common code not found: ${t.group}/${t.code}`);if(this.assertOwnership(i,t.workspaceId),e===null&&i.is_builtin!==1)throw new H("COMMON_CODE_NAME_INVALID","VALIDATION","User common-code names cannot be cleared");if(typeof e=="string"&&i.is_archived===0){let c=drizzleOrm.and(Dt(t.group,t.workspaceId),drizzleOrm.eq(m.is_archived,0));if(s.select({code:m.code}).from(m).where(drizzleOrm.and(c,drizzleOrm.eq(m.code_name,e),drizzleOrm.sql`${m.code} <> ${t.code}`)).limit(1).get())throw new H("COMMON_CODE_NAME_CONFLICT","CONFLICT",`Common-code name is already in use: ${e}`)}let a={updated_at:new Date().toISOString()};t.name!==void 0&&(a.code_name=e??null),t.color!==void 0&&(a.color=t.color),s.update(m).set(a).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t.group),drizzleOrm.eq(m.code,t.code))).run();let d=s.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t.group),drizzleOrm.eq(m.code,t.code))).limit(1).get();if(!d)throw new u("DB_ERROR","Updated common code could not be read back");return d},{behavior:"immediate"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to update common-code display values",s)}finally{r.close();}}archive(t,e,r,s=true){if(Kt(t),He(e),Vt(r),typeof s!="boolean")throw new H("COMMON_CODE_ARCHIVE_INVALID","VALIDATION","Archive state must be boolean");let i=this.openHandle(true);try{return i.db.transaction(a=>{let d=a.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t),drizzleOrm.eq(m.code,e))).limit(1).get();if(!d)throw new H("COMMON_CODE_NOT_FOUND","NOT_FOUND",`Common code not found: ${t}/${e}`);if(d.is_builtin===1)throw new H("COMMON_CODE_BUILTIN_ARCHIVE_FORBIDDEN","VALIDATION","Builtin common codes cannot be archived");if(this.assertOwnership(d,r),!s&&d.code_name!==null&&a.select({code:m.code}).from(m).where(drizzleOrm.and(Dt(t,r),drizzleOrm.eq(m.is_archived,0),drizzleOrm.eq(m.code_name,d.code_name),drizzleOrm.ne(m.code,e))).limit(1).get())throw new H("COMMON_CODE_NAME_CONFLICT","CONFLICT",`Common-code name is already in use: ${d.code_name}`);a.update(m).set({is_archived:s?1:0,updated_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t),drizzleOrm.eq(m.code,e))).run();let c=a.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,t),drizzleOrm.eq(m.code,e))).limit(1).get();if(!c)throw new u("DB_ERROR","Archived common code could not be read back");return c},{behavior:"immediate"})}catch(a){throw a instanceof u?a:new u("DB_ERROR","Failed to archive common code",a)}finally{i.close();}}assertOwnership(t,e){if(t.workspace_id!==null&&t.workspace_id!==e)throw new H("COMMON_CODE_SCOPE_FORBIDDEN","VALIDATION","Workspace does not own this common code")}};function Gs(n){return n.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
|
|
362
|
+
`).filter(s=>!(s.startsWith("Loaded ")&&s.includes("layouts from")||s.includes("[dotenv@")||s.includes("[Nest]")&&s.includes("DEBUG")||s.startsWith("Registered custom layout:")||s.startsWith("Updated custom layout:"))).join(`
|
|
363
|
+
`).trim()}function Ks(n){if(!n)return "";let t=n;try{let e=JSON.parse(t);Array.isArray(e)?t=e.filter(r=>r?.type==="text"&&r?.text).map(r=>r.text).join(`
|
|
364
|
+
`):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=Gs(t);}return t}var pe=class{dbPath;constructor(t){this.dbPath=t??dt.join(Qn.homedir(),".crewx","crewx.db");}getThreadRepo(){return new ie({dbPath:this.dbPath})}getThreadHistoryRepo(){return new ue({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,r){let s=this.getThreadRepo(),i=s.findThreadById(t);if(i){if(i.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${i.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return {created:false}}return s.ensureThread(t,e,r),{created:true}}async fetchHistory(t,e){let r=e?.limit??100,s=this.getThreadRepo(),i=s.findThreadById(t),a=s.findTopLevelTasks(t,void 0,r),d=new Set(["queued","cancelled"]);a=a.filter(p=>(!p.status||!d.has(p.status))&&(!e?.currentTraceId||p.trace_id!==e.currentTraceId));let c=i?.platform??"cli",l=this.rowsToMessages(a),_=e?.includeHighlights===false?void 0:this.readActiveHighlights(t,i?.workspace_id??null);return {threadId:t,platform:c,messages:l,..._?{highlights:_}:{},metadata:{title:i?.title??void 0,firstMessage:i?.first_message??void 0,lastMessage:i?.last_message??void 0,messageCount:i?.message_count??0,updatedAt:i?.updated_at?new Date(i.updated_at).getTime():void 0}}}async fetchThreadState(t){try{let e=this.getThreadHistoryRepo().getSnapshot(t);if(!e)return;let r=new he({dbPath:this.dbPath}),s=(i,a)=>{try{return r.resolve(i,a)?.code_name||a}catch{return a}};return {...e.title?{title:e.title}:{},...e.priority?{priority:{code:e.priority,name:s("THREAD_PRIORITY",e.priority)}}:{},...e.state?{state:{code:e.state,name:s("THREAD_STATE",e.state)}}:{}}}catch{return}}async fetchHighlights(t){let e=this.getThreadRepo().findThreadById(t);return this.readActiveHighlights(t,e?.workspace_id??null)}async saveUserMessage(t,e,r,s){let{firstMessage:i}=this.getThreadRepo().saveUserMessage(t,e);return {id:t,firstMessage:i}}async saveAssistantMessage(t,e,r,s){return this.getThreadRepo().saveAssistantMessage(t,e),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}readActiveHighlights(t,e){if(!e)return [];try{return (this.getThreadHistoryRepo().listActiveHighlights(t,e)??[]).filter(s=>typeof s.text=="string"&&s.text.length>0).map(s=>({id:s.id,text:s.text,kind:s.kind,source:s.source,coversFromTaskId:s.covers_from_task_id,coversToTaskId:s.covers_to_task_id,createdAt:s.created_at}))}catch{return}}rowsToMessages(t){let e=[];for(let r of t){r.prompt&&e.push({id:`${r.id}-user`,text:r.prompt,isAssistant:false,timestamp:new Date(r.started_at).getTime(),taskId:r.id,metadata:{caller_agent_id:r.caller_agent_id,task_id:r.id}});let s=Ks(r.result),i=this.normalizeStatus(r.status);if(s||i==="running"||i==="failed"){let a={agent_id:r.agent_id,task_id:r.id};i&&(a.status=i),i==="failed"&&r.error&&(a.reason=r.error.split(`
|
|
365
|
+
`)[0].slice(0,200)),e.push({id:`${r.id}-assistant`,text:s,isAssistant:true,timestamp:new Date(r.started_at).getTime(),taskId:r.id,metadata:a});}}return e}};var qe=class extends kt{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new pe(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,e,r,s){}async afterAssistantMessage(t,e,r){}attach(t){this.unsubStart=t.on("task:start",async e=>{if(!e.threadId)return;let r=e.platform??"cli";try{let s=await this._provider.ensureThread(e.threadId,r,e.workspaceId),i=await this._provider.saveUserMessage(e.threadId,e.message??"");await this.afterUserMessage(e.threadId,i.id,s.created||i.firstMessage,e);}catch{}}),this.unsubEnd=t.on("task:end",async e=>{if(!e.result)return;let r=e.metadata?.threadId;if(!r)return;let s=e.agentRef?.replace(/^@/,"")??"";try{let{id:i}=await this._provider.saveAssistantMessage(r,e.result,s);await this.afterAssistantMessage(r,i,e);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};exports.ConversationPlugin=qe;exports.FileLoggerPlugin=fe;exports.SqliteTracingPlugin=be;
|