@precisionutilityguild/liquid-shadow 1.0.10 → 1.0.11
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 +279 -62
- package/dist/entry/cli/index.js +1069 -748
- package/dist/entry/ember/index.js +287 -252
- package/dist/entry/mcp/server.js +973 -791
- package/dist/entry/tribunal/index.js +296 -261
- package/dist/index.js +966 -784
- package/dist/logic/domain/embeddings/worker.js +1 -1
- package/dist/logic/parser/index.js +12 -12
- package/dist/logic/parser/worker.js +1 -1
- package/dist/skills/shadow_workspace/SKILL.md +24 -2
- package/dist/web-manifest.json +6 -2
- package/package.json +2 -1
- package/skills/shadow_workspace/SKILL.md +24 -2
|
@@ -1,96 +1,73 @@
|
|
|
1
|
-
var bt=Object.defineProperty;var K=(n,e)=>()=>(n&&(e=n(n=0)),e);var yt=(n,e)=>{for(var t in e)bt(n,t,{get:e[t],enumerable:!0})};import Tt from"pino";var Rt,St,p,D=K(()=>{"use strict";Rt={10:"TRACE",20:"DEBUG",30:"INFO",40:"WARN",50:"ERROR",60:"FATAL"},St=Tt({level:process.env.LOG_LEVEL||"warn",base:{service:"liquid-shadow"},formatters:{level(n,e){return{level:n,severity:Rt[e]??"INFO"}}},transport:{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",destination:2,levelKey:"severity",messageKey:"message"}}}),p=St});import{fileURLToPath as zt}from"node:url";import{dirname as ge,join as $e,resolve as Yt}from"node:path";import{existsSync as Kt}from"node:fs";function Gt(){let n=Ue;for(;n!==ge(n);){if(Kt($e(n,"package.json")))return n;n=ge(n)}return Yt(Ue,"..","..")}function Be(...n){return $e(Gt(),...n)}var qt,Ue,je=K(()=>{"use strict";qt=zt(import.meta.url),Ue=ge(qt)});import{Worker as Vt}from"node:worker_threads";import{cpus as Jt}from"node:os";import{fileURLToPath as Qt}from"node:url";import{dirname as Xt,join as ze}from"node:path";import{existsSync as Ye}from"node:fs";function Zt(){if(qe.endsWith(".ts")){let e=ze(Ke,"worker.ts");if(Ye(e))return e}let n=ze(Ke,"worker.js");return Ye(n)?n:Be("dist/logic/domain/embeddings/worker.js")}function Z(n){return F||(F=new P(n)),F}async function Ge(){F&&(await F.shutdown(),F=null)}var qe,Ke,P,F,Ve=K(()=>{"use strict";D();je();qe=Qt(import.meta.url),Ke=Xt(qe);P=class{workers=[];taskQueue=[];pendingTasks=new Map;taskIdCounter=0;initialized=!1;initPromise;shutdownRequested=!1;numWorkers;cacheDir;initTimeout;constructor(e={}){this.numWorkers=e.numWorkers??Math.max(1,Math.min(2,Jt().length-1)),this.cacheDir=e.cacheDir??"./.cache",this.initTimeout=e.initTimeout??6e4}async initialize(){if(!this.initialized)return this.initPromise?this.initPromise:(this.initPromise=this._doInitialize(),this.initPromise)}async _doInitialize(){let e;try{p.info({numWorkers:this.numWorkers},"Initializing embedding worker pool");let t=new Promise((i,s)=>{e=setTimeout(()=>s(new Error(`Worker pool initialization timed out after ${this.initTimeout}ms`)),this.initTimeout)});if(await Promise.race([this._initializeWorkers(),t]),e&&clearTimeout(e),this.shutdownRequested){this.initialized=!1,this.initPromise=void 0,p.debug("Initialization completed but shutdown was requested");return}this.initialized=!0,p.info({numWorkers:this.workers.length},"Embedding worker pool ready")}catch(t){throw e&&clearTimeout(e),this.initPromise=void 0,this.initialized=!1,await this.shutdown(),t}}async _initializeWorkers(){let e=Zt();p.debug({workerPath:e},"Resolved worker path");let t=[];for(let i=0;i<this.numWorkers;i++)i>0&&await new Promise(s=>setTimeout(s,25)),t.push(this.createWorker(e,i));await Promise.all(t)}async createWorker(e,t){return new Promise((i,s)=>{let r=setTimeout(()=>{s(new Error(`Worker ${t} initialization timed out`))},this.initTimeout),l=new Vt(e,{workerData:{cacheDir:this.cacheDir},execArgv:process.execArgv}),c={worker:l,busy:!1,currentTaskId:null};l.on("message",a=>{if(a.type==="ready"){if(clearTimeout(r),this.shutdownRequested){p.debug({workerIndex:t},"Worker ready but shutdown requested, terminating"),l.terminate().catch(()=>{}),i();return}this.workers.push(c),p.debug({workerIndex:t},"Worker ready"),i()}else a.type==="result"&&a.id?this.handleTaskComplete(c,a.id,a.embeddings||[]):a.type==="error"&&a.id&&this.handleTaskError(c,a.id,new Error(a.error||"Unknown error"))}),l.on("error",a=>{if(clearTimeout(r),p.error({err:a,workerIndex:t},"Worker error"),c.currentTaskId&&this.handleTaskError(c,c.currentTaskId,a),!this.initialized){s(a);return}let o=this.workers.indexOf(c);o!==-1&&this.workers.splice(o,1),!this.shutdownRequested&&this.initialized&&this.createWorker(e,t).catch(u=>{p.error({err:u},"Failed to replace crashed worker")})}),l.on("exit",a=>{a!==0&&!this.shutdownRequested&&p.warn({workerIndex:t,code:a},"Worker exited unexpectedly")})})}handleTaskComplete(e,t,i){let s=this.pendingTasks.get(t);s&&(this.pendingTasks.delete(t),s.resolve(i)),e.busy=!1,e.currentTaskId=null,this.processQueue()}handleTaskError(e,t,i){let s=this.pendingTasks.get(t);s&&(this.pendingTasks.delete(t),s.reject(i)),e.busy=!1,e.currentTaskId=null,this.processQueue()}processQueue(){if(this.taskQueue.length===0)return;let e=this.workers.find(i=>!i.busy);if(!e)return;let t=this.taskQueue.shift();t&&(e.busy=!0,e.currentTaskId=t.id,this.pendingTasks.set(t.id,t),e.worker.postMessage({type:"embed",id:t.id,texts:t.texts}))}async generateEmbeddings(e,t=128,i){if(this.initialized||await this.initialize(),e.length===0)return[];let s=[];for(let o=0;o<e.length;o+=t)s.push(e.slice(o,o+t));let r=new Array(s.length),l=0,c=s.map((o,u)=>new Promise((d,m)=>{let h={id:`task_${++this.taskIdCounter}`,texts:o,resolve:S=>{if(r[u]=S,l++,i){let w=Math.min(l*t,e.length);i(w,e.length)}d()},reject:S=>{if(r[u]=new Array(o.length).fill(null),l++,p.warn({err:S,chunkIndex:u},"Chunk embedding failed"),i){let w=Math.min(l*t,e.length);i(w,e.length)}d()}};this.taskQueue.push(h),this.processQueue()}));await Promise.all(c);let a=[];for(let o of r)a.push(...o);return p.info({total:e.length,successful:a.filter(o=>o!==null).length,workers:this.workers.length},"Parallel embedding generation complete"),a}get workerCount(){return this.workers.length}get busyWorkers(){return this.workers.filter(e=>e.busy).length}get queueSize(){return this.taskQueue.length}get isInitialized(){return this.initialized}async shutdown(){if(this.shutdownRequested=!0,this.initPromise)try{await this.initPromise}catch{}if(!this.initialized&&this.workers.length===0){this.shutdownRequested=!1,this.initPromise=void 0;return}p.info({numWorkers:this.workers.length},"Shutting down embedding worker pool");let e=this.workers.map(t=>new Promise(i=>{t.worker.postMessage({type:"shutdown"}),t.worker.once("exit",()=>i()),setTimeout(()=>{t.worker.terminate().then(()=>i())},5e3)}));await Promise.all(e),this.workers=[],this.taskQueue=[],this.pendingTasks.clear(),this.initialized=!1,this.shutdownRequested=!1,p.info("Embedding worker pool shutdown complete")}},F=null});var x={};yt(x,{EmbeddingPriorityQueue:()=>_e,EmbeddingWorkerPool:()=>P,cosineSimilarity:()=>ri,generateEmbedding:()=>ni,generateEmbeddingsBatch:()=>si,getDefaultPool:()=>Z,setUseWorkerThreads:()=>ti,shutdownDefaultPool:()=>Ge});async function ei(){return U||(U=await import("@xenova/transformers"),U.env.cacheDir="./.cache",U.env.allowLocalModels=!0),U}function ti(n){be=n,p.info({useWorkerThreads:n},"Worker thread mode updated")}function Je(n=!1){let e=($||"").toLowerCase(),t={};return $&&(t.dtype=$),n?(t.quantized=!1,t):(e==="fp32"||e==="fp16"||e==="float32"||e==="float16"?t.quantized=!1:e.startsWith("q")&&(t.quantized=!0),t)}async function ii(){p.info({model:ee,dtype:$},"Loading embedding model...");let{pipeline:n}=await ei(),e=Je(!1);try{return await n("feature-extraction",ee,e)}catch(t){let i=t?.message||"";if(!(i.includes("/onnx/model_quantized.onnx")||i.includes("model_quantized.onnx")))throw t;return p.warn({model:ee,dtype:$},"Quantized ONNX artifact missing, retrying with unquantized ONNX"),await n("feature-extraction",ee,Je(!0))}}async function Xe(){return Ee||(Ee=ii()),Ee}async function ni(n){try{let t=await(await Xe())(n,{pooling:"mean",normalize:!0});return Array.from(t.data)}catch(e){return p.error({err:e},"Failed to generate embedding"),null}}async function si(n,e=Qe,t){return n.length===0?[]:be?Z().generateEmbeddings(n,e,t):Ze(n,e,t)}async function Ze(n,e,t){let i=new Array(n.length).fill(null),s=await Xe();for(let r=0;r<n.length;r+=e){let l=Math.min(r+e,n.length),c=n.slice(r,l);try{let a=await s(c,{pooling:"mean",normalize:!0}),[o,u]=a.dims;for(let d=0;d<o;d++){let m=d*u,b=m+u;i[r+d]=Array.from(a.data.slice(m,b))}}catch(a){p.error({err:a,batchStart:r,batchEnd:l},"Single-threaded batch embedding failed, falling back to sequential for this chunk");for(let o=0;o<c.length;o++)try{let u=c[o];if(!u||u.trim().length===0)continue;let d=await s(u,{pooling:"mean",normalize:!0});i[r+o]=Array.from(d.data)}catch{i[r+o]=null}}t&&t(l,n.length)}return p.debug({total:n.length,successful:i.filter(r=>r!==null).length},"Batch embedding complete"),i}function ri(n,e){let t=0,i=0,s=0;for(let r=0;r<n.length;r++)t+=n[r]*e[r],i+=n[r]*n[r],s+=e[r]*e[r];return t/(Math.sqrt(i)*Math.sqrt(s))}var ee,$,U,Qe,be,Ee,_e,v=K(()=>{"use strict";D();Ve();ee=process.env.EMBEDDING_MODEL??"Xenova/all-MiniLM-L6-v2",$=process.env.EMBEDDING_DTYPE??"fp32",U=null;Qe=128,be=!1;Ee=null;_e=class{queue=[];processing=!1;results=new Map;enqueue(e){this.queue.push(e),this.queue.sort((t,i)=>i.priority-t.priority)}enqueueMany(e){this.queue.push(...e),this.queue.sort((t,i)=>i.priority-t.priority)}get size(){return this.queue.length}get isProcessing(){return this.processing}getResult(e){return this.results.get(e)}async processQueue(e=Qe,t){if(this.processing)return p.warn("Queue processing already in progress"),this.results;this.processing=!0;let i=this.queue.length;try{be?await this.processQueueParallel(e,i,t):await this.processQueueSequential(e,i,t)}finally{this.processing=!1}return this.results}async processQueueSequential(e,t,i){for(;this.queue.length>0;){let s=this.queue.splice(0,e),r=s.map(c=>c.text),l=await Ze(r,r.length);if(s.forEach((c,a)=>{this.results.set(c.id,l[a])}),i){let c=t-this.queue.length;i(c,t)}}}async processQueueParallel(e,t,i){let s=this.queue.splice(0),r=s.map(a=>a.text),c=await Z().generateEmbeddings(r,e,(a,o)=>{i&&i(a,o)});s.forEach((a,o)=>{this.results.set(a.id,c[o])})}clear(){this.queue=[],this.results.clear()}}});import Te from"node:os";import{spawn as oi}from"node:child_process";D();import Mt from"better-sqlite3";import G from"path";import De from"fs";import Dt from"crypto";D();import C from"fs";import q from"path";import{fileURLToPath as Lt}from"url";var L=p.child({module:"migrations"}),Nt=Lt(import.meta.url),Ot=q.dirname(Nt);function It(){let n=Ot;if(C.readdirSync(n).some(i=>i.match(/^\d{3}_.*\.sql$/)))return n;let t=q.resolve(n,"../../data/migrations");return C.existsSync(t)&&C.readdirSync(t).some(i=>i.match(/^\d{3}_.*\.sql$/))?t:n}function wt(n){n.exec(`
|
|
1
|
+
var bt=Object.defineProperty;var K=(n,e)=>()=>(n&&(e=n(n=0)),e);var yt=(n,e)=>{for(var t in e)bt(n,t,{get:e[t],enumerable:!0})};import Tt from"pino";var Rt,St,p,D=K(()=>{"use strict";Rt={10:"TRACE",20:"DEBUG",30:"INFO",40:"WARN",50:"ERROR",60:"FATAL"},St=Tt({level:process.env.LOG_LEVEL||"warn",base:{service:"liquid-shadow"},formatters:{level(n,e){return{level:n,severity:Rt[e]??"INFO"}}},transport:{target:"pino-pretty",options:{colorize:!0,translateTime:"HH:MM:ss",destination:2,levelKey:"severity",messageKey:"message"}}}),p=St});import{existsSync as zt}from"node:fs";import{dirname as ge,join as $e,resolve as Yt}from"node:path";import{fileURLToPath as Kt}from"node:url";function Gt(){let n=Ue;for(;n!==ge(n);){if(zt($e(n,"package.json")))return n;n=ge(n)}return Yt(Ue,"..","..")}function Be(...n){return $e(Gt(),...n)}var qt,Ue,je=K(()=>{"use strict";qt=Kt(import.meta.url),Ue=ge(qt)});import{existsSync as ze}from"node:fs";import{cpus as Vt}from"node:os";import{dirname as Jt,join as Ye}from"node:path";import{fileURLToPath as Qt}from"node:url";import{Worker as Xt}from"node:worker_threads";function Zt(){if(qe.endsWith(".ts")){let e=Ye(Ke,"worker.ts");if(ze(e))return e}let n=Ye(Ke,"worker.js");return ze(n)?n:Be("dist/logic/domain/embeddings/worker.js")}function ne(n){return F||(F=new P(n)),F}async function Ge(){F&&(await F.shutdown(),F=null)}var qe,Ke,P,F,Ve=K(()=>{"use strict";je();D();qe=Qt(import.meta.url),Ke=Jt(qe);P=class{workers=[];taskQueue=[];pendingTasks=new Map;taskIdCounter=0;initialized=!1;initPromise;shutdownRequested=!1;numWorkers;cacheDir;initTimeout;constructor(e={}){this.numWorkers=e.numWorkers??Math.max(1,Math.min(2,Vt().length-1)),this.cacheDir=e.cacheDir??"./.cache",this.initTimeout=e.initTimeout??6e4}async initialize(){if(!this.initialized)return this.initPromise?this.initPromise:(this.initPromise=this._doInitialize(),this.initPromise)}async _doInitialize(){let e;try{p.info({numWorkers:this.numWorkers},"Initializing embedding worker pool");let t=new Promise((i,s)=>{e=setTimeout(()=>s(new Error(`Worker pool initialization timed out after ${this.initTimeout}ms`)),this.initTimeout)});if(await Promise.race([this._initializeWorkers(),t]),e&&clearTimeout(e),this.shutdownRequested){this.initialized=!1,this.initPromise=void 0,p.debug("Initialization completed but shutdown was requested");return}this.initialized=!0,p.info({numWorkers:this.workers.length},"Embedding worker pool ready")}catch(t){throw e&&clearTimeout(e),this.initPromise=void 0,this.initialized=!1,await this.shutdown(),t}}async _initializeWorkers(){let e=Zt();p.debug({workerPath:e},"Resolved worker path");let t=[];for(let i=0;i<this.numWorkers;i++)i>0&&await new Promise(s=>setTimeout(s,25)),t.push(this.createWorker(e,i));await Promise.all(t)}async createWorker(e,t){return new Promise((i,s)=>{let r=setTimeout(()=>{s(new Error(`Worker ${t} initialization timed out`))},this.initTimeout),l=new Xt(e,{workerData:{cacheDir:this.cacheDir},execArgv:process.execArgv}),c={worker:l,busy:!1,currentTaskId:null};l.on("message",a=>{if(a.type==="ready"){if(clearTimeout(r),this.shutdownRequested){p.debug({workerIndex:t},"Worker ready but shutdown requested, terminating"),l.terminate().catch(()=>{}),i();return}this.workers.push(c),p.debug({workerIndex:t},"Worker ready"),i()}else a.type==="result"&&a.id?this.handleTaskComplete(c,a.id,a.embeddings||[]):a.type==="error"&&a.id&&this.handleTaskError(c,a.id,new Error(a.error||"Unknown error"))}),l.on("error",a=>{if(clearTimeout(r),p.error({err:a,workerIndex:t},"Worker error"),c.currentTaskId&&this.handleTaskError(c,c.currentTaskId,a),!this.initialized){s(a);return}let o=this.workers.indexOf(c);o!==-1&&this.workers.splice(o,1),!this.shutdownRequested&&this.initialized&&this.createWorker(e,t).catch(u=>{p.error({err:u},"Failed to replace crashed worker")})}),l.on("exit",a=>{a!==0&&!this.shutdownRequested&&p.warn({workerIndex:t,code:a},"Worker exited unexpectedly")})})}handleTaskComplete(e,t,i){let s=this.pendingTasks.get(t);s&&(this.pendingTasks.delete(t),s.resolve(i)),e.busy=!1,e.currentTaskId=null,this.processQueue()}handleTaskError(e,t,i){let s=this.pendingTasks.get(t);s&&(this.pendingTasks.delete(t),s.reject(i)),e.busy=!1,e.currentTaskId=null,this.processQueue()}processQueue(){if(this.taskQueue.length===0)return;let e=this.workers.find(i=>!i.busy);if(!e)return;let t=this.taskQueue.shift();t&&(e.busy=!0,e.currentTaskId=t.id,this.pendingTasks.set(t.id,t),e.worker.postMessage({type:"embed",id:t.id,texts:t.texts}))}async generateEmbeddings(e,t=128,i){if(this.initialized||await this.initialize(),e.length===0)return[];let s=[];for(let o=0;o<e.length;o+=t)s.push(e.slice(o,o+t));let r=new Array(s.length),l=0,c=s.map((o,u)=>new Promise((d,m)=>{let h={id:`task_${++this.taskIdCounter}`,texts:o,resolve:S=>{if(r[u]=S,l++,i){let C=Math.min(l*t,e.length);i(C,e.length)}d()},reject:S=>{if(r[u]=new Array(o.length).fill(null),l++,p.warn({err:S,chunkIndex:u},"Chunk embedding failed"),i){let C=Math.min(l*t,e.length);i(C,e.length)}d()}};this.taskQueue.push(h),this.processQueue()}));await Promise.all(c);let a=[];for(let o of r)a.push(...o);return p.info({total:e.length,successful:a.filter(o=>o!==null).length,workers:this.workers.length},"Parallel embedding generation complete"),a}get workerCount(){return this.workers.length}get busyWorkers(){return this.workers.filter(e=>e.busy).length}get queueSize(){return this.taskQueue.length}get isInitialized(){return this.initialized}async shutdown(){if(this.shutdownRequested=!0,this.initPromise)try{await this.initPromise}catch{}if(!this.initialized&&this.workers.length===0){this.shutdownRequested=!1,this.initPromise=void 0;return}p.info({numWorkers:this.workers.length},"Shutting down embedding worker pool");let e=this.workers.map(t=>new Promise(i=>{t.worker.postMessage({type:"shutdown"}),t.worker.once("exit",()=>i()),setTimeout(()=>{t.worker.terminate().then(()=>i())},5e3)}));await Promise.all(e),this.workers=[],this.taskQueue=[],this.pendingTasks.clear(),this.initialized=!1,this.shutdownRequested=!1,p.info("Embedding worker pool shutdown complete")}},F=null});var x={};yt(x,{EmbeddingPriorityQueue:()=>_e,EmbeddingWorkerPool:()=>P,cosineSimilarity:()=>ri,generateEmbedding:()=>ni,generateEmbeddingsBatch:()=>si,getDefaultPool:()=>ne,setUseWorkerThreads:()=>ti,shutdownDefaultPool:()=>Ge});async function ei(){return U||(U=await import("@xenova/transformers"),U.env.cacheDir="./.cache",U.env.allowLocalModels=!0),U}function ti(n){be=n,p.info({useWorkerThreads:n},"Worker thread mode updated")}function Je(n=!1){let e=($||"").toLowerCase(),t={};return $&&(t.dtype=$),n?(t.quantized=!1,t):(e==="fp32"||e==="fp16"||e==="float32"||e==="float16"?t.quantized=!1:e.startsWith("q")&&(t.quantized=!0),t)}async function ii(){p.info({model:se,dtype:$},"Loading embedding model...");let{pipeline:n}=await ei(),e=Je(!1);try{return await n("feature-extraction",se,e)}catch(t){let i=t?.message||"";if(!(i.includes("/onnx/model_quantized.onnx")||i.includes("model_quantized.onnx")))throw t;return p.warn({model:se,dtype:$},"Quantized ONNX artifact missing, retrying with unquantized ONNX"),await n("feature-extraction",se,Je(!0))}}async function Xe(){return Ee||(Ee=ii()),Ee}async function ni(n){try{let t=await(await Xe())(n,{pooling:"mean",normalize:!0});return Array.from(t.data)}catch(e){return p.error({err:e},"Failed to generate embedding"),null}}async function si(n,e=Qe,t){return n.length===0?[]:be?ne().generateEmbeddings(n,e,t):Ze(n,e,t)}async function Ze(n,e,t){let i=new Array(n.length).fill(null),s=await Xe();for(let r=0;r<n.length;r+=e){let l=Math.min(r+e,n.length),c=n.slice(r,l);try{let a=await s(c,{pooling:"mean",normalize:!0}),[o,u]=a.dims;for(let d=0;d<o;d++){let m=d*u,b=m+u;i[r+d]=Array.from(a.data.slice(m,b))}}catch(a){p.error({err:a,batchStart:r,batchEnd:l},"Single-threaded batch embedding failed, falling back to sequential for this chunk");for(let o=0;o<c.length;o++)try{let u=c[o];if(!u||u.trim().length===0)continue;let d=await s(u,{pooling:"mean",normalize:!0});i[r+o]=Array.from(d.data)}catch{i[r+o]=null}}t&&t(l,n.length)}return p.debug({total:n.length,successful:i.filter(r=>r!==null).length},"Batch embedding complete"),i}function ri(n,e){let t=0,i=0,s=0;for(let r=0;r<n.length;r++)t+=n[r]*e[r],i+=n[r]*n[r],s+=e[r]*e[r];return t/(Math.sqrt(i)*Math.sqrt(s))}var se,$,U,Qe,be,Ee,_e,A=K(()=>{"use strict";D();Ve();se=process.env.EMBEDDING_MODEL??"Xenova/all-MiniLM-L6-v2",$=process.env.EMBEDDING_DTYPE??"fp32",U=null;Qe=128,be=!1;Ee=null;_e=class{queue=[];processing=!1;results=new Map;enqueue(e){this.queue.push(e),this.queue.sort((t,i)=>i.priority-t.priority)}enqueueMany(e){this.queue.push(...e),this.queue.sort((t,i)=>i.priority-t.priority)}get size(){return this.queue.length}get isProcessing(){return this.processing}getResult(e){return this.results.get(e)}async processQueue(e=Qe,t){if(this.processing)return p.warn("Queue processing already in progress"),this.results;this.processing=!0;let i=this.queue.length;try{be?await this.processQueueParallel(e,i,t):await this.processQueueSequential(e,i,t)}finally{this.processing=!1}return this.results}async processQueueSequential(e,t,i){for(;this.queue.length>0;){let s=this.queue.splice(0,e),r=s.map(c=>c.text),l=await Ze(r,r.length);if(s.forEach((c,a)=>{this.results.set(c.id,l[a])}),i){let c=t-this.queue.length;i(c,t)}}}async processQueueParallel(e,t,i){let s=this.queue.splice(0),r=s.map(a=>a.text),c=await ne().generateEmbeddings(r,e,(a,o)=>{i&&i(a,o)});s.forEach((a,o)=>{this.results.set(a.id,c[o])})}clear(){this.queue=[],this.results.clear()}}});import{spawn as oi}from"node:child_process";import Te from"node:os";D();import Mt from"better-sqlite3";import Dt from"crypto";import De from"fs";import G from"path";D();import w from"fs";import q from"path";import{fileURLToPath as Lt}from"url";var L=p.child({module:"migrations"}),Nt=Lt(import.meta.url),It=q.dirname(Nt);function Ot(){let n=It;if(w.readdirSync(n).some(i=>i.match(/^\d{3}_.*\.sql$/)))return n;let t=q.resolve(n,"../../data/migrations");return w.existsSync(t)&&w.readdirSync(t).some(i=>i.match(/^\d{3}_.*\.sql$/))?t:n}function Ct(n){n.exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
3
3
|
version INTEGER PRIMARY KEY,
|
|
4
4
|
name TEXT NOT NULL,
|
|
5
5
|
applied_at REAL DEFAULT (unixepoch())
|
|
6
6
|
);
|
|
7
|
-
`)}function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
`,`${s}%`,i)}findWithEmbeddings(){return this.all("SELECT * FROM files WHERE embedding IS NOT NULL")}findFts(e,t=10){return this.all(`
|
|
12
|
-
SELECT files.*, files_fts.rank
|
|
13
|
-
FROM files_fts
|
|
14
|
-
JOIN files ON files.rowid = files_fts.rowid
|
|
15
|
-
WHERE files_fts MATCH ?
|
|
16
|
-
ORDER BY rank
|
|
17
|
-
LIMIT ?
|
|
18
|
-
`,e,t)}findByPathKeywords(e,t=10){let i=e.map(()=>"LOWER(path) LIKE ?").join(" OR ");return this.all(`
|
|
19
|
-
SELECT * FROM files
|
|
20
|
-
WHERE ${i}
|
|
21
|
-
LIMIT ?
|
|
22
|
-
`,...e.map(s=>`%${s}%`),t)}findContentFts(e,t=50){let i=this.buildContentFtsQuery(e);return i?this.all(`
|
|
7
|
+
`)}function wt(n){Ct(n);let e=n.prepare("SELECT version FROM schema_migrations ORDER BY version").all();return new Set(e.map(t=>t.version))}function xt(n){return w.readdirSync(n).filter(t=>t.match(/^\d{3}_.*\.sql$/)&&!t.startsWith("000_")).sort().map(t=>{let i=t.match(/^(\d{3})_(.+)\.sql$/),s=parseInt(i[1],10),r=i[2],c=w.readFileSync(q.join(n,t),"utf-8").split(/^-- DOWN$/m);return{version:s,name:r,up:c[0].trim(),down:c[1]?.trim()}})}function At(n,e){L.info({version:e.version,name:e.name},"Applying migration"),n.transaction(()=>{n.exec(e.up),n.prepare("INSERT INTO schema_migrations (version, name) VALUES (?, ?)").run(e.version,e.name)})(),L.info({version:e.version},"Migration applied successfully")}function vt(n,e,t){let i=q.join(e,"000_baseline.sql");if(!w.existsSync(i)){L.warn("000_baseline.sql not found \u2014 falling back to incremental migrations");return}L.info("Fresh database detected \u2014 applying consolidated baseline schema");let s=w.readFileSync(i,"utf-8");n.transaction(()=>{n.exec(s);let r=n.prepare("INSERT OR IGNORE INTO schema_migrations (version, name) VALUES (?, ?)");for(let l of t)r.run(l.version,l.name)})(),L.info({stamped:t.length},"Baseline applied \u2014 incremental migrations stamped")}function Me(n){let e=wt(n),t=Ot(),i=xt(t);if(e.size===0){vt(n,t,i);return}let s=i.filter(r=>!e.has(r.version));if(s.length===0){L.debug("No pending migrations");return}L.info({count:s.length},"Running pending migrations");for(let r of s)At(n,r);L.info("All migrations complete")}import kt from"os";var k=p.child({module:"db"});function he(n){let e=kt.homedir(),t=G.join(e,".mcp-liquid-shadow"),i=G.join(t,"dbs");De.existsSync(i)||De.mkdirSync(i,{recursive:!0});let s=Dt.createHash("sha256").update(n).digest("hex").substring(0,12),l=`${G.basename(n).replace(/[^a-zA-Z0-9-_]/g,"_")}_${s}.db`;return G.join(i,l)}function Ft(n,e){let t=e||he(n);k.debug({repoPath:n,dbPath:t},"Initializing database");let i=new Mt(t);return i.pragma("journal_mode = WAL"),i.pragma("busy_timeout = 5000"),Me(i),V.set(n,t),N.set(t,i),k.debug({repoPath:n,dbPath:t},"Database initialized successfully"),i}var N=new Map,V=new Map;function H(n){let e=V.get(n)||he(n),t=N.get(e);if(t){if(t.open)return t;N.delete(e)}let i=Ft(n);return N.set(e,i),i}function ke(n){let e=V.get(n)||he(n),t=N.get(e);t&&(t.open&&(k.debug({repoPath:n,dbPath:e},"Closing database connection"),t.close()),N.delete(e)),V.delete(n)}function Fe(){for(let[n,e]of N.entries())try{e.open&&(k.debug({dbPath:n},"Closing database connection"),e.close())}catch(t){k.error({dbPath:n,err:t},"Error closing database execution")}N.clear()}process.on("exit",()=>Fe());var We=n=>{k.debug({signal:n},"Received termination signal, closing databases"),Fe(),process.exit(0)};process.on("SIGINT",()=>We("SIGINT"));process.on("SIGTERM",()=>We("SIGTERM"));var f=class{db;constructor(e){this.db=e}get database(){return this.db}all(e,...t){return this.db.prepare(e).all(...t)}get(e,...t){return this.db.prepare(e).get(...t)}run(e,...t){return this.db.prepare(e).run(...t).changes}insert(e,...t){return this.db.prepare(e).run(...t).lastInsertRowid}transaction(e){return this.db.transaction(e)()}};var J=class extends f{claimFile(e,t){try{this.run(`
|
|
8
|
+
INSERT INTO file_claims (file_path, mission_id, claimed_at, updated_at)
|
|
9
|
+
VALUES (?, ?, unixepoch(), unixepoch())
|
|
10
|
+
`,e,t);let i=this.getClaim(e);if(!i)throw new Error(`Failed to hydrate claim after insert for file ${e}`);return{status:"claimed",claim:i}}catch{let i=this.getClaim(e);if(!i)throw new Error(`Failed to read existing claim for file ${e}`);return i.mission_id===t?(this.run("UPDATE file_claims SET updated_at = unixepoch() WHERE file_path = ?",e),{status:"already_claimed",claim:this.getClaim(e)??i}):{status:"conflict",claim:i}}}releaseFile(e,t){let i=this.getClaim(e);return i?t!==void 0&&i.mission_id!==t?{released:!1,reason:"not_owner",claim:i}:(this.run("DELETE FROM file_claims WHERE file_path = ?",e),{released:!0}):{released:!1,reason:"not_found"}}releaseAllForMission(e){return this.run("DELETE FROM file_claims WHERE mission_id = ?",e)}getClaim(e){return this.get(`
|
|
23
11
|
SELECT
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
fc.file_path,
|
|
13
|
+
fc.mission_id,
|
|
14
|
+
fc.claimed_at,
|
|
15
|
+
fc.updated_at,
|
|
16
|
+
m.name AS mission_name,
|
|
17
|
+
m.status AS mission_status,
|
|
18
|
+
m.git_branch AS mission_branch
|
|
19
|
+
FROM file_claims fc
|
|
20
|
+
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
21
|
+
WHERE fc.file_path = ?
|
|
22
|
+
`,e)}getClaimsForMission(e){return this.all(`
|
|
23
|
+
SELECT
|
|
24
|
+
fc.file_path,
|
|
25
|
+
fc.mission_id,
|
|
26
|
+
fc.claimed_at,
|
|
27
|
+
fc.updated_at,
|
|
28
|
+
m.name AS mission_name,
|
|
29
|
+
m.status AS mission_status,
|
|
30
|
+
m.git_branch AS mission_branch
|
|
31
|
+
FROM file_claims fc
|
|
32
|
+
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
33
|
+
WHERE fc.mission_id = ?
|
|
34
|
+
ORDER BY fc.file_path ASC
|
|
35
|
+
`,e)}listClaims(){return this.all(`
|
|
36
|
+
SELECT
|
|
37
|
+
fc.file_path,
|
|
38
|
+
fc.mission_id,
|
|
39
|
+
fc.claimed_at,
|
|
40
|
+
fc.updated_at,
|
|
41
|
+
m.name AS mission_name,
|
|
42
|
+
m.status AS mission_status,
|
|
43
|
+
m.git_branch AS mission_branch
|
|
44
|
+
FROM file_claims fc
|
|
45
|
+
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
46
|
+
ORDER BY fc.updated_at DESC, fc.file_path ASC
|
|
47
|
+
`)}getClaimsByFiles(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.all(`
|
|
48
|
+
SELECT
|
|
49
|
+
fc.file_path,
|
|
50
|
+
fc.mission_id,
|
|
51
|
+
fc.claimed_at,
|
|
52
|
+
fc.updated_at,
|
|
53
|
+
m.name AS mission_name,
|
|
54
|
+
m.status AS mission_status,
|
|
55
|
+
m.git_branch AS mission_branch
|
|
56
|
+
FROM file_claims fc
|
|
57
|
+
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
58
|
+
WHERE fc.file_path IN (${t})
|
|
59
|
+
ORDER BY fc.file_path ASC
|
|
60
|
+
`,...e)}};var Q=class extends f{findByKey(e,t=20){return this.all(`
|
|
61
|
+
SELECT file_path, key, value, kind
|
|
62
|
+
FROM configs
|
|
63
|
+
WHERE key LIKE ? OR value LIKE ?
|
|
64
|
+
LIMIT ?
|
|
65
|
+
`,`%${e}%`,`%${e}%`,t)}findByKind(e,t=50){let i="SELECT key, value, kind, file_path FROM configs",s=[];return e&&(i+=" WHERE kind = ?",s.push(e)),i+=" LIMIT ?",s.push(t),this.all(i,...s)}findEnvValue(e){return this.get("SELECT value FROM configs WHERE key LIKE ? OR key = ? LIMIT 1",`%:env:${e}`,e)?.value}countByKind(e){return this.get("SELECT COUNT(*) as count FROM configs WHERE kind = ?",e)?.count||0}getAll(){return this.all("SELECT key, value, kind, file_path FROM configs")}};var X=class extends f{search(e,t=10){return this.all(`
|
|
66
|
+
SELECT file_path, snippet(content_fts, 1, '<b>', '</b>', '...', 20) as snippet
|
|
26
67
|
FROM content_fts
|
|
27
|
-
JOIN files ON files.path = content_fts.file_path
|
|
28
68
|
WHERE content_fts MATCH ?
|
|
29
|
-
ORDER BY bm25_rank ASC
|
|
30
69
|
LIMIT ?
|
|
31
|
-
|
|
32
|
-
SELECT file_path
|
|
33
|
-
FROM content_fts
|
|
34
|
-
WHERE content_fts MATCH ?
|
|
35
|
-
AND (file_path LIKE '%.ts' OR file_path LIKE '%.tsx' OR file_path LIKE '%.js' OR file_path LIKE '%.py' OR file_path LIKE '%.php')
|
|
36
|
-
AND file_path NOT LIKE '%/test/%'
|
|
37
|
-
AND file_path NOT LIKE '%.spec.%'
|
|
38
|
-
LIMIT ?
|
|
39
|
-
`,`"${e.replace(/[^a-zA-Z0-9_\/]/g," ")}"`,t).map(s=>s.file_path)}findSynapses(e){let t="SELECT * FROM event_synapses WHERE 1=1",i=[];if(e.type&&(t+=" AND type = ?",i.push(e.type)),e.name){let s=e.name;s.startsWith("/")&&(s=s.substring(1)),s.endsWith("/")&&(s=s.substring(0,s.length-1)),s.length>0&&(t+=" AND (name LIKE ? OR name LIKE ? OR name = ?)",i.push(`${s}%`),i.push(`%/${s}%`),i.push(e.name))}return e.direction&&(t+=" AND direction = ?",i.push(e.direction)),t+=` LIMIT ${e.limit||50}`,this.all(t,...i)}exists(e){return!!this.get("SELECT 1 FROM files WHERE path = ?",e)}update(e,t){let i=Object.keys(t);if(i.length===0)return;let s=i.map(l=>`${l} = ?`).join(", "),r=Object.values(t);r.push(e),this.run(`UPDATE files SET ${s} WHERE path = ?`,...r)}getStats(){let e=this.get(`
|
|
40
|
-
SELECT
|
|
41
|
-
COUNT(*) as total,
|
|
42
|
-
SUM(CASE WHEN summary IS NOT NULL AND summary != '' THEN 1 ELSE 0 END) as withSummary
|
|
43
|
-
FROM files
|
|
44
|
-
`);return{total:e?.total||0,withSummary:e?.withSummary||0}}getGravityMap(e=[],t){let i={},s=`
|
|
45
|
-
SELECT ws.file_path, m.name as mission_name, m.status
|
|
46
|
-
FROM working_set ws
|
|
47
|
-
JOIN missions m ON ws.mission_id = m.id
|
|
48
|
-
WHERE (
|
|
49
|
-
(m.status IN ('in-progress', 'verifying') ${t?"AND m.git_branch = ?":""})
|
|
50
|
-
OR m.id IN (${e.length>0?e.join(","):"-1"})
|
|
51
|
-
)
|
|
52
|
-
AND ws.file_path IS NOT NULL
|
|
53
|
-
`,r=[];t&&r.push(t);let l=this.all(s,...r);for(let o of l){i[o.file_path]||(i[o.file_path]={score:1,reasons:[]});let u=o.status==="in-progress"||o.status==="verifying"?1:.5;i[o.file_path].score+=u;let d=o.status==="in-progress"||o.status==="verifying"?"Working Set":"Lineage Bleed";i[o.file_path].reasons.push(`${d}: ${o.mission_name}`)}let c=Math.floor(Date.now()/1e3)-86400,a=this.all(`
|
|
54
|
-
SELECT file_path, type, mission_id
|
|
55
|
-
FROM intent_logs
|
|
56
|
-
WHERE (created_at > ? OR mission_id IN (${e.length>0?e.join(","):"-1"}))
|
|
57
|
-
AND file_path IS NOT NULL
|
|
58
|
-
ORDER BY created_at DESC
|
|
59
|
-
LIMIT 100
|
|
60
|
-
`,c);for(let o of a){i[o.file_path]||(i[o.file_path]={score:1,reasons:[]});let u=o.mission_id?e.includes(o.mission_id):!1,d=u?.1:.2;i[o.file_path].score<5&&(i[o.file_path].score+=d);let m=u?`Lineage Intent: ${o.type}`:`Recent Intent: ${o.type}`;!i[o.file_path].reasons.includes(m)&&i[o.file_path].reasons.length<5&&i[o.file_path].reasons.push(m)}return i}getCount(){return this.get("SELECT COUNT(*) as count FROM files")?.count||0}getTopDirectories(e,t=8){return this.all(`
|
|
61
|
-
SELECT
|
|
62
|
-
SUBSTR(path, LENGTH(?) + 2,
|
|
63
|
-
INSTR(SUBSTR(path, LENGTH(?) + 2), '/') - 1
|
|
64
|
-
) as root,
|
|
65
|
-
COUNT(*) as total_files,
|
|
66
|
-
SUM(CASE
|
|
67
|
-
WHEN path LIKE '%.ts' OR path LIKE '%.tsx'
|
|
68
|
-
OR path LIKE '%.js' OR path LIKE '%.jsx'
|
|
69
|
-
OR path LIKE '%.mjs' OR path LIKE '%.cjs'
|
|
70
|
-
THEN 1 ELSE 0
|
|
71
|
-
END) as ts_files
|
|
72
|
-
FROM files
|
|
73
|
-
WHERE path LIKE ? || '/%/%'
|
|
74
|
-
GROUP BY root
|
|
75
|
-
ORDER BY total_files DESC
|
|
76
|
-
LIMIT ?
|
|
77
|
-
`,e,e,e,t)}hasFilesPattern(e){return!!this.get("SELECT 1 FROM files WHERE path LIKE ? LIMIT 1",e)}findPackageJsonChildren(e){return this.all(`
|
|
78
|
-
SELECT
|
|
79
|
-
path,
|
|
80
|
-
SUBSTR(path, LENGTH(?) + 2) as relPath
|
|
81
|
-
FROM files
|
|
82
|
-
WHERE path LIKE ? || '/%/package.json'
|
|
83
|
-
`,e,e)}deletePaths(e){if(e.length===0)return;let t=this.db.prepare("DELETE FROM files WHERE path = ?");this.db.transaction(s=>{for(let r of s)t.run(r)})(e)}updateMtime(e,t){this.run("UPDATE files SET mtime = ? WHERE path = ?",t,e)}batchSaveIndexResults(e,t,i,s){let r=this.db.prepare("DELETE FROM exports WHERE file_path = ?"),l=this.db.prepare("DELETE FROM imports WHERE file_path = ?"),c=this.db.prepare("DELETE FROM configs WHERE file_path = ?"),a=this.db.prepare("DELETE FROM file_content WHERE file_path = ?"),o=this.db.prepare("DELETE FROM event_synapses WHERE file_path = ?"),u=this.db.prepare("DELETE FROM type_graph_edges WHERE file_path = ?"),d=this.db.prepare("INSERT INTO exports (file_path, name, kind, signature, doc, start_line, end_line, classification, capabilities, parent_id, embedding) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),m=this.db.prepare("INSERT INTO imports (file_path, module_specifier, imported_symbols, resolved_path) VALUES (?, ?, ?, ?)"),b=this.db.prepare("INSERT INTO configs (file_path, key, value, kind) VALUES (?, ?, ?, ?)"),h=this.db.prepare("INSERT INTO file_content (file_path, content) VALUES (?, ?)"),S=this.db.prepare("INSERT INTO event_synapses (file_path, type, name, direction, line_number, code_snippet) VALUES (?, ?, ?, ?, ?, ?)"),w=this.db.prepare("INSERT INTO type_graph_edges (file_path, source_symbol_id, source_symbol_name, target_symbol_name, relationship, line_number, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)"),lt=this.db.prepare(`
|
|
84
|
-
INSERT INTO files (path, mtime, last_scanned_at, classification, summary, embedding, content_hash)
|
|
85
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
86
|
-
ON CONFLICT(path) DO UPDATE SET
|
|
87
|
-
mtime=excluded.mtime,
|
|
88
|
-
last_scanned_at=excluded.last_scanned_at,
|
|
89
|
-
classification=excluded.classification,
|
|
90
|
-
summary=excluded.summary,
|
|
91
|
-
embedding=excluded.embedding,
|
|
92
|
-
content_hash=excluded.content_hash
|
|
93
|
-
`),ct=this.db.transaction(M=>{for(let ut of M){let{meta:y,exports:Oe,imports:Ie,configs:we,events:Ce,content:z,classification:dt,summary:mt,embedding:xe,contentHash:pt}=ut;r.run(y.path),l.run(y.path),c.run(y.path),a.run(y.path),o.run(y.path),u.run(y.path);let ht=pt??(z&&i?i(z):null);if(lt.run(y.path,y.mtime,Date.now(),dt||"Unknown",mt||"",xe?JSON.stringify(xe):null,ht),Oe){let E=(W,ft,gt)=>{for(let _ of ft){let Et=_.embedding?JSON.stringify(_.embedding):null,ve=d.run(W,_.name,_.kind,_.signature,_.doc||"",_.line,_.endLine||_.line,_.classification||"Other",_.capabilities||"[]",gt,Et),Ae=Number(ve.lastInsertRowid);if(Number.isFinite(Ae)){let _t=He(_.signature);for(let Y of _t)Y.targetName!==_.name&&w.run(W,Ae,_.name,Y.targetName,Y.relationship,_.line,Y.metadata||null)}_.members&&_.members.length>0&&E(W,_.members,ve.lastInsertRowid)}};E(y.path,Oe,null)}if(Ie)for(let E of Ie){let W=E.resolved_path!==void 0?E.resolved_path:s?.(E.module,y.path,t)??"";m.run(y.path,E.module,E.name,W)}if(we)for(let E of we)b.run(y.path,E.key,E.value,E.kind);if(z!==void 0&&h.run(y.path,z),Ce)for(let E of Ce)S.run(y.path,E.type,E.name,E.direction,E.line,E.snippet)}}),Ne=500;for(let M=0;M<e.length;M+=Ne)ct(e.slice(M,M+Ne))}getLatestScanTime(){return this.get("SELECT MAX(last_scanned_at) as t FROM files")?.t||null}buildContentFtsQuery(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9_]+/).map(r=>r.trim()).filter(r=>r.length>=2).slice(0,12);if(t.length===0)return"";if(t.length===1)return`${t[0]}*`;let i=`"${t.join(" ")}"`,s=t.map(r=>`${r}*`).join(" OR ");return`${i} OR ${s}`}};var Q=class n extends f{static HTTP_METHOD_EXPORTS=new Set(["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]);findByNameAndFile(e,t){return this.all("SELECT * FROM exports WHERE file_path = ? AND name = ?",t,e)}findByNameGlobal(e){return this.all("SELECT * FROM exports WHERE name = ?",e)}findTopLevelByNameGlobal(e){return this.all("SELECT * FROM exports WHERE name = ? AND parent_id IS NULL",e)}findAtLine(e,t){return this.get(`
|
|
70
|
+
`,e,t)}};var Z=class n extends f{static HTTP_METHOD_EXPORTS=new Set(["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"]);findByNameAndFile(e,t){return this.all("SELECT * FROM exports WHERE file_path = ? AND name = ?",t,e)}findByNameGlobal(e){return this.all("SELECT * FROM exports WHERE name = ?",e)}findTopLevelByNameGlobal(e){return this.all("SELECT * FROM exports WHERE name = ? AND parent_id IS NULL",e)}findAtLine(e,t){return this.get(`
|
|
94
71
|
SELECT * FROM exports
|
|
95
72
|
WHERE file_path = ? AND start_line <= ? AND end_line >= ?
|
|
96
73
|
ORDER BY (end_line - start_line) ASC -- Get innermost symbol
|
|
@@ -208,7 +185,7 @@ var bt=Object.defineProperty;var K=(n,e)=>()=>(n&&(e=n(n=0)),e);var yt=(n,e)=>{f
|
|
|
208
185
|
AND NOT EXISTS (SELECT 1 FROM imports i WHERE i.resolved_path = e.file_path AND i.imported_symbols LIKE '%*%')
|
|
209
186
|
ORDER BY e.file_path, e.start_line
|
|
210
187
|
LIMIT ?
|
|
211
|
-
`,t*2).filter(h=>!this.isFrameworkEntrypointExport(h)).map(h=>{let{confidence:S,reason:
|
|
188
|
+
`,t*2).filter(h=>!this.isFrameworkEntrypointExport(h)).map(h=>{let{confidence:S,reason:C}=this.scoreDeadExportConfidence(h);return{...h,confidence:S,reason:C}}),b=m;return c==="high"?b=m.filter(h=>h.confidence==="high"):c==="medium"&&(b=m.filter(h=>h.confidence==="high"||h.confidence==="medium")),b.slice(0,t)}scoreDeadExportConfidence(e){let t=e.file_path.toLowerCase(),i=e.name;return t.includes("/index.")||t.endsWith("index.ts")||t.endsWith("index.js")?{confidence:"low",reason:"Barrel/index file - likely re-export"}:e.kind==="TsInterfaceDeclaration"||e.kind==="TsTypeAliasDeclaration"?{confidence:"medium",reason:"Type definition - may be used externally"}:t.includes("/entry/")||t.includes("/bin/")||t.includes("main.")||t.includes("server.")||t.includes("cli.")?{confidence:"medium",reason:"Entry point - may be invoked externally"}:(t.includes("/components/")||t.endsWith(".tsx")||t.endsWith(".jsx"))&&/^[A-Z][A-Za-z0-9_]*$/.test(i)?{confidence:"medium",reason:"Component export - may be used by runtime composition"}:(t.includes("/contexts/")||t.includes("/context/"))&&(/Provider$/.test(i)||i.startsWith("use"))?{confidence:"medium",reason:"Context/provider export - may be wired dynamically"}:i.startsWith("create")||i.endsWith("Factory")||i.endsWith("Builder")?{confidence:"medium",reason:"Factory/builder pattern - may be used dynamically"}:i.startsWith("use")&&i.length>3?{confidence:"medium",reason:"Hook pattern - may be used in components"}:{confidence:"high",reason:"No detected usage"}}isFrameworkEntrypointExport(e){let i=e.file_path.toLowerCase().replace(/\\/g,"/"),s=e.name;return!!(/(^|\/)(src\/)?app\/.*\/route\.(t|j)sx?$/.test(i)&&n.HTTP_METHOD_EXPORTS.has(s)||/(^|\/)(src\/)?app\/.*\/(page|layout|loading|error|not-found|default|template)\.(t|j)sx?$/.test(i)||/(^|\/)(src\/)?middleware\.(t|j)sx?$/.test(i)||i.includes("/app/exceptions/handler.php")||i.includes("/app/http/middleware/")||i.includes("/app/providers/")||i.includes("/app/console/commands/")||i.includes("/database/seeds/")||i.includes("/config/")&&i.endsWith(".php")||i.includes("/routes/")&&["loader","action","meta","headers"].includes(s))}getGravityMap(e=[],t){let i={},s=`
|
|
212
189
|
SELECT ws.symbol_id, m.name as mission_name, m.status
|
|
213
190
|
FROM working_set ws
|
|
214
191
|
JOIN missions m ON ws.mission_id = m.id
|
|
@@ -263,7 +240,99 @@ var bt=Object.defineProperty;var K=(n,e)=>()=>(n&&(e=n(n=0)),e);var yt=(n,e)=>{f
|
|
|
263
240
|
'inbound' AS direction
|
|
264
241
|
FROM type_graph_edges
|
|
265
242
|
WHERE target_symbol_name = ?
|
|
266
|
-
`,u=[e];r&&(o+=" AND relationship = ?",u.push(r)),o+=" ORDER BY file_path ASC, line_number ASC, source_symbol_name ASC LIMIT ?",u.push(c),a.push(...this.all(o,...u))}return a.slice(0,c)}findTypeGraphEdgesBySymbolId(e,t={}){let i=this.findById(e);return i?this.findTypeGraphEdges(i.name,{...t,filePath:i.file_path}):[]}};var
|
|
243
|
+
`,u=[e];r&&(o+=" AND relationship = ?",u.push(r)),o+=" ORDER BY file_path ASC, line_number ASC, source_symbol_name ASC LIMIT ?",u.push(c),a.push(...this.all(o,...u))}return a.slice(0,c)}findTypeGraphEdgesBySymbolId(e,t={}){let i=this.findById(e);return i?this.findTypeGraphEdges(i.name,{...t,filePath:i.file_path}):[]}};import jt from"path";var Wt=new Set(["any","unknown","never","void","null","undefined","string","number","boolean","symbol","object","bigint","readonly","keyof","infer","extends","implements","class","interface","type","function","new"]);function Ht(n,e){if(!n)return!1;let t=n.trim();return!t||Wt.has(t.toLowerCase())||e.has(t)?!1:/^[A-Za-z_$][A-Za-z0-9_$.]*$/.test(t)}function Pt(n){return n.split(/[,|&]/).map(e=>e.trim()).filter(Boolean)}function Ut(n){let e=n.replace(/^[({[]+/,"").replace(/[)}\]]+$/,"").replace(/^readonly\s+/,"").trim();return e&&e.match(/^([A-Za-z_$][A-Za-z0-9_$.]*)/)?.[1]||null}function $t(n){let e=[],t=0,i="",s=!1;for(let r of n){if(r==="<"&&(t++,t===1)){s=!0,i="";continue}if(r===">"&&(t>0&&t--,t===0&&s)){s=!1,i.trim()&&e.push(i),i="";continue}s&&(i+=r)}return e}function Bt(n){let e=new Set;for(let t of n){let i=t.split(",").map(s=>s.trim());for(let s of i){let r=s.match(/^([A-Za-z_$][A-Za-z0-9_$]*)/);r?.[1]&&e.add(r[1])}}return e}function fe(n,e){let t=[];for(let i of Pt(n)){let s=Ut(i);s&&Ht(s,e)&&t.push(s)}return t}function He(n){if(!n)return[];let e=n.replace(/\s+/g," ").trim();if(!e)return[];let t=$t(e),i=Bt(t),s=[],r=new Set,l=(o,u,d)=>{let m=`${o}:${u}`;r.has(m)||(r.add(m),s.push({relationship:o,targetName:u,...d?{metadata:d}:{}}))},c=e.match(/\bextends\s+(.+?)(?=\bimplements\b|\{|=|$)/);if(c?.[1]){let o=fe(c[1],i);for(let u of o)l("extends",u,c[1].trim())}let a=e.match(/\bimplements\s+(.+?)(?=\{|=|$)/);if(a?.[1]){let o=fe(a[1],i);for(let u of o)l("implements",u,a[1].trim())}for(let o of t){let u=/([A-Za-z_$][A-Za-z0-9_$]*)\s+extends\s+([^,>]+)/g,d=null;for(;(d=u.exec(o))!==null;){let m=d[2]?.trim();if(!m)continue;let b=fe(m,i);for(let h of b)l("constrained_by",h,m)}}return s}var ee=class extends f{findByPath(e){return this.get("SELECT * FROM files WHERE path = ?",e)}findAll(e){let t="SELECT * FROM files ORDER BY path ASC";return e&&(t+=` LIMIT ${e}`),this.all(t)}getAllPaths(){return this.all("SELECT path FROM files").map(t=>t.path)}findInSubPath(e,t){let i=jt.resolve(e,t),s=i.endsWith("/")?i:i+"/";return this.all(`
|
|
244
|
+
SELECT * FROM files
|
|
245
|
+
WHERE (path LIKE ? OR path = ?)
|
|
246
|
+
ORDER BY path ASC
|
|
247
|
+
`,`${s}%`,i)}findWithEmbeddings(){return this.all("SELECT * FROM files WHERE embedding IS NOT NULL")}findFts(e,t=10){return this.all(`
|
|
248
|
+
SELECT files.*, files_fts.rank
|
|
249
|
+
FROM files_fts
|
|
250
|
+
JOIN files ON files.rowid = files_fts.rowid
|
|
251
|
+
WHERE files_fts MATCH ?
|
|
252
|
+
ORDER BY rank
|
|
253
|
+
LIMIT ?
|
|
254
|
+
`,e,t)}findByPathKeywords(e,t=10){let i=e.map(()=>"LOWER(path) LIKE ?").join(" OR ");return this.all(`
|
|
255
|
+
SELECT * FROM files
|
|
256
|
+
WHERE ${i}
|
|
257
|
+
LIMIT ?
|
|
258
|
+
`,...e.map(s=>`%${s}%`),t)}findContentFts(e,t=50){let i=this.buildContentFtsQuery(e);return i?this.all(`
|
|
259
|
+
SELECT
|
|
260
|
+
files.*,
|
|
261
|
+
bm25(content_fts, 0.2, 1.0) AS bm25_rank
|
|
262
|
+
FROM content_fts
|
|
263
|
+
JOIN files ON files.path = content_fts.file_path
|
|
264
|
+
WHERE content_fts MATCH ?
|
|
265
|
+
ORDER BY bm25_rank ASC
|
|
266
|
+
LIMIT ?
|
|
267
|
+
`,i,Math.max(1,Math.min(t,1e3))):[]}getContent(e){return this.get("SELECT content FROM file_content WHERE file_path = ?",e)?.content}findContentByToken(e,t=10){return this.all(`
|
|
268
|
+
SELECT file_path
|
|
269
|
+
FROM content_fts
|
|
270
|
+
WHERE content_fts MATCH ?
|
|
271
|
+
AND (file_path LIKE '%.ts' OR file_path LIKE '%.tsx' OR file_path LIKE '%.js' OR file_path LIKE '%.py' OR file_path LIKE '%.php')
|
|
272
|
+
AND file_path NOT LIKE '%/test/%'
|
|
273
|
+
AND file_path NOT LIKE '%.spec.%'
|
|
274
|
+
LIMIT ?
|
|
275
|
+
`,`"${e.replace(/[^a-zA-Z0-9_/]/g," ")}"`,t).map(s=>s.file_path)}findSynapses(e){let t="SELECT * FROM event_synapses WHERE 1=1",i=[];if(e.type&&(t+=" AND type = ?",i.push(e.type)),e.name){let s=e.name;s.startsWith("/")&&(s=s.substring(1)),s.endsWith("/")&&(s=s.substring(0,s.length-1)),s.length>0&&(t+=" AND (name LIKE ? OR name LIKE ? OR name = ?)",i.push(`${s}%`),i.push(`%/${s}%`),i.push(e.name))}return e.direction&&(t+=" AND direction = ?",i.push(e.direction)),t+=` LIMIT ${e.limit||50}`,this.all(t,...i)}exists(e){return!!this.get("SELECT 1 FROM files WHERE path = ?",e)}update(e,t){let i=Object.keys(t);if(i.length===0)return;let s=i.map(l=>`${l} = ?`).join(", "),r=Object.values(t);r.push(e),this.run(`UPDATE files SET ${s} WHERE path = ?`,...r)}getStats(){let e=this.get(`
|
|
276
|
+
SELECT
|
|
277
|
+
COUNT(*) as total,
|
|
278
|
+
SUM(CASE WHEN summary IS NOT NULL AND summary != '' THEN 1 ELSE 0 END) as withSummary
|
|
279
|
+
FROM files
|
|
280
|
+
`);return{total:e?.total||0,withSummary:e?.withSummary||0}}getGravityMap(e=[],t){let i={},s=`
|
|
281
|
+
SELECT ws.file_path, m.name as mission_name, m.status
|
|
282
|
+
FROM working_set ws
|
|
283
|
+
JOIN missions m ON ws.mission_id = m.id
|
|
284
|
+
WHERE (
|
|
285
|
+
(m.status IN ('in-progress', 'verifying') ${t?"AND m.git_branch = ?":""})
|
|
286
|
+
OR m.id IN (${e.length>0?e.join(","):"-1"})
|
|
287
|
+
)
|
|
288
|
+
AND ws.file_path IS NOT NULL
|
|
289
|
+
`,r=[];t&&r.push(t);let l=this.all(s,...r);for(let o of l){i[o.file_path]||(i[o.file_path]={score:1,reasons:[]});let u=o.status==="in-progress"||o.status==="verifying"?1:.5;i[o.file_path].score+=u;let d=o.status==="in-progress"||o.status==="verifying"?"Working Set":"Lineage Bleed";i[o.file_path].reasons.push(`${d}: ${o.mission_name}`)}let c=Math.floor(Date.now()/1e3)-86400,a=this.all(`
|
|
290
|
+
SELECT file_path, type, mission_id
|
|
291
|
+
FROM intent_logs
|
|
292
|
+
WHERE (created_at > ? OR mission_id IN (${e.length>0?e.join(","):"-1"}))
|
|
293
|
+
AND file_path IS NOT NULL
|
|
294
|
+
ORDER BY created_at DESC
|
|
295
|
+
LIMIT 100
|
|
296
|
+
`,c);for(let o of a){i[o.file_path]||(i[o.file_path]={score:1,reasons:[]});let u=o.mission_id?e.includes(o.mission_id):!1,d=u?.1:.2;i[o.file_path].score<5&&(i[o.file_path].score+=d);let m=u?`Lineage Intent: ${o.type}`:`Recent Intent: ${o.type}`;!i[o.file_path].reasons.includes(m)&&i[o.file_path].reasons.length<5&&i[o.file_path].reasons.push(m)}return i}getCount(){return this.get("SELECT COUNT(*) as count FROM files")?.count||0}getTopDirectories(e,t=8){return this.all(`
|
|
297
|
+
SELECT
|
|
298
|
+
SUBSTR(path, LENGTH(?) + 2,
|
|
299
|
+
INSTR(SUBSTR(path, LENGTH(?) + 2), '/') - 1
|
|
300
|
+
) as root,
|
|
301
|
+
COUNT(*) as total_files,
|
|
302
|
+
SUM(CASE
|
|
303
|
+
WHEN path LIKE '%.ts' OR path LIKE '%.tsx'
|
|
304
|
+
OR path LIKE '%.js' OR path LIKE '%.jsx'
|
|
305
|
+
OR path LIKE '%.mjs' OR path LIKE '%.cjs'
|
|
306
|
+
THEN 1 ELSE 0
|
|
307
|
+
END) as ts_files
|
|
308
|
+
FROM files
|
|
309
|
+
WHERE path LIKE ? || '/%/%'
|
|
310
|
+
GROUP BY root
|
|
311
|
+
ORDER BY total_files DESC
|
|
312
|
+
LIMIT ?
|
|
313
|
+
`,e,e,e,t)}hasFilesPattern(e){return!!this.get("SELECT 1 FROM files WHERE path LIKE ? LIMIT 1",e)}findPackageJsonChildren(e){return this.all(`
|
|
314
|
+
SELECT
|
|
315
|
+
path,
|
|
316
|
+
SUBSTR(path, LENGTH(?) + 2) as relPath
|
|
317
|
+
FROM files
|
|
318
|
+
WHERE path LIKE ? || '/%/package.json'
|
|
319
|
+
`,e,e)}deletePaths(e){if(e.length===0)return;let t=this.db.prepare("DELETE FROM files WHERE path = ?");this.db.transaction(s=>{for(let r of s)t.run(r)})(e)}updateMtime(e,t){this.run("UPDATE files SET mtime = ? WHERE path = ?",t,e)}batchSaveIndexResults(e,t,i,s){let r=this.db.prepare("DELETE FROM exports WHERE file_path = ?"),l=this.db.prepare("DELETE FROM imports WHERE file_path = ?"),c=this.db.prepare("DELETE FROM configs WHERE file_path = ?"),a=this.db.prepare("DELETE FROM file_content WHERE file_path = ?"),o=this.db.prepare("DELETE FROM event_synapses WHERE file_path = ?"),u=this.db.prepare("DELETE FROM type_graph_edges WHERE file_path = ?"),d=this.db.prepare("INSERT INTO exports (file_path, name, kind, signature, doc, start_line, end_line, classification, capabilities, parent_id, embedding) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),m=this.db.prepare("INSERT INTO imports (file_path, module_specifier, imported_symbols, resolved_path) VALUES (?, ?, ?, ?)"),b=this.db.prepare("INSERT INTO configs (file_path, key, value, kind) VALUES (?, ?, ?, ?)"),h=this.db.prepare("INSERT INTO file_content (file_path, content) VALUES (?, ?)"),S=this.db.prepare("INSERT INTO event_synapses (file_path, type, name, direction, line_number, code_snippet) VALUES (?, ?, ?, ?, ?, ?)"),C=this.db.prepare("INSERT INTO type_graph_edges (file_path, source_symbol_id, source_symbol_name, target_symbol_name, relationship, line_number, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)"),lt=this.db.prepare(`
|
|
320
|
+
INSERT INTO files (path, mtime, last_scanned_at, classification, summary, embedding, content_hash)
|
|
321
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
322
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
323
|
+
mtime=excluded.mtime,
|
|
324
|
+
last_scanned_at=excluded.last_scanned_at,
|
|
325
|
+
classification=excluded.classification,
|
|
326
|
+
summary=excluded.summary,
|
|
327
|
+
embedding=excluded.embedding,
|
|
328
|
+
content_hash=excluded.content_hash
|
|
329
|
+
`),ct=this.db.transaction(M=>{for(let ut of M){let{meta:y,exports:Ie,imports:Oe,configs:Ce,events:we,content:z,classification:dt,summary:mt,embedding:xe,contentHash:pt}=ut;r.run(y.path),l.run(y.path),c.run(y.path),a.run(y.path),o.run(y.path),u.run(y.path);let ht=pt??(z&&i?i(z):null);if(lt.run(y.path,y.mtime,Date.now(),dt||"Unknown",mt||"",xe?JSON.stringify(xe):null,ht),Ie){let E=(W,ft,gt)=>{for(let _ of ft){let Et=_.embedding?JSON.stringify(_.embedding):null,Ae=d.run(W,_.name,_.kind,_.signature,_.doc||"",_.line,_.endLine||_.line,_.classification||"Other",_.capabilities||"[]",gt,Et),ve=Number(Ae.lastInsertRowid);if(Number.isFinite(ve)){let _t=He(_.signature);for(let Y of _t)Y.targetName!==_.name&&C.run(W,ve,_.name,Y.targetName,Y.relationship,_.line,Y.metadata||null)}_.members&&_.members.length>0&&E(W,_.members,Ae.lastInsertRowid)}};E(y.path,Ie,null)}if(Oe)for(let E of Oe){let W=E.resolved_path!==void 0?E.resolved_path:s?.(E.module,y.path,t)??"";m.run(y.path,E.module,E.name,W)}if(Ce)for(let E of Ce)b.run(y.path,E.key,E.value,E.kind);if(z!==void 0&&h.run(y.path,z),we)for(let E of we)S.run(y.path,E.type,E.name,E.direction,E.line,E.snippet)}}),Ne=500;for(let M=0;M<e.length;M+=Ne)ct(e.slice(M,M+Ne))}getLatestScanTime(){return this.get("SELECT MAX(last_scanned_at) as t FROM files")?.t||null}buildContentFtsQuery(e){let t=e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9_]+/).map(r=>r.trim()).filter(r=>r.length>=2).slice(0,12);if(t.length===0)return"";if(t.length===1)return`${t[0]}*`;let i=`"${t.join(" ")}"`,s=t.map(r=>`${r}*`).join(" OR ");return`${i} OR ${s}`}};var te=class extends f{getSection(e){return this.get("SELECT section, data, updated_at FROM hologram_snapshot WHERE section = ?",e)}getAllSections(){return this.all("SELECT section, data, updated_at FROM hologram_snapshot ORDER BY section")}upsertSection(e,t){this.run(`
|
|
330
|
+
INSERT INTO hologram_snapshot (section, data, updated_at)
|
|
331
|
+
VALUES (?, ?, unixepoch())
|
|
332
|
+
ON CONFLICT(section) DO UPDATE SET
|
|
333
|
+
data = excluded.data,
|
|
334
|
+
updated_at = excluded.updated_at
|
|
335
|
+
`,e,t)}deleteSection(e){this.run("DELETE FROM hologram_snapshot WHERE section = ?",e)}deleteAll(){this.run("DELETE FROM hologram_snapshot")}hasSection(e){return(this.get("SELECT COUNT(*) as count FROM hologram_snapshot WHERE section = ?",e)?.count??0)>0}};var Pe=`
|
|
267
336
|
WITH RECURSIVE dependency_chain AS (
|
|
268
337
|
-- Base case: Direct dependents of the target symbol
|
|
269
338
|
-- Meaning: Files that import the file where the symbol is defined
|
|
@@ -314,7 +383,7 @@ SELECT DISTINCT
|
|
|
314
383
|
dc.imported_symbols
|
|
315
384
|
FROM dependency_chain dc
|
|
316
385
|
ORDER BY dc.depth, dc.consumer_path;
|
|
317
|
-
`;var
|
|
386
|
+
`;var ie=class extends f{findByFile(e){return this.all("SELECT * FROM imports WHERE file_path = ?",e)}findByFiles(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.all(`SELECT * FROM imports WHERE file_path IN (${t}) ORDER BY file_path`,...e)}getAllResolved(){return this.all(`
|
|
318
387
|
SELECT * FROM imports
|
|
319
388
|
WHERE resolved_path IS NOT NULL AND resolved_path != ''
|
|
320
389
|
`)}findDependents(e){return this.all("SELECT * FROM imports WHERE resolved_path = ?",e)}countByFile(e){return this.get("SELECT COUNT(*) as count FROM imports WHERE file_path = ?",e)?.count||0}countDependents(e){return this.get("SELECT COUNT(*) as count FROM imports WHERE resolved_path = ?",e)?.count||0}getImportsForFile(e){return this.all("SELECT module_specifier, imported_symbols, resolved_path FROM imports WHERE file_path = ?",e)}findImportSource(e,t){return this.get(`
|
|
@@ -340,98 +409,7 @@ ORDER BY dc.depth, dc.consumer_path;
|
|
|
340
409
|
SELECT COUNT(*) as count FROM imports
|
|
341
410
|
WHERE resolved_path IN (${i})
|
|
342
411
|
AND (imported_symbols LIKE ? OR imported_symbols = '' OR imported_symbols = '*')
|
|
343
|
-
`,...e,`%${t}%`)?.count||0}findImpactDependents(e,t,i){return this.all(Pe,e,t,i,t)}getCount(){return this.get("SELECT COUNT(*) as count FROM imports")?.count||0}};var
|
|
344
|
-
CASE WHEN status = 'in-progress' THEN 0 WHEN status = 'verifying' THEN 1 ELSE 2 END,
|
|
345
|
-
created_at ASC`,this.all(t,...i)}findAll(e){let t="SELECT * FROM missions",i=[];return e&&(t+=" WHERE status = ?",i.push(e)),t+=` ORDER BY
|
|
346
|
-
CASE WHEN status = 'in-progress' THEN 0 WHEN status = 'verifying' THEN 1 ELSE 2 END,
|
|
347
|
-
created_at ASC`,this.all(t,...i)}findRecentCompleted(e=3){return this.all(`
|
|
348
|
-
SELECT * FROM missions
|
|
349
|
-
WHERE status = 'completed'
|
|
350
|
-
ORDER BY updated_at DESC, id DESC
|
|
351
|
-
LIMIT ?
|
|
352
|
-
`,e)}create(e){return this.insert(`
|
|
353
|
-
INSERT INTO missions (name, goal, strategy_graph, status, git_branch, commit_sha, parent_id, verification_context, outcome_contract)
|
|
354
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
355
|
-
`,e.name,e.goal,e.strategy_graph,e.status,e.git_branch,e.commit_sha,e.parent_id,e.verification_context,e.outcome_contract)}addArtifact(e,t,i,s){this.run("INSERT INTO mission_artifacts (mission_id, type, identifier, metadata) VALUES (?, ?, ?, ?)",e,t,i,s?JSON.stringify(s):null)}getArtifacts(e){return this.all("SELECT * FROM mission_artifacts WHERE mission_id = ?",e)}update(e,t){let i=Object.keys(t);if(i.length===0)return;let s=i.map(l=>`${l} = ?`).join(", "),r=Object.values(t);r.push(e),this.run(`UPDATE missions SET ${s}, updated_at = unixepoch() WHERE id = ?`,...r)}updateStatus(e,t,i){i?this.run("UPDATE missions SET status = ?, updated_at = unixepoch(), commit_sha = ? WHERE id = ?",t,i,e):this.run("UPDATE missions SET status = ?, updated_at = unixepoch() WHERE id = ?",t,e)}getWorkingSet(e){let t=this.all(`
|
|
356
|
-
SELECT file_path, type, source_priority, created_at
|
|
357
|
-
FROM (
|
|
358
|
-
SELECT
|
|
359
|
-
ws.file_path,
|
|
360
|
-
COALESCE(ws.type, 'file') AS type,
|
|
361
|
-
0 AS source_priority,
|
|
362
|
-
ws.created_at
|
|
363
|
-
FROM working_set ws
|
|
364
|
-
WHERE ws.mission_id = ?
|
|
365
|
-
|
|
366
|
-
UNION ALL
|
|
367
|
-
|
|
368
|
-
SELECT
|
|
369
|
-
il.file_path,
|
|
370
|
-
'intent' AS type,
|
|
371
|
-
1 AS source_priority,
|
|
372
|
-
il.created_at
|
|
373
|
-
FROM intent_logs il
|
|
374
|
-
WHERE il.mission_id = ?
|
|
375
|
-
AND il.file_path IS NOT NULL
|
|
376
|
-
|
|
377
|
-
UNION ALL
|
|
378
|
-
|
|
379
|
-
SELECT
|
|
380
|
-
e.file_path,
|
|
381
|
-
'symbol' AS type,
|
|
382
|
-
2 AS source_priority,
|
|
383
|
-
il.created_at
|
|
384
|
-
FROM intent_logs il
|
|
385
|
-
JOIN exports e ON e.id = il.symbol_id
|
|
386
|
-
WHERE il.mission_id = ?
|
|
387
|
-
AND e.file_path IS NOT NULL
|
|
388
|
-
)
|
|
389
|
-
WHERE file_path IS NOT NULL
|
|
390
|
-
ORDER BY source_priority ASC, created_at DESC, file_path ASC
|
|
391
|
-
`,e,e,e),i=new Map;for(let s of t)!s.file_path||i.has(s.file_path)||i.set(s.file_path,{file_path:s.file_path,type:s.type||"file"});return[...i.values()]}clearWorkingSet(e){this.run("DELETE FROM working_set WHERE mission_id = ?",e)}addToWorkingSet(e,t,i="file"){this.run("INSERT OR IGNORE INTO files (path, mtime, last_scanned_at) VALUES (?, unixepoch(), unixepoch())",t),this.run("INSERT INTO working_set (mission_id, file_path, type) VALUES (?, ?, ?)",e,t,i)}findColdMissions(e,t=10){return this.all(`
|
|
392
|
-
SELECT m.id, COUNT(il.id) as log_count
|
|
393
|
-
FROM missions m
|
|
394
|
-
LEFT JOIN intent_logs il ON il.mission_id = m.id
|
|
395
|
-
WHERE m.updated_at < ?
|
|
396
|
-
AND m.status != 'distilled'
|
|
397
|
-
GROUP BY m.id
|
|
398
|
-
HAVING log_count > ?
|
|
399
|
-
`,e,t).map(s=>s.id)}getStats(){let e=this.get(`
|
|
400
|
-
SELECT
|
|
401
|
-
COUNT(*) as total,
|
|
402
|
-
SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as completed,
|
|
403
|
-
SUM(CASE WHEN status IN ('in-progress', 'planned', 'verifying') THEN 1 ELSE 0 END) as active
|
|
404
|
-
FROM missions
|
|
405
|
-
`);return{total:e?.total||0,completed:e?.completed||0,active:e?.active||0}}getAnalytics(){let e=this.getStats(),t=e.total>0?Math.round(e.completed/e.total*100):0,i=this.get(`
|
|
406
|
-
SELECT AVG(updated_at - created_at) AS avg_duration
|
|
407
|
-
FROM missions
|
|
408
|
-
WHERE status = 'completed' AND updated_at > created_at
|
|
409
|
-
`),s=i?.avg_duration!=null?Math.round(i.avg_duration):null,r=Math.floor(Date.now()/1e3)-168*3600,l=Math.floor(Date.now()/1e3)-720*3600,c=this.get("SELECT COUNT(*) AS n FROM missions WHERE status = 'completed' AND updated_at >= ?",r),a=this.get("SELECT COUNT(*) AS n FROM missions WHERE status = 'completed' AND updated_at >= ?",l),o=c?.n??0,u=a?.n??0,d=`${o} completed in last 7 days, ${u} in last 30 days.`;if(s!=null){let m=Math.round(s/60);d+=` Avg mission duration: ${m} min.`}return{completionRate:t,averageDurationSeconds:s,completedLast7Days:o,completedLast30Days:u,velocityNote:d}}suspendByBranch(e){return this.run(`UPDATE missions
|
|
410
|
-
SET status = 'suspended', updated_at = unixepoch()
|
|
411
|
-
WHERE git_branch = ? AND status IN ('in-progress', 'verifying')`,e)}resumeByBranch(e){return this.run(`UPDATE missions
|
|
412
|
-
SET status = 'in-progress', updated_at = unixepoch()
|
|
413
|
-
WHERE git_branch = ? AND status = 'suspended'`,e)}findMergedMissions(e,t){if(t.length===0)return[];let i=t.filter(r=>r!==e);if(i.length===0)return[];let s=i.map(()=>"?").join(",");return this.all(`SELECT * FROM missions
|
|
414
|
-
WHERE status IN ('in-progress', 'planned', 'verifying', 'suspended')
|
|
415
|
-
AND git_branch IN (${s})`,...i)}findByCommitShas(e){if(e.length===0)return[];let t=e.map(()=>"?").join(",");return this.all(`SELECT * FROM missions WHERE commit_sha IN (${t})`,...e)}findByParentId(e){return this.all("SELECT * FROM missions WHERE parent_id = ?",e)}hasChildren(e){return!!this.get("SELECT 1 FROM missions WHERE parent_id = ? LIMIT 1",e)}hasNoSteps(e){if(!e.strategy_graph)return!0;try{let t=JSON.parse(e.strategy_graph),i=t?.steps??t;return!Array.isArray(i)||i.length===0}catch{return!0}}findParentOnlyIds(e){return e.filter(t=>t.parent_id!=null||!this.hasChildren(t.id)?!1:this.hasNoSteps(t)).map(t=>t.id)}createLink(e,t,i,s,r){this.db.exec(`
|
|
416
|
-
CREATE TABLE IF NOT EXISTS cross_repo_links (
|
|
417
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
418
|
-
mission_id INTEGER NOT NULL,
|
|
419
|
-
linked_repo_path TEXT NOT NULL,
|
|
420
|
-
linked_mission_id INTEGER NOT NULL,
|
|
421
|
-
relationship TEXT,
|
|
422
|
-
direction TEXT,
|
|
423
|
-
created_at REAL DEFAULT (unixepoch()),
|
|
424
|
-
FOREIGN KEY(mission_id) REFERENCES missions(id) ON DELETE CASCADE
|
|
425
|
-
);
|
|
426
|
-
CREATE INDEX IF NOT EXISTS idx_cross_repo_mission ON cross_repo_links(mission_id);
|
|
427
|
-
`),this.run(`
|
|
428
|
-
INSERT INTO cross_repo_links (mission_id, linked_repo_path, linked_mission_id, relationship, direction)
|
|
429
|
-
VALUES (?, ?, ?, ?, ?)
|
|
430
|
-
`,e,t,i,s,r)}getLinks(e){try{return this.all(`
|
|
431
|
-
SELECT linked_repo_path, linked_mission_id, relationship, direction
|
|
432
|
-
FROM cross_repo_links
|
|
433
|
-
WHERE mission_id = ?
|
|
434
|
-
`,e)}catch{return[]}}findLastMission(){return this.get("SELECT * FROM missions ORDER BY updated_at DESC, id DESC LIMIT 1")}findActiveByPriority(){return this.get("SELECT * FROM missions WHERE status IN ('in-progress', 'active', 'verifying') ORDER BY CASE WHEN status = 'in-progress' THEN 0 ELSE 1 END, created_at ASC LIMIT 1")}addHandoff(e,t){let i=JSON.stringify(t),s=this.insert("INSERT INTO mission_artifacts (mission_id, type, identifier, metadata) VALUES (?, ?, ?, ?)",e,"handoff",t.kind,i),r=[`[handoff:${t.kind}]`,...t.findings.map(l=>l.statement),...t.risks.map(l=>l.description),...t.gaps].filter(Boolean).join(" ");return Promise.resolve().then(()=>(v(),x)).then(({generateEmbedding:l})=>l(r)).then(l=>{l&&this.run("UPDATE mission_artifacts SET embedding = ? WHERE id = ?",JSON.stringify(l),s)}).catch(()=>{}),s}getHandoffs(e,t,i=20){let s=["type = 'handoff'"],r=[];e!==void 0&&(e===null?s.push("mission_id IS NULL"):(s.push("mission_id = ?"),r.push(e))),t&&(s.push("identifier = ?"),r.push(t));let l=`SELECT * FROM mission_artifacts WHERE ${s.join(" AND ")} ORDER BY created_at DESC LIMIT ?`;return r.push(i),this.all(l,...r)}async findSemanticHandoffs(e,t){let{cosineSimilarity:i}=await Promise.resolve().then(()=>(v(),x)),s=["type = 'handoff'","embedding IS NOT NULL"],r=[];t?.missionId!==void 0&&(t.missionId===null?s.push("mission_id IS NULL"):(s.push("mission_id = ?"),r.push(t.missionId))),t?.kind&&(s.push("identifier = ?"),r.push(t.kind));let l=this.all(`SELECT * FROM mission_artifacts WHERE ${s.join(" AND ")}`,...r),c=[];for(let a of l)try{let o=JSON.parse(a.embedding),u=i(e,o);u>.3&&c.push({...a,similarity:u})}catch{}return c.sort((a,o)=>o.similarity-a.similarity).slice(0,t?.limit??5)}};D();var ie=class n extends f{findByMission(e,t=50){return this.all(`
|
|
412
|
+
`,...e,`%${t}%`)?.count||0}findImpactDependents(e,t,i){return this.all(Pe,e,t,i,t)}getCount(){return this.get("SELECT COUNT(*) as count FROM imports")?.count||0}};D();var re=class n extends f{findByMission(e,t=50){return this.all(`
|
|
435
413
|
SELECT
|
|
436
414
|
id, mission_id, symbol_id, file_path, type, content, confidence,
|
|
437
415
|
symbol_name, signature, commit_sha, is_crystallized, crystal_id,
|
|
@@ -452,7 +430,7 @@ ORDER BY dc.depth, dc.consumer_path;
|
|
|
452
430
|
`,e)}create(e){let t=this.insert(`
|
|
453
431
|
INSERT INTO intent_logs (mission_id, symbol_id, file_path, type, content, confidence, symbol_name, signature, commit_sha)
|
|
454
432
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
455
|
-
`,e.mission_id,e.symbol_id,e.file_path,e.type,e.content,e.confidence,e.symbol_name,e.signature,e.commit_sha);return n.EMBEDDABLE_TYPES.has(e.type)&&this.generateAndStoreEmbedding(Number(t),e).catch(i=>{p.debug({err:i,intentLogId:t},"Failed to generate intent log embedding")}),t}static EMBEDDABLE_TYPES=new Set(["decision","discovery","fix","blocker","note","heritage","crystal"]);static buildEmbeddingText(e){let t=[`[${e.type}]`];return e.symbol_name&&t.push(`symbol: ${e.symbol_name}`),e.file_path&&t.push(`file: ${e.file_path.split("/").pop()}`),t.push(e.content),t.join(" ")}async generateAndStoreEmbedding(e,t){let{generateEmbedding:i}=await Promise.resolve().then(()=>(
|
|
433
|
+
`,e.mission_id,e.symbol_id,e.file_path,e.type,e.content,e.confidence,e.symbol_name,e.signature,e.commit_sha);return n.EMBEDDABLE_TYPES.has(e.type)&&this.generateAndStoreEmbedding(Number(t),e).catch(i=>{p.debug({err:i,intentLogId:t},"Failed to generate intent log embedding")}),t}static EMBEDDABLE_TYPES=new Set(["decision","discovery","fix","blocker","note","heritage","crystal"]);static buildEmbeddingText(e){let t=[`[${e.type}]`];return e.symbol_name&&t.push(`symbol: ${e.symbol_name}`),e.file_path&&t.push(`file: ${e.file_path.split("/").pop()}`),t.push(e.content),t.join(" ")}async generateAndStoreEmbedding(e,t){let{generateEmbedding:i}=await Promise.resolve().then(()=>(A(),x)),s=n.buildEmbeddingText(t),r=await i(s);r&&this.run("UPDATE intent_logs SET embedding = ? WHERE id = ?",JSON.stringify(r),e)}findWithEmbeddings(){return this.all("SELECT * FROM intent_logs WHERE embedding IS NOT NULL AND type NOT IN ('system', 'lapsed')")}async findSemanticMatches(e,t,i){let{cosineSimilarity:s}=await Promise.resolve().then(()=>(A(),x)),r=this.findWithEmbeddings();if(r.length>5e3)return p.warn({count:r.length},"Intent log count exceeds brute-force vector scan limit (5000). Skipping semantic recall."),[];let l=[];for(let c of r)if(!(i&&c.symbol_id===i))try{let a=JSON.parse(c.embedding),o=s(e,a);o>.25&&l.push({id:c.id,mission_id:c.mission_id,type:c.type,content:c.content,symbol_name:c.symbol_name,file_path:c.file_path,similarity:o,created_at:c.created_at})}catch{}return l.sort((c,a)=>a.similarity-c.similarity).slice(0,t)}delete(e){this.run("DELETE FROM intent_logs WHERE id = ?",e)}update(e,t){let i=Object.keys(t);if(i.length===0)return;let s=i.map(l=>`${l} = ?`).join(", "),r=Object.values(t);r.push(e),this.run(`UPDATE intent_logs SET ${s} WHERE id = ?`,...r)}findRepairableOrphans(){return this.all(`
|
|
456
434
|
SELECT id, file_path, symbol_name, signature
|
|
457
435
|
FROM intent_logs
|
|
458
436
|
WHERE symbol_id IS NULL AND symbol_name IS NOT NULL
|
|
@@ -539,82 +517,139 @@ ORDER BY dc.depth, dc.consumer_path;
|
|
|
539
517
|
FROM intent_logs
|
|
540
518
|
WHERE mission_id = ? AND is_crystallized = 0 AND type NOT IN ('adr', 'system', 'crystal', 'lapsed')
|
|
541
519
|
AND created_at > ?
|
|
542
|
-
ORDER BY created_at DESC LIMIT ?`,e,i.created_at,t-1);return[i,...s]}return this.findByMission(e,t)}async findSemanticTheme(e,t,i=200){let{cosineSimilarity:s}=await Promise.resolve().then(()=>(
|
|
543
|
-
VALUES (NULL, 'crystal', ?, 1.0, 0, NULL, NULL, NULL, NULL, NULL)`,i);if(t.length>0){let r=t.map(()=>"?").join(",");this.run(`UPDATE intent_logs SET is_crystallized = 1, crystal_id = ? WHERE id IN (${r})`,s,...t)}return s})}async backfillEmbeddings(e=64,t){let{generateEmbeddingsBatch:i}=await Promise.resolve().then(()=>(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
WHERE content_fts MATCH ?
|
|
520
|
+
ORDER BY created_at DESC LIMIT ?`,e,i.created_at,t-1);return[i,...s]}return this.findByMission(e,t)}async findSemanticTheme(e,t,i=200){let{cosineSimilarity:s}=await Promise.resolve().then(()=>(A(),x)),r=this.findWithEmbeddings(),l=[];for(let c of r)if(n.EMBEDDABLE_TYPES.has(c.type)&&c.type!=="crystal"&&c.mission_id!=null&&!(t&&!t.includes(c.mission_id)))try{let a=JSON.parse(c.embedding),o=s(e,a);o>.35&&l.push({...c,_similarity:o})}catch{}return l.sort((c,a)=>a._similarity-c._similarity).slice(0,i).map(({_similarity:c,...a})=>a)}crystallizeTheme(e,t,i){return this.transaction(()=>{let s=this.insert(`INSERT INTO intent_logs (mission_id, type, content, confidence, is_crystallized, symbol_id, file_path, symbol_name, signature, commit_sha)
|
|
521
|
+
VALUES (NULL, 'crystal', ?, 1.0, 0, NULL, NULL, NULL, NULL, NULL)`,i);if(t.length>0){let r=t.map(()=>"?").join(",");this.run(`UPDATE intent_logs SET is_crystallized = 1, crystal_id = ? WHERE id IN (${r})`,s,...t)}return s})}async backfillEmbeddings(e=64,t){let{generateEmbeddingsBatch:i}=await Promise.resolve().then(()=>(A(),x)),s=[...n.EMBEDDABLE_TYPES].map(u=>`'${u}'`).join(","),r=this.all(`SELECT * FROM intent_logs WHERE embedding IS NULL AND type IN (${s})`);if(r.length===0)return 0;let l=r.map(u=>n.buildEmbeddingText(u)),c=await i(l,e,t),a=this.db.prepare("UPDATE intent_logs SET embedding = ? WHERE id = ?"),o=0;return this.transaction(()=>{for(let u=0;u<r.length;u++)c[u]&&(a.run(JSON.stringify(c[u]),r[u].id),o++)}),p.info({total:r.length,embedded:o},"Intent log embedding backfill complete"),o}};var oe=class extends f{findById(e){return this.get("SELECT * FROM missions WHERE id = ?",e)}findByIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.all(`SELECT * FROM missions WHERE id IN (${t})`,...e)}findActive(e){let t="SELECT * FROM missions WHERE status IN ('in-progress', 'planned', 'verifying')",i=[];return e&&(t+=" AND git_branch = ?",i.push(e)),t+=` ORDER BY
|
|
522
|
+
CASE WHEN status = 'in-progress' THEN 0 WHEN status = 'verifying' THEN 1 ELSE 2 END,
|
|
523
|
+
created_at ASC`,this.all(t,...i)}findAll(e){let t="SELECT * FROM missions",i=[];return e&&(t+=" WHERE status = ?",i.push(e)),t+=` ORDER BY
|
|
524
|
+
CASE WHEN status = 'in-progress' THEN 0 WHEN status = 'verifying' THEN 1 ELSE 2 END,
|
|
525
|
+
created_at ASC`,this.all(t,...i)}findRecentCompleted(e=3){return this.all(`
|
|
526
|
+
SELECT * FROM missions
|
|
527
|
+
WHERE status = 'completed'
|
|
528
|
+
ORDER BY updated_at DESC, id DESC
|
|
552
529
|
LIMIT ?
|
|
553
|
-
|
|
530
|
+
`,e)}create(e){return this.insert(`
|
|
531
|
+
INSERT INTO missions (name, goal, strategy_graph, status, git_branch, commit_sha, parent_id, verification_context, outcome_contract)
|
|
532
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
533
|
+
`,e.name,e.goal,e.strategy_graph,e.status,e.git_branch,e.commit_sha,e.parent_id,e.verification_context,e.outcome_contract)}addArtifact(e,t,i,s){this.run("INSERT INTO mission_artifacts (mission_id, type, identifier, metadata) VALUES (?, ?, ?, ?)",e,t,i,s?JSON.stringify(s):null)}getArtifacts(e){return this.all("SELECT * FROM mission_artifacts WHERE mission_id = ?",e)}update(e,t){let i=Object.keys(t);if(i.length===0)return;let s=i.map(l=>`${l} = ?`).join(", "),r=Object.values(t);r.push(e),this.run(`UPDATE missions SET ${s}, updated_at = unixepoch() WHERE id = ?`,...r)}updateStatus(e,t,i){i?this.run("UPDATE missions SET status = ?, updated_at = unixepoch(), commit_sha = ? WHERE id = ?",t,i,e):this.run("UPDATE missions SET status = ?, updated_at = unixepoch() WHERE id = ?",t,e)}getWorkingSet(e){let t=this.all(`
|
|
534
|
+
SELECT file_path, type, source_priority, created_at
|
|
535
|
+
FROM (
|
|
536
|
+
SELECT
|
|
537
|
+
ws.file_path,
|
|
538
|
+
COALESCE(ws.type, 'file') AS type,
|
|
539
|
+
0 AS source_priority,
|
|
540
|
+
ws.created_at
|
|
541
|
+
FROM working_set ws
|
|
542
|
+
WHERE ws.mission_id = ?
|
|
543
|
+
|
|
544
|
+
UNION ALL
|
|
545
|
+
|
|
546
|
+
SELECT
|
|
547
|
+
il.file_path,
|
|
548
|
+
'intent' AS type,
|
|
549
|
+
1 AS source_priority,
|
|
550
|
+
il.created_at
|
|
551
|
+
FROM intent_logs il
|
|
552
|
+
WHERE il.mission_id = ?
|
|
553
|
+
AND il.file_path IS NOT NULL
|
|
554
|
+
|
|
555
|
+
UNION ALL
|
|
556
|
+
|
|
557
|
+
SELECT
|
|
558
|
+
e.file_path,
|
|
559
|
+
'symbol' AS type,
|
|
560
|
+
2 AS source_priority,
|
|
561
|
+
il.created_at
|
|
562
|
+
FROM intent_logs il
|
|
563
|
+
JOIN exports e ON e.id = il.symbol_id
|
|
564
|
+
WHERE il.mission_id = ?
|
|
565
|
+
AND e.file_path IS NOT NULL
|
|
566
|
+
)
|
|
567
|
+
WHERE file_path IS NOT NULL
|
|
568
|
+
ORDER BY source_priority ASC, created_at DESC, file_path ASC
|
|
569
|
+
`,e,e,e),i=new Map;for(let s of t)!s.file_path||i.has(s.file_path)||i.set(s.file_path,{file_path:s.file_path,type:s.type||"file"});return[...i.values()]}clearWorkingSet(e){this.run("DELETE FROM working_set WHERE mission_id = ?",e)}addToWorkingSet(e,t,i="file"){this.run("INSERT OR IGNORE INTO files (path, mtime, last_scanned_at) VALUES (?, unixepoch(), unixepoch())",t),this.run("INSERT INTO working_set (mission_id, file_path, type) VALUES (?, ?, ?)",e,t,i)}findColdMissions(e,t=10){return this.all(`
|
|
570
|
+
SELECT m.id, COUNT(il.id) as log_count
|
|
571
|
+
FROM missions m
|
|
572
|
+
LEFT JOIN intent_logs il ON il.mission_id = m.id
|
|
573
|
+
WHERE m.updated_at < ?
|
|
574
|
+
AND m.status != 'distilled'
|
|
575
|
+
GROUP BY m.id
|
|
576
|
+
HAVING log_count > ?
|
|
577
|
+
`,e,t).map(s=>s.id)}getStats(){let e=this.get(`
|
|
578
|
+
SELECT
|
|
579
|
+
COUNT(*) as total,
|
|
580
|
+
SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) as completed,
|
|
581
|
+
SUM(CASE WHEN status IN ('in-progress', 'planned', 'verifying') THEN 1 ELSE 0 END) as active
|
|
582
|
+
FROM missions
|
|
583
|
+
`);return{total:e?.total||0,completed:e?.completed||0,active:e?.active||0}}getAnalytics(){let e=this.getStats(),t=e.total>0?Math.round(e.completed/e.total*100):0,i=this.get(`
|
|
584
|
+
SELECT AVG(updated_at - created_at) AS avg_duration
|
|
585
|
+
FROM missions
|
|
586
|
+
WHERE status = 'completed' AND updated_at > created_at
|
|
587
|
+
`),s=i?.avg_duration!=null?Math.round(i.avg_duration):null,r=Math.floor(Date.now()/1e3)-168*3600,l=Math.floor(Date.now()/1e3)-720*3600,c=this.get("SELECT COUNT(*) AS n FROM missions WHERE status = 'completed' AND updated_at >= ?",r),a=this.get("SELECT COUNT(*) AS n FROM missions WHERE status = 'completed' AND updated_at >= ?",l),o=c?.n??0,u=a?.n??0,d=`${o} completed in last 7 days, ${u} in last 30 days.`;if(s!=null){let m=Math.round(s/60);d+=` Avg mission duration: ${m} min.`}return{completionRate:t,averageDurationSeconds:s,completedLast7Days:o,completedLast30Days:u,velocityNote:d}}suspendByBranch(e){return this.run(`UPDATE missions
|
|
588
|
+
SET status = 'suspended', updated_at = unixepoch()
|
|
589
|
+
WHERE git_branch = ? AND status IN ('in-progress', 'verifying')`,e)}resumeByBranch(e){return this.run(`UPDATE missions
|
|
590
|
+
SET status = 'in-progress', updated_at = unixepoch()
|
|
591
|
+
WHERE git_branch = ? AND status = 'suspended'`,e)}findMergedMissions(e,t){if(t.length===0)return[];let i=t.filter(r=>r!==e);if(i.length===0)return[];let s=i.map(()=>"?").join(",");return this.all(`SELECT * FROM missions
|
|
592
|
+
WHERE status IN ('in-progress', 'planned', 'verifying', 'suspended')
|
|
593
|
+
AND git_branch IN (${s})`,...i)}findByCommitShas(e){if(e.length===0)return[];let t=e.map(()=>"?").join(",");return this.all(`SELECT * FROM missions WHERE commit_sha IN (${t})`,...e)}findByParentId(e){return this.all("SELECT * FROM missions WHERE parent_id = ?",e)}hasChildren(e){return!!this.get("SELECT 1 FROM missions WHERE parent_id = ? LIMIT 1",e)}hasNoSteps(e){if(!e.strategy_graph)return!0;try{let t=JSON.parse(e.strategy_graph),i=t?.steps??t;return!Array.isArray(i)||i.length===0}catch{return!0}}findParentOnlyIds(e){return e.filter(t=>t.parent_id!=null||!this.hasChildren(t.id)?!1:this.hasNoSteps(t)).map(t=>t.id)}createLink(e,t,i,s,r){return this.ensureCrossRepoLinksSchema(),this.run(`
|
|
594
|
+
INSERT OR IGNORE INTO cross_repo_links (mission_id, linked_repo_path, linked_mission_id, relationship, direction)
|
|
595
|
+
VALUES (?, ?, ?, ?, ?)
|
|
596
|
+
`,e,t,i,s,r)}getLink(e,t,i,s){return this.ensureCrossRepoLinksSchema(),this.get(`
|
|
597
|
+
SELECT relationship, direction
|
|
598
|
+
FROM cross_repo_links
|
|
599
|
+
WHERE mission_id = ?
|
|
600
|
+
AND linked_repo_path = ?
|
|
601
|
+
AND linked_mission_id = ?
|
|
602
|
+
AND direction = ?
|
|
603
|
+
LIMIT 1
|
|
604
|
+
`,e,t,i,s)}upsertLink(e,t,i,s,r){return this.ensureCrossRepoLinksSchema(),this.run(`
|
|
605
|
+
INSERT INTO cross_repo_links (
|
|
606
|
+
mission_id,
|
|
607
|
+
linked_repo_path,
|
|
608
|
+
linked_mission_id,
|
|
609
|
+
relationship,
|
|
610
|
+
direction
|
|
611
|
+
)
|
|
612
|
+
VALUES (?, ?, ?, ?, ?)
|
|
613
|
+
ON CONFLICT(mission_id, linked_repo_path, linked_mission_id, direction)
|
|
614
|
+
DO UPDATE SET relationship = excluded.relationship
|
|
615
|
+
`,e,t,i,s,r)}hasLink(e,t,i,s){return this.ensureCrossRepoLinksSchema(),!!this.get(`
|
|
616
|
+
SELECT id
|
|
617
|
+
FROM cross_repo_links
|
|
618
|
+
WHERE mission_id = ?
|
|
619
|
+
AND linked_repo_path = ?
|
|
620
|
+
AND linked_mission_id = ?
|
|
621
|
+
AND direction = ?
|
|
622
|
+
LIMIT 1
|
|
623
|
+
`,e,t,i,s)}deleteLink(e,t,i,s){return this.ensureCrossRepoLinksSchema(),this.run(`
|
|
624
|
+
DELETE FROM cross_repo_links
|
|
625
|
+
WHERE mission_id = ?
|
|
626
|
+
AND linked_repo_path = ?
|
|
627
|
+
AND linked_mission_id = ?
|
|
628
|
+
AND direction = ?
|
|
629
|
+
`,e,t,i,s)}ensureCrossRepoLinksSchema(){this.db.exec(`
|
|
630
|
+
CREATE TABLE IF NOT EXISTS cross_repo_links (
|
|
631
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
632
|
+
mission_id INTEGER NOT NULL,
|
|
633
|
+
linked_repo_path TEXT NOT NULL,
|
|
634
|
+
linked_mission_id INTEGER NOT NULL,
|
|
635
|
+
relationship TEXT,
|
|
636
|
+
direction TEXT,
|
|
637
|
+
created_at REAL DEFAULT (unixepoch()),
|
|
638
|
+
FOREIGN KEY(mission_id) REFERENCES missions(id) ON DELETE CASCADE
|
|
639
|
+
);
|
|
640
|
+
CREATE INDEX IF NOT EXISTS idx_cross_repo_mission ON cross_repo_links(mission_id);
|
|
641
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_cross_repo_unique
|
|
642
|
+
ON cross_repo_links(mission_id, linked_repo_path, linked_mission_id, direction);
|
|
643
|
+
`)}getLinks(e){try{return this.all(`
|
|
644
|
+
SELECT linked_repo_path, linked_mission_id, relationship, direction
|
|
645
|
+
FROM cross_repo_links
|
|
646
|
+
WHERE mission_id = ?
|
|
647
|
+
`,e)}catch{return[]}}findLastMission(){return this.get("SELECT * FROM missions ORDER BY updated_at DESC, id DESC LIMIT 1")}findActiveByPriority(){return this.get("SELECT * FROM missions WHERE status IN ('in-progress', 'active', 'verifying') ORDER BY CASE WHEN status = 'in-progress' THEN 0 ELSE 1 END, created_at ASC LIMIT 1")}addHandoff(e,t){let i=JSON.stringify(t),s=this.insert("INSERT INTO mission_artifacts (mission_id, type, identifier, metadata) VALUES (?, ?, ?, ?)",e,"handoff",t.kind,i),r=[`[handoff:${t.kind}]`,...t.findings.map(l=>l.statement),...t.risks.map(l=>l.description),...t.gaps].filter(Boolean).join(" ");return Promise.resolve().then(()=>(A(),x)).then(({generateEmbedding:l})=>l(r)).then(l=>{l&&this.run("UPDATE mission_artifacts SET embedding = ? WHERE id = ?",JSON.stringify(l),s)}).catch(()=>{}),s}getHandoffs(e,t,i=20){let s=["type = 'handoff'"],r=[];e!==void 0&&(e===null?s.push("mission_id IS NULL"):(s.push("mission_id = ?"),r.push(e))),t&&(s.push("identifier = ?"),r.push(t));let l=`SELECT * FROM mission_artifacts WHERE ${s.join(" AND ")} ORDER BY created_at DESC LIMIT ?`;return r.push(i),this.all(l,...r)}async findSemanticHandoffs(e,t){let{cosineSimilarity:i}=await Promise.resolve().then(()=>(A(),x)),s=["type = 'handoff'","embedding IS NOT NULL"],r=[];t?.missionId!==void 0&&(t.missionId===null?s.push("mission_id IS NULL"):(s.push("mission_id = ?"),r.push(t.missionId))),t?.kind&&(s.push("identifier = ?"),r.push(t.kind));let l=this.all(`SELECT * FROM mission_artifacts WHERE ${s.join(" AND ")}`,...r),c=[];for(let a of l)try{let o=JSON.parse(a.embedding),u=i(e,o);u>.3&&c.push({...a,similarity:u})}catch{}return c.sort((a,o)=>o.similarity-a.similarity).slice(0,t?.limit??5)}};var et=500,ae=class extends f{record(e,t,i=null){this.run("INSERT INTO search_history (query, mode, branch) VALUES (?, ?, ?)",e,t,i),this.pruneIfNeeded()}findRecent(e=20){return this.all("SELECT id, query, mode, branch, created_at FROM search_history ORDER BY created_at DESC LIMIT ?",e)}findRecentByQueryPrefix(e,t=10){return e.trim()?this.all(`SELECT id, query, mode, branch, created_at FROM search_history
|
|
554
648
|
WHERE query LIKE ? ORDER BY created_at DESC LIMIT ?`,`${e}%`,t):this.findRecent(t)}pruneIfNeeded(){(this.get("SELECT COUNT(*) as count FROM search_history")?.count??0)<=et||this.run(`DELETE FROM search_history WHERE id NOT IN (
|
|
555
649
|
SELECT id FROM search_history ORDER BY created_at DESC LIMIT ?
|
|
556
|
-
)`,et)}};var
|
|
557
|
-
INSERT INTO hologram_snapshot (section, data, updated_at)
|
|
558
|
-
VALUES (?, ?, unixepoch())
|
|
559
|
-
ON CONFLICT(section) DO UPDATE SET
|
|
560
|
-
data = excluded.data,
|
|
561
|
-
updated_at = excluded.updated_at
|
|
562
|
-
`,e,t)}deleteSection(e){this.run("DELETE FROM hologram_snapshot WHERE section = ?",e)}deleteAll(){this.run("DELETE FROM hologram_snapshot")}hasSection(e){return(this.get("SELECT COUNT(*) as count FROM hologram_snapshot WHERE section = ?",e)?.count??0)>0}};var ae=class extends f{claimFile(e,t){try{this.run(`
|
|
563
|
-
INSERT INTO file_claims (file_path, mission_id, claimed_at, updated_at)
|
|
564
|
-
VALUES (?, ?, unixepoch(), unixepoch())
|
|
565
|
-
`,e,t);let i=this.getClaim(e);if(!i)throw new Error(`Failed to hydrate claim after insert for file ${e}`);return{status:"claimed",claim:i}}catch{let i=this.getClaim(e);if(!i)throw new Error(`Failed to read existing claim for file ${e}`);return i.mission_id===t?(this.run("UPDATE file_claims SET updated_at = unixepoch() WHERE file_path = ?",e),{status:"already_claimed",claim:this.getClaim(e)??i}):{status:"conflict",claim:i}}}releaseFile(e,t){let i=this.getClaim(e);return i?t!==void 0&&i.mission_id!==t?{released:!1,reason:"not_owner",claim:i}:(this.run("DELETE FROM file_claims WHERE file_path = ?",e),{released:!0}):{released:!1,reason:"not_found"}}releaseAllForMission(e){return this.run("DELETE FROM file_claims WHERE mission_id = ?",e)}getClaim(e){return this.get(`
|
|
566
|
-
SELECT
|
|
567
|
-
fc.file_path,
|
|
568
|
-
fc.mission_id,
|
|
569
|
-
fc.claimed_at,
|
|
570
|
-
fc.updated_at,
|
|
571
|
-
m.name AS mission_name,
|
|
572
|
-
m.status AS mission_status,
|
|
573
|
-
m.git_branch AS mission_branch
|
|
574
|
-
FROM file_claims fc
|
|
575
|
-
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
576
|
-
WHERE fc.file_path = ?
|
|
577
|
-
`,e)}getClaimsForMission(e){return this.all(`
|
|
578
|
-
SELECT
|
|
579
|
-
fc.file_path,
|
|
580
|
-
fc.mission_id,
|
|
581
|
-
fc.claimed_at,
|
|
582
|
-
fc.updated_at,
|
|
583
|
-
m.name AS mission_name,
|
|
584
|
-
m.status AS mission_status,
|
|
585
|
-
m.git_branch AS mission_branch
|
|
586
|
-
FROM file_claims fc
|
|
587
|
-
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
588
|
-
WHERE fc.mission_id = ?
|
|
589
|
-
ORDER BY fc.file_path ASC
|
|
590
|
-
`,e)}listClaims(){return this.all(`
|
|
591
|
-
SELECT
|
|
592
|
-
fc.file_path,
|
|
593
|
-
fc.mission_id,
|
|
594
|
-
fc.claimed_at,
|
|
595
|
-
fc.updated_at,
|
|
596
|
-
m.name AS mission_name,
|
|
597
|
-
m.status AS mission_status,
|
|
598
|
-
m.git_branch AS mission_branch
|
|
599
|
-
FROM file_claims fc
|
|
600
|
-
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
601
|
-
ORDER BY fc.updated_at DESC, fc.file_path ASC
|
|
602
|
-
`)}getClaimsByFiles(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.all(`
|
|
603
|
-
SELECT
|
|
604
|
-
fc.file_path,
|
|
605
|
-
fc.mission_id,
|
|
606
|
-
fc.claimed_at,
|
|
607
|
-
fc.updated_at,
|
|
608
|
-
m.name AS mission_name,
|
|
609
|
-
m.status AS mission_status,
|
|
610
|
-
m.git_branch AS mission_branch
|
|
611
|
-
FROM file_claims fc
|
|
612
|
-
LEFT JOIN missions m ON m.id = fc.mission_id
|
|
613
|
-
WHERE fc.file_path IN (${t})
|
|
614
|
-
ORDER BY fc.file_path ASC
|
|
615
|
-
`,...e)}};var le=class{static repositoryCache=new Map;static getInstance(e){let t=this.repositoryCache.get(e);if(t){let r=H(e),l=t.files?.database,a=!t.intentLogs||!t.searchHistory||!t.missions||!t.hologram||!t.claims;if(l===r&&r.open&&!a)return t;this.repositoryCache.delete(e)}let i=H(e),s={files:new J(i),exports:new Q(i),imports:new X(i),missions:new te(i),intentLogs:new ie(i),configs:new ne(i),content:new se(i),searchHistory:new re(i),hologram:new oe(i),claims:new ae(i)};return this.repositoryCache.set(e,s),s}static closeInstance(e){this.repositoryCache.delete(e),ke(e)}static clearCache(e){this.repositoryCache.delete(e)}};var ai=Te.constants.priority.PRIORITY_LOWEST??Te.constants.priority.PRIORITY_LOW,li={visionary:3*6e4,architect:3*6e4,pragmatist:4*6e4,verdict:3*6e4},g=class extends Error{constructor(t,i){super(t);this.reason=i;this.name="TribunalStepError"}},me=process.argv[2],Re=process.argv[3],B=process.argv[4];(!me||!Re||!B)&&(process.stderr.write(`Tribunal: required args missing. Usage: node dist/entry/tribunal/index.js <repoPath> <missionId> <sessionId>
|
|
650
|
+
)`,et)}};var le=class n{static repositoryCache=new Map;static getInstance(e){let t=n.repositoryCache.get(e);if(t){let r=H(e),l=t.files?.database,a=!t.intentLogs||!t.searchHistory||!t.missions||!t.hologram||!t.claims;if(l===r&&r.open&&!a)return t;n.repositoryCache.delete(e)}let i=H(e),s={files:new ee(i),exports:new Z(i),imports:new ie(i),missions:new oe(i),intentLogs:new re(i),configs:new Q(i),content:new X(i),searchHistory:new ae(i),hologram:new te(i),claims:new J(i)};return n.repositoryCache.set(e,s),s}static closeInstance(e){n.repositoryCache.delete(e),ke(e)}static clearCache(e){n.repositoryCache.delete(e)}};var ai=Te.constants.priority.PRIORITY_LOWEST??Te.constants.priority.PRIORITY_LOW,li={visionary:3*6e4,architect:3*6e4,pragmatist:4*6e4,verdict:3*6e4},g=class extends Error{constructor(t,i){super(t);this.reason=i;this.name="TribunalStepError"}},me=process.argv[2],Re=process.argv[3],B=process.argv[4];(!me||!Re||!B)&&(process.stderr.write(`Tribunal: required args missing. Usage: node dist/entry/tribunal/index.js <repoPath> <missionId> <sessionId>
|
|
616
651
|
`),process.exit(1));var R=Number(Re);(!Number.isFinite(R)||R<=0)&&(process.stderr.write(`Tribunal: invalid missionId "${Re}"
|
|
617
|
-
`),process.exit(1));try{Te.setPriority(ai)}catch{}var st=H(me),{missions:
|
|
652
|
+
`),process.exit(1));try{Te.setPriority(ai)}catch{}var st=H(me),{missions:v}=le.getInstance(me),j=!1,T="initializing",I=[];function ci(){st.prepare(`INSERT OR REPLACE INTO tribunal_state (
|
|
618
653
|
session_id,
|
|
619
654
|
mission_id,
|
|
620
655
|
repo_path,
|
|
@@ -634,17 +669,17 @@ ORDER BY dc.depth, dc.consumer_path;
|
|
|
634
669
|
COALESCE((SELECT artifact_id FROM tribunal_state WHERE session_id = ?), NULL),
|
|
635
670
|
COALESCE((SELECT started_at FROM tribunal_state WHERE session_id = ?), unixepoch()),
|
|
636
671
|
NULL
|
|
637
|
-
)`).run(B,R,me,process.pid,B,B)}function
|
|
672
|
+
)`).run(B,R,me,process.pid,B,B)}function O(n){let e=[],t=[];n.status!==void 0&&(e.push("status = ?"),t.push(n.status)),n.phase!==void 0&&(e.push("phase = ?"),t.push(n.phase)),n.artifact_id!==void 0&&(e.push("artifact_id = ?"),t.push(n.artifact_id)),n.completed_at!==void 0&&(e.push("completed_at = ?"),t.push(n.completed_at)),n.pid!==void 0&&(e.push("pid = ?"),t.push(n.pid)),n.mission_id!==void 0&&(e.push("mission_id = ?"),t.push(n.mission_id)),n.repo_path!==void 0&&(e.push("repo_path = ?"),t.push(n.repo_path)),e.length!==0&&(t.push(B),st.prepare(`UPDATE tribunal_state SET ${e.join(", ")} WHERE session_id = ?`).run(...t))}function de(n){return Number.isFinite(n)?n<0?0:n>1?1:Number(n.toFixed(3)):.2}function Se(n,e=1200){let t=n.trim().replace(/\s+/g," ");return t.length<=e?t:`${t.slice(0,e-1)}\u2026`}function rt(n){let e=n.trim();if(!e)throw new g("Empty CLI output","json_parse_failed");try{return JSON.parse(e)}catch{let t=e.indexOf("{"),i=e.lastIndexOf("}");if(t>=0&&i>t)try{return JSON.parse(e.slice(t,i+1))}catch{throw new g("Failed to parse JSON output","json_parse_failed")}throw new g("Failed to parse JSON output","json_parse_failed")}}function ui(n){let e=rt(n),t=e.verdict;if(t!=="solid"&&t!=="needs_revision")throw new g("Invalid verdict value in JSON output","json_parse_failed");if(typeof e.summary!="string"||e.summary.trim().length===0)throw new g("Missing summary in JSON output","json_parse_failed");return{verdict:t,confidence:de(typeof e.confidence=="number"?e.confidence:.5),summary:Se(e.summary)}}function pe(n){switch(n){case"visionary":return"Visionary";case"architect":return"Architect";case"pragmatist":return"Pragmatist";case"verdict":return"Verdict";default:return"Initialization"}}function di(n){return n==="timed_out"?"timed out":n==="json_parse_failed"?"JSON parse failed":"non-zero exit"}var ye=JSON.stringify({type:"object",properties:{verdict:{type:"string",enum:["solid","needs_revision"]},confidence:{type:"number"},summary:{type:"string"}},required:["verdict","confidence","summary"]});function ot(n){let e=n==="visionary"?process.env.TRIBUNAL_VISIONARY_CMD:n==="architect"?process.env.TRIBUNAL_ARCHITECT_CMD:n==="pragmatist"?process.env.TRIBUNAL_PRAGMATIST_CMD:process.env.TRIBUNAL_VERDICT_CMD;return e?{command:e,kind:"raw"}:n==="visionary"?{command:`claude --print --model haiku --output-format json --json-schema '${ye}'`,kind:"claude"}:n==="architect"?{command:`claude --print --model sonnet --output-format json --json-schema '${ye}'`,kind:"claude"}:n==="pragmatist"?{command:"codex exec --ephemeral -m gpt-5.3-codex -",kind:"codex"}:{command:`claude --print --model sonnet --output-format json --json-schema '${ye}'`,kind:"claude"}}function mi(n){let e=rt(n);if(e.is_error===!0){let t=typeof e.result=="string"?e.result:"Claude API error";throw new g(Se(t),"non_zero_exit")}if(e.structured_output&&typeof e.structured_output=="object")return JSON.stringify(e.structured_output);if(typeof e.result=="string")return e.result;throw new g("Unexpected claude JSON envelope shape","json_parse_failed")}function pi(n){let e=n.split(`
|
|
638
673
|
`).filter(Boolean);for(let t=e.length-1;t>=0;t--)try{let i=JSON.parse(e[t]);if(i.type==="item.completed"){let s=i.item;if(s?.type==="agent_message"&&typeof s.text=="string")return s.text}}catch{}throw new g("No agent_message found in codex JSONL output","json_parse_failed")}function hi(n,e){return n==="claude"?mi(e):n==="codex"?pi(e):e}async function tt(n,e){let{command:t,kind:i}=ot(n),s=i==="codex"?`${t} --json`:t,r=oi(s,{shell:!0,stdio:["pipe","pipe","pipe"],env:process.env}),l="",c="",a=null,o=new Promise((d,m)=>{a=setTimeout(()=>{try{r.kill("SIGKILL")}catch{}m(new g(`Timeout in ${n} step`,"timed_out"))},li[n])}),u=new Promise((d,m)=>{r.stdout.on("data",b=>{l+=b.toString()}),r.stderr.on("data",b=>{c+=b.toString()}),r.on("error",()=>{m(new g(`Failed to start command: ${t}`,"non_zero_exit"))}),r.on("close",b=>{if(b!==0){let h=Se(c||l||`exit code ${b}`);m(new g(`${t} failed (${h})`,"non_zero_exit"));return}try{let h=hi(i,l);d(ui(h))}catch(h){if(h instanceof g){m(h);return}m(new g("Invalid JSON output","json_parse_failed"))}})});try{r.stdin.write(e),r.stdin.end()}catch{throw new g(`Failed to write prompt to ${t}`,"non_zero_exit")}try{return await Promise.race([u,o])}finally{a&&clearTimeout(a)}}async function ce(n,e){try{return await tt(n,e)}catch(t){if(t instanceof g&&t.reason==="json_parse_failed"){let i=`${e}
|
|
639
674
|
|
|
640
|
-
CRITICAL: Your previous response could not be parsed as JSON. Respond with ONLY a raw JSON object. The very first character of your response MUST be '{' and the last must be '}'. No markdown, no explanation, no code fences.`;return await tt(n,i)}throw t}}function fi(){let n=
|
|
675
|
+
CRITICAL: Your previous response could not be parsed as JSON. Respond with ONLY a raw JSON object. The very first character of your response MUST be '{' and the last must be '}'. No markdown, no explanation, no code fences.`;return await tt(n,i)}throw t}}function fi(){let n=v.findById(R);if(!n)return`Mission ${R} not found.`;let e=n.strategy_graph&&n.strategy_graph.trim().length>0?n.strategy_graph:'{"steps": []}',t=n.outcome_contract??"No explicit outcome contract provided.",i=n.verification_context&&n.verification_context.trim().length>0?n.verification_context:"None specified.",s=n.parent_id!=null?`Sub-mission of Mission ${n.parent_id}`:"Top-level mission",r="";try{let l=JSON.parse(e);Array.isArray(l.steps)&&l.steps.length>0&&(r=l.steps.map((c,a)=>{let o=c.dependencies?.length?` [depends: ${c.dependencies.join(", ")}]`:"";return` ${a+1}. [${c.id??"?"}] ${c.description??""}${o} (${c.status??"pending"})`}).join(`
|
|
641
676
|
`))}catch{}return[`Mission ID: ${n.id}`,`Name: ${n.name}`,`Status: ${n.status}`,`Hierarchy: ${s}`,"",`GOAL: ${n.goal}`,"","OUTCOME CONTRACT (success criteria the author defined):",t,"","VERIFICATION CONTEXT (test harness / acceptance conditions):",i,"","STRATEGY STEPS:",r||e].join(`
|
|
642
677
|
`)}function ue(n,e,t,i){let s={visionary:["You are the Visionary on a Tribunal review board. Your job is the hardest and most valuable: you decide whether this mission is worth doing at all.","","You are NOT here to rubber-stamp well-written plans. You are here to catch missions that are solving the wrong problem, chasing phantom requirements, or missing the actual user need.","","Ask yourself:"," - What problem does this mission actually solve? Is that problem real and documented, or assumed?"," - Does the outcome contract measure whether the problem is *solved*, or just whether code was written?"," - Would a knowledgeable engineer, handed only the goal and outcome contract, agree this is the right thing to build?"," - What is the cost of being wrong here \u2014 if the mission is misaimed, how much work gets thrown away?","",'Issue "solid" only if you are confident the mission is solving a real, well-understood problem with appropriate scope.','Issue "needs_revision" if the goal is vague, the outcome contract is implementation-focused instead of outcome-focused, the scope is disproportionate to the problem, or the real need is unclear.','In your summary: name the specific gap and give a concrete fix ("Add X to outcome contract", "Narrow scope to Y", "Validate assumption Z before proceeding").'],architect:["You are the Architect on a Tribunal review board. Your job is to stress-test the implementation plan's structure.","","You are NOT evaluating whether the mission is worth doing (that is the Visionary's job). You are evaluating whether the plan, as written, will actually produce the stated outcome.","","Examine:"," - Dependency ordering: do steps depend on artifacts that earlier steps do not produce?"," - Missing steps: is there work implied by the outcome contract that no step in the strategy covers?"," - Coupling risk: are two steps that should be co-designed sequenced as independent tracks?"," - Reversibility: does the plan have checkpoints, or is it a single long sequence that fails atomically?"," - Backward compatibility: does any step break existing callers without a migration path?","",'Issue "solid" if the dependency graph is sound and the steps collectively produce the stated outcome.','Issue "needs_revision" if you find a structural gap \u2014 but be specific: name the step, name the gap, name the fix.',"Do not penalize good work for hypothetical future problems. Only flag gaps that will actually cause this mission to fail."],pragmatist:["You are the Pragmatist on a Tribunal review board. Your job is adversarial: find the ways this mission will fail in the real world.","","You are NOT here to agree with the other reviewers or to validate the plan. You are the last line of defense before execution.","","Think like an engineer who has been burned before:"," - What external dependencies (APIs, CLIs, DBs, file systems) can fail, rate-limit, or behave inconsistently?"," - What concurrency or race conditions exist between components?"," - What happens on partial failure \u2014 does the system leave behind corrupt state?"," - What contracts are underspecified \u2014 where will an implementer make an assumption that turns out to be wrong?"," - What does the outcome contract NOT test that could still go wrong silently?","",'Issue "solid" only if the execution risks are manageable and the plan has sufficient guardrails.','Issue "needs_revision" if there are concrete, unmitigated failure modes \u2014 name each one and state what contract or guardrail would address it.','Vague concerns ("this might be slow") are not findings. Concrete risks ("the DB write at step 3 is not idempotent so a retry on failure duplicates the artifact") are findings.'],verdict:["You are the Verdict on a Tribunal review board. Your job is synthesis and final authority.","","You have three prior reviews. Your job is NOT to average them. It is to reason about which concerns are blocking and which are advisory, and to issue a single authoritative verdict the mission owner can act on.","","How to reason:",' - A "needs_revision" from Visionary outweighs the others if the mission goal is unclear \u2014 there is no point fixing the plan if the goal is wrong.',' - A "needs_revision" from Architect is blocking if a missing step means the outcome contract cannot be met as written.',' - A "needs_revision" from Pragmatist is blocking if the failure mode is concrete and unmitigated \u2014 not just "could be risky".',' - If two reviewers say "solid" and one says "needs_revision" with a specific, fixable gap, the verdict can be "solid" if you judge the gap is addressable during execution rather than before.',' - If all three say "needs_revision", issue "needs_revision" with a prioritized list: what must be fixed first, and why.',"","Your summary must be actionable: the mission owner should be able to read your summary and know exactly what to do next.","Do not repeat the reviewers' findings \u2014 synthesize them. Resolve conflicts explicitly."]},r=["## Output Format","Respond with ONLY a raw JSON object. No markdown, no preamble, no explanation.",'{"verdict":"solid|needs_revision","confidence":0.0\u20131.0,"summary":"..."}',"",'verdict: "solid" = ready to execute. "needs_revision" = specific gaps must be addressed first.',"confidence: your certainty. 0.9+ means you are certain. 0.5 means genuinely uncertain. Never default to 0.5 \u2014 commit to a position.","summary: max 4 sentences. If needs_revision: name each gap, name the concrete fix. If solid: state why the plan is trustworthy."],l=[...s[n],"",...r,"","## Mission Under Review",e];return i.trim().length>0&&l.push("","## Round Context",i),t.trim().length>0?l.push("","## Prior Reviewer Findings",t):l.push("","## Prior Reviewer Findings","None \u2014 you are the first reviewer this round."),l.join(`
|
|
643
|
-
`)}function Le(){return
|
|
644
|
-
`):"";T="visionary",
|
|
645
|
-
`),i));
|
|
646
|
-
NOTE: Reviewers split \u2014 (${c.join(", ")}). Your job is to decide which "needs_revision" concerns are hard blockers vs. execution-time concerns, and issue the final call.`:"";T="verdict",
|
|
647
|
-
`),i));return
|
|
648
|
-
${l}`;
|
|
678
|
+
`)}function Le(){return I.map(({phase:n,review:e})=>({statement:`${pe(n)}: ${e.summary}`,confidence:de(e.confidence),refs:{traces:[n]}}))}function gi(){return I.filter(({review:n})=>n.verdict==="needs_revision").map(({phase:n,review:e})=>({severity:"medium",description:`${pe(n)}: ${e.summary}`,refs:{symbols:[n]}}))}function it(n,e){if(j)return;j=!0;let t=`${pe(e)} ${di(n.reason)}`,i={kind:"risk_assessment",findings:Le(),risks:[],missionsCreated:[],gaps:[t],confidence:.2,agentTag:"tribunal-daemon",verdict:"needs_revision",summary:t},s=Number(v.addHandoff(R,i));O({status:"failed",phase:e,artifact_id:Number.isFinite(s)?s:null,completed_at:Math.floor(Date.now()/1e3)}),process.exit(0)}function at(n){if(j)return;j=!0;let e=`${n} received during ${pe(T)} phase`,t={kind:"risk_assessment",findings:Le(),risks:[],missionsCreated:[],gaps:[e],confidence:.2,agentTag:"tribunal-daemon",verdict:"needs_revision",summary:e},i=Number(v.addHandoff(R,t));O({status:"failed",phase:T,artifact_id:Number.isFinite(i)?i:null,completed_at:Math.floor(Date.now()/1e3)}),process.exit(0)}var nt=3;async function Ei(n,e,t){let i=t>1?[`This is round ${t} of review. The prior round identified these unresolved gaps:`,`"${e}"`,"","Your job this round:"," 1. For each gap above \u2014 is it a hard blocker (must be fixed before execution) or an execution-time concern (can be addressed during implementation)?",' 2. If ALL remaining gaps are execution-time concerns, issue "solid" with a note about what to watch.',' 3. If ANY gap is a hard blocker, issue "needs_revision" \u2014 but propose the concrete fix, not just the problem.'," 4. Do NOT introduce new concerns unless they are directly caused by an unresolved prior gap.","The goal is resolution, not iteration."].join(`
|
|
679
|
+
`):"";T="visionary",O({status:"running",phase:T});let s=await ce("visionary",ue("visionary",n,"",i));I.push({phase:"visionary",review:s}),T="architect",O({status:"running",phase:T});let r=await ce("architect",ue("architect",n,`Visionary (${s.verdict}, ${s.confidence}): ${s.summary}`,i));I.push({phase:"architect",review:r}),T="pragmatist",O({status:"running",phase:T});let l=await ce("pragmatist",ue("pragmatist",n,[`Visionary (${s.verdict}, ${s.confidence}): ${s.summary}`,`Architect (${r.verdict}, ${r.confidence}): ${r.summary}`].join(`
|
|
680
|
+
`),i));I.push({phase:"pragmatist",review:l});let c=[s.verdict,r.verdict,l.verdict],a=new Set(c).size>1?`
|
|
681
|
+
NOTE: Reviewers split \u2014 (${c.join(", ")}). Your job is to decide which "needs_revision" concerns are hard blockers vs. execution-time concerns, and issue the final call.`:"";T="verdict",O({status:"running",phase:T});let o=await ce("verdict",ue("verdict",n,[`Visionary (${s.verdict}, ${s.confidence}): ${s.summary}`,`Architect (${r.verdict}, ${r.confidence}): ${r.summary}`,`Pragmatist (${l.verdict}, ${l.confidence}): ${l.summary}`,a].filter(Boolean).join(`
|
|
682
|
+
`),i));return I.push({phase:"verdict",review:o}),o}async function _i(){ci();let n=fi(),t=`tribunal/${["visionary","architect","pragmatist","verdict"].map(u=>ot(u).kind).join("/")}`,i=null,s="";for(let u=1;u<=nt&&(O({status:"running",phase:"visionary",pid:process.pid}),i=await Ei(n,s,u),i.verdict!=="solid");u++)s=i.summary;let r=i.verdict,l=i.verdict==="needs_revision"?`Needs revision after ${nt} rounds. ${i.summary}`:i.summary,c=de(I.reduce((u,{review:d})=>u+d.confidence,0)/I.length)*(.7+.3*i.confidence),a={kind:"risk_assessment",findings:Le(),risks:gi(),missionsCreated:[],gaps:r==="needs_revision"?[l]:[],confidence:de(c),agentTag:t,verdict:r,summary:l},o=Number(v.addHandoff(R,a));if(r==="needs_revision"){let d=v.findById(R)?.verification_context?.trim()??"",m=`[Tribunal needs_revision]
|
|
683
|
+
${l}`;v.update(R,{verification_context:d.length>0?`${d}
|
|
649
684
|
|
|
650
|
-
${m}`:m,status:"needs_revision"})}else
|
|
685
|
+
${m}`:m,status:"needs_revision"})}else v.updateStatus(R,"planned");O({status:"completed",phase:"verdict",artifact_id:Number.isFinite(o)?o:null,completed_at:Math.floor(Date.now()/1e3)}),j=!0,process.exit(0)}process.prependListener("SIGTERM",()=>{at("SIGTERM")});process.prependListener("SIGINT",()=>{at("SIGINT")});_i().catch(n=>{if(n instanceof g){it(n,T);return}let e=new g(n instanceof Error?n.message:String(n),"non_zero_exit");it(e,T)});
|