@crewx/sdk 0.9.0-rc.8 → 0.9.0-rc.80
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/README.md +1 -1
- package/dist/activity-log/builder.d.ts +55 -6
- package/dist/config/canonicalize-agent-options.d.ts +17 -0
- package/dist/config/global-settings.d.ts +33 -0
- package/dist/config/migrate-grok-mode.d.ts +6 -0
- package/dist/config/model-compat.d.ts +31 -0
- package/dist/config/models.generated.d.ts +33 -0
- package/dist/config/models.remote.d.ts +1 -0
- package/dist/config/overdrive.d.ts +7 -0
- package/dist/config/pricing.d.ts +8 -5
- package/dist/config/pricing.generated.d.ts +4 -0
- package/dist/config/pricing.types.d.ts +4 -10
- package/dist/config/timeout.config.d.ts +3 -0
- package/dist/config/wi-boards.d.ts +19 -0
- package/dist/context-budget/continuity.d.ts +61 -0
- package/dist/context-budget/index.d.ts +140 -0
- package/dist/conversation/index.d.ts +1 -1
- package/dist/conversation/sqlite-provider.d.ts +5 -1
- package/dist/conversation/to-template-messages.d.ts +7 -0
- package/dist/conversation/types.d.ts +43 -0
- package/dist/desktop/command-runner.d.ts +4 -0
- package/dist/desktop/default-adapters.d.ts +4 -0
- package/dist/desktop/global-install.d.ts +19 -0
- package/dist/desktop/index.d.ts +2 -0
- package/dist/desktop/index.js +3 -0
- package/dist/desktop/install.d.ts +5 -0
- package/dist/desktop/lnk.d.ts +22 -0
- package/dist/desktop/manifest.d.ts +21 -0
- package/dist/desktop/types.d.ts +67 -0
- package/dist/desktop/version.d.ts +1 -0
- package/dist/desktop/windows-paths.d.ts +21 -0
- package/dist/desktop/wrapper.d.ts +18 -0
- package/dist/esm/desktop/index.js +3 -0
- package/dist/esm/index.js +345 -96
- package/dist/esm/plugins/index.js +187 -93
- package/dist/esm/publish/index.js +1 -0
- package/dist/esm/repository/index.js +203 -94
- package/dist/esm/testing/index.js +1 -1
- package/dist/events/types.d.ts +4 -0
- package/dist/facade/Crewx.d.ts +38 -2
- package/dist/highlight/thread-highlight-prompt.d.ts +2 -0
- package/dist/highlight/thread-highlighter.d.ts +326 -0
- package/dist/index.browser.d.ts +9 -1
- package/dist/index.browser.js +6 -2
- package/dist/index.d.ts +57 -8
- package/dist/index.js +345 -96
- package/dist/internal/windows-spawn.d.ts +10 -0
- package/dist/layout/types.d.ts +17 -1
- package/dist/local-server/base-url.d.ts +18 -0
- package/dist/local-server/index.d.ts +8 -0
- package/dist/local-server/opencode.d.ts +8 -0
- package/dist/local-server/probe.d.ts +3 -0
- package/dist/local-server/runtime.d.ts +26 -0
- package/dist/local-server/types.d.ts +43 -0
- package/dist/migrations/0008_careful_black_bird.sql +17 -0
- package/dist/migrations/0009_hot_dark_phoenix.sql +1 -0
- package/dist/migrations/0010_analyze_stats.sql +6 -0
- package/dist/migrations/0011_far_black_tarantula.sql +1 -0
- package/dist/migrations/0012_blue_turbo.sql +23 -0
- package/dist/migrations/0013_hesitant_adam_destine.sql +15 -0
- package/dist/migrations/0014_organic_mongu.sql +73 -0
- package/dist/migrations/0015_panoramic_gorilla_man.sql +71 -0
- package/dist/migrations/0016_fuzzy_hemingway.sql +14 -0
- package/dist/migrations/0017_project_stage_sdk_migration.sql +29 -0
- package/dist/migrations/0018_bored_jackal.sql +33 -0
- package/dist/migrations/0019_backfill_task_thread_ids.sql +74 -0
- package/dist/migrations/0020_useful_iron_lad.sql +55 -0
- package/dist/migrations/0021_dashing_peter_quill.sql +51 -0
- package/dist/migrations/meta/0008_snapshot.json +1327 -0
- package/dist/migrations/meta/0009_snapshot.json +1335 -0
- package/dist/migrations/meta/0010_snapshot.json +1335 -0
- package/dist/migrations/meta/0011_snapshot.json +1342 -0
- package/dist/migrations/meta/0012_snapshot.json +1494 -0
- package/dist/migrations/meta/0013_snapshot.json +1592 -0
- package/dist/migrations/meta/0014_snapshot.json +1975 -0
- package/dist/migrations/meta/0015_snapshot.json +2315 -0
- package/dist/migrations/meta/0016_snapshot.json +2419 -0
- package/dist/migrations/meta/0017_snapshot.json +2419 -0
- package/dist/migrations/meta/0018_snapshot.json +2570 -0
- package/dist/migrations/meta/0020_snapshot.json +2895 -0
- package/dist/migrations/meta/0021_snapshot.json +3031 -0
- package/dist/migrations/meta/_journal.json +98 -0
- package/dist/paths.d.ts +1 -0
- package/dist/plugin/types.d.ts +1 -0
- package/dist/plugins/index.js +187 -93
- package/dist/plugins/sqlite-tracing.d.ts +22 -0
- package/dist/provider/acp/connection.d.ts +4 -0
- package/dist/provider/acp/meta.d.ts +11 -0
- package/dist/provider/bridge.d.ts +6 -0
- package/dist/provider/classify-task-error.d.ts +2 -0
- package/dist/provider/cli/adapter.types.d.ts +6 -0
- package/dist/provider/cli/adapters/cli-knob.util.d.ts +7 -0
- package/dist/provider/cli/adapters/grok.d.ts +2 -0
- package/dist/provider/cli/adapters/index.d.ts +1 -0
- package/dist/provider/cli/index.d.ts +1 -1
- package/dist/provider/cli/meta.d.ts +5 -0
- package/dist/provider/errors.d.ts +1 -0
- package/dist/provider/idle-watchdog.d.ts +19 -0
- package/dist/provider/models.d.ts +17 -12
- package/dist/provider/order.d.ts +1 -1
- package/dist/provider/parse-usage.d.ts +6 -0
- package/dist/provider/provider-selection.d.ts +8 -0
- package/dist/provider/redact-technical-message.d.ts +1 -0
- package/dist/provider/task-error.types.d.ts +16 -0
- package/dist/publish/auth-boundary.d.ts +22 -0
- package/dist/publish/auth-json.d.ts +11 -0
- package/dist/publish/constants.d.ts +6 -0
- package/dist/publish/index.d.ts +30 -0
- package/dist/publish/index.js +1 -0
- package/dist/publish/manifest.d.ts +17 -0
- package/dist/publish/marketplace-api.constants.d.ts +1 -0
- package/dist/publish/pack.d.ts +2 -0
- package/dist/publish/scan.d.ts +9 -0
- package/dist/publish/secrets.d.ts +6 -0
- package/dist/publish/upload.d.ts +18 -0
- package/dist/repository/agent-suggestion.repository.d.ts +34 -0
- package/dist/repository/common-code.repository.d.ts +39 -0
- package/dist/repository/db.d.ts +8 -0
- package/dist/repository/index.d.ts +28 -4
- package/dist/repository/index.js +203 -94
- package/dist/repository/notification.repository.d.ts +58 -0
- package/dist/repository/project.repository.d.ts +90 -0
- package/dist/repository/request-log.repository.d.ts +1 -0
- package/dist/repository/task-log-migration.d.ts +74 -0
- package/dist/repository/task-log.repository.d.ts +44 -0
- package/dist/repository/task.repository.d.ts +119 -0
- package/dist/repository/thread-history.repository.d.ts +193 -0
- package/dist/repository/thread-title-common-code-migration.d.ts +13 -0
- package/dist/repository/thread-title.types.d.ts +29 -0
- package/dist/repository/thread.repository.d.ts +21 -2
- package/dist/repository/usage-report.repository.d.ts +27 -0
- package/dist/schema/agent-suggestions.d.ts +199 -0
- package/dist/schema/common-codes.d.ts +216 -0
- package/dist/schema/index.d.ts +9 -0
- package/dist/schema/notifications.d.ts +303 -0
- package/dist/schema/projects.d.ts +610 -0
- package/dist/schema/task-log-events.d.ts +119 -0
- package/dist/schema/tasks.d.ts +53 -0
- package/dist/schema/thread-history.d.ts +734 -0
- package/dist/schema/threads.d.ts +2 -0
- package/dist/schema/ui-action-receipts.d.ts +303 -0
- package/dist/schema/ui-instances.d.ts +267 -0
- package/dist/schema/usage-reports.d.ts +252 -0
- package/dist/testing/index.js +1 -1
- package/dist/types/index.d.ts +1536 -3
- package/dist/ui-card/index.d.ts +2 -0
- package/dist/ui-card/legacy-card-parser.d.ts +11 -0
- package/dist/ui-instance/definition.d.ts +6 -0
- package/dist/ui-instance/errors.d.ts +17 -0
- package/dist/ui-instance/index.d.ts +6 -0
- package/dist/ui-instance/json.d.ts +5 -0
- package/dist/ui-instance/runtime.d.ts +13 -0
- package/dist/ui-instance/store.d.ts +65 -0
- package/dist/ui-instance/types.d.ts +200 -0
- package/dist/ui-plugin/index.d.ts +3 -0
- package/dist/ui-plugin/manifest.d.ts +3 -0
- package/dist/ui-plugin/types.d.ts +76 -0
- package/dist/ui-plugin/validator.d.ts +9 -0
- package/dist/utils/crewx-home.d.ts +1 -0
- package/dist/utils/id.d.ts +1 -1
- package/dist/utils/timestamp.d.ts +1 -0
- package/dist/wi/create.d.ts +48 -0
- package/dist/wi/select.d.ts +20 -0
- package/package.json +18 -2
- package/templates/agents/default.yaml +240 -116
- package/templates/documents/crewx-manual.md +138 -138
- package/templates/workflows/wi-default-flow.yaml +65 -0
- package/templates/workflows/wi-plan-flow.yaml +140 -0
package/dist/plugins/index.js
CHANGED
|
@@ -1,19 +1,59 @@
|
|
|
1
|
-
'use strict';var fs=require('fs'),
|
|
1
|
+
'use strict';var fs$1=require('fs'),ge=require('path'),dr=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 ge__namespace=/*#__PURE__*/_interopNamespace(ge);var dr__default=/*#__PURE__*/_interopDefault(dr);var je=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var ve=class{detach(e){}};function nn(r){let e=t=>String(t).padStart(2,"0");return `${r.getFullYear()}${e(r.getMonth()+1)}${e(r.getDate())}T${e(r.getHours())}${e(r.getMinutes())}${e(r.getSeconds())}`}function St(r){let e=r.toISOString();return `${e.slice(0,10)} ${e.slice(11,19)} UTC`}var vt=class extends ve{name="file-logger";unsubs=[];logFiles=new Map;logsDir;version;constructor(e){super(),this.logsDir=ge.join(e?.workspaceRoot??process.cwd(),".crewx","logs"),this.version=e?.version??"unknown";}attach(e){this.unsubs.push(e.on("task:start",t=>{try{fs$1.existsSync(this.logsDir)||fs$1.mkdirSync(this.logsDir,{recursive:!0});let n=nn(t.timestamp),s=ge.join(this.logsDir,`${n}_${t.traceId}.log`);this.logFiles.set(t.traceId,s);let i=`=== TASK LOG: ${t.traceId} ===
|
|
2
2
|
CrewX Version: ${this.version}
|
|
3
|
-
Mode: ${
|
|
4
|
-
Agent: ${
|
|
5
|
-
Started: ${
|
|
6
|
-
Message: ${
|
|
3
|
+
Mode: ${t.mode}
|
|
4
|
+
Agent: ${t.agentRef}
|
|
5
|
+
Started: ${St(t.timestamp)}
|
|
6
|
+
Message: ${t.message}
|
|
7
7
|
|
|
8
|
-
`;fs.writeFileSync(
|
|
9
|
-
`,"utf8");}catch{}}),
|
|
10
|
-
[${
|
|
11
|
-
`;fs.appendFileSync(
|
|
12
|
-
${
|
|
13
|
-
`)}`);let r=d.get(e`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),i=0;r?.cnt&&(i=d.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),jt(d,i),r?.cnt&&(Xt(d,n,e),Gt(d,n,e)),t(d,{migrationsFolder:n});let l=(d.get(e`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0)-i;if(l>0){let c=r?.cnt?"Database migrated":"Database initialized";console.error(`[crewx] ${c} (${l} migration${l>1?"s":""} applied).`);}}function et(d,t){yt.has(t)||(Yt(d),yt.add(t));}var _=class extends Error{code;cause;constructor(t,e,s){super(e),this.name="RepositoryError",this.code=t,this.cause=s,Object.setPrototypeOf(this,new.target.prototype);}};var X=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"),thread_id:sqliteCore.text("thread_id"),workspace_ref:sqliteCore.text("workspace_ref"),project_id:sqliteCore.text("project_id"),project_ref:sqliteCore.text("project_ref"),cached_input_tokens:sqliteCore.integer("cached_input_tokens").default(0),run_epoch:sqliteCore.integer("run_epoch").default(0)},d=>({idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(d.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(d.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(d.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(d.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(d.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(d.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(d.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(d.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(d.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(d.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(d.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(d.workspace_id,d.started_at)}));var u=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>X.id,{onDelete:"set null"}),platform:sqliteCore.text("platform").notNull().default("cli"),title:sqliteCore.text("title"),first_message:sqliteCore.text("first_message"),last_message:sqliteCore.text("last_message"),message_count:sqliteCore.integer("message_count").notNull().default(0),created_at:sqliteCore.text("created_at").notNull(),updated_at:sqliteCore.text("updated_at").notNull(),metadata:sqliteCore.text("metadata"),title_locked:sqliteCore.integer("title_locked").notNull().default(0),pinned:sqliteCore.integer("pinned").notNull().default(0),starred:sqliteCore.integer("starred").notNull().default(0)},d=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(d.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(d.workspace_id)}));var ne=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(()=>ne.id,{onDelete:"set null"}),name:sqliteCore.text("name").notNull(),kind:sqliteCore.text("kind").notNull().default("internal"),status:sqliteCore.text("status").notNull().default("ok"),started_at:sqliteCore.text("started_at").notNull(),completed_at:sqliteCore.text("completed_at"),duration_ms:sqliteCore.integer("duration_ms"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),error:sqliteCore.text("error"),attributes:sqliteCore.text("attributes")},d=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(d.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(d.parent_span_id)}));sqliteCore.sqliteTable("tool_calls",{id:sqliteCore.text("id").primaryKey(),task_id:sqliteCore.text("task_id").references(()=>o.id,{onDelete:"cascade"}),session_id:sqliteCore.text("session_id"),tool_name:sqliteCore.text("tool_name").notNull(),files:sqliteCore.text("files"),input:sqliteCore.text("input"),output:sqliteCore.text("output"),duration_ms:sqliteCore.integer("duration_ms"),timestamp:sqliteCore.text("timestamp").notNull()},d=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(d.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(d.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(d.timestamp)}));sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>u.id,{onDelete:"cascade"}),seq:sqliteCore.integer("seq").notNull(),first_task_id:sqliteCore.text("first_task_id").notNull(),mid_task_id:sqliteCore.text("mid_task_id").notNull(),last_task_id:sqliteCore.text("last_task_id").notNull(),task_count:sqliteCore.integer("task_count").notNull(),summary:sqliteCore.text("summary"),source_tokens:sqliteCore.integer("source_tokens").notNull(),summary_tokens:sqliteCore.integer("summary_tokens"),created_at:sqliteCore.text("created_at").notNull()},d=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(d.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(d.thread_id,d.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(d.thread_id,d.seq)}));sqliteCore.sqliteTable("request_logs",{id:sqliteCore.text("id").primaryKey(),path:sqliteCore.text("path").notNull(),method:sqliteCore.text("method").notNull(),status_code:sqliteCore.integer("status_code").notNull(),duration_ms:sqliteCore.integer("duration_ms").notNull(),ip:sqliteCore.text("ip"),request_headers:sqliteCore.text("request_headers"),response_headers:sqliteCore.text("response_headers"),request_body:sqliteCore.text("request_body"),response_body:sqliteCore.text("response_body"),query:sqliteCore.text("query"),user_id:sqliteCore.text("user_id"),project_id:sqliteCore.text("project_id"),partition_key:sqliteCore.text("partition_key").notNull(),timestamp:sqliteCore.text("timestamp").notNull().default(drizzleOrm.sql`(datetime('now'))`),metadata:sqliteCore.text("metadata")},d=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(d.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(d.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(d.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(d.partition_key)}));sqliteCore.sqliteTable("usage_limit_snapshots",{id:sqliteCore.text("id").primaryKey(),provider:sqliteCore.text("provider").notNull(),account_ref:sqliteCore.text("account_ref").notNull().default("default"),limit_window:sqliteCore.text("limit_window").notNull(),bucket_start:sqliteCore.text("bucket_start").notNull(),captured_at:sqliteCore.text("captured_at").notNull(),used_percent:sqliteCore.integer("used_percent").notNull(),remaining_percent:sqliteCore.integer("remaining_percent").notNull(),resets_at:sqliteCore.text("resets_at"),source:sqliteCore.text("source").notNull(),metadata:sqliteCore.text("metadata")},d=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(d.provider,d.account_ref,d.limit_window,d.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(d.limit_window,d.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(d.provider,d.limit_window,d.bucket_start)}));var z="2026-05-09",ge="0.8.9-rc.13",W=10,j=parseInt(ge.split("rc.")[1]),at=class extends G{dbPath;constructor(t={}){super(),t.dbPath?this.dbPath=t.dbPath:t.dbRoot&&(this.dbPath=L.join(t.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(t){let e=this.resolveDbPath();if(t){let n=L.dirname(e);fs.existsSync(n)||fs.mkdirSync(n,{recursive:true});}else if(!fs.existsSync(e))throw new _("NOT_FOUND","Database not found");let s=b(e);if(t)try{et(s.db,e);}catch(n){throw s.close(),n}return s}startTask(t){let e=this.openHandle(true);try{e.db.insert(o).values({id:t.id,agent_id:t.agentId,prompt:t.prompt,mode:t.mode,status:t.status,started_at:t.startedAt,pid:t.pid??null,parent_task_id:t.parentTaskId??null,caller_agent_id:t.callerAgentId??null,trace_id:t.traceId??null,command:t.command??null,metadata:t.metadata??null,workspace_id:t.workspaceId??null,platform:t.platform??"cli",crewx_version:t.crewxVersion??null,thread_id:t.threadId??null,model:t.model??null,rendered_prompt:t.renderedPrompt??null,coding_agent_command:t.codingAgentCommand??null}).onConflictDoUpdate({target:o.id,set:{pid:drizzleOrm.sql`COALESCE(excluded.pid, ${o.pid})`},setWhere:drizzleOrm.eq(o.status,"running")}).run();}catch(s){throw s instanceof _?s:new _("DB_ERROR","Failed to start task",s)}finally{e.close();}}finishTask(t){let e=this.openHandle(true);try{let s=t.runEpoch??null;e.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
|
|
8
|
+
`;fs$1.writeFileSync(s,i,{encoding:"utf8",mode:384});}catch{}}),e.on("task:output",t=>{try{let n=this.logFiles.get(t.traceId);if(!n)return;let s=new Date().toISOString();fs$1.appendFileSync(n,`[${s}] STDOUT: ${t.output}
|
|
9
|
+
`,"utf8");}catch{}}),e.on("task:end",t=>{try{let n=this.logFiles.get(t.traceId);if(!n)return;let s=St(new Date),i=t.error?`failed: ${t.error.message}`:"completed successfully",a=`[${s}] INFO: Task ${i} in ${t.durationMs}ms
|
|
10
|
+
[${s}] INFO: Process closed with exit code: ${t.error?1:0}
|
|
11
|
+
`;fs$1.appendFileSync(n,a,"utf8"),this.logFiles.delete(t.traceId);}catch{}}));}detach(e){this.unsubs.forEach(t=>t()),this.unsubs=[],this.logFiles.clear();}};function or(r){let e=ge__namespace.resolve(r);return process.platform==="win32"&&(e=e.replace(/\\/g,"/"),e=e.replace(/^([A-Z]):/,(t,n)=>`${n.toLowerCase()}:`)),e.length>1&&!/^[a-zA-Z]:\/$/.test(e)&&(e=e.replace(/\/+$/,"")),e}function an(r){let e=or(r);return crypto.createHash("sha256").update(e).digest("hex")}var u=class extends Error{code;cause;constructor(e,t,n){super(t),this.name="RepositoryError",this.code=e,this.cause=n,Object.setPrototypeOf(this,new.target.prototype);}};var Q=class{resolveDbPath(){return process.env.CREWX_DB?process.env.CREWX_DB:process.env.CREWX_TRACES_DB?process.env.CREWX_TRACES_DB:ge.join(dr__default.default.homedir(),".crewx","crewx.db")}resolveDbPaths(){return [this.resolveDbPath()]}isMissingTableError(e){return e instanceof Error&&/no such table:/i.test(e.message)}dbExists(e){return fs$1.existsSync(e??this.resolveDbPath())}};var lr=32*1024*1024;function L(r){let e=je("better-sqlite3"),{drizzle:t}=je("drizzle-orm/better-sqlite3"),n=new e(r);return n.exec("PRAGMA journal_mode = WAL"),n.exec(`PRAGMA journal_size_limit = ${lr}`),n.exec("PRAGMA busy_timeout = 5000"),n.exec("PRAGMA foreign_keys = ON"),n.exec("PRAGMA analysis_limit = 400"),{db:t(n),runRaw:(s,i=[])=>n.prepare(s).run(...i),close:()=>n.close()}}var dn=new Set,ur={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 Nt(r,e){return (r.get(`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='${e}'`)?.cnt??0)>0}function hr(r,e){if(e>0||!Nt(r,"tasks"))return;let t=r.all("PRAGMA table_info(tasks)"),n=new Set(t.map(s=>s.name));for(let[s,i]of Object.entries(ur))n.has(s)||r.run(`ALTER TABLE tasks ADD COLUMN ${s} ${i}`);}var _r={"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 pr(r,e,t){if(!Nt(r,"__drizzle_migrations")||!Nt(r,"tasks"))return;let n=r.all(t`SELECT hash FROM __drizzle_migrations`),s=new Set(n.map(a=>a.hash)),i=JSON.parse(fs$1.readFileSync(ge__namespace.default.join(e,"meta/_journal.json"),"utf-8"));for(let a of i.entries){let d=_r[a.tag];if(!d)continue;let c=ge__namespace.default.join(e,`${a.tag}.sql`);if(!fs$1.existsSync(c))continue;let l=fs$1.readFileSync(c,"utf-8"),h=crypto.createHash("sha256").update(l).digest("hex");if(s.has(h))continue;let p=r.all("PRAGMA table_info(tasks)"),g=new Set(p.map(f=>f.name));for(let[f,D]of Object.entries(d))g.has(f)||(r.run(`ALTER TABLE tasks ADD COLUMN ${f} ${D}`),g.add(f));}}function gr(r,e,t){let n=r.all(t`SELECT hash FROM __drizzle_migrations`),s=new Set(n.map(a=>a.hash)),i=JSON.parse(fs$1.readFileSync(ge__namespace.default.join(e,"meta/_journal.json"),"utf-8"));for(let a of i.entries){let d=ge__namespace.default.join(e,`${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 h=/ALTER\s+TABLE\s+[`"]?(\w+)[`"]?\s+ADD\s+[`"]?(\w+)[`"]?/gi,p=[],g;for(;(g=h.exec(c))!==null;)p.push({table:g[1],column:g[2]});if(p.length===0||!c.split(/-->\s*statement-breakpoint/).map(v=>v.trim()).filter(Boolean).every(v=>/^ALTER\s+TABLE\s+.+\s+ADD\s+/i.test(v)))continue;p.every(({table:v,column:S})=>r.all(`PRAGMA table_info("${v}")`).some(F=>F.name===S))&&r.run(t`INSERT INTO __drizzle_migrations (hash, created_at) VALUES (${l}, ${a.when})`);}}function fr(r){let{migrate:e}=je("drizzle-orm/better-sqlite3/migrator"),{sql:t}=je("drizzle-orm"),n=[ge__namespace.default.join(__dirname,"../migrations"),ge__namespace.default.join(__dirname,"migrations"),ge__namespace.default.join(__dirname,"../../../../drizzle/migrations"),ge__namespace.default.join(process.cwd(),"drizzle/migrations")],s=n.find(l=>fs$1.existsSync(ge__namespace.default.join(l,"meta/_journal.json")));if(!s)throw new Error(`migrations folder not found. Searched:
|
|
12
|
+
${n.join(`
|
|
13
|
+
`)}`);let i=r.get(t`SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='__drizzle_migrations'`),a=0;i?.cnt&&(a=r.get(t`SELECT count(*) as cnt FROM __drizzle_migrations`)?.cnt??0),hr(r,a),i?.cnt&&(gr(r,s,t),pr(r,s,t)),e(r,{migrationsFolder:s});let c=(r.get(t`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 ae(r,e){dn.has(e)||(fr(r),dn.add(e));}var Pe=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)},r=>({log_storage_check:sqliteCore.check("tasks_log_storage_ck",drizzleOrm.sql`${r.log_storage} IN ('blob', 'events')`),idx_tasks_agent_id:sqliteCore.index("idx_tasks_agent_id").on(r.agent_id),idx_tasks_status:sqliteCore.index("idx_tasks_status").on(r.status),idx_tasks_started_at:sqliteCore.index("idx_tasks_started_at").on(r.started_at),idx_tasks_trace_id:sqliteCore.index("idx_tasks_trace_id").on(r.trace_id),idx_tasks_parent_task_id:sqliteCore.index("idx_tasks_parent_task_id").on(r.parent_task_id),idx_tasks_crewx_version:sqliteCore.index("idx_tasks_crewx_version").on(r.crewx_version),idx_tasks_pid:sqliteCore.index("idx_tasks_pid").on(r.pid),idx_tasks_thread_id:sqliteCore.index("idx_tasks_thread_id").on(r.thread_id),idx_tasks_workspace_id:sqliteCore.index("idx_tasks_workspace_id").on(r.workspace_id),idx_tasks_workspace_ref:sqliteCore.index("idx_tasks_workspace_ref").on(r.workspace_ref),idx_tasks_project_id:sqliteCore.index("idx_tasks_project_id").on(r.project_id),idx_tasks_ws_started:sqliteCore.index("idx_tasks_ws_started").on(r.workspace_id,r.started_at)}));var de=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()},r=>({taskSeqUnique:sqliteCore.uniqueIndex("task_log_events_task_seq_uq").on(r.task_id,r.seq)}));var vr="json_extract(metadata, '$.threadTitle.state')",Nr="json_extract(metadata, '$.threadTitle.priority')",_=sqliteCore.sqliteTable("threads",{id:sqliteCore.text("id").primaryKey(),workspace_id:sqliteCore.text("workspace_id").references(()=>Pe.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)},r=>({idx_threads_updated_at:sqliteCore.index("idx_threads_updated_at").on(r.updated_at),idx_threads_workspace_id:sqliteCore.index("idx_threads_workspace_id").on(r.workspace_id),idx_threads_ws_updated:sqliteCore.index("idx_threads_ws_updated").on(r.workspace_id,r.updated_at),idx_threads_title:sqliteCore.index("idx_threads_title").on(r.title),idx_threads_workspace_thread_state:sqliteCore.index("idx_threads_workspace_thread_state").on(r.workspace_id,drizzleOrm.sql.raw(vr)),idx_threads_workspace_thread_priority:sqliteCore.index("idx_threads_workspace_thread_priority").on(r.workspace_id,drizzleOrm.sql.raw(Nr))}));var Or=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(()=>Or.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")},r=>({idx_spans_task_id:sqliteCore.index("idx_spans_task_id").on(r.task_id),idx_spans_parent_span_id:sqliteCore.index("idx_spans_parent_span_id").on(r.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()},r=>({idx_tool_calls_task_id:sqliteCore.index("idx_tool_calls_task_id").on(r.task_id),idx_tool_calls_tool_name:sqliteCore.index("idx_tool_calls_tool_name").on(r.tool_name),idx_tool_calls_timestamp:sqliteCore.index("idx_tool_calls_timestamp").on(r.timestamp)}));sqliteCore.sqliteTable("thread_boxes",{id:sqliteCore.text("id").primaryKey(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>_.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()},r=>({idx_thread_boxes_thread_id:sqliteCore.index("idx_thread_boxes_thread_id").on(r.thread_id),idx_thread_boxes_seq:sqliteCore.index("idx_thread_boxes_seq").on(r.thread_id,r.seq),uniq_thread_boxes_thread_seq:sqliteCore.unique().on(r.thread_id,r.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")},r=>({idx_request_logs_timestamp:sqliteCore.index("idx_request_logs_timestamp").on(r.timestamp),idx_request_logs_path:sqliteCore.index("idx_request_logs_path").on(r.path),idx_request_logs_status_code:sqliteCore.index("idx_request_logs_status_code").on(r.status_code),idx_request_logs_partition_key:sqliteCore.index("idx_request_logs_partition_key").on(r.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")},r=>({uniq_usage_limit_snapshots_bucket:sqliteCore.uniqueIndex("uniq_usage_limit_snapshots_bucket").on(r.provider,r.account_ref,r.limit_window,r.bucket_start),idx_usage_limit_snapshots_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_window_bucket").on(r.limit_window,r.bucket_start),idx_usage_limit_snapshots_provider_window_bucket:sqliteCore.index("idx_usage_limit_snapshots_provider_window_bucket").on(r.provider,r.limit_window,r.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")},r=>({uniq_usage_reports_ws_month:sqliteCore.uniqueIndex("uniq_usage_reports_ws_month").on(r.workspace_id,r.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")},r=>({idx_notifications_ws_created:sqliteCore.index("idx_notifications_ws_created").on(r.workspace_id,drizzleOrm.sql`${r.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()},r=>({pk:sqliteCore.primaryKey({columns:[r.notification_id,r.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()},r=>({idx_agent_suggestions_ws_agent:sqliteCore.index("idx_agent_suggestions_ws_agent").on(r.workspace_id,r.agent_id),idx_agent_suggestions_ws_created:sqliteCore.index("idx_agent_suggestions_ws_created").on(r.workspace_id,r.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()},r=>({idCheck:sqliteCore.check("ui_instances_id_ck",drizzleOrm.sql`length(${r.id}) BETWEEN 5 AND 128 AND ${r.id} GLOB 'uic_*'`),definitionIdCheck:sqliteCore.check("ui_instances_definition_id_ck",drizzleOrm.sql`length(${r.definition_id}) BETWEEN 1 AND 128`),definitionVersionCheck:sqliteCore.check("ui_instances_definition_version_ck",drizzleOrm.sql`${r.definition_version} >= 1`),definitionHashCheck:sqliteCore.check("ui_instances_definition_hash_ck",drizzleOrm.sql`length(${r.definition_hash}) = 64 AND ${r.definition_hash} NOT GLOB '*[^0-9a-f]*'`),workspaceIdCheck:sqliteCore.check("ui_instances_workspace_id_ck",drizzleOrm.sql`length(${r.workspace_id}) BETWEEN 1 AND 256`),threadIdCheck:sqliteCore.check("ui_instances_thread_id_ck",drizzleOrm.sql`length(${r.thread_id}) BETWEEN 1 AND 256`),domainRefJsonCheck:sqliteCore.check("ui_instances_domain_ref_json_ck",drizzleOrm.sql`json_valid(${r.domain_ref_json}) AND json_type(${r.domain_ref_json}) = 'object'`),stateJsonCheck:sqliteCore.check("ui_instances_state_json_ck",drizzleOrm.sql`json_valid(${r.state_json}) AND json_type(${r.state_json}) = 'object'`),revisionCheck:sqliteCore.check("ui_instances_revision_ck",drizzleOrm.sql`${r.revision} >= 0`),statusCheck:sqliteCore.check("ui_instances_status_ck",drizzleOrm.sql`${r.status} IN ('active', 'completed', 'expired', 'revoked', 'unsupported')`),grantedCapabilitiesJsonCheck:sqliteCore.check("ui_instances_granted_capabilities_json_ck",drizzleOrm.sql`json_valid(${r.granted_capabilities_json}) AND json_type(${r.granted_capabilities_json}) = 'array'`),createdAtCheck:sqliteCore.check("ui_instances_created_at_ck",drizzleOrm.sql`${r.created_at} >= 0`),updatedAtCheck:sqliteCore.check("ui_instances_updated_at_ck",drizzleOrm.sql`${r.updated_at} >= ${r.created_at}`),workspaceThreadIdx:sqliteCore.index("ui_instances_workspace_thread_idx").on(r.workspace_id,r.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")},r=>({idCheck:sqliteCore.check("ui_action_receipts_id_ck",drizzleOrm.sql`length(${r.id}) BETWEEN 5 AND 128`),instanceIdCheck:sqliteCore.check("ui_action_receipts_instance_id_ck",drizzleOrm.sql`length(${r.instance_id}) BETWEEN 1 AND 128`),requestIdCheck:sqliteCore.check("ui_action_receipts_request_id_ck",drizzleOrm.sql`length(${r.request_id}) BETWEEN 1 AND 128`),actionIdCheck:sqliteCore.check("ui_action_receipts_action_id_ck",drizzleOrm.sql`length(${r.action_id}) BETWEEN 1 AND 128`),actorJsonCheck:sqliteCore.check("ui_action_receipts_actor_json_ck",drizzleOrm.sql`json_valid(${r.actor_json}) AND json_type(${r.actor_json}) = 'object'`),sourceCheck:sqliteCore.check("ui_action_receipts_source_ck",drizzleOrm.sql`${r.source} IN ('ui_host', 'cli', 'system')`),expectedRevisionCheck:sqliteCore.check("ui_action_receipts_expected_revision_ck",drizzleOrm.sql`${r.expected_revision} >= 0`),beforeRevisionCheck:sqliteCore.check("ui_action_receipts_before_revision_ck",drizzleOrm.sql`${r.before_revision} >= 0`),afterRevisionCheck:sqliteCore.check("ui_action_receipts_after_revision_ck",drizzleOrm.sql`${r.after_revision} IS NULL OR ${r.after_revision} >= 0`),statusCheck:sqliteCore.check("ui_action_receipts_status_ck",drizzleOrm.sql`${r.status} IN ('requested', 'settled')`),outcomeCheck:sqliteCore.check("ui_action_receipts_outcome_ck",drizzleOrm.sql`${r.outcome} IS NULL OR ${r.outcome} IN ('succeeded', 'rejected', 'failed', 'conflicted', 'expired')`),inputJsonCheck:sqliteCore.check("ui_action_receipts_input_json_ck",drizzleOrm.sql`json_valid(${r.input_json}) AND json_type(${r.input_json}) = 'object'`),resultJsonCheck:sqliteCore.check("ui_action_receipts_result_json_ck",drizzleOrm.sql`${r.result_json} IS NULL OR (json_valid(${r.result_json}) AND json_type(${r.result_json}) = 'object')`),requestedAtCheck:sqliteCore.check("ui_action_receipts_requested_at_ck",drizzleOrm.sql`${r.requested_at} >= 0`),settledAtCheck:sqliteCore.check("ui_action_receipts_settled_at_ck",drizzleOrm.sql`${r.settled_at} IS NULL OR ${r.settled_at} >= ${r.requested_at}`),statusTransitionCheck:sqliteCore.check("ui_action_receipts_status_transition_ck",drizzleOrm.sql`(
|
|
14
|
+
(${r.status} = 'requested' AND ${r.after_revision} IS NULL AND ${r.outcome} IS NULL AND ${r.settled_at} IS NULL)
|
|
15
|
+
OR
|
|
16
|
+
(${r.status} = 'settled' AND ${r.after_revision} IS NOT NULL AND ${r.outcome} IS NOT NULL AND ${r.settled_at} IS NOT NULL)
|
|
17
|
+
)`),instanceRequestUnique:sqliteCore.uniqueIndex("ui_action_receipts_instance_request_uq").on(r.instance_id,r.request_id),instanceIdIdx:sqliteCore.index("ui_action_receipts_instance_id_idx").on(r.instance_id),requestedAtIdx:sqliteCore.index("ui_action_receipts_requested_at_idx").on(r.requested_at)}));var yn=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")},r=>({idCheck:sqliteCore.check("projects_id_ck",drizzleOrm.sql`${r.id} GLOB 'prj_*'`),sceneCheck:sqliteCore.check("projects_scene_ck",drizzleOrm.sql`${r.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(${r.stages_json}) AND json_type(${r.stages_json}) = 'array'`),stageIndexCheck:sqliteCore.check("projects_stage_index_ck",drizzleOrm.sql`${r.stage_index} >= 1`)}));sqliteCore.sqliteTable("project_criteria",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>yn.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()},r=>({idCheck:sqliteCore.check("project_criteria_id_ck",drizzleOrm.sql`${r.id} GLOB 'pjc_*'`),verifyStatusCheck:sqliteCore.check("project_criteria_verify_status_ck",drizzleOrm.sql`${r.verify_status} IN ('pending', 'verifying', 'passed', 'failed')`),evidenceJsonCheck:sqliteCore.check("project_criteria_evidence_json_ck",drizzleOrm.sql`json_valid(${r.evidence_json}) AND json_type(${r.evidence_json}) = 'array'`),projectPositionUnique:sqliteCore.uniqueIndex("project_criteria_project_position_uq").on(r.project_id,r.position)}));sqliteCore.sqliteTable("project_events",{id:sqliteCore.text("id").primaryKey().notNull(),project_id:sqliteCore.text("project_id").notNull().references(()=>yn.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()},r=>({idCheck:sqliteCore.check("project_events_id_ck",drizzleOrm.sql`${r.id} GLOB 'pje_*'`),actorTypeCheck:sqliteCore.check("project_events_actor_type_ck",drizzleOrm.sql`${r.actor_type} IN ('user', 'project_manager', 'system')`),payloadJsonCheck:sqliteCore.check("project_events_payload_json_ck",drizzleOrm.sql`json_valid(${r.payload_json}) AND json_type(${r.payload_json}) = 'object'`),projectSeqUnique:sqliteCore.uniqueIndex("project_events_project_seq_uq").on(r.project_id,r.seq)}));var $t=["THREAD_STATE","THREAD_PRIORITY"],Ht=["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()},r=>({pk:sqliteCore.primaryKey({columns:[r.code_group,r.code]}),metadataCheck:sqliteCore.check("common_codes_metadata_ck",drizzleOrm.sql`${r.metadata} IS NULL OR (json_valid(${r.metadata}) AND json_type(${r.metadata}) = 'object')`),builtinCheck:sqliteCore.check("common_codes_builtin_ck",drizzleOrm.sql`${r.is_builtin} IN (0, 1)`),archivedCheck:sqliteCore.check("common_codes_archived_ck",drizzleOrm.sql`${r.is_archived} IN (0, 1)`),idxCommonCodesSelection:sqliteCore.index("idx_common_codes_group_archived_order").on(r.code_group,r.is_archived,r.sort_order)}));var En=["thread.snapshot.imported","thread.title.changed","thread.priority.changed","thread.state.changed","thread.highlight.created","thread.highlight.updated","thread.highlight.deleted","thread.highlights.regenerated"],Rn=["user","agent","system"],In=["auto","manual"],Sn=["decision","judgment","issue","result","pivot"];var vn=["queued","running","completed","failed"],C=sqliteCore.sqliteTable("thread_events",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>_.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")},r=>({typeCheck:sqliteCore.check("thread_events_type_ck",drizzleOrm.sql`${r.type} IN ('thread.snapshot.imported', 'thread.title.changed', 'thread.priority.changed', 'thread.state.changed', 'thread.highlight.created', 'thread.highlight.updated', 'thread.highlight.deleted', 'thread.highlights.regenerated')`),actorTypeCheck:sqliteCore.check("thread_events_actor_type_ck",drizzleOrm.sql`${r.actor_type} IN ('user', 'agent', 'system')`),payloadJsonCheck:sqliteCore.check("thread_events_payload_json_ck",drizzleOrm.sql`json_valid(${r.payload_json}) AND json_type(${r.payload_json}) = 'object'`),threadSeqIndex:sqliteCore.index("idx_thread_events_thread_seq").on(r.thread_id,r.seq),threadCreatedIndex:sqliteCore.index("idx_thread_events_thread_created").on(r.thread_id,r.created_at),threadSeqUnique:sqliteCore.uniqueIndex("thread_events_thread_seq_uq").on(r.thread_id,r.seq)})),I=sqliteCore.sqliteTable("thread_highlight_runs",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>_.id,{onDelete:"cascade"}),request_id:sqliteCore.text("request_id").notNull(),status:sqliteCore.text("status").notNull(),detector_version:sqliteCore.text("detector_version").notNull(),requested_at:sqliteCore.text("requested_at").notNull(),started_at:sqliteCore.text("started_at"),completed_at:sqliteCore.text("completed_at"),error_code:sqliteCore.text("error_code"),previous_auto_count:sqliteCore.integer("previous_auto_count"),new_auto_count:sqliteCore.integer("new_auto_count")},r=>({statusCheck:sqliteCore.check("thread_highlight_runs_status_ck",drizzleOrm.sql`${r.status} IN ('queued', 'running', 'completed', 'failed')`),countCheck:sqliteCore.check("thread_highlight_runs_counts_ck",drizzleOrm.sql`(${r.previous_auto_count} IS NULL OR ${r.previous_auto_count} >= 0) AND (${r.new_auto_count} IS NULL OR ${r.new_auto_count} >= 0)`),threadRequestUnique:sqliteCore.uniqueIndex("thread_highlight_runs_thread_request_uq").on(r.thread_id,r.request_id),inProgressThreadUnique:sqliteCore.uniqueIndex("thread_highlight_runs_in_progress_thread_uq").on(r.thread_id).where(drizzleOrm.sql`${r.status} IN ('queued', 'running')`),threadStatusRequestedIndex:sqliteCore.index("idx_thread_highlight_runs_thread_status_requested").on(r.thread_id,r.status,r.requested_at)})),w=sqliteCore.sqliteTable("thread_highlights",{id:sqliteCore.text("id").primaryKey().notNull(),thread_id:sqliteCore.text("thread_id").notNull().references(()=>_.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")},r=>({sourceCheck:sqliteCore.check("thread_highlights_source_ck",drizzleOrm.sql`${r.source} IN ('auto', 'manual')`),kindCheck:sqliteCore.check("thread_highlights_kind_ck",drizzleOrm.sql`${r.kind} IN ('decision', 'judgment', 'issue', 'result', 'pivot')`),statusCheck:sqliteCore.check("thread_highlights_status_ck",drizzleOrm.sql`${r.status} IN ('active', 'dismissed')`),activeTextCheck:sqliteCore.check("thread_highlights_active_text_ck",drizzleOrm.sql`${r.status} = 'dismissed' OR (${r.text} IS NOT NULL AND length(${r.text}) > 0)`),coversCheck:sqliteCore.check("thread_highlights_covers_ck",drizzleOrm.sql`length(${r.covers_from_task_id}) > 0 AND length(${r.covers_to_task_id}) > 0`),autoKeyCheck:sqliteCore.check("thread_highlights_auto_key_ck",drizzleOrm.sql`${r.source} = 'manual' OR (${r.source} = 'auto' AND ${r.source_task_id} IS NOT NULL AND ${r.detector_version} IS NOT NULL AND ${r.content_fingerprint} IS NOT NULL AND length(${r.source_task_id}) > 0 AND length(${r.detector_version}) > 0 AND length(${r.content_fingerprint}) > 0)`),threadStatusCreatedIndex:sqliteCore.index("idx_thread_highlights_thread_status_created").on(r.thread_id,r.status,r.created_at),threadCoversIndex:sqliteCore.index("idx_thread_highlights_thread_covers").on(r.thread_id,r.covers_from_task_id,r.covers_to_task_id),autoIdempotencyUnique:sqliteCore.uniqueIndex("thread_highlights_auto_idempotency_uq").on(r.thread_id,r.source_task_id,r.detector_version,r.content_fingerprint).where(drizzleOrm.sql`${r.source} = 'auto'`)}));function Nn(r){let e=r.toLowerCase().trim();e=e.replace(/\[[^\]]*\]$/g,"");let t=e.lastIndexOf("/");return t>=0&&(e=e.slice(t+1)),e=e.replace(/-\d{8}$/,""),e}function xn(r,e){let t=e===void 0?"":` at index ${e}`;if(!r||typeof r!="object")throw new u("VALIDATION",`Task log entry${t} must be an object`);if(typeof r.timestamp!="string"||typeof r.level!="string"||typeof r.message!="string")throw new u("VALIDATION",`Task log entry${t} must contain string timestamp, level, and message fields`);return {timestamp:r.timestamp,level:r.level,message:r.message}}function On(r,e){if(e===null||e.trim()==="")return [];let t;try{t=JSON.parse(e);}catch(n){throw new u("DB_ERROR",`Malformed legacy task logs: ${r}`,n)}if(!Array.isArray(t))throw new u("DB_ERROR",`Malformed legacy task logs: ${r} (expected an array)`);try{return t.map((n,s)=>xn(n,s))}catch(n){throw n instanceof u?new u("DB_ERROR",`Malformed legacy task logs: ${r}`,n):n}}function Dn(r){if(r.log_storage!=="blob"&&r.log_storage!=="events")throw new u("DB_ERROR",`Invalid task log storage for task: ${r.id}`);if(!Number.isInteger(r.last_log_seq)||r.last_log_seq<0)throw new u("DB_ERROR",`Invalid task log sequence for task: ${r.id}`);if(!Number.isInteger(r.log_revision)||r.log_revision<0)throw new u("DB_ERROR",`Invalid task log revision for task: ${r.id}`);return r.log_storage}function bn(r){return {taskId:r.id,source:Dn(r),revision:r.log_revision,lastSeq:r.last_log_seq}}function as(r){if(!Number.isInteger(r)||r<0)throw new u("VALIDATION","Task log tail limit must be a non-negative integer")}var pt=class extends Q{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ge.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let s=ge.dirname(t);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}else if(!fs$1.existsSync(t))throw new u("NOT_FOUND","Database not found");let n=L(t);if(e)try{ae(n.db,t);}catch(s){throw n.close(),s}return n}findStateRow(e,t){return e.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,t)).limit(1).get()}findStateRowInTransaction(e,t){return e.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,t)).limit(1).get()}requireStateRowInTransaction(e,t){let n=this.findStateRowInTransaction(e,t);if(!n)throw new u("NOT_FOUND",`Task not found: ${t}`);return n}appendLog(e,t){return this.appendLogs(e,[t])}appendLogs(e,t){let n=t.map((i,a)=>xn(i,a));if(n.length===0){let i=this.getLogState(e);if(!i)throw new u("NOT_FOUND",`Task not found: ${e}`);return i}let s=this.openHandle(true);try{return s.db.transaction(a=>{let d=this.requireStateRowInTransaction(a,e),c=Dn(d);if(c==="blob"){let g=On(e,d.logs);if(a.update(o).set({logs:JSON.stringify([...g,...n]),log_revision:drizzleOrm.sql`${o.log_revision} + 1`}).where(drizzleOrm.eq(o.id,e)).run().changes!==1)throw new u("NOT_FOUND",`Task not found: ${e}`);return {taskId:e,source:c,revision:d.log_revision+1,lastSeq:d.last_log_seq}}let l=d.last_log_seq+1,h=d.last_log_seq+n.length;if(a.insert(de).values(n.map((g,f)=>({task_id:e,seq:l+f,timestamp:g.timestamp,level:g.level,message:g.message}))).run(),a.update(o).set({last_log_seq:h,log_revision:drizzleOrm.sql`${o.log_revision} + 1`}).where(drizzleOrm.eq(o.id,e)).run().changes!==1)throw new u("NOT_FOUND",`Task not found: ${e}`);return {taskId:e,source:c,revision:d.log_revision+1,lastSeq:h}},{behavior:"immediate"})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to append task log",i)}finally{s.close();}}getLogState(e){if(!this.dbExists())return;let t=this.openHandle(false);try{let n=this.findStateRow(t,e);return n?bn(n):void 0}catch(n){throw n instanceof u?n:new u("DB_ERROR","Failed to read task log state",n)}finally{t.close();}}readLogs(e){return this.readLogsInternal(e)}readLogsTail(e,t){return as(t),this.readLogsInternal(e,t)}readTail(e,t){return this.readLogsTail(e,t)}readLogsInternal(e,t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.transaction(s=>{let i=this.findStateRowInTransaction(s,e);if(!i)return;let a=bn(i);if(a.source==="blob"){let h=On(e,i.logs);return {...a,entries:t===void 0?h:h.slice(Math.max(0,h.length-t))}}let d=s.select({seq:de.seq,timestamp:de.timestamp,level:de.level,message:de.message}).from(de).where(drizzleOrm.eq(de.task_id,e)).orderBy(t===void 0?drizzleOrm.asc(de.seq):drizzleOrm.desc(de.seq)),l=(t===void 0?d.all():d.limit(t).all()).map(({timestamp:h,level:p,message:g})=>({timestamp:h,level:p,message:g}));return t!==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{n.close();}}};var qt=40,ye="2026-05-09",_s="0.8.9-rc.13",Ee=10,Re=parseInt(_s.split("rc.")[1]);function Ln(){let r=drizzleOrm.sql`
|
|
18
|
+
CASE
|
|
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
|
+
ELSE 'unknown'
|
|
27
|
+
END
|
|
28
|
+
`,e=drizzleOrm.sql`json_extract(${o.metadata}, '$.provider')`,t=drizzleOrm.sql`trim(${e})`,n=drizzleOrm.sql`substr(${t}, 1, instr(${t}, '/') - 1)`,s=drizzleOrm.sql`
|
|
29
|
+
CASE
|
|
30
|
+
WHEN instr(${t}, '/') > 0
|
|
31
|
+
AND ${n} IN ('cli', 'acp', 'api', 'plugin', 'remote')
|
|
32
|
+
THEN substr(${t}, instr(${t}, '/') + 1)
|
|
33
|
+
ELSE ${t}
|
|
34
|
+
END
|
|
35
|
+
`;return drizzleOrm.sql`
|
|
36
|
+
CASE
|
|
37
|
+
WHEN ${o.metadata} IS NULL THEN ${r}
|
|
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 ${r}
|
|
41
|
+
WHEN json_type(${o.metadata}, '$.provider') IS NOT 'text' THEN 'unknown'
|
|
42
|
+
WHEN ${t} = '' THEN 'unknown'
|
|
43
|
+
WHEN trim(${s}) = '' THEN 'unknown'
|
|
44
|
+
ELSE ${s}
|
|
45
|
+
END
|
|
46
|
+
`}var ps=new Set(["workflow","mcp"]),$n=600*1e3,ft=class extends Q{dbPath;taskLogRepository;pidNullObservedSince=new Map;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ge.join(e.dbRoot,".crewx","crewx.db")),this.taskLogRepository=new pt({dbPath:this.dbPath});}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let s=ge.dirname(t);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}else if(!fs$1.existsSync(t))throw new u("NOT_FOUND","Database not found");let n=L(t);if(e)try{ae(n.db,t);}catch(s){throw n.close(),s}return n}startTask(e){let t=this.openHandle(true);try{let n={id:e.id,agent_id:e.agentId,prompt:e.prompt,mode:e.mode,status:e.status,started_at:e.startedAt,pid:e.pid??null,parent_task_id:e.parentTaskId??null,caller_agent_id:e.callerAgentId??null,trace_id:e.traceId??null,command:e.command??null,metadata:e.metadata??null,workspace_id:e.workspaceId??null,project_id:e.projectId??null,platform:e.platform??"cli",crewx_version:e.crewxVersion??null,thread_id:e.threadId??null,model:e.model??null,rendered_prompt:e.renderedPrompt??null,coding_agent_command:e.codingAgentCommand??null,log_storage:"events"},s=i=>{t.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(n);}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;t.runRaw(`INSERT INTO tasks (
|
|
47
|
+
id, agent_id, prompt, mode, status, started_at, pid,
|
|
48
|
+
parent_task_id, caller_agent_id, trace_id, command, metadata,
|
|
49
|
+
workspace_id, project_id, platform, crewx_version, thread_id,
|
|
50
|
+
model, rendered_prompt, coding_agent_command
|
|
51
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
52
|
+
ON CONFLICT(id) DO UPDATE SET pid = COALESCE(excluded.pid, tasks.pid)
|
|
53
|
+
WHERE tasks.status = 'running'`,[n.id,n.agent_id,n.prompt,n.mode,n.status,n.started_at,n.pid,n.parent_task_id,n.caller_agent_id,n.trace_id,n.command,n.metadata,n.workspace_id,n.project_id,n.platform,n.crewx_version,n.thread_id,n.model,n.rendered_prompt,n.coding_agent_command]);}}catch(n){throw n instanceof u?n:new u("DB_ERROR","Failed to start task",n)}finally{t.close();}}listTasksByProjectId(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.select().from(o).where(drizzleOrm.eq(o.project_id,e)).orderBy(drizzleOrm.desc(o.started_at)).all()}catch(n){throw n instanceof u?n:new u("DB_ERROR","Failed to list tasks by project",n)}finally{t.close();}}finishTask(e){let t=this.openHandle(true);try{let n=e.runEpoch??null;t.runRaw(`UPDATE tasks SET status=?, result=?, error=?, completed_at=?, duration_ms=?,
|
|
14
54
|
exit_code=?, input_tokens=?, output_tokens=?, cached_input_tokens=?, cost_usd=?,
|
|
15
55
|
model=COALESCE(?, model)
|
|
16
|
-
WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[
|
|
56
|
+
WHERE id=? AND status='running' AND COALESCE(run_epoch, 0) = COALESCE(?, 0)`,[e.status,e.result??null,e.error??null,e.completedAt,e.durationMs??null,e.exitCode??null,e.inputTokens??0,e.outputTokens??0,e.cachedInputTokens??0,e.costUsd??0,e.model??null,e.id,n]);}catch(n){throw n instanceof u?n:new u("DB_ERROR","Failed to finish task",n)}finally{t.close();}}appendLog(e,t){this.taskLogRepository.appendLog(e,t);}appendLogs(e,t){this.taskLogRepository.appendLogs(e,t);}readLogs(e){return this.taskLogRepository.readLogs(e)}readLogsTail(e,t){return this.taskLogRepository.readLogsTail(e,t)}getLogState(e){return this.taskLogRepository.getLogState(e)}getRunningTasks(){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(o).where(drizzleOrm.eq(o.status,"running")).orderBy(drizzleOrm.desc(o.started_at)).all()}catch(t){throw new u("DB_ERROR","Failed to get running tasks",t)}finally{e.close();}}getAllTasks(){if(!this.dbExists())return [];let e=this.openHandle(false);try{return e.db.select().from(o).orderBy(drizzleOrm.desc(o.started_at)).limit(100).all()}catch(t){throw new u("DB_ERROR","Failed to get all tasks",t)}finally{e.close();}}getTask(e){if(!this.dbExists())return;let t=this.openHandle(false);try{return t.db.select().from(o).where(drizzleOrm.eq(o.id,e)).limit(1).get()??void 0}catch(n){throw new u("DB_ERROR","Failed to get task",n)}finally{t.close();}}killTask(e){if(!this.dbExists())return {killed:false};let t=this.openHandle(true);try{let n=t.db.select({id:o.id,status:o.status,pid:o.pid}).from(o).where(drizzleOrm.eq(o.id,e)).limit(1).get();if(!n||n.status!=="running")return {killed:!1};if(n.pid)try{process.kill(n.pid,"SIGTERM");}catch{}return t.db.update(o).set({status:"failed",error:"Killed by user",completed_at:new Date().toISOString()}).where(drizzleOrm.and(drizzleOrm.eq(o.id,e),drizzleOrm.eq(o.status,"running"))).run(),{killed:!0,pid:n.pid??void 0}}catch(n){throw n instanceof u?n:new u("DB_ERROR","Failed to kill task",n)}finally{t.close();}}reapOrphanedTasks(){if(!this.dbExists())return 0;let e=this.openHandle(true);try{let t=e.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(),n=Date.now(),s=new Set,i=0;for(let a of t){if(a.pid){let l=!1;try{process.kill(a.pid,0),l=!0;}catch{}l||(e.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(ps.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,n);continue}n-c>=$n&&(e.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{e.close();}}reapRunningWorkflowTasks(e=$n){if(!this.dbExists())return 0;let t=this.openHandle(true);try{let n=new Date(Date.now()-e).toISOString();return t.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,n),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{t.close();}}findTaskStatus(e,t){let n=this.resolveDbPaths();for(let s of n){if(!fs$1.existsSync(s))continue;let i=L(s);try{let a=t?drizzleOrm.eq(o.workspace_id,t):void 0,d=a?drizzleOrm.and(drizzleOrm.eq(o.id,e),a):drizzleOrm.eq(o.id,e),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,e),a):drizzleOrm.eq(o.thread_id,e);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(e,t){let n=this.resolveDbPaths(),s=new Set,i=[];for(let a of n){if(!fs$1.existsSync(a))continue;let d=L(a);try{let c=t?drizzleOrm.and(drizzleOrm.eq(o.parent_task_id,e),drizzleOrm.eq(o.workspace_id,t)):drizzleOrm.eq(o.parent_task_id,e),l=d.db.select().from(o).where(c).orderBy(drizzleOrm.asc(o.started_at)).all();for(let h of l)s.has(h.id)||(s.add(h.id),i.push(h));}catch(c){throw new u("DB_ERROR","Failed to find child tasks",c)}finally{d.close();}}return i}getWorkspaceUsageSummary(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{return t.db.all(e?drizzleOrm.sql`
|
|
17
57
|
SELECT
|
|
18
58
|
COALESCE(workspace_id, 'unknown') AS workspace_id,
|
|
19
59
|
COALESCE(SUM(input_tokens), 0) AS input_tokens,
|
|
@@ -21,7 +61,7 @@ ${s.join(`
|
|
|
21
61
|
COALESCE(SUM(cost_usd), 0) AS cost_usd,
|
|
22
62
|
COUNT(*) AS task_count
|
|
23
63
|
FROM tasks
|
|
24
|
-
WHERE workspace_id = ${
|
|
64
|
+
WHERE workspace_id = ${e}
|
|
25
65
|
GROUP BY workspace_id
|
|
26
66
|
ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
|
|
27
67
|
`:drizzleOrm.sql`
|
|
@@ -34,7 +74,7 @@ ${s.join(`
|
|
|
34
74
|
FROM tasks
|
|
35
75
|
GROUP BY workspace_id
|
|
36
76
|
ORDER BY (COALESCE(SUM(input_tokens), 0) + COALESCE(SUM(output_tokens), 0)) DESC
|
|
37
|
-
`)}catch(
|
|
77
|
+
`)}catch(n){throw new u("DB_ERROR","Failed to get workspace usage summary",n)}finally{t.close();}}getThreadTokenUsage(e,t){let n=this.resolveDbPaths(),s=new Set,i=0,a=0,d=0;for(let c of n){if(!fs$1.existsSync(c))continue;let l=L(c);try{let h=drizzleOrm.eq(o.thread_id,e),p=t?drizzleOrm.and(h,drizzleOrm.eq(o.workspace_id,t)):h,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(h){throw new u("DB_ERROR","Failed to get thread token usage",h)}finally{l.close();}}return {inputTokens:i,outputTokens:a,costUsd:d}}findTasksByThread(e,t,n){let s=this.resolveDbPaths(),i=new Set,a=[],d=n?.projection==="activity-log";for(let c of s){if(!fs$1.existsSync(c))continue;let l=L(c);try{let h=drizzleOrm.eq(o.thread_id,e),p=t?drizzleOrm.and(h,drizzleOrm.eq(o.workspace_id,t)):h,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(h){throw new u("DB_ERROR","Failed to find tasks by thread",h)}finally{l.close();}}return a}parseWorkflowCardMetadata(e){if(!e)return {};try{let t=JSON.parse(e);return {kind:typeof t.kind=="string"?t.kind:void 0,workflowRunId:typeof t.workflowRunId=="string"?t.workflowRunId:void 0}}catch{return {}}}extractThreadIdFromCommand(e){return e?/--thread=(\S+)/.exec(e)?.[1]??null:null}findRunningWorkflowParentTasks(){if(!this.dbExists())return [];let e=[];for(let t of this.resolveDbPaths()){if(!fs$1.existsSync(t))continue;let n=L(t);try{e.push(...n.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{n.close();}}return e}batchFetchWorkflowCards(e,t){let n=new Map;if(e.length===0)return n;let s=new Set(e),i=new Map,a=t?drizzleOrm.eq(o.workspace_id,t):void 0,d=(c,l)=>{if(!c)return;let h=i.get(c);if(h&&l.started_at<=h)return;let p=this.parseWorkflowCardMetadata(l.metadata);p.kind!=="workflow_card"&&p.kind!=="workflow_ui_instance"||(i.set(c,l.started_at),n.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=L(c);try{let h=drizzleOrm.and(drizzleOrm.inArray(o.thread_id,e),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(h,a):h).all();for(let D of p)d(D.thread_id,D);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 D of f){let v=this.extractThreadIdFromCommand(D.command);!v||!s.has(v)||d(v,D);}}catch(h){throw new u("DB_ERROR","Failed to batch fetch workflow cards",h)}finally{l.close();}}return n}findAllTasks(e){if(!this.dbExists())return {rows:[],total:0};let t=this.openHandle(false);try{let n=[];e.workspaceId&&n.push(drizzleOrm.eq(o.workspace_id,e.workspaceId));let s=e.agents&&e.agents.length>0?e.agents:e.agentId?[e.agentId]:null;s&&n.push(drizzleOrm.inArray(o.agent_id,s));let i=e.statuses&&e.statuses.length>0?e.statuses:e.status?[e.status]:null;i&&n.push(drizzleOrm.inArray(o.status,i));let a=e.q??e.search;a&&n.push(drizzleOrm.like(o.prompt,`%${a}%`)),e.from&&n.push(drizzleOrm.gte(o.started_at,e.from)),e.to&&n.push(drizzleOrm.lt(o.started_at,e.to));let d=n.length>0?drizzleOrm.and(...n):void 0,c=t.db.select({count:drizzleOrm.sql`count(*)`}).from(o).where(d).get(),l=(e.sortDir??"DESC")==="ASC"?drizzleOrm.asc(o.started_at):drizzleOrm.desc(o.started_at);return {rows:t.db.select().from(o).where(d).orderBy(l).limit(e.limit).offset(e.offset).all(),total:c?.count??0}}catch(n){throw new u("DB_ERROR","Failed to find all tasks",n)}finally{t.close();}}getAgentUsage(e,t,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(n?drizzleOrm.sql`
|
|
38
78
|
SELECT
|
|
39
79
|
t.agent_id,
|
|
40
80
|
t.workspace_id,
|
|
@@ -42,11 +82,11 @@ ${s.join(`
|
|
|
42
82
|
COALESCE(SUM(
|
|
43
83
|
COALESCE(t.input_tokens, 0)
|
|
44
84
|
+ CASE
|
|
45
|
-
WHEN t.started_at >= ${
|
|
85
|
+
WHEN t.started_at >= ${ye}
|
|
46
86
|
AND (
|
|
47
87
|
t.crewx_version IS NULL
|
|
48
88
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
49
|
-
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, ${Ee}) AS INTEGER) < ${Re})
|
|
50
90
|
)
|
|
51
91
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
52
92
|
ELSE 0
|
|
@@ -57,19 +97,19 @@ ${s.join(`
|
|
|
57
97
|
COALESCE(SUM(t.cost_usd), 0) AS cost_usd
|
|
58
98
|
FROM tasks t
|
|
59
99
|
WHERE t.status IN ('completed', 'success')
|
|
60
|
-
AND t.started_at >= ${
|
|
61
|
-
AND t.started_at < ${
|
|
62
|
-
AND t.workspace_id = ${
|
|
100
|
+
AND t.started_at >= ${e}
|
|
101
|
+
AND t.started_at < ${t}
|
|
102
|
+
AND t.workspace_id = ${n}
|
|
63
103
|
GROUP BY t.agent_id, t.workspace_id
|
|
64
104
|
ORDER BY (
|
|
65
105
|
COALESCE(SUM(
|
|
66
106
|
COALESCE(t.input_tokens, 0)
|
|
67
107
|
+ CASE
|
|
68
|
-
WHEN t.started_at >= ${
|
|
108
|
+
WHEN t.started_at >= ${ye}
|
|
69
109
|
AND (
|
|
70
110
|
t.crewx_version IS NULL
|
|
71
111
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
72
|
-
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, ${Ee}) AS INTEGER) < ${Re})
|
|
73
113
|
)
|
|
74
114
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
75
115
|
ELSE 0
|
|
@@ -85,11 +125,11 @@ ${s.join(`
|
|
|
85
125
|
COALESCE(SUM(
|
|
86
126
|
COALESCE(t.input_tokens, 0)
|
|
87
127
|
+ CASE
|
|
88
|
-
WHEN t.started_at >= ${
|
|
128
|
+
WHEN t.started_at >= ${ye}
|
|
89
129
|
AND (
|
|
90
130
|
t.crewx_version IS NULL
|
|
91
131
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
92
|
-
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, ${Ee}) AS INTEGER) < ${Re})
|
|
93
133
|
)
|
|
94
134
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
95
135
|
ELSE 0
|
|
@@ -100,18 +140,18 @@ ${s.join(`
|
|
|
100
140
|
COALESCE(SUM(t.cost_usd), 0) AS cost_usd
|
|
101
141
|
FROM tasks t
|
|
102
142
|
WHERE t.status IN ('completed', 'success')
|
|
103
|
-
AND t.started_at >= ${
|
|
104
|
-
AND t.started_at < ${
|
|
143
|
+
AND t.started_at >= ${e}
|
|
144
|
+
AND t.started_at < ${t}
|
|
105
145
|
GROUP BY t.agent_id, t.workspace_id
|
|
106
146
|
ORDER BY (
|
|
107
147
|
COALESCE(SUM(
|
|
108
148
|
COALESCE(t.input_tokens, 0)
|
|
109
149
|
+ CASE
|
|
110
|
-
WHEN t.started_at >= ${
|
|
150
|
+
WHEN t.started_at >= ${ye}
|
|
111
151
|
AND (
|
|
112
152
|
t.crewx_version IS NULL
|
|
113
153
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
114
|
-
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, ${Ee}) AS INTEGER) < ${Re})
|
|
115
155
|
)
|
|
116
156
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
117
157
|
ELSE 0
|
|
@@ -119,18 +159,18 @@ ${s.join(`
|
|
|
119
159
|
), 0)
|
|
120
160
|
+ COALESCE(SUM(t.output_tokens), 0)
|
|
121
161
|
) DESC
|
|
122
|
-
`).map(
|
|
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(e,t,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{return s.db.all(n?drizzleOrm.sql`
|
|
123
163
|
SELECT
|
|
124
164
|
date(t.started_at) AS date,
|
|
125
165
|
t.agent_id,
|
|
126
166
|
COALESCE(SUM(
|
|
127
167
|
COALESCE(t.input_tokens, 0)
|
|
128
168
|
+ CASE
|
|
129
|
-
WHEN t.started_at >= ${
|
|
169
|
+
WHEN t.started_at >= ${ye}
|
|
130
170
|
AND (
|
|
131
171
|
t.crewx_version IS NULL
|
|
132
172
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
133
|
-
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, ${Ee}) AS INTEGER) < ${Re})
|
|
134
174
|
)
|
|
135
175
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
136
176
|
ELSE 0
|
|
@@ -141,9 +181,9 @@ ${s.join(`
|
|
|
141
181
|
COALESCE(SUM(t.cost_usd), 0) AS cost_usd
|
|
142
182
|
FROM tasks t
|
|
143
183
|
WHERE t.status IN ('completed', 'success')
|
|
144
|
-
AND t.started_at >= ${
|
|
145
|
-
AND t.started_at < ${
|
|
146
|
-
AND t.workspace_id = ${
|
|
184
|
+
AND t.started_at >= ${e}
|
|
185
|
+
AND t.started_at < ${t}
|
|
186
|
+
AND t.workspace_id = ${n}
|
|
147
187
|
GROUP BY date(t.started_at), t.agent_id
|
|
148
188
|
ORDER BY date(t.started_at) ASC
|
|
149
189
|
`:drizzleOrm.sql`
|
|
@@ -153,11 +193,11 @@ ${s.join(`
|
|
|
153
193
|
COALESCE(SUM(
|
|
154
194
|
COALESCE(t.input_tokens, 0)
|
|
155
195
|
+ CASE
|
|
156
|
-
WHEN t.started_at >= ${
|
|
196
|
+
WHEN t.started_at >= ${ye}
|
|
157
197
|
AND (
|
|
158
198
|
t.crewx_version IS NULL
|
|
159
199
|
OR (t.crewx_version LIKE '0.8.%' AND t.crewx_version NOT LIKE '0.8.9%')
|
|
160
|
-
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, ${Ee}) AS INTEGER) < ${Re})
|
|
161
201
|
)
|
|
162
202
|
THEN COALESCE(t.cached_input_tokens, 0)
|
|
163
203
|
ELSE 0
|
|
@@ -168,55 +208,102 @@ ${s.join(`
|
|
|
168
208
|
COALESCE(SUM(t.cost_usd), 0) AS cost_usd
|
|
169
209
|
FROM tasks t
|
|
170
210
|
WHERE t.status IN ('completed', 'success')
|
|
171
|
-
AND t.started_at >= ${
|
|
172
|
-
AND t.started_at < ${
|
|
211
|
+
AND t.started_at >= ${e}
|
|
212
|
+
AND t.started_at < ${t}
|
|
173
213
|
GROUP BY date(t.started_at), t.agent_id
|
|
174
214
|
ORDER BY date(t.started_at) ASC
|
|
175
|
-
`).map(
|
|
176
|
-
CASE
|
|
177
|
-
WHEN ${o.model} LIKE 'claude-%' OR ${o.model} IN ('opus', 'sonnet', 'haiku', 'opus[1m]', 'sonnet[1m]') THEN 'claude'
|
|
178
|
-
WHEN ${o.model} LIKE 'gpt-%' OR ${o.model} LIKE 'codex-%' THEN 'codex'
|
|
179
|
-
WHEN ${o.model} LIKE 'gemini-%' THEN 'gemini'
|
|
180
|
-
WHEN ${o.model} LIKE 'zai-%' OR ${o.model} LIKE 'openrouter/z-ai/%' THEN 'opencode'
|
|
181
|
-
WHEN ${o.model} LIKE 'minimax/%' THEN 'minimax'
|
|
182
|
-
WHEN ${o.model} LIKE 'qwen%' THEN 'qwen'
|
|
183
|
-
ELSE 'unknown'
|
|
184
|
-
END
|
|
185
|
-
`,i=drizzleOrm.sql`
|
|
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(e,t){if(!this.dbExists())return;let n=this.openHandle(false);try{return n.db.select().from(o).where(drizzleOrm.and(drizzleOrm.eq(o.id,e),drizzleOrm.eq(o.workspace_id,t))).limit(1).get()??void 0}catch(s){throw new u("DB_ERROR","Failed to find task for stop",s)}finally{n.close();}}findLatestTaskByMetadata(e){if(!this.dbExists())return null;let t=this.openHandle(false);try{return t.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,e.agentId),drizzleOrm.eq(o.workspace_id,e.workspaceId),drizzleOrm.sql`${o.metadata} IS NOT NULL AND json_valid(${o.metadata}) AND json_extract(${o.metadata}, '$.' || ${e.metaKey}) = ${e.metaValue}`)).orderBy(drizzleOrm.desc(o.started_at)).limit(1).get()??null}catch(n){throw new u("DB_ERROR","Failed to find latest task by metadata",n)}finally{t.close();}}markTaskFailed(e,t,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let i=new Date().toISOString(),a=n?drizzleOrm.and(drizzleOrm.eq(o.id,e),drizzleOrm.eq(o.status,"running"),drizzleOrm.eq(o.workspace_id,n)):drizzleOrm.and(drizzleOrm.eq(o.id,e),drizzleOrm.eq(o.status,"running"));s.db.update(o).set({status:"failed",error:t,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(e,t){let n=this.resolveDbPaths(),s=new Set,i=[];for(let a of n){if(!fs$1.existsSync(a))continue;let d=L(a);try{let c=t?drizzleOrm.and(drizzleOrm.like(o.prompt,`%${e}%`),drizzleOrm.eq(o.workspace_id,t)):drizzleOrm.like(o.prompt,`%${e}%`),l=d.db.select().from(o).where(c).orderBy(drizzleOrm.asc(o.started_at)).all();for(let h of l)s.has(h.id)||(s.add(h.id),i.push(h));}catch(c){throw new u("DB_ERROR","Failed to find tasks by prompt hint",c)}finally{d.close();}}return i}getProviderUsage(e,t,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{let i=Ln(),a=drizzleOrm.sql`
|
|
186
216
|
COALESCE(${o.input_tokens}, 0)
|
|
187
217
|
+ CASE
|
|
188
|
-
WHEN ${o.started_at} >= ${
|
|
218
|
+
WHEN ${o.started_at} >= ${ye}
|
|
189
219
|
AND (
|
|
190
220
|
${o.crewx_version} IS NULL
|
|
191
221
|
OR (${o.crewx_version} LIKE '0.8.%' AND ${o.crewx_version} NOT LIKE '0.8.9%')
|
|
192
|
-
OR (${o.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${o.crewx_version}, ${
|
|
222
|
+
OR (${o.crewx_version} LIKE '0.8.9-rc.%' AND CAST(SUBSTR(${o.crewx_version}, ${Ee}) AS INTEGER) < ${Re})
|
|
193
223
|
)
|
|
194
224
|
THEN COALESCE(${o.cached_input_tokens}, 0)
|
|
195
225
|
ELSE 0
|
|
196
226
|
END
|
|
197
|
-
`,
|
|
227
|
+
`,d=n?drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${e} AND ${o.started_at} < ${t} AND ${o.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${e} AND ${o.started_at} < ${t}`;return s.db.all(drizzleOrm.sql`
|
|
198
228
|
SELECT
|
|
199
|
-
${
|
|
229
|
+
${i} AS provider,
|
|
200
230
|
COUNT(*) AS total_tasks,
|
|
201
|
-
COALESCE(SUM(${
|
|
231
|
+
COALESCE(SUM(${a}), 0) AS input_tokens,
|
|
202
232
|
COALESCE(SUM(${o.output_tokens}), 0) AS output_tokens,
|
|
203
233
|
COALESCE(SUM(${o.cached_input_tokens}), 0) AS cached_input_tokens,
|
|
204
234
|
COALESCE(SUM(${o.cost_usd}), 0) AS cost_usd,
|
|
205
235
|
COALESCE(SUM(${o.duration_ms}), 0) AS active_duration_ms,
|
|
206
236
|
MAX(${o.completed_at}) AS last_active_at
|
|
207
237
|
FROM ${o}
|
|
238
|
+
${d}
|
|
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(e,t,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{let i=Ln(),a=drizzleOrm.sql`
|
|
242
|
+
COALESCE(${o.input_tokens}, 0)
|
|
243
|
+
+ CASE
|
|
244
|
+
WHEN ${o.started_at} >= ${ye}
|
|
245
|
+
AND (
|
|
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}, ${Ee}) AS INTEGER) < ${Re})
|
|
249
|
+
)
|
|
250
|
+
THEN COALESCE(${o.cached_input_tokens}, 0)
|
|
251
|
+
ELSE 0
|
|
252
|
+
END
|
|
253
|
+
`,d=n?drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${e} AND ${o.started_at} < ${t} AND ${o.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${e} AND ${o.started_at} < ${t}`,c=s.db.all(drizzleOrm.sql`
|
|
254
|
+
SELECT
|
|
255
|
+
${o.model} AS model,
|
|
256
|
+
${i} AS provider,
|
|
257
|
+
COUNT(*) AS total_tasks,
|
|
258
|
+
COALESCE(SUM(${a}), 0) AS input_tokens,
|
|
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
|
+
${d}
|
|
266
|
+
GROUP BY ${o.model}, ${i}
|
|
267
|
+
`),l=new Map;for(let h of c){let p=Nn(h.model??""),g=JSON.stringify([h.provider,p]),f=l.get(g);f?(f.totalTasks+=h.total_tasks,f.inputTokens+=h.input_tokens,f.outputTokens+=h.output_tokens,f.cachedInputTokens+=h.cached_input_tokens,f.costUsd+=h.cost_usd,f.totalTokens+=h.input_tokens+h.output_tokens,f.activeDurationMs+=h.active_duration_ms??0,h.last_active_at&&(!f.lastActiveAt||h.last_active_at>f.lastActiveAt)&&(f.lastActiveAt=h.last_active_at)):l.set(g,{model:p,provider:h.provider,totalTasks:h.total_tasks,inputTokens:h.input_tokens,outputTokens:h.output_tokens,cachedInputTokens:h.cached_input_tokens,costUsd:h.cost_usd,totalTokens:h.input_tokens+h.output_tokens,activeDurationMs:h.active_duration_ms??0,lastActiveAt:h.last_active_at??null});}return Array.from(l.values()).sort((h,p)=>p.costUsd-h.costUsd)}catch(i){throw new u("DB_ERROR","Failed to get model usage",i)}finally{s.close();}}getTasksForReport(e,t,n){if(!this.dbExists())return [];let s=this.openHandle(false);try{let i=n?drizzleOrm.sql`WHERE ${o.started_at} >= ${e} AND ${o.started_at} < ${t} AND ${o.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${o.started_at} >= ${e} AND ${o.started_at} < ${t}`;return s.db.all(drizzleOrm.sql`
|
|
268
|
+
SELECT
|
|
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(e,t,n){if(!this.dbExists())return {edges:[],truncated:false};let s=this.openHandle(false);try{let i=drizzleOrm.sql`
|
|
279
|
+
COALESCE(${o.input_tokens}, 0)
|
|
280
|
+
+ CASE
|
|
281
|
+
WHEN ${o.started_at} >= ${ye}
|
|
282
|
+
AND (
|
|
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}, ${Ee}) AS INTEGER) < ${Re})
|
|
286
|
+
)
|
|
287
|
+
THEN COALESCE(${o.cached_input_tokens}, 0)
|
|
288
|
+
ELSE 0
|
|
289
|
+
END
|
|
290
|
+
`,a=n?drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${e} AND ${o.started_at} < ${t} AND ${o.workspace_id} = ${n}`:drizzleOrm.sql`WHERE ${o.status} IN ('completed', 'success') AND ${o.started_at} >= ${e} AND ${o.started_at} < ${t}`,d=s.db.all(drizzleOrm.sql`
|
|
291
|
+
SELECT
|
|
292
|
+
${o.caller_agent_id} AS caller_agent_id,
|
|
293
|
+
${o.agent_id} AS agent_id,
|
|
294
|
+
COUNT(*) AS task_count,
|
|
295
|
+
COALESCE(SUM(${i}), 0) AS input_tokens,
|
|
296
|
+
COALESCE(SUM(${o.output_tokens}), 0) AS output_tokens
|
|
297
|
+
FROM ${o}
|
|
208
298
|
${a}
|
|
209
|
-
GROUP BY
|
|
210
|
-
ORDER BY
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
AND parent.thread_id = ${t}.thread_id
|
|
218
|
-
)
|
|
219
|
-
)`)}findAllThreads(t){let e=this.resolveDbPaths(),s=new Set,n=[];for(let r of e){if(!fs.existsSync(r))continue;let i=b(r);try{let a=t?drizzleOrm.eq(u.workspace_id,t):void 0,l=i.db.select().from(u).where(a).orderBy(drizzleOrm.desc(u.updated_at)).all();for(let c of l)s.has(c.id)||(s.add(c.id),n.push(c));}catch(a){throw new _("DB_ERROR","Failed to find all threads",a)}finally{i.close();}}return n}findThreadById(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=b(n);try{let i=drizzleOrm.eq(u.id,t),a=e?drizzleOrm.and(i,drizzleOrm.eq(u.workspace_id,e)):i,l=r.db.select().from(u).where(a).limit(1).get()??void 0;if(l)return l}catch(i){throw new _("DB_ERROR","Failed to find thread by id",i)}finally{r.close();}}}threadExists(t,e){let s=this.resolveDbPaths();for(let n of s){if(!fs.existsSync(n))continue;let r=b(n);try{let i=drizzleOrm.eq(u.id,t),a=e?drizzleOrm.and(i,drizzleOrm.eq(u.workspace_id,e)):i;if(r.db.select({id:u.id}).from(u).where(a).limit(1).get())return !0}catch(i){throw new _("DB_ERROR","Failed to check thread existence",i)}finally{r.close();}}return false}aggregateTaskStats(t,e){let s=this.resolveDbPaths(),n=0,r=0,i=0,a=0,l=0,c=new Set;for(let p of s){if(!fs.existsSync(p))continue;let f=b(p);try{let g=f.db.get(drizzleOrm.sql`
|
|
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 ${qt+1}
|
|
302
|
+
`),c=d.length>qt;return {edges:d.slice(0,qt).map(h=>({callerAgentId:h.caller_agent_id??null,agentId:h.agent_id,taskCount:h.task_count,totalTokens:h.input_tokens+h.output_tokens,outputTokens:h.output_tokens})),truncated:c}}catch(i){throw new u("DB_ERROR","Failed to get delegation matrix",i)}finally{s.close();}}findTaskEvidence(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{let n=[];e.workspaceId&&n.push(drizzleOrm.eq(o.workspace_id,e.workspaceId)),e.agents&&e.agents.length>0&&n.push(drizzleOrm.inArray(o.agent_id,e.agents)),e.statuses&&e.statuses.length>0&&n.push(drizzleOrm.inArray(o.status,e.statuses)),e.from&&n.push(drizzleOrm.gte(o.started_at,e.from)),e.to&&n.push(drizzleOrm.lt(o.started_at,e.to));let s=n.length>0?drizzleOrm.and(...n):void 0,i=(e.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 e.limit?t.db.select(a).from(o).where(s).orderBy(i).limit(e.limit).all():t.db.select(a).from(o).where(s).orderBy(i).all()}catch(n){throw new u("DB_ERROR","Failed to find task evidence",n)}finally{t.close();}}findThreadChains(e){if(!this.dbExists())return [];let t=this.openHandle(false);try{let n=e.maxThreads??8,s=e.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"%'))];e.workspaceId&&i.push(drizzleOrm.eq(o.workspace_id,e.workspaceId)),e.from&&i.push(drizzleOrm.gte(o.started_at,e.from)),e.to&&i.push(drizzleOrm.lt(o.started_at,e.to));let a=t.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 h={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(h):d.set(l.thread_id,[h]);}let c=[];for(let[l,h]of d){let p=h.filter(g=>g.agentId===e.targetAgentId).length;p<2||c.push({threadId:l,targetAgentTurnCount:p,turns:h});}return c.sort((l,h)=>{let p=l.turns[l.turns.length-1].startedAt,g=h.turns[h.turns.length-1].startedAt;return p<g?1:p>g?-1:0}),c.slice(0,n).map(l=>({threadId:l.threadId,targetAgentTurnCount:l.targetAgentTurnCount,turns:l.turns.slice(-s)}))}catch(n){throw new u("DB_ERROR","Failed to find thread chains",n)}finally{t.close();}}};var fs=200,ms=200;function Ts(r){if(typeof r!="object"||r===null||!("code"in r))return;let e=r.code;return typeof e=="string"&&e.length>0?e:void 0}function ks(r){let e=r instanceof u?r.code:void 0,t=r instanceof u?r.cause:r,n=Ts(t);return {code:e??n??"DB_ERROR",cause:n??(t instanceof Error?t.name:e??typeof t)}}function Pn(r){return Buffer.byteLength(JSON.stringify(r),"utf8")}var Ft=class extends ve{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(e){super(),this.dbPath=ge.join(e?.dbRoot??dr.homedir(),".crewx","crewx.db"),this.version=e?.version??"unknown";}attach(e){let t=new ft({dbPath:this.dbPath});this.taskRepo=t;let n=process.cwd(),i=fs$1.existsSync(ge.join(n,"crewx.yaml"))||fs$1.existsSync(ge.join(n,"crewx.yml"))?an(n):null,a=process.argv.join(" ");this.unsubs.push(e.on("task:start",d=>{try{let c=d.callerAgentId??null,l=d.parentTaskId??null,h=d.rootTraceId??d.traceId,p=d.metadata?JSON.stringify(d.metadata):JSON.stringify({provider:d.provider??"cli/claude"});t.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:h,metadata:p,threadId:d.threadId??null});}catch{}}),e.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],Pn(l));}}),e.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;t.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(e){try{this.flushAllTaskLogs();}finally{this.clearAllTimers(),this.unsubs.forEach(t=>t()),this.unsubs=[],this.queues.clear(),this.taskRepo=void 0;}}getMetrics(){let e=0,t=0;for(let n of this.queues.values())e+=n.entries.length,t+=n.bytes;return {...this.metrics,appendFailureByCode:{...this.metrics.appendFailureByCode},appendFailureByCause:{...this.metrics.appendFailureByCause},pendingQueueEntries:e,pendingQueueBytes:t}}enqueueLog(e,t){let n=this.queues.get(e);if(n||(n={entries:[],bytes:0},this.queues.set(e,n)),n.entries.push(t),n.bytes+=Pn(t),this.metrics.maxQueueEntries=Math.max(this.metrics.maxQueueEntries,n.entries.length),this.metrics.maxQueueBytes=Math.max(this.metrics.maxQueueBytes,n.bytes),n.entries.length>=fs){this.flushTaskLogs(e);return}if(!n.timer){let s=setTimeout(()=>{let i=this.queues.get(e);!i||i.timer!==s||(i.timer=void 0,this.flushTaskLogs(e));},ms);n.timer=s;}}flushTaskLogs(e){let t=this.queues.get(e);if(!t||t.entries.length===0){t?.timer&&clearTimeout(t.timer),this.queues.delete(e);return}t.timer&&(clearTimeout(t.timer),t.timer=void 0);let n=t.entries,s=t.bytes;t.entries=[],t.bytes=0,this.metrics.flushCount+=1;try{this.taskRepo?.appendLogs(e,n),this.metrics.flushedEntries+=n.length;}catch(a){this.recordAppendFailure(a,n,s);}let i=this.queues.get(e);i&&i.entries.length===0&&(i.timer&&clearTimeout(i.timer),this.queues.delete(e));}flushAllTaskLogs(){for(let e of [...this.queues.keys()])this.flushTaskLogs(e);}clearAllTimers(){for(let e of this.queues.values())e.timer&&(clearTimeout(e.timer),e.timer=void 0);}recordAppendFailure(e,t,n){let s=ks(e);this.metrics.appendFailureCount+=1,this.metrics.appendFailureEntries+=t.length,this.metrics.appendFailureBytes+=n,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:t.length,pendingBytes:n});}};var qe=class extends u{reason;constructor(e,t=e){super("VALIDATION",t),this.name="ThreadTitleMetadataPatchError",this.reason=e;}};function Xe(r){if(!r)return {};try{let e=JSON.parse(r);return !e||typeof e!="object"||Array.isArray(e)?{}:e}catch{return {}}}function Is(r){let t=Xe(r).threadTitle;if(!t||typeof t!="object"||Array.isArray(t))return {priority:null,state:null};let n=t;return {priority:typeof n.priority=="string"?n.priority:null,state:typeof n.state=="string"?n.state:null}}var mt=class extends Q{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ge.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath?this.dbPath:super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(e){let s=ge.dirname(t);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}else if(!fs$1.existsSync(t))throw new u("NOT_FOUND","Database not found");let n=L(t);if(e)try{ae(n.db,t);}catch(s){throw n.close(),s}return n}validateWorkspaceId(e,t){return e.db.select({id:Pe.id}).from(Pe).where(drizzleOrm.eq(Pe.id,t)).limit(1).get()?t:null}topLevelTaskPredicateSql(e="child"){return drizzleOrm.sql.raw(`NOT EXISTS (
|
|
303
|
+
SELECT 1 FROM tasks parent
|
|
304
|
+
WHERE parent.id = ${e}.parent_task_id
|
|
305
|
+
AND parent.thread_id = ${e}.thread_id
|
|
306
|
+
)`)}findAllThreads(e){let t=this.resolveDbPaths(),n=new Set,s=[];for(let i of t){if(!fs$1.existsSync(i))continue;let a=L(i);try{let d=e?drizzleOrm.eq(_.workspace_id,e):void 0,c=a.db.select().from(_).where(d).orderBy(drizzleOrm.desc(_.updated_at)).all();for(let l of c)n.has(l.id)||(n.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(e,t){if(e.length===0)return [];let n=this.resolveDbPaths(),s=new Set,i=[];for(let a of n){if(!fs$1.existsSync(a))continue;let d=L(a);try{let c=drizzleOrm.or(drizzleOrm.inArray(_.id,e),drizzleOrm.inArray(_.title,e)),l=t?drizzleOrm.and(c,drizzleOrm.eq(_.workspace_id,t)):c,h=d.db.select().from(_).where(l).orderBy(drizzleOrm.desc(_.updated_at)).all();for(let p of h)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(e,t){let n=this.resolveDbPaths();for(let s of n){if(!fs$1.existsSync(s))continue;let i=L(s);try{let a=drizzleOrm.eq(_.id,e),d=t?drizzleOrm.and(a,drizzleOrm.eq(_.workspace_id,t)):a,c=i.db.select().from(_).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(e,t){let n=this.resolveDbPaths();for(let s of n){if(!fs$1.existsSync(s))continue;let i=L(s);try{let a=drizzleOrm.eq(_.id,e),d=t?drizzleOrm.and(a,drizzleOrm.eq(_.workspace_id,t)):a;if(i.db.select({id:_.id}).from(_).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(e,t){let n=this.resolveDbPaths(),s=0,i=0,a=0,d=0,c=0,l=new Set;for(let h of n){if(!fs$1.existsSync(h))continue;let p=L(h);try{let g=p.db.get(drizzleOrm.sql`
|
|
220
307
|
SELECT
|
|
221
308
|
count(*) AS cnt,
|
|
222
309
|
COALESCE(SUM(child.input_tokens), 0) AS total_input,
|
|
@@ -224,48 +311,55 @@ ${s.join(`
|
|
|
224
311
|
COALESCE(SUM(child.cached_input_tokens), 0) AS total_cached,
|
|
225
312
|
COALESCE(SUM(child.cost_usd), 0) AS total_cost
|
|
226
313
|
FROM tasks child
|
|
227
|
-
WHERE child.thread_id = ${
|
|
314
|
+
WHERE child.thread_id = ${e}
|
|
228
315
|
AND ${this.topLevelTaskPredicateSql()}
|
|
229
|
-
${
|
|
230
|
-
`);g&&(
|
|
316
|
+
${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
|
|
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`
|
|
231
318
|
SELECT DISTINCT child.agent_id FROM tasks child
|
|
232
|
-
WHERE child.thread_id = ${
|
|
319
|
+
WHERE child.thread_id = ${e}
|
|
233
320
|
AND child.agent_id IS NOT NULL AND child.agent_id != ''
|
|
234
321
|
AND ${this.topLevelTaskPredicateSql()}
|
|
235
|
-
${
|
|
236
|
-
`);for(let
|
|
322
|
+
${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
|
|
323
|
+
`);for(let D of f)l.add(D.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(e,t,n){let s=this.resolveDbPaths(),i=new Set,a=[];for(let d of s){if(!fs$1.existsSync(d))continue;let c=L(d);try{let l;n!==void 0?l=c.db.all(drizzleOrm.sql`
|
|
237
324
|
SELECT * FROM (
|
|
238
325
|
SELECT child.*,
|
|
239
326
|
ROW_NUMBER() OVER (PARTITION BY child.agent_id ORDER BY child.started_at DESC) AS rn
|
|
240
327
|
FROM tasks child
|
|
241
|
-
WHERE child.thread_id = ${
|
|
328
|
+
WHERE child.thread_id = ${e}
|
|
242
329
|
AND ${this.topLevelTaskPredicateSql()}
|
|
243
|
-
${
|
|
330
|
+
${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
|
|
244
331
|
) ranked
|
|
245
|
-
WHERE rn <= ${
|
|
332
|
+
WHERE rn <= ${n}
|
|
246
333
|
ORDER BY started_at ASC
|
|
247
|
-
`):c
|
|
334
|
+
`):l=c.db.all(drizzleOrm.sql`
|
|
248
335
|
SELECT child.* FROM tasks child
|
|
249
|
-
WHERE child.thread_id = ${
|
|
336
|
+
WHERE child.thread_id = ${e}
|
|
250
337
|
AND ${this.topLevelTaskPredicateSql()}
|
|
251
|
-
${
|
|
338
|
+
${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
|
|
252
339
|
ORDER BY child.started_at ASC
|
|
253
|
-
`);for(let
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
340
|
+
`);for(let h of l)i.has(h.id)||(i.add(h.id),a.push(h));}catch(l){throw new u("DB_ERROR","Failed to find top-level tasks",l)}finally{c.close();}}if(n!==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,h)=>(h.started_at??"").localeCompare(l.started_at??"")),a.push(...c.slice(0,n));a.sort((c,l)=>(c.started_at??"").localeCompare(l.started_at??""));}return a}findAllTasks(e,t){let n=this.resolveDbPaths(),s=new Set,i=[];for(let a of n){if(!fs$1.existsSync(a))continue;let d=L(a);try{let c=drizzleOrm.eq(o.thread_id,e),l=t?drizzleOrm.and(c,drizzleOrm.eq(o.workspace_id,t)):c,h=d.db.select().from(o).where(l).orderBy(drizzleOrm.asc(o.started_at)).all();for(let p of h)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(e,t,n){let s=this.resolveDbPaths();for(let i of s){if(!fs$1.existsSync(i))continue;let a=L(i);try{let d=drizzleOrm.and(drizzleOrm.eq(o.id,t),drizzleOrm.eq(o.thread_id,e)),c=n?drizzleOrm.and(d,drizzleOrm.eq(o.workspace_id,n)):d,l=a.db.select().from(o).where(c).limit(1).get();if(!l)continue;let h=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:h}}catch(d){throw new u("DB_ERROR","Failed to find task by id",d)}finally{a.close();}}}batchFetchTasksQuery(e,t){return drizzleOrm.sql`
|
|
341
|
+
SELECT child.id, child.thread_id, child.agent_id, child.status,
|
|
342
|
+
child.parent_task_id, child.started_at, child.completed_at,
|
|
343
|
+
child.duration_ms, child.input_tokens, child.output_tokens,
|
|
344
|
+
child.cost_usd, child.error
|
|
345
|
+
FROM tasks child INDEXED BY idx_tasks_thread_id
|
|
346
|
+
WHERE child.thread_id IN (${drizzleOrm.sql.join(e.map(n=>drizzleOrm.sql`${n}`),drizzleOrm.sql`, `)})
|
|
347
|
+
AND ${this.topLevelTaskPredicateSql()}
|
|
348
|
+
${t?drizzleOrm.sql`AND child.workspace_id = ${t}`:drizzleOrm.sql``}
|
|
349
|
+
ORDER BY child.started_at ASC
|
|
350
|
+
`}batchFetchTasks(e,t){let n=new Map;if(e.length===0)return n;let s=this.resolveDbPaths();for(let i of s){if(!fs$1.existsSync(i))continue;let a=L(i);try{let d=a.db.all(this.batchFetchTasksQuery(e,t));for(let c of d){let l=c.thread_id;n.has(l)||n.set(l,[]),n.get(l).push(c);}}catch(d){throw new u("DB_ERROR","Failed to batch fetch tasks",d)}finally{a.close();}}return n}explainBatchFetchTasksPlan(e,t){let n=this.resolveDbPaths();for(let s of n){if(!fs$1.existsSync(s))continue;let i=L(s);try{return i.db.all(drizzleOrm.sql`EXPLAIN QUERY PLAN ${this.batchFetchTasksQuery(e,t)}`).map(d=>d.detail)}finally{i.close();}}return []}updateThreadTitle(e,t,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let i=drizzleOrm.eq(_.id,e),a=n?drizzleOrm.and(i,drizzleOrm.eq(_.workspace_id,n)):i;if(!s.db.select({id:_.id}).from(_).where(a).limit(1).get())return;s.db.update(_).set({title:t,title_locked:1,updated_at:new Date().toISOString()}).where(drizzleOrm.eq(_.id,e)).run();}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to update thread title",i)}finally{s.close();}}upsertThread(e,t){let n=this.openHandle(true);try{let s=t.workspaceId?this.validateWorkspaceId(n,t.workspaceId):null,i=new Date().toISOString();if(n.db.select({id:_.id,message_count:_.message_count}).from(_).where(drizzleOrm.eq(_.id,e)).limit(1).get()){let d={updated_at:i};t.title!==void 0&&(d.title=t.title),t.titleLocked!==void 0&&(d.title_locked=t.titleLocked?1:0),n.db.update(_).set(d).where(drizzleOrm.eq(_.id,e)).run();}else n.db.insert(_).values({id:e,platform:t.platform,workspace_id:s,title:t.title??null,title_locked:t.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{n.close();}}ensureThread(e,t,n){let s=this.openHandle(true);try{let i=n?this.validateWorkspaceId(s,n):null,a=s.db.select({id:_.id,platform:_.platform,workspace_id:_.workspace_id}).from(_).where(drizzleOrm.eq(_.id,e)).limit(1).get();if(a){i&&!a.workspace_id&&s.db.update(_).set({workspace_id:i}).where(drizzleOrm.eq(_.id,e)).run();return}let d=new Date().toISOString();s.db.insert(_).values({id:e,platform:t,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(e,t,n){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:_.message_count}).from(_).where(drizzleOrm.eq(_.id,e)).limit(1).get()?.message_count===0;return d.run(drizzleOrm.sql`
|
|
260
351
|
UPDATE threads
|
|
261
|
-
SET first_message = COALESCE(first_message, ${
|
|
262
|
-
title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${
|
|
263
|
-
last_message = ${
|
|
352
|
+
SET first_message = COALESCE(first_message, ${t}),
|
|
353
|
+
title = CASE WHEN title_locked = 0 AND title IS NULL THEN substr(${t}, 1, 60) ELSE title END,
|
|
354
|
+
last_message = ${t},
|
|
264
355
|
message_count = message_count + 1,
|
|
265
|
-
updated_at = ${
|
|
266
|
-
WHERE id = ${
|
|
267
|
-
`),c},{behavior:"immediate"})}}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to save user message",r)}finally{n.close();}}saveAssistantMessage(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString();n.db.update(u).set({last_message:e,updated_at:r}).where(drizzleOrm.eq(u.id,t)).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to save assistant message",r)}finally{n.close();}}updateThread(t,e){if(!this.dbExists())return;let s=this.openHandle(true);try{let n={updated_at:new Date().toISOString()};e.title!==void 0&&(n.title=e.title,n.title_locked=1),e.titleLocked!==void 0&&(n.title_locked=e.titleLocked?1:0),s.db.update(u).set(n).where(drizzleOrm.eq(u.id,t)).run();}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to update thread",n)}finally{s.close();}}togglePin(t,e){let s=this.openHandle(true);try{let n=e?drizzleOrm.and(drizzleOrm.eq(u.id,t),drizzleOrm.eq(u.workspace_id,e)):drizzleOrm.eq(u.id,t),r=s.db.select({pinned:u.pinned,metadata:u.metadata}).from(u).where(n).get();if(!r)return null;let i=r.pinned?0:1,a=r.metadata?JSON.parse(r.metadata):{};if(i){let l=e?drizzleOrm.and(drizzleOrm.eq(u.pinned,1),drizzleOrm.eq(u.workspace_id,e)):drizzleOrm.eq(u.pinned,1),c=s.db.select({metadata:u.metadata}).from(u).where(l).all(),p=0;for(let f of c){let g=f.metadata?JSON.parse(f.metadata):{};typeof g.pinOrder=="number"&&g.pinOrder>p&&(p=g.pinOrder);}a.pinOrder=p+1;}else delete a.pinOrder;return s.db.update(u).set({pinned:i,metadata:Object.keys(a).length>0?JSON.stringify(a):null}).where(n).run(),{pinned:!!i}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to toggle pin",n)}finally{s.close();}}reorderPins(t,e){let s=this.openHandle(true);try{for(let n=0;n<t.length;n++){let r=e?drizzleOrm.and(drizzleOrm.eq(u.id,t[n]),drizzleOrm.eq(u.workspace_id,e)):drizzleOrm.eq(u.id,t[n]),i=s.db.select({metadata:u.metadata}).from(u).where(r).get();if(!i)continue;let a=i.metadata?JSON.parse(i.metadata):{};a.pinOrder=n+1,s.db.update(u).set({metadata:JSON.stringify(a)}).where(r).run();}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to reorder pins",n)}finally{s.close();}}toggleStar(t,e){let s=this.openHandle(true);try{let n=e?drizzleOrm.and(drizzleOrm.eq(u.id,t),drizzleOrm.eq(u.workspace_id,e)):drizzleOrm.eq(u.id,t),r=s.db.select({starred:u.starred}).from(u).where(n).get();if(!r)return null;let i=r.starred?0:1;return s.db.update(u).set({starred:i}).where(n).run(),{starred:!!i}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to toggle star",n)}finally{s.close();}}resolveOverdriveForRequest(t,e,s,n){let i=this.openHandle(true);try{let a=e?drizzleOrm.and(drizzleOrm.eq(u.id,t),drizzleOrm.eq(u.workspace_id,e)):drizzleOrm.eq(u.id,t);return i.db.transaction(c=>{let p=c.select({metadata:u.metadata}).from(u).where(a).get();if(!p)return null;let f=p.metadata?JSON.parse(p.metadata):{},g=f.overdrive??{},S=n?.defaultTurns??g.defaultTurns??3,K=n?.updatedBy??"ui",I=new Date().toISOString(),C,D,v,J;switch(s){case "enable-count":{let V=n?.turns??S,Q=n?.consumeCurrent?Math.max(V-1,0):V;C=Q>0?"count":"off",D=Q,v=!0,J="count";break}case "enable-latch":{C="latch",D=0,v=!0,J="latch";break}case "disable":{C="off",D=0,v=!1;break}default:{let V=g.state??"off",Q=typeof g.remaining=="number"?g.remaining:0;if(V==="count"&&Q>0){let wt=Q-1;wt<=0?(C="off",D=0):(C="count",D=wt),v=!0,J="count";}else V==="latch"?(C="latch",D=0,v=!0,J="latch"):(C="off",D=0,v=!1);break}}return f.overdrive={state:C,remaining:D,defaultTurns:S,updatedAt:I,updatedBy:K},c.update(u).set({metadata:JSON.stringify(f),updated_at:I}).where(a).run(),{applied:v,appliedMode:J,state:C,remaining:D}},{behavior:"immediate"})}catch(a){throw a instanceof _?a:new _("DB_ERROR","Failed to resolve overdrive",a)}finally{i.close();}}};function ye(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
`):
|
|
271
|
-
`)
|
|
356
|
+
updated_at = ${i}
|
|
357
|
+
WHERE id = ${e}
|
|
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(e,t,n){if(!this.dbExists())return;let s=this.openHandle(true);try{let i=new Date().toISOString();s.db.update(_).set({last_message:t,updated_at:i}).where(drizzleOrm.eq(_.id,e)).run();}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to save assistant message",i)}finally{s.close();}}updateThread(e,t){if(!this.dbExists())return;let n=this.openHandle(true);try{let s={updated_at:new Date().toISOString()};t.title!==void 0&&(s.title=t.title,s.title_locked=1),t.titleLocked!==void 0&&(s.title_locked=t.titleLocked?1:0),n.db.update(_).set(s).where(drizzleOrm.eq(_.id,e)).run();}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to update thread",s)}finally{n.close();}}patchThreadTitleMetadata(e,t,n){let s=t;if(!s||typeof s!="object"||Array.isArray(s))return new qe("THREAD_TITLE_PATCH_INVALID","Thread-title metadata patch must be an object");if(Object.keys(s).some(c=>c!=="priority"&&c!=="state"))return new qe("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 qe("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 qe("THREAD_TITLE_PATCH_INVALID","Thread-title metadata values must be non-empty strings or null");let d=this.openHandle(true);try{let c=n?drizzleOrm.and(drizzleOrm.eq(_.id,e),drizzleOrm.eq(_.workspace_id,n)):drizzleOrm.eq(_.id,e);return d.db.transaction(l=>{let h=l.select({metadata:_.metadata}).from(_).where(c).get();if(!h)return null;let p=Xe(h.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 D=Object.keys(p).length>0?JSON.stringify(p):null,v=new Date().toISOString();l.update(_).set({metadata:D,updated_at:v}).where(c).run();let S=l.select({metadata:_.metadata}).from(_).where(c).get();if(!S)throw new u("DB_ERROR","Thread-title metadata update could not be read back");let M=Is(S.metadata);return {threadId:e,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(e,t){let n=this.openHandle(true);try{let s=t?drizzleOrm.and(drizzleOrm.eq(_.id,e),drizzleOrm.eq(_.workspace_id,t)):drizzleOrm.eq(_.id,e);return n.db.transaction(i=>{let a=i.select({pinned:_.pinned,metadata:_.metadata}).from(_).where(s).get();if(!a)return null;let d=a.pinned?0:1,c=Xe(a.metadata);if(d){let l=t?drizzleOrm.and(drizzleOrm.eq(_.pinned,1),drizzleOrm.eq(_.workspace_id,t)):drizzleOrm.eq(_.pinned,1),h=i.select({metadata:_.metadata}).from(_).where(l).all(),p=null;for(let g of h){let f=Xe(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(_).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{n.close();}}reorderPins(e,t){let n=this.openHandle(true);try{n.db.transaction(s=>{for(let i=0;i<e.length;i++){let a=t?drizzleOrm.and(drizzleOrm.eq(_.id,e[i]),drizzleOrm.eq(_.workspace_id,t)):drizzleOrm.eq(_.id,e[i]),d=s.select({metadata:_.metadata}).from(_).where(a).get();if(!d)continue;let c=Xe(d.metadata);c.pinOrder=i+1,s.update(_).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{n.close();}}toggleStar(e,t){let n=this.openHandle(true);try{let s=t?drizzleOrm.and(drizzleOrm.eq(_.id,e),drizzleOrm.eq(_.workspace_id,t)):drizzleOrm.eq(_.id,e),i=n.db.select({starred:_.starred}).from(_).where(s).get();if(!i)return null;let a=i.starred?0:1;return n.db.update(_).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{n.close();}}resolveOverdriveForRequest(e,t,n,s){let a=this.openHandle(true);try{let d=t?drizzleOrm.and(drizzleOrm.eq(_.id,e),drizzleOrm.eq(_.workspace_id,t)):drizzleOrm.eq(_.id,e);return a.db.transaction(l=>{let h=l.select({metadata:_.metadata}).from(_).where(d).get();if(!h)return null;let p=h.metadata?JSON.parse(h.metadata):{},g=p.overdrive??{},f=s?.defaultTurns??g.defaultTurns??3,D=s?.updatedBy??"ui",v=new Date().toISOString(),S,M,F,He;switch(n){case "enable-count":{let pe=s?.turns??f,Se=s?.consumeCurrent?Math.max(pe-1,0):pe;S=Se>0?"count":"off",M=Se,F=!0,He="count";break}case "enable-latch":{S="latch",M=0,F=!0,He="latch";break}case "disable":{S="off",M=0,F=!1;break}default:{let pe=g.state??"off",Se=typeof g.remaining=="number"?g.remaining:0;if(pe==="count"&&Se>0){let A=Se-1;A<=0?(S="off",M=0):(S="count",M=A),F=!0,He="count";}else pe==="latch"?(S="latch",M=0,F=!0,He="latch"):(S="off",M=0,F=!1);break}}return p.overdrive={state:S,remaining:M,defaultTurns:f,updatedAt:v,updatedBy:D},l.update(_).set({metadata:JSON.stringify(p),updated_at:v}).where(d).run(),{applied:F,appliedMode:He,state:S,remaining:M}},{behavior:"immediate"})}catch(d){throw d instanceof u?d:new u("DB_ERROR","Failed to resolve overdrive",d)}finally{a.close();}}};var Ut="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function Ss(r){let e=crypto.randomBytes(r*2),t="";for(let n=0;n<e.length&&t.length<r;n++){let s=e[n];s<248&&(t+=Ut[s%62]);}for(;t.length<r;)t+=Ut[crypto.randomBytes(1)[0]%62];return t}function Ye(r){return `${r}_${Ss(8)}`}function Un(r,e){let{createHash:t}=je("crypto"),n=t("sha256").update(e).digest(),s=Buffer.alloc(8);for(let a=0;a<32;a++)s[a%8]^=n[a];let i="";for(let a of s)i+=Ut[a%62];return `${r}_${i}`}var vs=["urgent","high","medium","low"],Ns=["investigating","in-progress","in-review","on-hold","done"],jn="custom:";var As=new Set(vs),Cs=new Set(Ns);function jt(r){return typeof r=="string"&&As.has(r)}function Gt(r){if(typeof r!="string")return false;if(Cs.has(r))return true;if(r.startsWith("c_"))return r.length>2;if(!r.startsWith(jn))return false;let e=r.slice(jn.length);return e.length>=1&&e.length<=20}function Gn(r){if(!r)return null;try{let e=JSON.parse(r);return !e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}function zt(r){let e=Gn(r);if(!e)return {};let t=e.threadTitle;if(!t||typeof t!="object"||Array.isArray(t))return {};let n=t,s={};return jt(n.priority)&&(s.priority=n.priority),Gt(n.state)&&(s.state=n.state),s}function zn(r,e){let t=Gn(r)??{},n={...zt(r)};return e.priority===null?delete n.priority:e.priority!==void 0&&(n.priority=e.priority),e.state===null?delete n.state:e.state!==void 0&&(n.state=e.state),n.priority===void 0&&n.state===void 0?delete t.threadTitle:t.threadTitle=n,Object.keys(t).length===0?null:JSON.stringify(t)}var Ls="regeneration_replaced";var $s="THREAD_HIGHLIGHT_REGENERATION_INTERRUPTED";var Hs="THREAD_HIGHLIGHT_REGENERATION_COMMIT_FAILED",Vt=class extends u{threadId;highlightId;expectedRevision;currentRevision;constructor(e,t,n,s){super("CONFLICT",`Highlight revision conflict: expected ${n}, current ${s}`),this.name="ThreadHistoryConflictError",this.threadId=e,this.highlightId=t,this.expectedRevision=n,this.currentRevision=s;}},rt=class extends Vt{},Xt=class extends u{stableCode="THREAD_HIGHLIGHT_REGENERATION_IN_PROGRESS";run;constructor(e){super("CONFLICT","THREAD_HIGHLIGHT_REGENERATION_IN_PROGRESS"),this.name="ThreadHighlightRegenerationConflictError",this.run=e;}},Ps=new Set(Rn),Ms=new Set(En),qs=new Set(In),Bs=new Set(Sn),Fs=50,Kn=100,Vn=280,Xn=40,Us=new Set(vn),Tt=["queued","running"],js=["success","completed","done","failed","error"];function Kt(r){return Us.has(r)}function b(r){throw new u("VALIDATION",r)}function ie(r){throw new u("NOT_FOUND",r)}function k(r,e){(typeof r!="string"||r.trim().length===0)&&b(`${e} is required`);}function Qe(r={}){let e=r.actor??r,t=e.actorType??"system";return Ps.has(t)||b(`invalid actorType: ${String(t)}`),e.actorId!==void 0&&e.actorId!==null&&typeof e.actorId!="string"&&b("actorId must be a string or null"),{actorType:t,actorId:e.actorId??null}}function Gs(r){k(r.threadId,"threadId"),r.workspaceId!==void 0&&r.workspaceId!==null&&k(r.workspaceId,"workspaceId"),r.title!==void 0&&r.title!==null&&((typeof r.title!="string"||r.title.trim().length===0)&&b("title must not be empty"),r.title.length>120&&b("title must be at most 120 characters")),r.priority!==void 0&&r.priority!==null&&!jt(r.priority)&&b(`invalid priority: ${String(r.priority)}`),r.state!==void 0&&r.state!==null&&!Gt(r.state)&&b(`invalid state: ${String(r.state)}`);}function zs(r){r.beforeSeq!==void 0&&r.afterSeq!==void 0&&b("beforeSeq and afterSeq cannot be used together");for(let[t,n]of [["beforeSeq",r.beforeSeq],["afterSeq",r.afterSeq]])n!==void 0&&(!Number.isInteger(n)||n<0)&&b(`${t} must be a non-negative integer`);let e=r.limit??Fs;return (!Number.isInteger(e)||e<1||e>Kn)&&b(`limit must be between 1 and ${Kn}`),e}function Yt(r){typeof r!="string"&&b("text is required");let e=r.trim();return e.length===0&&b("text must not be empty"),e.length>Vn&&b(`text must be at most ${Vn} characters`),e}function Ie(r,e){return k(r??"",e),r}function Jt(r){Bs.has(r)||b(`invalid highlight kind: ${String(r)}`);}function Ws(r){qs.has(r)||b(`invalid highlight source: ${String(r)}`);}function Ks(r){k(r.threadId,"threadId"),k(r.workspaceId,"workspaceId");let e=r.source??"manual";Ws(e),Jt(r.kind);let t=Yt(r.text),n=r.coversFromTaskId??r.fromTaskId??r.taskId,s=r.coversToTaskId??r.toTaskId??r.taskId;if(e==="manual"){let h=r.taskId??(n&&s&&n===s?n:void 0),p=Ie(h,"taskId");return (n!==p||s!==p)&&b("manual highlights must cover exactly one task"),{source:e,kind:r.kind,text:t,coversFromTaskId:p,coversToTaskId:p,agentId:r.agentId??null,sourceTaskId:null,detectorVersion:null,contentFingerprint:null}}let i=Ie(n,"coversFromTaskId"),a=Ie(s,"coversToTaskId"),d=r.sourceTaskId??i,c=r.detectorVersion??(r.idempotencyKey!==void 0?"default":null),l=r.contentFingerprint??r.idempotencyKey??null;return Ie(d??void 0,"sourceTaskId"),Ie(c??void 0,"detectorVersion"),Ie(l??void 0,"contentFingerprint"),{source:e,kind:r.kind,text:t,coversFromTaskId:i,coversToTaskId:a,agentId:r.agentId??null,sourceTaskId:d,detectorVersion:c,contentFingerprint:l}}function Vs(r,e){(!r||typeof r!="object")&&b(`candidates[${e}] is required`),Jt(r.kind);let t=Yt(r.text),n=Ie(r.anchorTaskId,`candidates[${e}].anchorTaskId`),s=Ie(r.coversFromTaskId,`candidates[${e}].coversFromTaskId`),i=Ie(r.coversToTaskId,`candidates[${e}].coversToTaskId`),a=r.contentFingerprint?.trim()||Un("thl",JSON.stringify({kind:r.kind,text:t,anchorTaskId:n,coversFromTaskId:s,coversToTaskId:i}));return k(a,`candidates[${e}].contentFingerprint`),{kind:r.kind,text:t,anchorTaskId:n,coversFromTaskId:s,coversToTaskId:i,contentFingerprint:a}}function Xs(r){Array.isArray(r)||b("candidates must be an array"),r.length>Xn&&b(`candidates must contain at most ${Xn} items`);let e=new Map;for(let[t,n]of r.entries()){let s=Vs(n,t);e.set(s.contentFingerprint,s);}return [...e.values()]}function nt(r){let e=zt(r.metadata);return {threadId:r.id,workspaceId:r.workspace_id,title:r.title,priority:e.priority??null,state:e.state??null,metadata:r.metadata,titleLocked:r.title_locked===1,updatedAt:r.updated_at}}function Ys(r){try{let e=JSON.stringify(r);return (!e||e==="null"||e.startsWith("["))&&b("event payload must be a JSON object"),e}catch(e){throw new u("VALIDATION","event payload must be JSON serializable",e)}}function Ze(r,e){return r.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${C.seq}), 0)`}).from(C).where(drizzleOrm.eq(C.thread_id,e)).get()?.maxSeq??0}function et(r,e){return !!r.select({id:C.id}).from(C).where(drizzleOrm.eq(C.thread_id,e)).limit(1).get()}function $e(r,e){Ms.has(e.type)||b(`invalid thread event type: ${String(e.type)}`);let t=Ye("the");r.insert(C).values({id:t,thread_id:e.threadId,seq:e.seq,type:e.type,actor_type:e.actorType,actor_id:e.actorId,task_id:e.taskId??null,highlight_id:e.highlightId??null,payload_json:Ys(e.payload),created_at:e.createdAt}).run();let n=r.select().from(C).where(drizzleOrm.eq(C.id,t)).get();if(!n)throw new u("DB_ERROR","Thread event insert did not return a row");return n}function tt(r,e,t,n,s){let i=nt(e);$e(r,{threadId:e.id,seq:s,type:"thread.snapshot.imported",actorType:t.actorType,actorId:t.actorId,createdAt:n,payload:{title:i.title,priority:i.priority,state:i.state}});}function wt(r){return {highlightId:r.id,source:r.source,kind:r.kind,status:r.status,coversFromTaskId:r.covers_from_task_id,coversToTaskId:r.covers_to_task_id,revision:r.revision,...r.dismissed_at===null?{}:{dismissedAt:r.dismissed_at}}}function kt(r,e,t,n,s,i,a){let d=s==="thread.highlight.created"?wt(e):{before:a?wt({...e,...a,id:e.id}):void 0,after:wt(e)};return $e(r,{threadId:e.thread_id,seq:i,type:s,actorType:t.actorType,actorId:t.actorId,createdAt:n,taskId:e.source==="manual"?e.covers_from_task_id:e.source_task_id??e.covers_from_task_id,highlightId:e.id,payload:d})}function Js(r,e,t,n,s,i){return $e(r,{threadId:e.thread_id,seq:s,type:"thread.highlight.deleted",actorType:t.actorType,actorId:t.actorId,createdAt:n,taskId:e.source_task_id??e.covers_from_task_id,highlightId:e.id,payload:{before:wt(e),...i??{}}})}var yt=class extends Q{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ge.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(!e&&!fs$1.existsSync(t))throw new u("NOT_FOUND","Database not found");if(e){let s=ge.dirname(t);fs$1.existsSync(s)||fs$1.mkdirSync(s,{recursive:true});}let n=L(t);if(e)try{ae(n.db,t);}catch(s){throw n.close(),s}return n}findThread(e,t,n){let s=drizzleOrm.eq(_.id,t),i=n===void 0?s:n===null?drizzleOrm.and(s,drizzleOrm.isNull(_.workspace_id)):drizzleOrm.and(s,drizzleOrm.eq(_.workspace_id,n));return e.select().from(_).where(i).limit(1).get()}findRegenerationRun(e,t,n){let s=e.select().from(I).where(drizzleOrm.eq(I.id,t)).limit(1).get();if(s&&!(n!==void 0&&!this.findThread(e,s.thread_id,n)))return s}resolveWorkspaceId(e){if(k(e,"threadId"),!fs$1.existsSync(this.resolveDbPath()))return null;let t=this.openHandle(false);try{return t.db.select({workspaceId:_.workspace_id}).from(_).where(drizzleOrm.eq(_.id,e)).limit(1).get()?.workspaceId??null}catch(n){throw n instanceof u?n:new u("DB_ERROR","Failed to resolve thread workspace",n)}finally{t.close();}}getSnapshot(e,t){if(k(e,"threadId"),!fs$1.existsSync(this.resolveDbPath()))return null;let n=this.openHandle(false);try{let s=this.findThread(n.db,e,t);return s?nt(s):null}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read thread snapshot",s)}finally{n.close();}}updateSnapshot(e){Gs(e);let t=Qe(e),n=new Date().toISOString(),s=this.openHandle(true);try{return s.db.transaction(i=>{let a=this.findThread(i,e.threadId,e.workspaceId);a||ie(`Thread ${e.threadId} not found`);let d=nt(a),c=e.title!==void 0,l=c&&e.title!==d.title,h=c&&a.title_locked!==1,p=e.priority!==void 0&&e.priority!==d.priority,g=e.state!==void 0&&e.state!==d.state,f=l||p||g;if(!f&&!h)return d;let D=a.metadata;(p||g)&&(D=zn(a.metadata,{priority:e.priority,state:e.state}));let v={};if(f&&(v.metadata=D,v.updated_at=n),l&&(v.title=e.title),c&&(v.title_locked=1),i.update(_).set(v).where(e.workspaceId===void 0?drizzleOrm.eq(_.id,e.threadId):e.workspaceId===null?drizzleOrm.and(drizzleOrm.eq(_.id,e.threadId),drizzleOrm.isNull(_.workspace_id)):drizzleOrm.and(drizzleOrm.eq(_.id,e.threadId),drizzleOrm.eq(_.workspace_id,e.workspaceId))).run(),!f){let F={...a,title_locked:1};return nt(F)}let S=Ze(i,a.id)+1;et(i,a.id)||(tt(i,a,t,n,S),S+=1),l&&($e(i,{threadId:a.id,seq:S,type:"thread.title.changed",actorType:t.actorType,actorId:t.actorId,createdAt:n,taskId:e.taskId,payload:{before:d.title,after:e.title}}),S+=1),p&&($e(i,{threadId:a.id,seq:S,type:"thread.priority.changed",actorType:t.actorType,actorId:t.actorId,createdAt:n,taskId:e.taskId,payload:{before:d.priority,after:e.priority}}),S+=1),g&&$e(i,{threadId:a.id,seq:S,type:"thread.state.changed",actorType:t.actorType,actorId:t.actorId,createdAt:n,taskId:e.taskId,payload:{before:d.state,after:e.state}});let M={...a,title:l?e.title:a.title,metadata:D,title_locked:c?1:a.title_locked,updated_at:n};return nt(M)},{behavior:"immediate"})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to update thread snapshot",i)}finally{s.close();}}mutateSnapshot(e){return this.updateSnapshot(e)}updateThreadSnapshot(e){return this.updateSnapshot(e)}getLatestSeq(e,t){if(k(e,"threadId"),!fs$1.existsSync(this.resolveDbPath()))return null;let n=this.openHandle(false);try{return this.findThread(n.db,e,t)?n.db.select({maxSeq:drizzleOrm.sql`COALESCE(MAX(${C.seq}), 0)`}).from(C).where(drizzleOrm.eq(C.thread_id,e)).get()?.maxSeq??0:null}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read latest thread event sequence",s)}finally{n.close();}}listCompletedThreadHighlightTurns(e,t){if(k(e,"threadId"),k(t,"workspaceId"),!fs$1.existsSync(this.resolveDbPath()))return null;let n=this.openHandle(false);try{return this.findThread(n.db,e,t)?n.db.select({taskId:o.id,prompt:o.prompt,result:o.result,status:o.status,startedAt:o.started_at,completedAt:o.completed_at}).from(o).where(drizzleOrm.and(drizzleOrm.eq(o.thread_id,e),drizzleOrm.eq(o.workspace_id,t),drizzleOrm.inArray(o.status,js),drizzleOrm.or(drizzleOrm.isNull(o.parent_task_id),drizzleOrm.eq(o.parent_task_id,"")),drizzleOrm.sql`${o.result} IS NOT NULL AND length(trim(${o.result})) > 0`)).orderBy(drizzleOrm.asc(o.started_at),drizzleOrm.asc(o.id)).all().map(a=>({taskId:a.taskId,prompt:a.prompt,result:a.result,status:a.status,startedAt:a.startedAt,completedAt:a.completedAt})):null}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read completed thread highlight turns",s)}finally{n.close();}}createHighlightRegenerationRun(e){k(e.threadId,"threadId"),k(e.workspaceId,"workspaceId"),k(e.requestId,"requestId"),k(e.detectorVersion,"detectorVersion"),e.runId!==void 0&&k(e.runId,"runId");let t=new Date().toISOString(),n=this.openHandle(true);try{return n.db.transaction(s=>{let i=this.findThread(s,e.threadId,e.workspaceId);i||ie(`Thread ${e.threadId} not found`);let a=s.select().from(I).where(drizzleOrm.and(drizzleOrm.eq(I.thread_id,i.id),drizzleOrm.eq(I.request_id,e.requestId))).orderBy(drizzleOrm.desc(I.requested_at),drizzleOrm.desc(I.id)).limit(1).get();if(a)return {run:a,created:!1};let d=s.select().from(I).where(drizzleOrm.and(drizzleOrm.eq(I.thread_id,i.id),drizzleOrm.inArray(I.status,Tt))).orderBy(drizzleOrm.asc(I.requested_at),drizzleOrm.asc(I.id)).limit(1).get();if(d)throw new Xt(d);let c=e.runId??Ye("thr");s.insert(I).values({id:c,thread_id:i.id,request_id:e.requestId,status:"queued",detector_version:e.detectorVersion,requested_at:t,started_at:null,completed_at:null,error_code:null,previous_auto_count:null,new_auto_count:null}).run();let l=s.select().from(I).where(drizzleOrm.eq(I.id,c)).get();if(!l)throw new u("DB_ERROR","Highlight regeneration run insert did not return a row");return {run:l,created:!0}},{behavior:"immediate"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to create highlight regeneration run",s)}finally{n.close();}}beginHighlightRegenerationRun(e){return this.createHighlightRegenerationRun(e)}queueHighlightRegenerationRun(e){return this.createHighlightRegenerationRun(e)}getHighlightRegenerationRun(e,t){if(k(e,"runId"),t!==void 0&&k(t,"workspaceId"),!fs$1.existsSync(this.resolveDbPath()))return null;let n=this.openHandle(false);try{return this.findRegenerationRun(n.db,e,t)??null}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to read highlight regeneration run",s)}finally{n.close();}}getHighlightRegenerationRunByRequest(e,t,n){if(k(e,"threadId"),k(t,"workspaceId"),k(n,"requestId"),!fs$1.existsSync(this.resolveDbPath()))return null;let s=this.openHandle(false);try{return this.findThread(s.db,e,t)?s.db.select().from(I).where(drizzleOrm.and(drizzleOrm.eq(I.thread_id,e),drizzleOrm.eq(I.request_id,n))).orderBy(drizzleOrm.desc(I.requested_at),drizzleOrm.desc(I.id)).limit(1).get()??null:null}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to read highlight regeneration request",i)}finally{s.close();}}findHighlightRegenerationRun(e,t,n){return this.getHighlightRegenerationRunByRequest(e,t,n)}startHighlightRegenerationRun(e,t){k(e,"runId"),t!==void 0&&k(t,"workspaceId");let n=new Date().toISOString(),s=this.openHandle(true);try{return s.db.transaction(i=>{let a=this.findRegenerationRun(i,e,t);if(a||ie(`Highlight regeneration run ${e} not found`),Kt(a.status)||b(`invalid highlight regeneration status: ${a.status}`),a.status!=="queued")return a;i.update(I).set({status:"running",started_at:n}).where(drizzleOrm.and(drizzleOrm.eq(I.id,a.id),drizzleOrm.eq(I.status,"queued"))).run();let d=i.select().from(I).where(drizzleOrm.eq(I.id,a.id)).get();if(!d)throw new u("DB_ERROR","Highlight regeneration run start did not return a row");return d},{behavior:"immediate"})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to start highlight regeneration run",i)}finally{s.close();}}startHighlightRegeneration(e,t){return this.startHighlightRegenerationRun(e,t)}failHighlightRegenerationRun(e){k(e.runId,"runId"),k(e.errorCode,"errorCode"),e.workspaceId!==void 0&&k(e.workspaceId,"workspaceId");let t=new Date().toISOString(),n=this.openHandle(true);try{return n.db.transaction(s=>{let i=this.findRegenerationRun(s,e.runId,e.workspaceId);if(i||ie(`Highlight regeneration run ${e.runId} not found`),Kt(i.status)||b(`invalid highlight regeneration status: ${i.status}`),i.status==="completed"||i.status==="failed")return i;s.update(I).set({status:"failed",completed_at:t,error_code:e.errorCode}).where(drizzleOrm.and(drizzleOrm.eq(I.id,i.id),drizzleOrm.inArray(I.status,Tt))).run();let a=s.select().from(I).where(drizzleOrm.eq(I.id,i.id)).get();if(!a)throw new u("DB_ERROR","Highlight regeneration run failure did not return a row");return a},{behavior:"immediate"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to fail highlight regeneration run",s)}finally{n.close();}}failHighlightRegeneration(e){return this.failHighlightRegenerationRun(e)}recoverInterruptedHighlightRegenerationRuns(e=$s){k(e,"errorCode");let t=new Date().toISOString(),n=this.openHandle(true);try{return n.db.transaction(s=>s.update(I).set({status:"failed",completed_at:t,error_code:e}).where(drizzleOrm.inArray(I.status,Tt)).run().changes,{behavior:"immediate"})}catch(s){throw s instanceof u?s:new u("DB_ERROR","Failed to recover interrupted highlight runs",s)}finally{n.close();}}completeHighlightRegenerationRun(e){k(e.runId,"runId"),k(e.threadId,"threadId"),k(e.workspaceId,"workspaceId"),k(e.detectorVersion,"detectorVersion");let t=Xs(e.candidates),n=Qe(e),s=this.openHandle(true),i=false;try{return s.db.transaction(a=>{let d=this.findRegenerationRun(a,e.runId,e.workspaceId);if((!d||d.thread_id!==e.threadId)&&ie(`Highlight regeneration run ${e.runId} not found`),Kt(d.status)||b(`invalid highlight regeneration status: ${d.status}`),d.status==="failed")throw new u("CONFLICT","Highlight regeneration run has already failed");if(d.status==="completed")return {run:d,deletedCount:0,createdCount:0,previousAutoCount:d.previous_auto_count??0,newAutoCount:d.new_auto_count??0};i=!0;let c=this.findThread(a,e.threadId,e.workspaceId);c||ie(`Thread ${e.threadId} not found`),d.detector_version!==e.detectorVersion&&b("detectorVersion does not match the regeneration run");let l=a.select().from(w).where(drizzleOrm.eq(w.thread_id,c.id)).orderBy(drizzleOrm.asc(w.created_at),drizzleOrm.asc(w.id)).all(),h=new Set(t.map(A=>A.contentFingerprint)),p=l.filter(A=>A.source==="auto"&&A.status==="active"&&A.revision===0&&!h.has(A.content_fingerprint??"")),g=l.filter(A=>A.source==="auto"&&A.status==="active").length,f=new Set(l.filter(A=>!p.includes(A)&&A.content_fingerprint).map(A=>A.content_fingerprint)),D=t.filter(A=>!f.has(A.contentFingerprint)),v=new Date().toISOString(),S=Ze(a,c.id)+1;et(a,c.id)||(tt(a,c,n,v,S),S+=1);for(let A of p)a.delete(w).where(drizzleOrm.eq(w.id,A.id)).run(),Js(a,A,n,v,S,{runId:e.runId,reason:Ls}),S+=1;let M=0,F=e.agentId??(n.actorType==="agent"?n.actorId:null);for(let A of D){let en=Ye("thl");a.insert(w).values({id:en,thread_id:c.id,source:"auto",kind:A.kind,status:"active",text:A.text,covers_from_task_id:A.coversFromTaskId,covers_to_task_id:A.coversToTaskId,revision:0,created_at:v,updated_at:v,agent_id:F,source_task_id:A.anchorTaskId,detector_version:e.detectorVersion,content_fingerprint:A.contentFingerprint,dismissed_at:null}).run();let tn=a.select().from(w).where(drizzleOrm.eq(w.id,en)).get();if(!tn)throw new u("DB_ERROR","Regenerated highlight insert did not return a row");kt(a,tn,n,v,"thread.highlight.created",S),S+=1,M+=1;}let pe=a.select().from(w).where(drizzleOrm.eq(w.thread_id,c.id)).all().filter(A=>A.source==="auto"&&A.status==="active").length;$e(a,{threadId:c.id,seq:S,type:"thread.highlights.regenerated",actorType:n.actorType,actorId:n.actorId,createdAt:v,payload:{runId:d.id,detectorVersion:e.detectorVersion,previousAutoCount:g,newAutoCount:pe,deletedCount:p.length,createdCount:M}}),a.update(I).set({status:"completed",started_at:d.started_at??v,completed_at:v,error_code:null,previous_auto_count:g,new_auto_count:pe}).where(drizzleOrm.and(drizzleOrm.eq(I.id,d.id),drizzleOrm.inArray(I.status,Tt))).run();let Se=a.select().from(I).where(drizzleOrm.eq(I.id,d.id)).get();if(!Se)throw new u("DB_ERROR","Highlight regeneration completion did not return a row");return {run:Se,deletedCount:p.length,createdCount:M,previousAutoCount:g,newAutoCount:pe}},{behavior:"immediate"})}catch(a){if(i)try{this.failHighlightRegenerationRun({runId:e.runId,workspaceId:e.workspaceId,errorCode:Hs});}catch{}throw a instanceof u?a:new u("DB_ERROR","Failed to complete highlight regeneration",a)}finally{s.close();}}completeHighlightRegeneration(e){return this.completeHighlightRegenerationRun(e)}replaceAutoHighlightsAtomically(e){return this.completeHighlightRegenerationRun(e)}listTimeline(e,t,n={}){let s=typeof e=="string"?{...n,threadId:e,workspaceId:t}:e;k(s.threadId,"threadId"),k(s.workspaceId,"workspaceId");let i=zs(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(${C.seq}), 0)`}).from(C).where(drizzleOrm.eq(C.thread_id,s.threadId)).get()?.maxSeq??0,c;s.beforeSeq!==void 0?c=a.db.select().from(C).where(drizzleOrm.and(drizzleOrm.eq(C.thread_id,s.threadId),drizzleOrm.lt(C.seq,s.beforeSeq))).orderBy(drizzleOrm.desc(C.seq)).limit(i+1).all().reverse():s.afterSeq!==void 0?c=a.db.select().from(C).where(drizzleOrm.and(drizzleOrm.eq(C.thread_id,s.threadId),drizzleOrm.sql`${C.seq} > ${s.afterSeq}`)).orderBy(drizzleOrm.asc(C.seq)).limit(i+1).all():c=a.db.select().from(C).where(drizzleOrm.eq(C.thread_id,s.threadId)).orderBy(drizzleOrm.desc(C.seq)).limit(i+1).all().reverse();let l=c.length>i,h=s.afterSeq!==void 0?c.slice(0,i):l?c.slice(1):c,p=!1,g=h[0];return g&&(p=!!a.db.select({id:C.id}).from(C).where(drizzleOrm.and(drizzleOrm.eq(C.thread_id,s.threadId),drizzleOrm.lt(C.seq,g.seq))).limit(1).get()),{items:h,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(e,t,n){return this.listTimeline(e,t,n)}getTimeline(e,t,n){return this.listTimeline(e,t,n)}createHighlight(e){let t=Ks(e),n=Qe(e),s=new Date().toISOString(),i=this.openHandle(true);try{return i.db.transaction(a=>{let d=this.findThread(a,e.threadId,e.workspaceId);if(d||ie(`Thread ${e.threadId} not found`),t.source==="auto"){let g=a.select().from(w).where(drizzleOrm.and(drizzleOrm.eq(w.thread_id,e.threadId),drizzleOrm.eq(w.source_task_id,t.sourceTaskId),drizzleOrm.eq(w.detector_version,t.detectorVersion),drizzleOrm.eq(w.content_fingerprint,t.contentFingerprint))).orderBy(drizzleOrm.asc(w.created_at),drizzleOrm.asc(w.id)).limit(1).get();if(g)return g}let c=e.id??Ye("thl"),l={id:c,thread_id:e.threadId,source:t.source,kind:t.kind,status:"active",text:t.text,covers_from_task_id:t.coversFromTaskId,covers_to_task_id:t.coversToTaskId,revision:0,created_at:s,updated_at:s,agent_id:t.agentId,source_task_id:t.sourceTaskId,detector_version:t.detectorVersion,content_fingerprint:t.contentFingerprint,dismissed_at:null};a.insert(w).values(l).run();let h=a.select().from(w).where(drizzleOrm.eq(w.id,c)).get();if(!h)throw new u("DB_ERROR","Highlight insert did not return a row");let p=Ze(a,d.id)+1;return et(a,d.id)||(tt(a,d,n,s,p),p+=1),kt(a,h,n,s,"thread.highlight.created",p),h},{behavior:"immediate"})}catch(a){throw a instanceof u?a:new u("DB_ERROR","Failed to create thread highlight",a)}finally{i.close();}}updateHighlight(e){k(e.threadId,"threadId"),k(e.workspaceId,"workspaceId"),k(e.highlightId,"highlightId"),(!Number.isInteger(e.expectedRevision)||e.expectedRevision<0)&&b("expectedRevision must be a non-negative integer"),e.text===void 0&&e.kind===void 0&&e.coversFromTaskId===void 0&&e.coversToTaskId===void 0&&b("highlight update requires at least one field"),e.kind!==void 0&&Jt(e.kind);let t=e.text===void 0?void 0:Yt(e.text),n=Qe(e),s=new Date().toISOString(),i=this.openHandle(true);try{return i.db.transaction(a=>{let d=this.findThread(a,e.threadId,e.workspaceId);d||ie(`Thread ${e.threadId} not found`);let c=a.select().from(w).where(drizzleOrm.and(drizzleOrm.eq(w.id,e.highlightId),drizzleOrm.eq(w.thread_id,d.id))).limit(1).get();if(c||ie(`Highlight ${e.highlightId} not found`),c.revision!==e.expectedRevision)throw new rt(d.id,c.id,e.expectedRevision,c.revision);if(c.status!=="active")throw new rt(d.id,c.id,e.expectedRevision,c.revision);let l=e.kind??c.kind,h=t??c.text,p=e.coversFromTaskId??c.covers_from_task_id,g=e.coversToTaskId??c.covers_to_task_id;(!h||p.length===0||g.length===0)&&b("highlight projection is incomplete");let f=l!==c.kind||h!==c.text||p!==c.covers_from_task_id||g!==c.covers_to_task_id,D=n.actorType==="user"&&c.source==="auto"&&f?"manual":c.source;if(!(f||D!==c.source))return c;let S=c.revision+1;a.update(w).set({source:D,kind:l,text:h,covers_from_task_id:p,covers_to_task_id:g,revision:S,updated_at:s}).where(drizzleOrm.and(drizzleOrm.eq(w.id,c.id),drizzleOrm.eq(w.revision,c.revision))).run();let M=a.select().from(w).where(drizzleOrm.eq(w.id,c.id)).get();if(!M)throw new u("DB_ERROR","Highlight update did not return a row");let F=Ze(a,d.id)+1;return et(a,d.id)||(tt(a,d,n,s,F),F+=1),kt(a,M,n,s,"thread.highlight.updated",F,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(e){k(e.threadId,"threadId"),k(e.workspaceId,"workspaceId"),k(e.highlightId,"highlightId"),(!Number.isInteger(e.expectedRevision)||e.expectedRevision<0)&&b("expectedRevision must be a non-negative integer");let t=Qe(e),n=new Date().toISOString(),s=this.openHandle(true);try{return s.db.transaction(i=>{let a=this.findThread(i,e.threadId,e.workspaceId);a||ie(`Thread ${e.threadId} not found`);let d=i.select().from(w).where(drizzleOrm.and(drizzleOrm.eq(w.id,e.highlightId),drizzleOrm.eq(w.thread_id,a.id))).limit(1).get();if(d||ie(`Highlight ${e.highlightId} not found`),d.revision!==e.expectedRevision)throw new rt(a.id,d.id,e.expectedRevision,d.revision);if(d.status==="dismissed")return d;let c=d.revision+1;i.update(w).set({status:"dismissed",text:null,revision:c,updated_at:n,dismissed_at:n}).where(drizzleOrm.and(drizzleOrm.eq(w.id,d.id),drizzleOrm.eq(w.revision,d.revision))).run();let l=i.select().from(w).where(drizzleOrm.eq(w.id,d.id)).get();if(!l)throw new u("DB_ERROR","Highlight dismissal did not return a row");let h=Ze(i,a.id)+1;return et(i,a.id)||(tt(i,a,t,n,h),h+=1),kt(i,l,t,n,"thread.highlight.deleted",h,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(e,t,n={}){if(k(e,"threadId"),k(t,"workspaceId"),n.taskId!==void 0&&k(n.taskId,"taskId"),n.coversFromTaskId!==void 0&&k(n.coversFromTaskId,"coversFromTaskId"),n.coversToTaskId!==void 0&&k(n.coversToTaskId,"coversToTaskId"),!fs$1.existsSync(this.resolveDbPath()))return null;let s=this.openHandle(false);try{if(!this.findThread(s.db,e,t))return null;let a=s.db.select().from(w).where(drizzleOrm.and(drizzleOrm.eq(w.thread_id,e),drizzleOrm.eq(w.status,"active"))).orderBy(drizzleOrm.asc(w.created_at),drizzleOrm.asc(w.id)).all();if(n.taskId===void 0&&n.coversFromTaskId===void 0&&n.coversToTaskId===void 0)return a;let d=s.db.all(drizzleOrm.sql`
|
|
359
|
+
SELECT id, started_at FROM tasks WHERE thread_id = ${e}
|
|
360
|
+
ORDER BY started_at ASC, id ASC
|
|
361
|
+
`),c=new Map(d.map((g,f)=>[g.id,f])),l=n.taskId===void 0?void 0:c.get(n.taskId),h=n.coversFromTaskId===void 0?void 0:c.get(n.coversFromTaskId),p=n.coversToTaskId===void 0?void 0:c.get(n.coversToTaskId);return a.filter(g=>{let f=c.get(g.covers_from_task_id),D=c.get(g.covers_to_task_id);if(f===void 0||D===void 0)return !1;let v=Math.min(f,D),S=Math.max(f,D);return !(l!==void 0&&(l<v||l>S)||h!==void 0&&S<h||p!==void 0&&v>p)})}catch(i){throw i instanceof u?i:new u("DB_ERROR","Failed to list active thread highlights",i)}finally{s.close();}}listHighlights(e,t,n){return this.listActiveHighlights(e,t,n)}getActiveHighlights(e,t,n){return this.listActiveHighlights(e,t,n)}};var U=class extends u{reason;constructor(e,t="VALIDATION",n=e,s){super(t,n,s),this.name="CommonCodeRepositoryError",this.reason=e;}},Jn="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";function io(){let r=crypto.randomBytes(16),e="";for(let t of r)e+=Jn[t%Jn.length];return e.slice(0,12)}function Qn(){return `c_${io()}`}function ao(r){return typeof r=="string"&&$t.includes(r)}function co(r){return typeof r=="string"&&Ht.includes(r)}function st(r){if(!ao(r))throw new U("COMMON_CODE_GROUP_INVALID","VALIDATION",`Unsupported common-code group: ${r}`)}function Zn(r){if(!co(r))throw new U("COMMON_CODE_COLOR_INVALID","VALIDATION",`Unsupported common-code color: ${r}`)}function er(r){let e=typeof r=="string"?r.trim():"",t=[...e].length;if(t<1||t>20)throw new U("COMMON_CODE_NAME_INVALID","VALIDATION","Common-code names must contain 1 to 20 Unicode characters");return e}function ot(r){if(typeof r!="string"||r.trim().length===0)throw new U("COMMON_CODE_WORKSPACE_INVALID","VALIDATION","Workspace id is required for a user common code")}function Qt(r){if(typeof r!="string"||r.trim().length===0)throw new U("COMMON_CODE_CODE_INVALID","VALIDATION","Common-code code is required")}function Ue(r,e){return drizzleOrm.and(drizzleOrm.eq(m.code_group,r),drizzleOrm.or(drizzleOrm.isNull(m.workspace_id),drizzleOrm.eq(m.workspace_id,e)))}var Rt=class extends Q{dbPath;constructor(e={}){super(),e.dbPath?this.dbPath=e.dbPath:e.dbRoot&&(this.dbPath=ge.join(e.dbRoot,".crewx","crewx.db"));}resolveDbPath(){return this.dbPath??super.resolveDbPath()}openHandle(e){let t=this.resolveDbPath();if(!e&&!fs$1.existsSync(t))throw new u("NOT_FOUND","Database not found");e&&fs$1.mkdirSync(ge.dirname(t),{recursive:true});let n=L(t);if(e)try{ae(n.db,t);}catch(s){throw n.close(),s}return n}listSelectable(e,t){if(st(e),ot(t),!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.select().from(m).where(drizzleOrm.and(Ue(e,t),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{n.close();}}listForHistory(e,t){if(st(e),ot(t),!this.dbExists())return [];let n=this.openHandle(false);try{return n.db.select().from(m).where(Ue(e,t)).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{n.close();}}resolve(e,t){if(st(e),Qt(t),!this.dbExists())return null;let n=this.openHandle(false);try{return n.db.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,e),drizzleOrm.eq(m.code,t))).limit(1).get()??null}catch(s){throw new u("DB_ERROR","Failed to resolve common code",s)}finally{n.close();}}createThreadState(e){ot(e.workspaceId);let t=er(e.name);Zn(e.color);let n=this.openHandle(true);try{return n.db.transaction(s=>{if(s.select({code:m.code}).from(m).where(drizzleOrm.and(Ue("THREAD_STATE",e.workspaceId),drizzleOrm.eq(m.is_archived,0),drizzleOrm.eq(m.code_name,t))).limit(1).get())throw new U("COMMON_CODE_NAME_CONFLICT","CONFLICT",`Common-code name is already in use: ${t}`);let a=s.select({maxSortOrder:drizzleOrm.sql`max(${m.sort_order})`}).from(m).where(Ue("THREAD_STATE",e.workspaceId)).get(),d=new Date().toISOString(),c=Qn();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=Qn();s.insert(m).values({code_group:"THREAD_STATE",code:c,code_name:t,color:e.color,sort_order:(a?.maxSortOrder??-1)+1,workspace_id:e.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{n.close();}}updateDisplay(e){if(st(e.group),Qt(e.code),ot(e.workspaceId),e.name===void 0&&e.color===void 0)throw new U("COMMON_CODE_UPDATE_EMPTY","VALIDATION","At least one display value is required");let t=e.name===void 0||e.name===null?e.name:er(e.name);e.color!==void 0&&Zn(e.color);let n=this.openHandle(true);try{return n.db.transaction(s=>{let i=s.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,e.group),drizzleOrm.eq(m.code,e.code))).limit(1).get();if(!i)throw new U("COMMON_CODE_NOT_FOUND","NOT_FOUND",`Common code not found: ${e.group}/${e.code}`);if(this.assertOwnership(i,e.workspaceId),t===null&&i.is_builtin!==1)throw new U("COMMON_CODE_NAME_INVALID","VALIDATION","User common-code names cannot be cleared");if(typeof t=="string"&&i.is_archived===0){let c=drizzleOrm.and(Ue(e.group,e.workspaceId),drizzleOrm.eq(m.is_archived,0));if(s.select({code:m.code}).from(m).where(drizzleOrm.and(c,drizzleOrm.eq(m.code_name,t),drizzleOrm.sql`${m.code} <> ${e.code}`)).limit(1).get())throw new U("COMMON_CODE_NAME_CONFLICT","CONFLICT",`Common-code name is already in use: ${t}`)}let a={updated_at:new Date().toISOString()};e.name!==void 0&&(a.code_name=t??null),e.color!==void 0&&(a.color=e.color),s.update(m).set(a).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,e.group),drizzleOrm.eq(m.code,e.code))).run();let d=s.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,e.group),drizzleOrm.eq(m.code,e.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{n.close();}}archive(e,t,n,s=true){if(st(e),Qt(t),ot(n),typeof s!="boolean")throw new U("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,e),drizzleOrm.eq(m.code,t))).limit(1).get();if(!d)throw new U("COMMON_CODE_NOT_FOUND","NOT_FOUND",`Common code not found: ${e}/${t}`);if(d.is_builtin===1)throw new U("COMMON_CODE_BUILTIN_ARCHIVE_FORBIDDEN","VALIDATION","Builtin common codes cannot be archived");if(this.assertOwnership(d,n),!s&&d.code_name!==null&&a.select({code:m.code}).from(m).where(drizzleOrm.and(Ue(e,n),drizzleOrm.eq(m.is_archived,0),drizzleOrm.eq(m.code_name,d.code_name),drizzleOrm.ne(m.code,t))).limit(1).get())throw new U("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,e),drizzleOrm.eq(m.code,t))).run();let c=a.select().from(m).where(drizzleOrm.and(drizzleOrm.eq(m.code_group,e),drizzleOrm.eq(m.code,t))).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(e,t){if(e.workspace_id!==null&&e.workspace_id!==t)throw new U("COMMON_CODE_SCOPE_FORBIDDEN","VALIDATION","Workspace does not own this common code")}};function ho(r){return r.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 _o(r){if(!r)return "";let e=r;try{let t=JSON.parse(e);Array.isArray(t)?e=t.filter(n=>n?.type==="text"&&n?.text).map(n=>n.text).join(`
|
|
364
|
+
`):t&&typeof t=="object"&&t.result!==void 0&&(e=t.result||"");}catch{e=ho(e);}return e}var It=class{dbPath;constructor(e){this.dbPath=e??ge.join(dr.homedir(),".crewx","crewx.db");}getThreadRepo(){return new mt({dbPath:this.dbPath})}getThreadHistoryRepo(){return new yt({dbPath:this.dbPath})}updateThread(e,t){this.getThreadRepo().updateThread(e,{title:t.title});}async ensureThread(e,t,n){let s=this.getThreadRepo(),i=s.findThreadById(e);if(i){if(i.platform!==t)throw new Error(`Thread '${e}' already exists with platform '${i.platform}' \u2014 cannot change to '${t}' (platform is immutable)`);return {created:false}}return s.ensureThread(e,t,n),{created:true}}async fetchHistory(e,t){let n=t?.limit??100,s=this.getThreadRepo(),i=s.findThreadById(e),a=s.findTopLevelTasks(e,void 0,n),d=new Set(["queued","cancelled"]);a=a.filter(p=>(!p.status||!d.has(p.status))&&(!t?.currentTraceId||p.trace_id!==t.currentTraceId));let c=i?.platform??"cli",l=this.rowsToMessages(a),h=t?.includeHighlights===false?void 0:this.readActiveHighlights(e,i?.workspace_id??null);return {threadId:e,platform:c,messages:l,...h?{highlights:h}:{},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(e){try{let t=this.getThreadHistoryRepo().getSnapshot(e);if(!t)return;let n=new Rt({dbPath:this.dbPath}),s=(i,a)=>{try{return n.resolve(i,a)?.code_name||a}catch{return a}};return {...t.title?{title:t.title}:{},...t.priority?{priority:{code:t.priority,name:s("THREAD_PRIORITY",t.priority)}}:{},...t.state?{state:{code:t.state,name:s("THREAD_STATE",t.state)}}:{}}}catch{return}}async fetchHighlights(e){let t=this.getThreadRepo().findThreadById(e);return this.readActiveHighlights(e,t?.workspace_id??null)}async saveUserMessage(e,t,n,s){let{firstMessage:i}=this.getThreadRepo().saveUserMessage(e,t);return {id:e,firstMessage:i}}async saveAssistantMessage(e,t,n,s){return this.getThreadRepo().saveAssistantMessage(e,t),{id:e}}close(){}normalizeStatus(e){if(e&&!["success","completed","done"].includes(e)){if(["failed","error"].includes(e))return "failed";if(e==="running")return "running"}}readActiveHighlights(e,t){if(!t)return [];try{return (this.getThreadHistoryRepo().listActiveHighlights(e,t)??[]).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(e){let t=[];for(let n of e){n.prompt&&t.push({id:`${n.id}-user`,text:n.prompt,isAssistant:false,timestamp:new Date(n.started_at).getTime(),taskId:n.id,metadata:{caller_agent_id:n.caller_agent_id,task_id:n.id}});let s=_o(n.result),i=this.normalizeStatus(n.status);if(s||i==="running"||i==="failed"){let a={agent_id:n.agent_id,task_id:n.id};i&&(a.status=i),i==="failed"&&n.error&&(a.reason=n.error.split(`
|
|
365
|
+
`)[0].slice(0,200)),t.push({id:`${n.id}-assistant`,text:s,isAssistant:true,timestamp:new Date(n.started_at).getTime(),taskId:n.id,metadata:a});}}return t}};var Zt=class extends ve{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(e){super(),this._provider=new It(e?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(e,t,n,s){}async afterAssistantMessage(e,t,n){}attach(e){this.unsubStart=e.on("task:start",async t=>{if(!t.threadId)return;let n=t.platform??"cli";try{let s=await this._provider.ensureThread(t.threadId,n,t.workspaceId),i=await this._provider.saveUserMessage(t.threadId,t.message??"");await this.afterUserMessage(t.threadId,i.id,s.created||i.firstMessage,t);}catch{}}),this.unsubEnd=e.on("task:end",async t=>{if(!t.result)return;let n=t.metadata?.threadId;if(!n)return;let s=t.agentRef?.replace(/^@/,"")??"";try{let{id:i}=await this._provider.saveAssistantMessage(n,t.result,s);await this.afterAssistantMessage(n,i,t);}catch{}});}detach(e){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};exports.ConversationPlugin=Zt;exports.FileLoggerPlugin=vt;exports.SqliteTracingPlugin=Ft;
|