@crewx/sdk 0.8.1-rc.4 → 0.8.2-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,14 @@
1
- import {existsSync,mkdirSync,writeFileSync,appendFileSync}from'fs';import*as x from'path';import {join,dirname,basename}from'path';import {homedir}from'os';import $ from'better-sqlite3';import {createHash}from'crypto';var d=class{detach(s){}};function S(i){let s=t=>String(t).padStart(2,"0");return `${i.getFullYear()}${s(i.getMonth()+1)}${s(i.getDate())}T${s(i.getHours())}${s(i.getMinutes())}${s(i.getSeconds())}`}var h=class extends d{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(s){super(),this.logsDir=join(s?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=s?.version??"unknown";}attach(s){this.unsubs.push(s.on("task:start",t=>{try{existsSync(this.logsDir)||mkdirSync(this.logsDir,{recursive:!0});let r=S(t.timestamp),a=join(this.logsDir,`${r}_${t.traceId}.log`);this.logFiles.set(t.traceId,a);let n=`=== TASK LOG: ${t.traceId} ===
1
+ import {existsSync,mkdirSync,writeFileSync,appendFileSync}from'fs';import*as x from'path';import {join,dirname,basename}from'path';import {homedir}from'os';import U from'better-sqlite3';import {createHash}from'crypto';var l=class{detach(s){}};function S(i){let s=t=>String(t).padStart(2,"0");return `${i.getFullYear()}${s(i.getMonth()+1)}${s(i.getDate())}T${s(i.getHours())}${s(i.getMinutes())}${s(i.getSeconds())}`}var h=class extends l{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(s){super(),this.logsDir=join(s?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=s?.version??"unknown";}attach(s){this.unsubs.push(s.on("task:start",t=>{try{existsSync(this.logsDir)||mkdirSync(this.logsDir,{recursive:!0});let r=S(t.timestamp),a=join(this.logsDir,`${r}_${t.traceId}.log`);this.logFiles.set(t.traceId,a);let o=`=== TASK LOG: ${t.traceId} ===
2
2
  CrewX Version: ${this.version}
3
3
  Mode: ${t.mode}
4
4
  Agent: ${t.agentRef}
5
5
  Started: ${t.timestamp.toLocaleString()}
6
6
  Message: ${t.message}
7
7
 
8
- `;writeFileSync(a,n,{encoding:"utf8",mode:384});}catch{}}),s.on("task:output",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toISOString();appendFileSync(r,`[${a}] STDOUT: ${t.output}
9
- `,"utf8");}catch{}}),s.on("task:end",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toLocaleString(),n=t.error?`failed: ${t.error.message}`:"completed successfully",p=`[${a}] INFO: Task ${n} in ${t.durationMs}ms
8
+ `;writeFileSync(a,o,{encoding:"utf8",mode:384});}catch{}}),s.on("task:output",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toISOString();appendFileSync(r,`[${a}] STDOUT: ${t.output}
9
+ `,"utf8");}catch{}}),s.on("task:end",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toLocaleString(),o=t.error?`failed: ${t.error.message}`:"completed successfully",u=`[${a}] INFO: Task ${o} in ${t.durationMs}ms
10
10
  [${a}] INFO: Process closed with exit code: ${t.error?1:0}
11
- `;appendFileSync(r,p,"utf8"),this.logFiles.delete(t.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.logFiles.clear();}};function P(i){let s=x.resolve(i);return process.platform==="win32"&&(s=s.replace(/\\/g,"/"),s=s.replace(/^([A-Z]):/,(t,r)=>`${r.toLowerCase()}:`)),s.length>1&&!/^[a-zA-Z]:\/$/.test(s)&&(s=s.replace(/\/+$/,"")),s}function C(i){let s=P(i);return createHash("sha256").update(s).digest("hex")}var T=class extends d{name="sqlite-tracing";db=null;unsubs=[];dbPath;version;constructor(s){super(),this.dbPath=join(s?.dbRoot??homedir(),".crewx","crewx.db"),this.version=s?.version??"unknown";}attach(s){let t=dirname(this.dbPath);existsSync(t)||mkdirSync(t,{recursive:true}),this.db=new $(this.dbPath);let r=this.db.prepare("PRAGMA table_info(tasks)").all(),a=e=>r.some(o=>o.name===e);a("parent_task_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN parent_task_id TEXT"),a("caller_agent_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN caller_agent_id TEXT"),a("trace_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN trace_id TEXT");let n=process.cwd(),p=existsSync(join(n,"crewx.yaml"))||existsSync(join(n,"crewx.yml")),w=p?C(n):null,g=p?basename(n):null,f=process.argv.join(" ");this.unsubs.push(s.on("task:start",e=>{try{let o=process.env.CREWX_CALLER_AGENT_ID||null,u=process.env.CREWX_PARENT_TASK_ID||null,v=process.env.CREWX_TRACE_ID||e.traceId,I=e.metadata?JSON.stringify(e.metadata):JSON.stringify({provider:e.provider??"cli/claude"});this.db.prepare(`INSERT OR IGNORE INTO tasks
11
+ `;appendFileSync(r,u,"utf8"),this.logFiles.delete(t.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.logFiles.clear();}};function L(i){let s=x.resolve(i);return process.platform==="win32"&&(s=s.replace(/\\/g,"/"),s=s.replace(/^([A-Z]):/,(t,r)=>`${r.toLowerCase()}:`)),s.length>1&&!/^[a-zA-Z]:\/$/.test(s)&&(s=s.replace(/\/+$/,"")),s}function C(i){let s=L(i);return createHash("sha256").update(s).digest("hex")}var T=class extends l{name="sqlite-tracing";db=null;unsubs=[];dbPath;version;constructor(s){super(),this.dbPath=join(s?.dbRoot??homedir(),".crewx","crewx.db"),this.version=s?.version??"unknown";}attach(s){let t=dirname(this.dbPath);if(existsSync(t)||mkdirSync(t,{recursive:true}),this.db=new U(this.dbPath),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='tasks'").get()!==void 0){let e=this.db.prepare("PRAGMA table_info(tasks)").all(),n=d=>e.some(m=>m.name===d);n("parent_task_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN parent_task_id TEXT"),n("caller_agent_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN caller_agent_id TEXT"),n("trace_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN trace_id TEXT");}let a=process.cwd(),o=existsSync(join(a,"crewx.yaml"))||existsSync(join(a,"crewx.yml")),u=o?C(a):null,b=o?basename(a):null,f=process.argv.join(" ");this.unsubs.push(s.on("task:start",e=>{try{let n=process.env.CREWX_CALLER_AGENT_ID||null,d=process.env.CREWX_PARENT_TASK_ID||null,m=process.env.CREWX_TRACE_ID||e.traceId,v=e.metadata?JSON.stringify(e.metadata):JSON.stringify({provider:e.provider??"cli/claude"});this.db.prepare(`INSERT OR IGNORE INTO tasks
12
12
  (id, agent_id, prompt, mode, status, pid, started_at,
13
13
  crewx_version, platform,
14
14
  model, rendered_prompt, command, coding_agent_command,
@@ -18,14 +18,14 @@ Message: ${t.message}
18
18
  ?, ?,
19
19
  ?, ?, ?, ?,
20
20
  ?, ?,
21
- ?, ?, ?, ?, ?)`).run(e.traceId,e.agentRef.replace(/^@/,""),e.message,e.mode,e.pid??null,e.timestamp.toISOString(),this.version,e.platform??"cli",e.model??null,e.renderedPrompt??null,f,e.codingAgentCommand??null,e.workspaceId??w,e.workspaceName??g,o,u,v,I,e.threadId??null);}catch{}}),s.on("task:output",e=>{try{let o=this.db.prepare("SELECT logs FROM tasks WHERE id=?").get(e.traceId),u=o?.logs?JSON.parse(o.logs):[];u.push({timestamp:e.timestamp.toISOString(),level:e.level??"stdout",message:e.output}),this.db.prepare("UPDATE tasks SET logs=? WHERE id=?").run(JSON.stringify(u),e.traceId);}catch{}}),s.on("task:end",e=>{try{let o=e.error?"failed":"success";this.db.prepare(`UPDATE tasks
21
+ ?, ?, ?, ?, ?)`).run(e.traceId,e.agentRef.replace(/^@/,""),e.message,e.mode,e.pid??null,e.timestamp.toISOString(),this.version,e.platform??"cli",e.model??null,e.renderedPrompt??null,f,e.codingAgentCommand??null,e.workspaceId??u,e.workspaceName??b,n,d,m,v,e.threadId??null);}catch{}}),s.on("task:output",e=>{try{let n=this.db.prepare("SELECT logs FROM tasks WHERE id=?").get(e.traceId),d=n?.logs?JSON.parse(n.logs):[];d.push({timestamp:e.timestamp.toISOString(),level:e.level??"stdout",message:e.output}),this.db.prepare("UPDATE tasks SET logs=? WHERE id=?").run(JSON.stringify(d),e.traceId);}catch{}}),s.on("task:end",e=>{try{let n=e.error?"failed":"success";this.db.prepare(`UPDATE tasks
22
22
  SET status=?, result=?, error=?,
23
23
  completed_at=?, duration_ms=?,
24
24
  exit_code=?,
25
25
  input_tokens=?, output_tokens=?, cached_input_tokens=?,
26
26
  cost_usd=?,
27
27
  model=COALESCE(?, model)
28
- WHERE id=?`).run(o,e.result??null,e.error?JSON.stringify(e.error):null,e.timestamp.toISOString(),e.durationMs,e.exitCode??null,e.inputTokens??0,e.outputTokens??0,e.cachedInputTokens??0,e.costUsd??0,e.model??null,e.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.db?.close(),this.db=null;}};var X=`
28
+ WHERE id=?`).run(n,e.result??null,e.error?JSON.stringify(e.error):null,e.timestamp.toISOString(),e.durationMs,e.exitCode??null,e.inputTokens??0,e.outputTokens??0,e.cachedInputTokens??0,e.costUsd??0,e.model??null,e.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.db?.close(),this.db=null;}};var H=`
29
29
  CREATE TABLE IF NOT EXISTS threads (
30
30
  id TEXT PRIMARY KEY,
31
31
  workspace_id TEXT,
@@ -38,15 +38,15 @@ Message: ${t.message}
38
38
  updated_at TEXT NOT NULL,
39
39
  metadata TEXT
40
40
  )
41
- `,q=["id","thread_id","prompt","result","started_at","trace_id","status","parent_task_id","agent_id"];function j(i){return i.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
41
+ `,X=["id","thread_id","prompt","result","started_at","trace_id","status","parent_task_id","agent_id"];function q(i){return i.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
42
42
  `).filter(a=>!(a.startsWith("Loaded ")&&a.includes("layouts from")||a.includes("[dotenv@")||a.includes("[Nest]")&&a.includes("DEBUG")||a.startsWith("Registered custom layout:")||a.startsWith("Updated custom layout:"))).join(`
43
- `).trim()}function B(i){if(!i)return "";let s=i;try{let t=JSON.parse(s);Array.isArray(t)?s=t.filter(r=>r?.type==="text"&&r?.text).map(r=>r.text).join(`
44
- `):t&&typeof t=="object"&&t.result!==void 0&&(s=t.result||"");}catch{s=j(s);}return s}var m=class{db;constructor(s){let t=s??join(homedir(),".crewx","crewx.db");this.db=new $(t),this.init();}init(){this.db.pragma("journal_mode = WAL"),this.db.exec(X);}async ensureThread(s,t,r){let a=this.db.prepare("SELECT platform FROM threads WHERE id = ?").get(s);if(a){if(a.platform!==t)throw new Error(`Thread '${s}' already exists with platform '${a.platform}' \u2014 cannot change to '${t}' (platform is immutable)`);r&&this.db.prepare("UPDATE threads SET workspace_id = COALESCE(workspace_id, ?) WHERE id = ?").run(r,s);return}let n=new Date().toISOString();this.db.prepare("INSERT INTO threads (id, platform, workspace_id, message_count, created_at, updated_at) VALUES (?, ?, ?, 0, ?, ?)").run(s,t,r??null,n,n);}async fetchHistory(s,t){let r=t?.limit??100,a=["thread_id = ?","(parent_task_id IS NULL OR parent_task_id = '')","(status IN ('done', 'completed', 'success') OR status IS NULL)"],n=[s];t?.currentTraceId&&(a.push("trace_id != ?"),n.push(t.currentTraceId));let p=a.join(" AND "),g=`SELECT ${q.join(", ")} FROM tasks WHERE ${p} ORDER BY started_at ASC LIMIT ?`;n.push(r);let f=this.db.prepare(g).all(...n),e=this.db.prepare("SELECT platform, title, first_message, last_message, message_count, updated_at FROM threads WHERE id = ?").get(s),o=e?.platform??"cli",u=this.rowsToMessages(f);return {threadId:s,platform:o,messages:u,metadata:{title:e?.title??void 0,firstMessage:e?.first_message??void 0,lastMessage:e?.last_message??void 0,messageCount:e?.message_count??0,updatedAt:e?.updated_at?new Date(e.updated_at).getTime():void 0}}}async saveUserMessage(s,t,r,a){let n=new Date().toISOString();this.db.prepare(`UPDATE threads
43
+ `).trim()}function j(i){if(!i)return "";let s=i;try{let t=JSON.parse(s);Array.isArray(t)?s=t.filter(r=>r?.type==="text"&&r?.text).map(r=>r.text).join(`
44
+ `):t&&typeof t=="object"&&t.result!==void 0&&(s=t.result||"");}catch{s=q(s);}return s}var g=class{db;constructor(s){let t=s??join(homedir(),".crewx","crewx.db");this.db=new U(t),this.init();}init(){this.db.pragma("journal_mode = WAL"),this.db.exec(H);}async ensureThread(s,t,r){let a=this.db.prepare("SELECT platform FROM threads WHERE id = ?").get(s);if(a){if(a.platform!==t)throw new Error(`Thread '${s}' already exists with platform '${a.platform}' \u2014 cannot change to '${t}' (platform is immutable)`);r&&this.db.prepare("UPDATE threads SET workspace_id = COALESCE(workspace_id, ?) WHERE id = ?").run(r,s);return}let o=new Date().toISOString();this.db.prepare("INSERT INTO threads (id, platform, workspace_id, message_count, created_at, updated_at) VALUES (?, ?, ?, 0, ?, ?)").run(s,t,r??null,o,o);}async fetchHistory(s,t){let r=t?.limit??100,a=["thread_id = ?","(parent_task_id IS NULL OR parent_task_id = '')","(status IN ('done', 'completed', 'success') OR status IS NULL)"],o=[s];t?.currentTraceId&&(a.push("trace_id != ?"),o.push(t.currentTraceId));let u=a.join(" AND "),f=`SELECT ${X.join(", ")} FROM tasks WHERE ${u} ORDER BY started_at ASC LIMIT ?`;o.push(r);let e=this.db.prepare(f).all(...o),n=this.db.prepare("SELECT platform, title, first_message, last_message, message_count, updated_at FROM threads WHERE id = ?").get(s),d=n?.platform??"cli",m=this.rowsToMessages(e);return {threadId:s,platform:d,messages:m,metadata:{title:n?.title??void 0,firstMessage:n?.first_message??void 0,lastMessage:n?.last_message??void 0,messageCount:n?.message_count??0,updatedAt:n?.updated_at?new Date(n.updated_at).getTime():void 0}}}async saveUserMessage(s,t,r,a){let o=new Date().toISOString();this.db.prepare(`UPDATE threads
45
45
  SET first_message = COALESCE(first_message, ?),
46
46
  last_message = ?,
47
47
  message_count = message_count + 1,
48
48
  updated_at = ?
49
- WHERE id = ?`).run(t,t,n,s);}async saveAssistantMessage(s,t,r,a){let n=new Date().toISOString();this.db.prepare(`UPDATE threads
49
+ WHERE id = ?`).run(t,t,o,s);}async saveAssistantMessage(s,t,r,a){let o=new Date().toISOString();this.db.prepare(`UPDATE threads
50
50
  SET last_message = ?,
51
51
  updated_at = ?
52
- WHERE id = ?`).run(t,n,s);}close(){this.db.close();}rowsToMessages(s){let t=[];for(let r of s){r.prompt&&t.push({id:`${r.id}-user`,text:r.prompt,isAssistant:false,timestamp:new Date(r.started_at).getTime()});let a=B(r.result);a&&t.push({id:`${r.id}-assistant`,text:a,isAssistant:true,timestamp:new Date(r.started_at).getTime()});}return t}};var y=class extends d{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(s){super(),this._provider=new m(s?.dbPath);}get conversationProvider(){return this._provider}attach(s){this.unsubStart=s.on("task:start",async t=>{if(!t.threadId)return;let r=t.platform??"cli";try{await this._provider.ensureThread(t.threadId,r,t.workspaceId),await this._provider.saveUserMessage(t.threadId,t.message??"");}catch{}}),this.unsubEnd=s.on("task:end",async t=>{if(!t.result)return;let r=t.metadata?.threadId;if(!r)return;let a=t.agentRef?.replace(/^@/,"")??"";try{await this._provider.saveAssistantMessage(r,t.result,a);}catch{}});}detach(s){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{y as ConversationPlugin,h as FileLoggerPlugin,T as SqliteTracingPlugin};
52
+ WHERE id = ?`).run(t,o,s);}close(){this.db.close();}rowsToMessages(s){let t=[];for(let r of s){r.prompt&&t.push({id:`${r.id}-user`,text:r.prompt,isAssistant:false,timestamp:new Date(r.started_at).getTime()});let a=j(r.result);a&&t.push({id:`${r.id}-assistant`,text:a,isAssistant:true,timestamp:new Date(r.started_at).getTime()});}return t}};var y=class extends l{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(s){super(),this._provider=new g(s?.dbPath);}get conversationProvider(){return this._provider}attach(s){this.unsubStart=s.on("task:start",async t=>{if(!t.threadId)return;let r=t.platform??"cli";try{await this._provider.ensureThread(t.threadId,r,t.workspaceId),await this._provider.saveUserMessage(t.threadId,t.message??"");}catch{}}),this.unsubEnd=s.on("task:end",async t=>{if(!t.result)return;let r=t.metadata?.threadId;if(!r)return;let a=t.agentRef?.replace(/^@/,"")??"";try{await this._provider.saveAssistantMessage(r,t.result,a);}catch{}});}detach(s){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{y as ConversationPlugin,h as FileLoggerPlugin,T as SqliteTracingPlugin};
@@ -1,14 +1,14 @@
1
- 'use strict';var fs=require('fs'),k=require('path'),os=require('os'),U=require('better-sqlite3'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var k__namespace=/*#__PURE__*/_interopNamespace(k);var U__default=/*#__PURE__*/_interopDefault(U);var d=class{detach(s){}};function w(i){let s=t=>String(t).padStart(2,"0");return `${i.getFullYear()}${s(i.getMonth()+1)}${s(i.getDate())}T${s(i.getHours())}${s(i.getMinutes())}${s(i.getSeconds())}`}var f=class extends d{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(s){super(),this.logsDir=k.join(s?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=s?.version??"unknown";}attach(s){this.unsubs.push(s.on("task:start",t=>{try{fs.existsSync(this.logsDir)||fs.mkdirSync(this.logsDir,{recursive:!0});let r=w(t.timestamp),a=k.join(this.logsDir,`${r}_${t.traceId}.log`);this.logFiles.set(t.traceId,a);let n=`=== TASK LOG: ${t.traceId} ===
1
+ 'use strict';var fs=require('fs'),k=require('path'),os=require('os'),F=require('better-sqlite3'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var k__namespace=/*#__PURE__*/_interopNamespace(k);var F__default=/*#__PURE__*/_interopDefault(F);var l=class{detach(s){}};function b(i){let s=t=>String(t).padStart(2,"0");return `${i.getFullYear()}${s(i.getMonth()+1)}${s(i.getDate())}T${s(i.getHours())}${s(i.getMinutes())}${s(i.getSeconds())}`}var f=class extends l{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(s){super(),this.logsDir=k.join(s?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=s?.version??"unknown";}attach(s){this.unsubs.push(s.on("task:start",t=>{try{fs.existsSync(this.logsDir)||fs.mkdirSync(this.logsDir,{recursive:!0});let r=b(t.timestamp),a=k.join(this.logsDir,`${r}_${t.traceId}.log`);this.logFiles.set(t.traceId,a);let o=`=== TASK LOG: ${t.traceId} ===
2
2
  CrewX Version: ${this.version}
3
3
  Mode: ${t.mode}
4
4
  Agent: ${t.agentRef}
5
5
  Started: ${t.timestamp.toLocaleString()}
6
6
  Message: ${t.message}
7
7
 
8
- `;fs.writeFileSync(a,n,{encoding:"utf8",mode:384});}catch{}}),s.on("task:output",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toISOString();fs.appendFileSync(r,`[${a}] STDOUT: ${t.output}
9
- `,"utf8");}catch{}}),s.on("task:end",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toLocaleString(),n=t.error?`failed: ${t.error.message}`:"completed successfully",c=`[${a}] INFO: Task ${n} in ${t.durationMs}ms
8
+ `;fs.writeFileSync(a,o,{encoding:"utf8",mode:384});}catch{}}),s.on("task:output",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toISOString();fs.appendFileSync(r,`[${a}] STDOUT: ${t.output}
9
+ `,"utf8");}catch{}}),s.on("task:end",t=>{try{let r=this.logFiles.get(t.traceId);if(!r)return;let a=new Date().toLocaleString(),o=t.error?`failed: ${t.error.message}`:"completed successfully",p=`[${a}] INFO: Task ${o} in ${t.durationMs}ms
10
10
  [${a}] INFO: Process closed with exit code: ${t.error?1:0}
11
- `;fs.appendFileSync(r,c,"utf8"),this.logFiles.delete(t.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.logFiles.clear();}};function R(i){let s=k__namespace.resolve(i);return process.platform==="win32"&&(s=s.replace(/\\/g,"/"),s=s.replace(/^([A-Z]):/,(t,r)=>`${r.toLowerCase()}:`)),s.length>1&&!/^[a-zA-Z]:\/$/.test(s)&&(s=s.replace(/\/+$/,"")),s}function x(i){let s=R(i);return crypto.createHash("sha256").update(s).digest("hex")}var E=class extends d{name="sqlite-tracing";db=null;unsubs=[];dbPath;version;constructor(s){super(),this.dbPath=k.join(s?.dbRoot??os.homedir(),".crewx","crewx.db"),this.version=s?.version??"unknown";}attach(s){let t=k.dirname(this.dbPath);fs.existsSync(t)||fs.mkdirSync(t,{recursive:true}),this.db=new U__default.default(this.dbPath);let r=this.db.prepare("PRAGMA table_info(tasks)").all(),a=e=>r.some(o=>o.name===e);a("parent_task_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN parent_task_id TEXT"),a("caller_agent_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN caller_agent_id TEXT"),a("trace_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN trace_id TEXT");let n=process.cwd(),c=fs.existsSync(k.join(n,"crewx.yaml"))||fs.existsSync(k.join(n,"crewx.yml")),y=c?x(n):null,m=c?k.basename(n):null,g=process.argv.join(" ");this.unsubs.push(s.on("task:start",e=>{try{let o=process.env.CREWX_CALLER_AGENT_ID||null,p=process.env.CREWX_PARENT_TASK_ID||null,C=process.env.CREWX_TRACE_ID||e.traceId,v=e.metadata?JSON.stringify(e.metadata):JSON.stringify({provider:e.provider??"cli/claude"});this.db.prepare(`INSERT OR IGNORE INTO tasks
11
+ `;fs.appendFileSync(r,p,"utf8"),this.logFiles.delete(t.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.logFiles.clear();}};function R(i){let s=k__namespace.resolve(i);return process.platform==="win32"&&(s=s.replace(/\\/g,"/"),s=s.replace(/^([A-Z]):/,(t,r)=>`${r.toLowerCase()}:`)),s.length>1&&!/^[a-zA-Z]:\/$/.test(s)&&(s=s.replace(/\/+$/,"")),s}function x(i){let s=R(i);return crypto.createHash("sha256").update(s).digest("hex")}var _=class extends l{name="sqlite-tracing";db=null;unsubs=[];dbPath;version;constructor(s){super(),this.dbPath=k.join(s?.dbRoot??os.homedir(),".crewx","crewx.db"),this.version=s?.version??"unknown";}attach(s){let t=k.dirname(this.dbPath);if(fs.existsSync(t)||fs.mkdirSync(t,{recursive:true}),this.db=new F__default.default(this.dbPath),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='tasks'").get()!==void 0){let e=this.db.prepare("PRAGMA table_info(tasks)").all(),n=d=>e.some(u=>u.name===d);n("parent_task_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN parent_task_id TEXT"),n("caller_agent_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN caller_agent_id TEXT"),n("trace_id")||this.db.exec("ALTER TABLE tasks ADD COLUMN trace_id TEXT");}let a=process.cwd(),o=fs.existsSync(k.join(a,"crewx.yaml"))||fs.existsSync(k.join(a,"crewx.yml")),p=o?x(a):null,y=o?k.basename(a):null,g=process.argv.join(" ");this.unsubs.push(s.on("task:start",e=>{try{let n=process.env.CREWX_CALLER_AGENT_ID||null,d=process.env.CREWX_PARENT_TASK_ID||null,u=process.env.CREWX_TRACE_ID||e.traceId,C=e.metadata?JSON.stringify(e.metadata):JSON.stringify({provider:e.provider??"cli/claude"});this.db.prepare(`INSERT OR IGNORE INTO tasks
12
12
  (id, agent_id, prompt, mode, status, pid, started_at,
13
13
  crewx_version, platform,
14
14
  model, rendered_prompt, command, coding_agent_command,
@@ -18,14 +18,14 @@ Message: ${t.message}
18
18
  ?, ?,
19
19
  ?, ?, ?, ?,
20
20
  ?, ?,
21
- ?, ?, ?, ?, ?)`).run(e.traceId,e.agentRef.replace(/^@/,""),e.message,e.mode,e.pid??null,e.timestamp.toISOString(),this.version,e.platform??"cli",e.model??null,e.renderedPrompt??null,g,e.codingAgentCommand??null,e.workspaceId??y,e.workspaceName??m,o,p,C,v,e.threadId??null);}catch{}}),s.on("task:output",e=>{try{let o=this.db.prepare("SELECT logs FROM tasks WHERE id=?").get(e.traceId),p=o?.logs?JSON.parse(o.logs):[];p.push({timestamp:e.timestamp.toISOString(),level:e.level??"stdout",message:e.output}),this.db.prepare("UPDATE tasks SET logs=? WHERE id=?").run(JSON.stringify(p),e.traceId);}catch{}}),s.on("task:end",e=>{try{let o=e.error?"failed":"success";this.db.prepare(`UPDATE tasks
21
+ ?, ?, ?, ?, ?)`).run(e.traceId,e.agentRef.replace(/^@/,""),e.message,e.mode,e.pid??null,e.timestamp.toISOString(),this.version,e.platform??"cli",e.model??null,e.renderedPrompt??null,g,e.codingAgentCommand??null,e.workspaceId??p,e.workspaceName??y,n,d,u,C,e.threadId??null);}catch{}}),s.on("task:output",e=>{try{let n=this.db.prepare("SELECT logs FROM tasks WHERE id=?").get(e.traceId),d=n?.logs?JSON.parse(n.logs):[];d.push({timestamp:e.timestamp.toISOString(),level:e.level??"stdout",message:e.output}),this.db.prepare("UPDATE tasks SET logs=? WHERE id=?").run(JSON.stringify(d),e.traceId);}catch{}}),s.on("task:end",e=>{try{let n=e.error?"failed":"success";this.db.prepare(`UPDATE tasks
22
22
  SET status=?, result=?, error=?,
23
23
  completed_at=?, duration_ms=?,
24
24
  exit_code=?,
25
25
  input_tokens=?, output_tokens=?, cached_input_tokens=?,
26
26
  cost_usd=?,
27
27
  model=COALESCE(?, model)
28
- WHERE id=?`).run(o,e.result??null,e.error?JSON.stringify(e.error):null,e.timestamp.toISOString(),e.durationMs,e.exitCode??null,e.inputTokens??0,e.outputTokens??0,e.cachedInputTokens??0,e.costUsd??0,e.model??null,e.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.db?.close(),this.db=null;}};var H=`
28
+ WHERE id=?`).run(n,e.result??null,e.error?JSON.stringify(e.error):null,e.timestamp.toISOString(),e.durationMs,e.exitCode??null,e.inputTokens??0,e.outputTokens??0,e.cachedInputTokens??0,e.costUsd??0,e.model??null,e.traceId);}catch{}}));}detach(s){this.unsubs.forEach(t=>t()),this.unsubs=[],this.db?.close(),this.db=null;}};var W=`
29
29
  CREATE TABLE IF NOT EXISTS threads (
30
30
  id TEXT PRIMARY KEY,
31
31
  workspace_id TEXT,
@@ -38,15 +38,15 @@ Message: ${t.message}
38
38
  updated_at TEXT NOT NULL,
39
39
  metadata TEXT
40
40
  )
41
- `,X=["id","thread_id","prompt","result","started_at","trace_id","status","parent_task_id","agent_id"];function q(i){return i.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
41
+ `,H=["id","thread_id","prompt","result","started_at","trace_id","status","parent_task_id","agent_id"];function X(i){return i.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
42
42
  `).filter(a=>!(a.startsWith("Loaded ")&&a.includes("layouts from")||a.includes("[dotenv@")||a.includes("[Nest]")&&a.includes("DEBUG")||a.startsWith("Registered custom layout:")||a.startsWith("Updated custom layout:"))).join(`
43
- `).trim()}function j(i){if(!i)return "";let s=i;try{let t=JSON.parse(s);Array.isArray(t)?s=t.filter(r=>r?.type==="text"&&r?.text).map(r=>r.text).join(`
44
- `):t&&typeof t=="object"&&t.result!==void 0&&(s=t.result||"");}catch{s=q(s);}return s}var u=class{db;constructor(s){let t=s??k.join(os.homedir(),".crewx","crewx.db");this.db=new U__default.default(t),this.init();}init(){this.db.pragma("journal_mode = WAL"),this.db.exec(H);}async ensureThread(s,t,r){let a=this.db.prepare("SELECT platform FROM threads WHERE id = ?").get(s);if(a){if(a.platform!==t)throw new Error(`Thread '${s}' already exists with platform '${a.platform}' \u2014 cannot change to '${t}' (platform is immutable)`);r&&this.db.prepare("UPDATE threads SET workspace_id = COALESCE(workspace_id, ?) WHERE id = ?").run(r,s);return}let n=new Date().toISOString();this.db.prepare("INSERT INTO threads (id, platform, workspace_id, message_count, created_at, updated_at) VALUES (?, ?, ?, 0, ?, ?)").run(s,t,r??null,n,n);}async fetchHistory(s,t){let r=t?.limit??100,a=["thread_id = ?","(parent_task_id IS NULL OR parent_task_id = '')","(status IN ('done', 'completed', 'success') OR status IS NULL)"],n=[s];t?.currentTraceId&&(a.push("trace_id != ?"),n.push(t.currentTraceId));let c=a.join(" AND "),m=`SELECT ${X.join(", ")} FROM tasks WHERE ${c} ORDER BY started_at ASC LIMIT ?`;n.push(r);let g=this.db.prepare(m).all(...n),e=this.db.prepare("SELECT platform, title, first_message, last_message, message_count, updated_at FROM threads WHERE id = ?").get(s),o=e?.platform??"cli",p=this.rowsToMessages(g);return {threadId:s,platform:o,messages:p,metadata:{title:e?.title??void 0,firstMessage:e?.first_message??void 0,lastMessage:e?.last_message??void 0,messageCount:e?.message_count??0,updatedAt:e?.updated_at?new Date(e.updated_at).getTime():void 0}}}async saveUserMessage(s,t,r,a){let n=new Date().toISOString();this.db.prepare(`UPDATE threads
43
+ `).trim()}function q(i){if(!i)return "";let s=i;try{let t=JSON.parse(s);Array.isArray(t)?s=t.filter(r=>r?.type==="text"&&r?.text).map(r=>r.text).join(`
44
+ `):t&&typeof t=="object"&&t.result!==void 0&&(s=t.result||"");}catch{s=X(s);}return s}var m=class{db;constructor(s){let t=s??k.join(os.homedir(),".crewx","crewx.db");this.db=new F__default.default(t),this.init();}init(){this.db.pragma("journal_mode = WAL"),this.db.exec(W);}async ensureThread(s,t,r){let a=this.db.prepare("SELECT platform FROM threads WHERE id = ?").get(s);if(a){if(a.platform!==t)throw new Error(`Thread '${s}' already exists with platform '${a.platform}' \u2014 cannot change to '${t}' (platform is immutable)`);r&&this.db.prepare("UPDATE threads SET workspace_id = COALESCE(workspace_id, ?) WHERE id = ?").run(r,s);return}let o=new Date().toISOString();this.db.prepare("INSERT INTO threads (id, platform, workspace_id, message_count, created_at, updated_at) VALUES (?, ?, ?, 0, ?, ?)").run(s,t,r??null,o,o);}async fetchHistory(s,t){let r=t?.limit??100,a=["thread_id = ?","(parent_task_id IS NULL OR parent_task_id = '')","(status IN ('done', 'completed', 'success') OR status IS NULL)"],o=[s];t?.currentTraceId&&(a.push("trace_id != ?"),o.push(t.currentTraceId));let p=a.join(" AND "),g=`SELECT ${H.join(", ")} FROM tasks WHERE ${p} ORDER BY started_at ASC LIMIT ?`;o.push(r);let e=this.db.prepare(g).all(...o),n=this.db.prepare("SELECT platform, title, first_message, last_message, message_count, updated_at FROM threads WHERE id = ?").get(s),d=n?.platform??"cli",u=this.rowsToMessages(e);return {threadId:s,platform:d,messages:u,metadata:{title:n?.title??void 0,firstMessage:n?.first_message??void 0,lastMessage:n?.last_message??void 0,messageCount:n?.message_count??0,updatedAt:n?.updated_at?new Date(n.updated_at).getTime():void 0}}}async saveUserMessage(s,t,r,a){let o=new Date().toISOString();this.db.prepare(`UPDATE threads
45
45
  SET first_message = COALESCE(first_message, ?),
46
46
  last_message = ?,
47
47
  message_count = message_count + 1,
48
48
  updated_at = ?
49
- WHERE id = ?`).run(t,t,n,s);}async saveAssistantMessage(s,t,r,a){let n=new Date().toISOString();this.db.prepare(`UPDATE threads
49
+ WHERE id = ?`).run(t,t,o,s);}async saveAssistantMessage(s,t,r,a){let o=new Date().toISOString();this.db.prepare(`UPDATE threads
50
50
  SET last_message = ?,
51
51
  updated_at = ?
52
- WHERE id = ?`).run(t,n,s);}close(){this.db.close();}rowsToMessages(s){let t=[];for(let r of s){r.prompt&&t.push({id:`${r.id}-user`,text:r.prompt,isAssistant:false,timestamp:new Date(r.started_at).getTime()});let a=j(r.result);a&&t.push({id:`${r.id}-assistant`,text:a,isAssistant:true,timestamp:new Date(r.started_at).getTime()});}return t}};var T=class extends d{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(s){super(),this._provider=new u(s?.dbPath);}get conversationProvider(){return this._provider}attach(s){this.unsubStart=s.on("task:start",async t=>{if(!t.threadId)return;let r=t.platform??"cli";try{await this._provider.ensureThread(t.threadId,r,t.workspaceId),await this._provider.saveUserMessage(t.threadId,t.message??"");}catch{}}),this.unsubEnd=s.on("task:end",async t=>{if(!t.result)return;let r=t.metadata?.threadId;if(!r)return;let a=t.agentRef?.replace(/^@/,"")??"";try{await this._provider.saveAssistantMessage(r,t.result,a);}catch{}});}detach(s){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};exports.ConversationPlugin=T;exports.FileLoggerPlugin=f;exports.SqliteTracingPlugin=E;
52
+ WHERE id = ?`).run(t,o,s);}close(){this.db.close();}rowsToMessages(s){let t=[];for(let r of s){r.prompt&&t.push({id:`${r.id}-user`,text:r.prompt,isAssistant:false,timestamp:new Date(r.started_at).getTime()});let a=q(r.result);a&&t.push({id:`${r.id}-assistant`,text:a,isAssistant:true,timestamp:new Date(r.started_at).getTime()});}return t}};var T=class extends l{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(s){super(),this._provider=new m(s?.dbPath);}get conversationProvider(){return this._provider}attach(s){this.unsubStart=s.on("task:start",async t=>{if(!t.threadId)return;let r=t.platform??"cli";try{await this._provider.ensureThread(t.threadId,r,t.workspaceId),await this._provider.saveUserMessage(t.threadId,t.message??"");}catch{}}),this.unsubEnd=s.on("task:end",async t=>{if(!t.result)return;let r=t.metadata?.threadId;if(!r)return;let a=t.agentRef?.replace(/^@/,"")??"";try{await this._provider.saveAssistantMessage(r,t.result,a);}catch{}});}detach(s){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};exports.ConversationPlugin=T;exports.FileLoggerPlugin=f;exports.SqliteTracingPlugin=_;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewx/sdk",
3
- "version": "0.8.1-rc.4",
3
+ "version": "0.8.2-rc.1",
4
4
  "license": "UNLICENSED",
5
5
  "engines": {
6
6
  "node": ">=20.19.0"
@@ -1,59 +1,59 @@
1
- {
2
- "$id": "https://crewx.dev/schemas/hooks",
3
- "type": "array",
4
- "items": {
5
- "type": "object",
6
- "required": ["name"],
7
- "properties": {
8
- "name": { "type": "string" },
9
- "provider": {
10
- "oneOf": [
11
- { "enum": ["claude", "codex", "gemini", "copilot", "opencode"] },
12
- { "type": "array", "items": { "enum": ["claude", "codex", "gemini", "copilot", "opencode"] } }
13
- ]
14
- },
15
- "team": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
16
- "role": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
17
- "tag": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
18
- "agents": { "type": "array", "items": { "type": "string" } },
19
- "event": { "enum": ["PreToolUse"] },
20
- "config": { "type": "object" },
21
- "deny": {
22
- "type": "object",
23
- "required": ["reason"],
24
- "properties": {
25
- "when": { "type": "array", "items": { "type": "string" } },
26
- "pattern": { "type": "string" },
27
- "regex": { "type": "string" },
28
- "pathPattern": { "type": "string" },
29
- "pathSizeMin": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
30
- "pathSizeMax": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
31
- "reason": { "type": "string" }
32
- },
33
- "additionalProperties": false
34
- },
35
- "guide": {
36
- "type": "object",
37
- "required": ["say"],
38
- "properties": {
39
- "when": { "type": "array", "items": { "type": "string" } },
40
- "pattern": { "type": "string" },
41
- "regex": { "type": "string" },
42
- "pathPattern": { "type": "string" },
43
- "pathSizeMin": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
44
- "pathSizeMax": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
45
- "whenInputRegex": { "type": "string" },
46
- "say": { "type": "string" },
47
- "once": { "type": "boolean" }
48
- },
49
- "additionalProperties": false
50
- },
51
- "plugin": { "type": "string" }
52
- },
53
- "oneOf": [
54
- { "required": ["deny"] },
55
- { "required": ["guide"] },
56
- { "required": ["plugin"] }
57
- ]
58
- }
59
- }
1
+ {
2
+ "$id": "https://crewx.dev/schemas/hooks",
3
+ "type": "array",
4
+ "items": {
5
+ "type": "object",
6
+ "required": ["name"],
7
+ "properties": {
8
+ "name": { "type": "string" },
9
+ "provider": {
10
+ "oneOf": [
11
+ { "enum": ["claude", "codex", "gemini", "copilot", "opencode"] },
12
+ { "type": "array", "items": { "enum": ["claude", "codex", "gemini", "copilot", "opencode"] } }
13
+ ]
14
+ },
15
+ "team": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
16
+ "role": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
17
+ "tag": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }] },
18
+ "agents": { "type": "array", "items": { "type": "string" } },
19
+ "event": { "enum": ["PreToolUse"] },
20
+ "config": { "type": "object" },
21
+ "deny": {
22
+ "type": "object",
23
+ "required": ["reason"],
24
+ "properties": {
25
+ "when": { "type": "array", "items": { "type": "string" } },
26
+ "pattern": { "type": "string" },
27
+ "regex": { "type": "string" },
28
+ "pathPattern": { "type": "string" },
29
+ "pathSizeMin": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
30
+ "pathSizeMax": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
31
+ "reason": { "type": "string" }
32
+ },
33
+ "additionalProperties": false
34
+ },
35
+ "guide": {
36
+ "type": "object",
37
+ "required": ["say"],
38
+ "properties": {
39
+ "when": { "type": "array", "items": { "type": "string" } },
40
+ "pattern": { "type": "string" },
41
+ "regex": { "type": "string" },
42
+ "pathPattern": { "type": "string" },
43
+ "pathSizeMin": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
44
+ "pathSizeMax": { "oneOf": [{ "type": "number" }, { "type": "string" }] },
45
+ "whenInputRegex": { "type": "string" },
46
+ "say": { "type": "string" },
47
+ "once": { "type": "boolean" }
48
+ },
49
+ "additionalProperties": false
50
+ },
51
+ "plugin": { "type": "string" }
52
+ },
53
+ "oneOf": [
54
+ { "required": ["deny"] },
55
+ { "required": ["guide"] },
56
+ { "required": ["plugin"] }
57
+ ]
58
+ }
59
+ }